tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cffload.c (75240B)


      1 /****************************************************************************
      2 *
      3 * cffload.c
      4 *
      5 *   OpenType and CFF data/program tables loader (body).
      6 *
      7 * Copyright (C) 1996-2025 by
      8 * David Turner, Robert Wilhelm, and Werner Lemberg.
      9 *
     10 * This file is part of the FreeType project, and may only be used,
     11 * modified, and distributed under the terms of the FreeType project
     12 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     13 * this file you indicate that you have read the license and
     14 * understand and accept it fully.
     15 *
     16 */
     17 
     18 
     19 #include <freetype/internal/ftdebug.h>
     20 #include <freetype/internal/ftobjs.h>
     21 #include <freetype/internal/ftstream.h>
     22 #include <freetype/tttags.h>
     23 #include <freetype/t1tables.h>
     24 #include <freetype/internal/psaux.h>
     25 
     26 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     27 #include <freetype/ftmm.h>
     28 #include <freetype/internal/services/svmm.h>
     29 #endif
     30 
     31 #include "cffload.h"
     32 #include "cffparse.h"
     33 
     34 #include "cfferrs.h"
     35 
     36 
     37 #define FT_FIXED_ONE  ( (FT_Fixed)0x10000 )
     38 
     39 
     40 #if 1
     41 
     42  static const FT_UShort  cff_isoadobe_charset[229] =
     43  {
     44      0,   1,   2,   3,   4,   5,   6,   7,
     45      8,   9,  10,  11,  12,  13,  14,  15,
     46     16,  17,  18,  19,  20,  21,  22,  23,
     47     24,  25,  26,  27,  28,  29,  30,  31,
     48     32,  33,  34,  35,  36,  37,  38,  39,
     49     40,  41,  42,  43,  44,  45,  46,  47,
     50     48,  49,  50,  51,  52,  53,  54,  55,
     51     56,  57,  58,  59,  60,  61,  62,  63,
     52     64,  65,  66,  67,  68,  69,  70,  71,
     53     72,  73,  74,  75,  76,  77,  78,  79,
     54     80,  81,  82,  83,  84,  85,  86,  87,
     55     88,  89,  90,  91,  92,  93,  94,  95,
     56     96,  97,  98,  99, 100, 101, 102, 103,
     57    104, 105, 106, 107, 108, 109, 110, 111,
     58    112, 113, 114, 115, 116, 117, 118, 119,
     59    120, 121, 122, 123, 124, 125, 126, 127,
     60    128, 129, 130, 131, 132, 133, 134, 135,
     61    136, 137, 138, 139, 140, 141, 142, 143,
     62    144, 145, 146, 147, 148, 149, 150, 151,
     63    152, 153, 154, 155, 156, 157, 158, 159,
     64    160, 161, 162, 163, 164, 165, 166, 167,
     65    168, 169, 170, 171, 172, 173, 174, 175,
     66    176, 177, 178, 179, 180, 181, 182, 183,
     67    184, 185, 186, 187, 188, 189, 190, 191,
     68    192, 193, 194, 195, 196, 197, 198, 199,
     69    200, 201, 202, 203, 204, 205, 206, 207,
     70    208, 209, 210, 211, 212, 213, 214, 215,
     71    216, 217, 218, 219, 220, 221, 222, 223,
     72    224, 225, 226, 227, 228
     73  };
     74 
     75  static const FT_UShort  cff_expert_charset[166] =
     76  {
     77      0,   1, 229, 230, 231, 232, 233, 234,
     78    235, 236, 237, 238,  13,  14,  15,  99,
     79    239, 240, 241, 242, 243, 244, 245, 246,
     80    247, 248,  27,  28, 249, 250, 251, 252,
     81    253, 254, 255, 256, 257, 258, 259, 260,
     82    261, 262, 263, 264, 265, 266, 109, 110,
     83    267, 268, 269, 270, 271, 272, 273, 274,
     84    275, 276, 277, 278, 279, 280, 281, 282,
     85    283, 284, 285, 286, 287, 288, 289, 290,
     86    291, 292, 293, 294, 295, 296, 297, 298,
     87    299, 300, 301, 302, 303, 304, 305, 306,
     88    307, 308, 309, 310, 311, 312, 313, 314,
     89    315, 316, 317, 318, 158, 155, 163, 319,
     90    320, 321, 322, 323, 324, 325, 326, 150,
     91    164, 169, 327, 328, 329, 330, 331, 332,
     92    333, 334, 335, 336, 337, 338, 339, 340,
     93    341, 342, 343, 344, 345, 346, 347, 348,
     94    349, 350, 351, 352, 353, 354, 355, 356,
     95    357, 358, 359, 360, 361, 362, 363, 364,
     96    365, 366, 367, 368, 369, 370, 371, 372,
     97    373, 374, 375, 376, 377, 378
     98  };
     99 
    100  static const FT_UShort  cff_expertsubset_charset[87] =
    101  {
    102      0,   1, 231, 232, 235, 236, 237, 238,
    103     13,  14,  15,  99, 239, 240, 241, 242,
    104    243, 244, 245, 246, 247, 248,  27,  28,
    105    249, 250, 251, 253, 254, 255, 256, 257,
    106    258, 259, 260, 261, 262, 263, 264, 265,
    107    266, 109, 110, 267, 268, 269, 270, 272,
    108    300, 301, 302, 305, 314, 315, 158, 155,
    109    163, 320, 321, 322, 323, 324, 325, 326,
    110    150, 164, 169, 327, 328, 329, 330, 331,
    111    332, 333, 334, 335, 336, 337, 338, 339,
    112    340, 341, 342, 343, 344, 345, 346
    113  };
    114 
    115  static const FT_UShort  cff_standard_encoding[256] =
    116  {
    117      0,   0,   0,   0,   0,   0,   0,   0,
    118      0,   0,   0,   0,   0,   0,   0,   0,
    119      0,   0,   0,   0,   0,   0,   0,   0,
    120      0,   0,   0,   0,   0,   0,   0,   0,
    121      1,   2,   3,   4,   5,   6,   7,   8,
    122      9,  10,  11,  12,  13,  14,  15,  16,
    123     17,  18,  19,  20,  21,  22,  23,  24,
    124     25,  26,  27,  28,  29,  30,  31,  32,
    125     33,  34,  35,  36,  37,  38,  39,  40,
    126     41,  42,  43,  44,  45,  46,  47,  48,
    127     49,  50,  51,  52,  53,  54,  55,  56,
    128     57,  58,  59,  60,  61,  62,  63,  64,
    129     65,  66,  67,  68,  69,  70,  71,  72,
    130     73,  74,  75,  76,  77,  78,  79,  80,
    131     81,  82,  83,  84,  85,  86,  87,  88,
    132     89,  90,  91,  92,  93,  94,  95,   0,
    133      0,   0,   0,   0,   0,   0,   0,   0,
    134      0,   0,   0,   0,   0,   0,   0,   0,
    135      0,   0,   0,   0,   0,   0,   0,   0,
    136      0,   0,   0,   0,   0,   0,   0,   0,
    137      0,  96,  97,  98,  99, 100, 101, 102,
    138    103, 104, 105, 106, 107, 108, 109, 110,
    139      0, 111, 112, 113, 114,   0, 115, 116,
    140    117, 118, 119, 120, 121, 122,   0, 123,
    141      0, 124, 125, 126, 127, 128, 129, 130,
    142    131,   0, 132, 133,   0, 134, 135, 136,
    143    137,   0,   0,   0,   0,   0,   0,   0,
    144      0,   0,   0,   0,   0,   0,   0,   0,
    145      0, 138,   0, 139,   0,   0,   0,   0,
    146    140, 141, 142, 143,   0,   0,   0,   0,
    147      0, 144,   0,   0,   0, 145,   0,   0,
    148    146, 147, 148, 149,   0,   0,   0,   0
    149  };
    150 
    151  static const FT_UShort  cff_expert_encoding[256] =
    152  {
    153      0,   0,   0,   0,   0,   0,   0,   0,
    154      0,   0,   0,   0,   0,   0,   0,   0,
    155      0,   0,   0,   0,   0,   0,   0,   0,
    156      0,   0,   0,   0,   0,   0,   0,   0,
    157      1, 229, 230,   0, 231, 232, 233, 234,
    158    235, 236, 237, 238,  13,  14,  15,  99,
    159    239, 240, 241, 242, 243, 244, 245, 246,
    160    247, 248,  27,  28, 249, 250, 251, 252,
    161      0, 253, 254, 255, 256, 257,   0,   0,
    162      0, 258,   0,   0, 259, 260, 261, 262,
    163      0,   0, 263, 264, 265,   0, 266, 109,
    164    110, 267, 268, 269,   0, 270, 271, 272,
    165    273, 274, 275, 276, 277, 278, 279, 280,
    166    281, 282, 283, 284, 285, 286, 287, 288,
    167    289, 290, 291, 292, 293, 294, 295, 296,
    168    297, 298, 299, 300, 301, 302, 303,   0,
    169      0,   0,   0,   0,   0,   0,   0,   0,
    170      0,   0,   0,   0,   0,   0,   0,   0,
    171      0,   0,   0,   0,   0,   0,   0,   0,
    172      0,   0,   0,   0,   0,   0,   0,   0,
    173      0, 304, 305, 306,   0,   0, 307, 308,
    174    309, 310, 311,   0, 312,   0,   0, 312,
    175      0,   0, 314, 315,   0,   0, 316, 317,
    176    318,   0,   0,   0, 158, 155, 163, 319,
    177    320, 321, 322, 323, 324, 325,   0,   0,
    178    326, 150, 164, 169, 327, 328, 329, 330,
    179    331, 332, 333, 334, 335, 336, 337, 338,
    180    339, 340, 341, 342, 343, 344, 345, 346,
    181    347, 348, 349, 350, 351, 352, 353, 354,
    182    355, 356, 357, 358, 359, 360, 361, 362,
    183    363, 364, 365, 366, 367, 368, 369, 370,
    184    371, 372, 373, 374, 375, 376, 377, 378
    185  };
    186 
    187 #endif /* 1 */
    188 
    189 
    190  FT_LOCAL_DEF( FT_UShort )
    191  cff_get_standard_encoding( FT_UInt  charcode )
    192  {
    193    return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
    194                                       : 0 );
    195  }
    196 
    197 
    198  /**************************************************************************
    199   *
    200   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
    201   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
    202   * messages during execution.
    203   */
    204 #undef  FT_COMPONENT
    205 #define FT_COMPONENT  cffload
    206 
    207 
    208  /* read an offset from the index's stream current position */
    209  static FT_ULong
    210  cff_index_read_offset( CFF_Index  idx,
    211                         FT_Error  *errorp )
    212  {
    213    FT_Error   error;
    214    FT_Stream  stream = idx->stream;
    215    FT_Byte    tmp[4];
    216    FT_ULong   result = 0;
    217 
    218 
    219    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
    220    {
    221      FT_Int  nn;
    222 
    223 
    224      for ( nn = 0; nn < idx->off_size; nn++ )
    225        result = ( result << 8 ) | tmp[nn];
    226    }
    227 
    228    *errorp = error;
    229    return result;
    230  }
    231 
    232 
    233  static FT_Error
    234  cff_index_init( CFF_Index  idx,
    235                  FT_Stream  stream,
    236                  FT_Bool    load,
    237                  FT_Bool    cff2 )
    238  {
    239    FT_Error   error;
    240    FT_Memory  memory = stream->memory;
    241    FT_UInt    count;
    242 
    243 
    244    FT_ZERO( idx );
    245 
    246    idx->stream = stream;
    247    idx->start  = FT_STREAM_POS();
    248 
    249    if ( cff2 )
    250    {
    251      if ( FT_READ_ULONG( count ) )
    252        goto Exit;
    253      idx->hdr_size = 5;
    254    }
    255    else
    256    {
    257      if ( FT_READ_USHORT( count ) )
    258        goto Exit;
    259      idx->hdr_size = 3;
    260    }
    261 
    262    if ( count > 0 )
    263    {
    264      FT_Byte   offsize;
    265      FT_ULong  size;
    266 
    267 
    268      /* there is at least one element; read the offset size,           */
    269      /* then access the offset table to compute the index's total size */
    270      if ( FT_READ_BYTE( offsize ) )
    271        goto Exit;
    272 
    273      if ( offsize < 1 || offsize > 4 )
    274      {
    275        error = FT_THROW( Invalid_Table );
    276        goto Exit;
    277      }
    278 
    279      idx->count    = count;
    280      idx->off_size = offsize;
    281      size          = (FT_ULong)( count + 1 ) * offsize;
    282 
    283      idx->data_offset = idx->start + idx->hdr_size + size;
    284 
    285      if ( FT_STREAM_SKIP( size - offsize ) )
    286        goto Exit;
    287 
    288      size = cff_index_read_offset( idx, &error );
    289      if ( error )
    290        goto Exit;
    291 
    292      if ( size == 0 )
    293      {
    294        error = FT_THROW( Invalid_Table );
    295        goto Exit;
    296      }
    297 
    298      idx->data_size = --size;
    299 
    300      if ( load )
    301      {
    302        /* load the data */
    303        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
    304          goto Exit;
    305      }
    306      else
    307      {
    308        /* skip the data */
    309        if ( FT_STREAM_SKIP( size ) )
    310          goto Exit;
    311      }
    312    }
    313 
    314  Exit:
    315    if ( error )
    316      FT_FREE( idx->offsets );
    317 
    318    return error;
    319  }
    320 
    321 
    322  static void
    323  cff_index_done( CFF_Index  idx )
    324  {
    325    if ( idx->stream )
    326    {
    327      FT_Stream  stream = idx->stream;
    328      FT_Memory  memory = stream->memory;
    329 
    330 
    331      if ( idx->bytes )
    332        FT_FRAME_RELEASE( idx->bytes );
    333 
    334      FT_FREE( idx->offsets );
    335      FT_ZERO( idx );
    336    }
    337  }
    338 
    339 
    340  static FT_Error
    341  cff_index_load_offsets( CFF_Index  idx )
    342  {
    343    FT_Error   error  = FT_Err_Ok;
    344    FT_Stream  stream = idx->stream;
    345    FT_Memory  memory = stream->memory;
    346 
    347 
    348    if ( idx->count > 0 && !idx->offsets )
    349    {
    350      FT_Byte    offsize = idx->off_size;
    351      FT_ULong   data_size;
    352      FT_Byte*   p;
    353      FT_Byte*   p_end;
    354      FT_ULong*  poff;
    355 
    356 
    357      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
    358 
    359      if ( FT_QNEW_ARRAY( idx->offsets, idx->count + 1 ) ||
    360           FT_STREAM_SEEK( idx->start + idx->hdr_size )  ||
    361           FT_FRAME_ENTER( data_size )                   )
    362        goto Exit;
    363 
    364      poff   = idx->offsets;
    365      p      = (FT_Byte*)stream->cursor;
    366      p_end  = p + data_size;
    367 
    368      switch ( offsize )
    369      {
    370      case 1:
    371        for ( ; p < p_end; p++, poff++ )
    372          poff[0] = p[0];
    373        break;
    374 
    375      case 2:
    376        for ( ; p < p_end; p += 2, poff++ )
    377          poff[0] = FT_PEEK_USHORT( p );
    378        break;
    379 
    380      case 3:
    381        for ( ; p < p_end; p += 3, poff++ )
    382          poff[0] = FT_PEEK_UOFF3( p );
    383        break;
    384 
    385      default:
    386        for ( ; p < p_end; p += 4, poff++ )
    387          poff[0] = FT_PEEK_ULONG( p );
    388      }
    389 
    390      FT_FRAME_EXIT();
    391    }
    392 
    393  Exit:
    394    if ( error )
    395      FT_FREE( idx->offsets );
    396 
    397    return error;
    398  }
    399 
    400 
    401  /* Allocate a table containing pointers to an index's elements. */
    402  /* The `pool' argument makes this function convert the index    */
    403  /* entries to C-style strings (that is, null-terminated).       */
    404  static FT_Error
    405  cff_index_get_pointers( CFF_Index   idx,
    406                          FT_Byte***  table,
    407                          FT_Byte**   pool,
    408                          FT_ULong*   pool_size )
    409  {
    410    FT_Error   error     = FT_Err_Ok;
    411    FT_Memory  memory    = idx->stream->memory;
    412 
    413    FT_Byte**  tbl       = NULL;
    414    FT_Byte*   new_bytes = NULL;
    415    FT_ULong   new_size;
    416 
    417 
    418    *table = NULL;
    419 
    420    if ( !idx->offsets )
    421    {
    422      error = cff_index_load_offsets( idx );
    423      if ( error )
    424        goto Exit;
    425    }
    426 
    427    new_size = idx->data_size + idx->count;
    428 
    429    if ( idx->count > 0                                &&
    430         !FT_QNEW_ARRAY( tbl, idx->count + 1 )         &&
    431         ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
    432    {
    433      FT_ULong  n, cur_offset;
    434      FT_ULong  extra     = 0;
    435      FT_Byte*  org_bytes = idx->bytes;
    436 
    437 
    438      /* at this point, `idx->offsets' can't be NULL */
    439      cur_offset = idx->offsets[0] - 1;
    440 
    441      /* sanity check */
    442      if ( cur_offset != 0 )
    443      {
    444        FT_TRACE0(( "cff_index_get_pointers:"
    445                    " invalid first offset value %lu set to zero\n",
    446                    cur_offset ));
    447        cur_offset = 0;
    448      }
    449 
    450      if ( !pool )
    451        tbl[0] = org_bytes + cur_offset;
    452      else
    453        tbl[0] = new_bytes + cur_offset;
    454 
    455      for ( n = 1; n <= idx->count; n++ )
    456      {
    457        FT_ULong  next_offset = idx->offsets[n] - 1;
    458 
    459 
    460        /* two sanity checks for invalid offset tables */
    461        if ( next_offset < cur_offset )
    462          next_offset = cur_offset;
    463        else if ( next_offset > idx->data_size )
    464          next_offset = idx->data_size;
    465 
    466        if ( !pool )
    467          tbl[n] = org_bytes + next_offset;
    468        else
    469        {
    470          tbl[n] = new_bytes + next_offset + extra;
    471 
    472          if ( next_offset != cur_offset )
    473          {
    474            FT_MEM_COPY( tbl[n - 1],
    475                         org_bytes + cur_offset,
    476                         tbl[n] - tbl[n - 1] );
    477            tbl[n][0] = '\0';
    478            tbl[n]   += 1;
    479            extra++;
    480          }
    481        }
    482 
    483        cur_offset = next_offset;
    484      }
    485      *table = tbl;
    486 
    487      if ( pool )
    488        *pool = new_bytes;
    489      if ( pool_size )
    490        *pool_size = new_size;
    491    }
    492 
    493  Exit:
    494    if ( error && new_bytes )
    495      FT_FREE( new_bytes );
    496    if ( error && tbl )
    497      FT_FREE( tbl );
    498 
    499    return error;
    500  }
    501 
    502 
    503  FT_LOCAL_DEF( FT_Error )
    504  cff_index_access_element( CFF_Index  idx,
    505                            FT_UInt    element,
    506                            FT_Byte**  pbytes,
    507                            FT_ULong*  pbyte_len )
    508  {
    509    FT_Error  error = FT_Err_Ok;
    510 
    511 
    512    if ( idx && idx->count > element )
    513    {
    514      /* compute start and end offsets */
    515      FT_Stream  stream = idx->stream;
    516      FT_ULong   off1, off2 = 0;
    517 
    518 
    519      /* load offsets from file or the offset table */
    520      if ( !idx->offsets )
    521      {
    522        FT_ULong  pos = element * idx->off_size;
    523 
    524 
    525        if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
    526          goto Exit;
    527 
    528        off1 = cff_index_read_offset( idx, &error );
    529        if ( error )
    530          goto Exit;
    531 
    532        if ( off1 != 0 )
    533        {
    534          do
    535          {
    536            element++;
    537            off2 = cff_index_read_offset( idx, &error );
    538 
    539          } while ( off2 == 0 && element < idx->count );
    540        }
    541      }
    542      else   /* use offsets table */
    543      {
    544        off1 = idx->offsets[element];
    545        if ( off1 )
    546        {
    547          do
    548          {
    549            element++;
    550            off2 = idx->offsets[element];
    551 
    552          } while ( off2 == 0 && element < idx->count );
    553        }
    554      }
    555 
    556      /* XXX: should check off2 does not exceed the end of this entry; */
    557      /*      at present, only truncate off2 at the end of this stream */
    558      if ( off2 > stream->size + 1                    ||
    559           idx->data_offset > stream->size - off2 + 1 )
    560      {
    561        FT_ERROR(( "cff_index_access_element:"
    562                   " offset to next entry (%lu)"
    563                   " exceeds the end of stream (%lu)\n",
    564                   off2, stream->size - idx->data_offset + 1 ));
    565        off2 = stream->size - idx->data_offset + 1;
    566      }
    567 
    568      /* access element */
    569      if ( off1 && off2 > off1 )
    570      {
    571        *pbyte_len = off2 - off1;
    572 
    573        if ( idx->bytes )
    574        {
    575          /* this index was completely loaded in memory, that's easy */
    576          *pbytes = idx->bytes + off1 - 1;
    577        }
    578        else
    579        {
    580          /* this index is still on disk/file, access it through a frame */
    581          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
    582               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
    583            goto Exit;
    584        }
    585      }
    586      else
    587      {
    588        /* empty index element */
    589        *pbytes    = 0;
    590        *pbyte_len = 0;
    591      }
    592    }
    593    else
    594      error = FT_THROW( Invalid_Argument );
    595 
    596  Exit:
    597    return error;
    598  }
    599 
    600 
    601  FT_LOCAL_DEF( void )
    602  cff_index_forget_element( CFF_Index  idx,
    603                            FT_Byte**  pbytes )
    604  {
    605    if ( idx->bytes == 0 )
    606    {
    607      FT_Stream  stream = idx->stream;
    608 
    609 
    610      FT_FRAME_RELEASE( *pbytes );
    611    }
    612  }
    613 
    614 
    615  /* get an entry from Name INDEX */
    616  FT_LOCAL_DEF( FT_String* )
    617  cff_index_get_name( CFF_Font  font,
    618                      FT_UInt   element )
    619  {
    620    CFF_Index   idx = &font->name_index;
    621    FT_Memory   memory;
    622    FT_Byte*    bytes;
    623    FT_ULong    byte_len;
    624    FT_Error    error;
    625    FT_String*  name = NULL;
    626 
    627 
    628    if ( !idx->stream )  /* CFF2 does not include a name index */
    629      goto Exit;
    630 
    631    memory = idx->stream->memory;
    632 
    633    error = cff_index_access_element( idx, element, &bytes, &byte_len );
    634    if ( error )
    635      goto Exit;
    636 
    637    if ( !FT_QALLOC( name, byte_len + 1 ) )
    638    {
    639      FT_MEM_COPY( name, bytes, byte_len );
    640      name[byte_len] = 0;
    641    }
    642    cff_index_forget_element( idx, &bytes );
    643 
    644  Exit:
    645    return name;
    646  }
    647 
    648 
    649  /* get an entry from String INDEX */
    650  FT_LOCAL_DEF( FT_String* )
    651  cff_index_get_string( CFF_Font  font,
    652                        FT_UInt   element )
    653  {
    654    return ( element < font->num_strings )
    655             ? (FT_String*)font->strings[element]
    656             : NULL;
    657  }
    658 
    659 
    660  FT_LOCAL_DEF( FT_String* )
    661  cff_index_get_sid_string( CFF_Font  font,
    662                            FT_UInt   sid )
    663  {
    664    /* value 0xFFFFU indicates a missing dictionary entry */
    665    if ( sid == 0xFFFFU )
    666      return NULL;
    667 
    668    /* if it is not a standard string, return it */
    669    if ( sid > 390 )
    670      return cff_index_get_string( font, sid - 391 );
    671 
    672    /* CID-keyed CFF fonts don't have glyph names */
    673    if ( !font->psnames )
    674      return NULL;
    675 
    676    /* this is a standard string */
    677    return (FT_String *)font->psnames->adobe_std_strings( sid );
    678  }
    679 
    680 
    681  /*************************************************************************/
    682  /*************************************************************************/
    683  /***                                                                   ***/
    684  /***   FD Select table support                                         ***/
    685  /***                                                                   ***/
    686  /*************************************************************************/
    687  /*************************************************************************/
    688 
    689 
    690  static void
    691  CFF_Done_FD_Select( CFF_FDSelect  fdselect,
    692                      FT_Stream     stream )
    693  {
    694    if ( fdselect->data )
    695      FT_FRAME_RELEASE( fdselect->data );
    696 
    697    fdselect->data_size   = 0;
    698    fdselect->format      = 0;
    699    fdselect->range_count = 0;
    700  }
    701 
    702 
    703  static FT_Error
    704  CFF_Load_FD_Select( CFF_FDSelect  fdselect,
    705                      FT_UInt       num_glyphs,
    706                      FT_Stream     stream,
    707                      FT_ULong      offset )
    708  {
    709    FT_Error  error;
    710    FT_Byte   format;
    711    FT_UInt   num_ranges;
    712 
    713 
    714    /* read format */
    715    if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
    716      goto Exit;
    717 
    718    fdselect->format      = format;
    719    fdselect->cache_count = 0;   /* clear cache */
    720 
    721    switch ( format )
    722    {
    723    case 0:     /* format 0, that's simple */
    724      fdselect->data_size = num_glyphs;
    725      goto Load_Data;
    726 
    727    case 3:     /* format 3, a tad more complex */
    728      if ( FT_READ_USHORT( num_ranges ) )
    729        goto Exit;
    730 
    731      if ( !num_ranges )
    732      {
    733        FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
    734        error = FT_THROW( Invalid_File_Format );
    735        goto Exit;
    736      }
    737 
    738      fdselect->data_size = num_ranges * 3 + 2;
    739 
    740    Load_Data:
    741      if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
    742        goto Exit;
    743      break;
    744 
    745    default:    /* hmm... that's wrong */
    746      error = FT_THROW( Invalid_File_Format );
    747    }
    748 
    749  Exit:
    750    return error;
    751  }
    752 
    753 
    754  FT_LOCAL_DEF( FT_Byte )
    755  cff_fd_select_get( CFF_FDSelect  fdselect,
    756                     FT_UInt       glyph_index )
    757  {
    758    FT_Byte  fd = 0;
    759 
    760 
    761    /* if there is no FDSelect, return zero               */
    762    /* Note: CFF2 with just one Font Dict has no FDSelect */
    763    if ( !fdselect->data )
    764      goto Exit;
    765 
    766    switch ( fdselect->format )
    767    {
    768    case 0:
    769      fd = fdselect->data[glyph_index];
    770      break;
    771 
    772    case 3:
    773      /* first, compare to the cache */
    774      if ( glyph_index - fdselect->cache_first < fdselect->cache_count )
    775      {
    776        fd = fdselect->cache_fd;
    777        break;
    778      }
    779 
    780      /* then, look up the ranges array */
    781      {
    782        FT_Byte*  p       = fdselect->data;
    783        FT_Byte*  p_limit = p + fdselect->data_size;
    784        FT_Byte   fd2;
    785        FT_UInt   first, limit;
    786 
    787 
    788        first = FT_NEXT_USHORT( p );
    789        do
    790        {
    791          if ( glyph_index < first )
    792            break;
    793 
    794          fd2   = *p++;
    795          limit = FT_NEXT_USHORT( p );
    796 
    797          if ( glyph_index < limit )
    798          {
    799            fd = fd2;
    800 
    801            /* update cache */
    802            fdselect->cache_first = first;
    803            fdselect->cache_count = limit - first;
    804            fdselect->cache_fd    = fd2;
    805            break;
    806          }
    807          first = limit;
    808 
    809        } while ( p < p_limit );
    810      }
    811      break;
    812 
    813    default:
    814      ;
    815    }
    816 
    817  Exit:
    818    return fd;
    819  }
    820 
    821 
    822  /*************************************************************************/
    823  /*************************************************************************/
    824  /***                                                                   ***/
    825  /***   CFF font support                                                ***/
    826  /***                                                                   ***/
    827  /*************************************************************************/
    828  /*************************************************************************/
    829 
    830  static FT_Error
    831  cff_charset_compute_cids( CFF_Charset  charset,
    832                            FT_UInt      num_glyphs,
    833                            FT_Memory    memory )
    834  {
    835    FT_Error   error   = FT_Err_Ok;
    836    FT_UInt    i;
    837    FT_UShort  max_cid = 0;
    838 
    839 
    840    if ( charset->max_cid > 0 )
    841      goto Exit;
    842 
    843    for ( i = 0; i < num_glyphs; i++ )
    844    {
    845      if ( charset->sids[i] > max_cid )
    846        max_cid = charset->sids[i];
    847    }
    848 
    849    if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
    850      goto Exit;
    851 
    852    /* When multiple GIDs map to the same CID, we choose the lowest */
    853    /* GID.  This is not described in any spec, but it matches the  */
    854    /* behaviour of recent Acroread versions.  The loop stops when  */
    855    /* the unsigned index wraps around after reaching zero.         */
    856    for ( i = num_glyphs - 1; i < num_glyphs; i-- )
    857      charset->cids[charset->sids[i]] = (FT_UShort)i;
    858 
    859    charset->max_cid    = max_cid;
    860    charset->num_glyphs = num_glyphs;
    861 
    862  Exit:
    863    return error;
    864  }
    865 
    866 
    867  FT_LOCAL_DEF( FT_UInt )
    868  cff_charset_cid_to_gindex( CFF_Charset  charset,
    869                             FT_UInt      cid )
    870  {
    871    FT_UInt  result = 0;
    872 
    873 
    874    if ( cid <= charset->max_cid )
    875      result = charset->cids[cid];
    876 
    877    return result;
    878  }
    879 
    880 
    881  static void
    882  cff_charset_free_cids( CFF_Charset  charset,
    883                         FT_Memory    memory )
    884  {
    885    FT_FREE( charset->cids );
    886    charset->max_cid = 0;
    887  }
    888 
    889 
    890  static void
    891  cff_charset_done( CFF_Charset  charset,
    892                    FT_Stream    stream )
    893  {
    894    FT_Memory  memory = stream->memory;
    895 
    896 
    897    cff_charset_free_cids( charset, memory );
    898 
    899    FT_FREE( charset->sids );
    900    charset->format = 0;
    901    charset->offset = 0;
    902  }
    903 
    904 
    905  static FT_Error
    906  cff_charset_load( CFF_Charset  charset,
    907                    FT_UInt      num_glyphs,
    908                    FT_Stream    stream,
    909                    FT_ULong     base_offset,
    910                    FT_ULong     offset,
    911                    FT_Bool      invert )
    912  {
    913    FT_Memory  memory = stream->memory;
    914    FT_Error   error  = FT_Err_Ok;
    915    FT_UShort  glyph_sid;
    916 
    917 
    918    /* If the offset is greater than 2, we have to parse the charset */
    919    /* table.                                                        */
    920    if ( offset > 2 )
    921    {
    922      FT_UInt  j;
    923 
    924 
    925      charset->offset = base_offset + offset;
    926 
    927      /* Get the format of the table. */
    928      if ( FT_STREAM_SEEK( charset->offset ) ||
    929           FT_READ_BYTE( charset->format )   )
    930        goto Exit;
    931 
    932      /* Allocate memory for sids. */
    933      if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
    934        goto Exit;
    935 
    936      /* assign the .notdef glyph */
    937      charset->sids[0] = 0;
    938 
    939      switch ( charset->format )
    940      {
    941      case 0:
    942        if ( num_glyphs > 0 )
    943        {
    944          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
    945            goto Exit;
    946 
    947          for ( j = 1; j < num_glyphs; j++ )
    948            charset->sids[j] = FT_GET_USHORT();
    949 
    950          FT_FRAME_EXIT();
    951        }
    952        break;
    953 
    954      case 1:
    955      case 2:
    956        {
    957          FT_UInt  nleft;
    958          FT_UInt  i;
    959 
    960 
    961          j = 1;
    962 
    963          while ( j < num_glyphs )
    964          {
    965            /* Read the first glyph sid of the range. */
    966            if ( FT_READ_USHORT( glyph_sid ) )
    967              goto Exit;
    968 
    969            /* Read the number of glyphs in the range.  */
    970            if ( charset->format == 2 )
    971            {
    972              if ( FT_READ_USHORT( nleft ) )
    973                goto Exit;
    974            }
    975            else
    976            {
    977              if ( FT_READ_BYTE( nleft ) )
    978                goto Exit;
    979            }
    980 
    981            /* try to rescue some of the SIDs if `nleft' is too large */
    982            if ( glyph_sid > 0xFFFFL - nleft )
    983            {
    984              FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
    985                         " nleft=%u -> %ld\n", nleft, 0xFFFFL - glyph_sid ));
    986              nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
    987            }
    988 
    989            /* Fill in the range of sids -- `nleft + 1' glyphs. */
    990            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
    991              charset->sids[j] = glyph_sid;
    992          }
    993        }
    994        break;
    995 
    996      default:
    997        FT_ERROR(( "cff_charset_load: invalid table format\n" ));
    998        error = FT_THROW( Invalid_File_Format );
    999        goto Exit;
   1000      }
   1001    }
   1002    else
   1003    {
   1004      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
   1005      /* CFF specification intimates the following:                   */
   1006      /*                                                              */
   1007      /* In order to use a predefined charset, the following must be  */
   1008      /* true: The charset constructed for the glyphs in the font's   */
   1009      /* charstrings dictionary must match the predefined charset in  */
   1010      /* the first num_glyphs.                                        */
   1011 
   1012      charset->offset = offset;  /* record charset type */
   1013 
   1014      switch ( (FT_UInt)offset )
   1015      {
   1016      case 0:
   1017        if ( num_glyphs > 229 )
   1018        {
   1019          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
   1020          FT_ERROR(( "predefined charset (Adobe ISO-Latin)\n" ));
   1021          error = FT_THROW( Invalid_File_Format );
   1022          goto Exit;
   1023        }
   1024 
   1025        /* Allocate memory for sids. */
   1026        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
   1027          goto Exit;
   1028 
   1029        /* Copy the predefined charset into the allocated memory. */
   1030        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
   1031 
   1032        break;
   1033 
   1034      case 1:
   1035        if ( num_glyphs > 166 )
   1036        {
   1037          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
   1038          FT_ERROR(( "predefined charset (Adobe Expert)\n" ));
   1039          error = FT_THROW( Invalid_File_Format );
   1040          goto Exit;
   1041        }
   1042 
   1043        /* Allocate memory for sids. */
   1044        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
   1045          goto Exit;
   1046 
   1047        /* Copy the predefined charset into the allocated memory.     */
   1048        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
   1049 
   1050        break;
   1051 
   1052      case 2:
   1053        if ( num_glyphs > 87 )
   1054        {
   1055          FT_ERROR(( "cff_charset_load: implicit charset larger than\n" ));
   1056          FT_ERROR(( "predefined charset (Adobe Expert Subset)\n" ));
   1057          error = FT_THROW( Invalid_File_Format );
   1058          goto Exit;
   1059        }
   1060 
   1061        /* Allocate memory for sids. */
   1062        if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
   1063          goto Exit;
   1064 
   1065        /* Copy the predefined charset into the allocated memory.     */
   1066        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
   1067 
   1068        break;
   1069 
   1070      default:
   1071        error = FT_THROW( Invalid_File_Format );
   1072        goto Exit;
   1073      }
   1074    }
   1075 
   1076    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
   1077    if ( invert )
   1078      error = cff_charset_compute_cids( charset, num_glyphs, memory );
   1079 
   1080  Exit:
   1081    /* Clean up if there was an error. */
   1082    if ( error )
   1083    {
   1084      FT_FREE( charset->sids );
   1085      FT_FREE( charset->cids );
   1086      charset->format = 0;
   1087      charset->offset = 0;
   1088    }
   1089 
   1090    return error;
   1091  }
   1092 
   1093 
   1094  static void
   1095  cff_vstore_done( CFF_VStoreRec*  vstore,
   1096                   FT_Memory       memory )
   1097  {
   1098    FT_UInt  i;
   1099 
   1100 
   1101    /* free regionList and axisLists */
   1102    if ( vstore->varRegionList )
   1103    {
   1104      for ( i = 0; i < vstore->regionCount; i++ )
   1105        FT_FREE( vstore->varRegionList[i].axisList );
   1106    }
   1107    FT_FREE( vstore->varRegionList );
   1108 
   1109    /* free varData and indices */
   1110    if ( vstore->varData )
   1111    {
   1112      for ( i = 0; i < vstore->dataCount; i++ )
   1113        FT_FREE( vstore->varData[i].regionIndices );
   1114    }
   1115    FT_FREE( vstore->varData );
   1116  }
   1117 
   1118 
   1119  /* convert 2.14 to Fixed */
   1120  #define FT_fdot14ToFixed( x )  ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
   1121 
   1122 
   1123  static FT_Error
   1124  cff_vstore_load( CFF_VStoreRec*  vstore,
   1125                   FT_Stream       stream,
   1126                   FT_ULong        base_offset,
   1127                   FT_ULong        offset )
   1128  {
   1129    FT_Memory  memory = stream->memory;
   1130    FT_Error   error  = FT_ERR( Invalid_File_Format );
   1131 
   1132    FT_ULong*  dataOffsetArray = NULL;
   1133    FT_UInt    i, j;
   1134 
   1135 
   1136    /* no offset means no vstore to parse */
   1137    if ( offset )
   1138    {
   1139      FT_UInt   vsOffset;
   1140      FT_UInt   format;
   1141      FT_UInt   dataCount;
   1142      FT_UInt   regionCount;
   1143      FT_ULong  regionListOffset;
   1144 
   1145 
   1146      /* we need to parse the table to determine its size; */
   1147      /* skip table length                                 */
   1148      if ( FT_STREAM_SEEK( base_offset + offset ) ||
   1149           FT_STREAM_SKIP( 2 )                    )
   1150        goto Exit;
   1151 
   1152      /* actual variation store begins after the length */
   1153      vsOffset = FT_STREAM_POS();
   1154 
   1155      /* check the header */
   1156      if ( FT_READ_USHORT( format ) )
   1157        goto Exit;
   1158      if ( format != 1 )
   1159      {
   1160        error = FT_THROW( Invalid_File_Format );
   1161        goto Exit;
   1162      }
   1163 
   1164      /* read top level fields */
   1165      if ( FT_READ_ULONG( regionListOffset ) ||
   1166           FT_READ_USHORT( dataCount )       )
   1167        goto Exit;
   1168 
   1169      /* make temporary copy of item variation data offsets; */
   1170      /* we'll parse region list first, then come back       */
   1171      if ( FT_QNEW_ARRAY( dataOffsetArray, dataCount ) )
   1172        goto Exit;
   1173 
   1174      for ( i = 0; i < dataCount; i++ )
   1175      {
   1176        if ( FT_READ_ULONG( dataOffsetArray[i] ) )
   1177          goto Exit;
   1178      }
   1179 
   1180      /* parse regionList and axisLists */
   1181      if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
   1182           FT_READ_USHORT( vstore->axisCount )           ||
   1183           FT_READ_USHORT( regionCount )                 )
   1184        goto Exit;
   1185 
   1186      vstore->regionCount = 0;
   1187      if ( FT_QNEW_ARRAY( vstore->varRegionList, regionCount ) )
   1188        goto Exit;
   1189 
   1190      for ( i = 0; i < regionCount; i++ )
   1191      {
   1192        CFF_VarRegion*  region = &vstore->varRegionList[i];
   1193 
   1194 
   1195        if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
   1196          goto Exit;
   1197 
   1198        /* keep track of how many axisList to deallocate on error */
   1199        vstore->regionCount++;
   1200 
   1201        for ( j = 0; j < vstore->axisCount; j++ )
   1202        {
   1203          CFF_AxisCoords*  axis = &region->axisList[j];
   1204 
   1205          FT_Int  start, peak, end;
   1206 
   1207 
   1208          if ( FT_READ_SHORT( start ) ||
   1209               FT_READ_SHORT( peak )  ||
   1210               FT_READ_SHORT( end )   )
   1211            goto Exit;
   1212 
   1213          /* immediately tag invalid ranges with special peak = 0 */
   1214          if ( ( start < 0 && end > 0 ) || start > peak || peak > end )
   1215            peak = 0;
   1216 
   1217          axis->startCoord = FT_fdot14ToFixed( start );
   1218          axis->peakCoord  = FT_fdot14ToFixed( peak );
   1219          axis->endCoord   = FT_fdot14ToFixed( end );
   1220        }
   1221      }
   1222 
   1223      /* use dataOffsetArray now to parse varData items */
   1224      vstore->dataCount = 0;
   1225      if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) )
   1226        goto Exit;
   1227 
   1228      for ( i = 0; i < dataCount; i++ )
   1229      {
   1230        CFF_VarData*  data = &vstore->varData[i];
   1231 
   1232 
   1233        if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
   1234          goto Exit;
   1235 
   1236        /* ignore `itemCount' and `shortDeltaCount' */
   1237        /* because CFF2 has no delta sets           */
   1238        if ( FT_STREAM_SKIP( 4 ) )
   1239          goto Exit;
   1240 
   1241        /* Note: just record values; consistency is checked later    */
   1242        /*       by cff_blend_build_vector when it consumes `vstore' */
   1243 
   1244        if ( FT_READ_USHORT( data->regionIdxCount ) )
   1245          goto Exit;
   1246 
   1247        if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
   1248          goto Exit;
   1249 
   1250        /* keep track of how many regionIndices to deallocate on error */
   1251        vstore->dataCount++;
   1252 
   1253        for ( j = 0; j < data->regionIdxCount; j++ )
   1254        {
   1255          if ( FT_READ_USHORT( data->regionIndices[j] ) )
   1256            goto Exit;
   1257        }
   1258      }
   1259    }
   1260 
   1261    error = FT_Err_Ok;
   1262 
   1263  Exit:
   1264    FT_FREE( dataOffsetArray );
   1265    if ( error )
   1266      cff_vstore_done( vstore, memory );
   1267 
   1268    return error;
   1269  }
   1270 
   1271 
   1272  /* Clear blend stack (after blend values are consumed). */
   1273  /*                                                      */
   1274  /* TODO: Should do this in cff_run_parse, but subFont   */
   1275  /*       ref is not available there.                    */
   1276  /*                                                      */
   1277  /* Allocation is not changed when stack is cleared.     */
   1278  FT_LOCAL_DEF( void )
   1279  cff_blend_clear( CFF_SubFont  subFont )
   1280  {
   1281    subFont->blend_top  = subFont->blend_stack;
   1282    subFont->blend_used = 0;
   1283  }
   1284 
   1285 
   1286  /* Blend numOperands on the stack,                       */
   1287  /* store results into the first numBlends values,        */
   1288  /* then pop remaining arguments.                         */
   1289  /*                                                       */
   1290  /* This is comparable to `cf2_doBlend' but               */
   1291  /* the cffparse stack is different and can't be written. */
   1292  /* Blended values are written to a different buffer,     */
   1293  /* using reserved operator 255.                          */
   1294  /*                                                       */
   1295  /* Blend calculation is done in 16.16 fixed-point.       */
   1296  FT_LOCAL_DEF( FT_Error )
   1297  cff_blend_doBlend( CFF_SubFont  subFont,
   1298                     CFF_Parser   parser,
   1299                     FT_UInt      numBlends )
   1300  {
   1301    FT_UInt  delta;
   1302    FT_UInt  base;
   1303    FT_UInt  i, j;
   1304    FT_UInt  size;
   1305 
   1306    CFF_Blend  blend = &subFont->blend;
   1307 
   1308    FT_Memory  memory = subFont->blend.font->memory; /* for FT_REALLOC */
   1309    FT_Error   error  = FT_Err_Ok;                   /* for FT_REALLOC */
   1310 
   1311    /* compute expected number of operands for this blend */
   1312    FT_UInt  numOperands = (FT_UInt)( numBlends * blend->lenBV );
   1313    FT_UInt  count       = (FT_UInt)( parser->top - 1 - parser->stack );
   1314 
   1315 
   1316    if ( numOperands > count )
   1317    {
   1318      FT_TRACE4(( " cff_blend_doBlend: Stack underflow %u argument%s\n",
   1319                  count,
   1320                  count == 1 ? "" : "s" ));
   1321 
   1322      error = FT_THROW( Stack_Underflow );
   1323      goto Exit;
   1324    }
   1325 
   1326    /* check whether we have room for `numBlends' values at `blend_top' */
   1327    size = 5 * numBlends;           /* add 5 bytes per entry    */
   1328    if ( subFont->blend_used + size > subFont->blend_alloc )
   1329    {
   1330      FT_Byte*  blend_stack_old = subFont->blend_stack;
   1331      FT_Byte*  blend_top_old   = subFont->blend_top;
   1332 
   1333 
   1334      /* increase or allocate `blend_stack' and reset `blend_top'; */
   1335      /* prepare to append `numBlends' values to the buffer        */
   1336      if ( FT_QREALLOC( subFont->blend_stack,
   1337                        subFont->blend_alloc,
   1338                        subFont->blend_alloc + size ) )
   1339        goto Exit;
   1340 
   1341      subFont->blend_top    = subFont->blend_stack + subFont->blend_used;
   1342      subFont->blend_alloc += size;
   1343 
   1344      /* iterate over the parser stack and adjust pointers */
   1345      /* if the reallocated buffer has a different address */
   1346      if ( blend_stack_old                         &&
   1347           subFont->blend_stack != blend_stack_old )
   1348      {
   1349        FT_PtrDist  offset = subFont->blend_stack - blend_stack_old;
   1350        FT_Byte**   p;
   1351 
   1352 
   1353        for ( p = parser->stack; p < parser->top; p++ )
   1354        {
   1355          if ( *p >= blend_stack_old && *p < blend_top_old )
   1356            *p += offset;
   1357        }
   1358      }
   1359    }
   1360    subFont->blend_used += size;
   1361 
   1362    base  = count - numOperands;     /* index of first blend arg */
   1363    delta = base + numBlends;        /* index of first delta arg */
   1364 
   1365    for ( i = 0; i < numBlends; i++ )
   1366    {
   1367      const FT_Int32*  weight = &blend->BV[1];
   1368      FT_Fixed         sum;
   1369 
   1370 
   1371      /* convert inputs to 16.16 fixed point */
   1372      sum = cff_parse_fixed( parser, &parser->stack[i + base] );
   1373 
   1374      for ( j = 1; j < blend->lenBV; j++ )
   1375        sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ),
   1376                          *weight++ );
   1377 
   1378      /* point parser stack to new value on blend_stack */
   1379      parser->stack[i + base] = subFont->blend_top;
   1380 
   1381      /* Push blended result as Type 2 5-byte fixed-point number.  This */
   1382      /* will not conflict with actual DICTs because 255 is a reserved  */
   1383      /* opcode in both CFF and CFF2 DICTs.  See `cff_parse_num' for    */
   1384      /* decode of this, which rounds to an integer.                    */
   1385      *subFont->blend_top++ = 255;
   1386      *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 24 );
   1387      *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 16 );
   1388      *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >>  8 );
   1389      *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum );
   1390    }
   1391 
   1392    /* leave only numBlends results on parser stack */
   1393    parser->top = &parser->stack[base + numBlends];
   1394 
   1395  Exit:
   1396    return error;
   1397  }
   1398 
   1399 
   1400  /* Compute a blend vector from variation store index and normalized  */
   1401  /* vector based on pseudo-code in OpenType Font Variations Overview. */
   1402  /*                                                                   */
   1403  /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...).   */
   1404  FT_LOCAL_DEF( FT_Error )
   1405  cff_blend_build_vector( CFF_Blend  blend,
   1406                          FT_UInt    vsindex,
   1407                          FT_UInt    lenNDV,
   1408                          FT_Fixed*  NDV )
   1409  {
   1410    FT_Error   error  = FT_Err_Ok;            /* for FT_REALLOC */
   1411    FT_Memory  memory = blend->font->memory;  /* for FT_REALLOC */
   1412 
   1413    FT_UInt       len;
   1414    CFF_VStore    vs;
   1415    CFF_VarData*  varData;
   1416    FT_UInt       master;
   1417 
   1418 
   1419    /* protect against malformed fonts */
   1420    if ( !( lenNDV == 0 || NDV ) )
   1421    {
   1422      FT_TRACE4(( " cff_blend_build_vector:"
   1423                  " Malformed Normalize Design Vector data\n" ));
   1424      error = FT_THROW( Invalid_File_Format );
   1425      goto Exit;
   1426    }
   1427 
   1428    blend->builtBV = FALSE;
   1429 
   1430    vs = &blend->font->vstore;
   1431 
   1432    /* VStore and fvar must be consistent */
   1433    if ( lenNDV != 0 && lenNDV != vs->axisCount )
   1434    {
   1435      FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
   1436      error = FT_THROW( Invalid_File_Format );
   1437      goto Exit;
   1438    }
   1439 
   1440    if ( vsindex >= vs->dataCount )
   1441    {
   1442      FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
   1443      error = FT_THROW( Invalid_File_Format );
   1444      goto Exit;
   1445    }
   1446 
   1447    /* select the item variation data structure */
   1448    varData = &vs->varData[vsindex];
   1449 
   1450    /* prepare buffer for the blend vector */
   1451    len = varData->regionIdxCount + 1;    /* add 1 for default component */
   1452    if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) )
   1453      goto Exit;
   1454 
   1455    blend->lenBV = len;
   1456 
   1457    /* outer loop steps through master designs to be blended */
   1458    for ( master = 0; master < len; master++ )
   1459    {
   1460      FT_UInt         j;
   1461      FT_UInt         idx;
   1462      CFF_VarRegion*  varRegion;
   1463 
   1464 
   1465      /* default factor is always one */
   1466      if ( master == 0 )
   1467      {
   1468        blend->BV[master] = FT_FIXED_ONE;
   1469        FT_TRACE4(( "   build blend vector len %u\n", len ));
   1470        FT_TRACE4(( "   [ %f ", blend->BV[master] / 65536.0 ));
   1471        continue;
   1472      }
   1473 
   1474      /* VStore array does not include default master, so subtract one */
   1475      idx       = varData->regionIndices[master - 1];
   1476      varRegion = &vs->varRegionList[idx];
   1477 
   1478      if ( idx >= vs->regionCount )
   1479      {
   1480        FT_TRACE4(( " cff_blend_build_vector:"
   1481                    " region index out of range\n" ));
   1482        error = FT_THROW( Invalid_File_Format );
   1483        goto Exit;
   1484      }
   1485 
   1486      /* Note: `lenNDV' could be zero.                              */
   1487      /*       In that case, build default blend vector (1,0,0...). */
   1488      if ( !lenNDV )
   1489      {
   1490        blend->BV[master] = 0;
   1491        continue;
   1492      }
   1493 
   1494      /* In the normal case, initialize each component to 1 */
   1495      /* before inner loop.                                 */
   1496      blend->BV[master] = FT_FIXED_ONE; /* default */
   1497 
   1498      /* inner loop steps through axes in this region */
   1499      for ( j = 0; j < lenNDV; j++ )
   1500      {
   1501        CFF_AxisCoords*  axis = &varRegion->axisList[j];
   1502 
   1503 
   1504        /* compute the scalar contribution of this axis */
   1505        /* with peak of 0 used for invalid axes         */
   1506        if ( axis->peakCoord == NDV[j] ||
   1507             axis->peakCoord == 0      )
   1508          continue;
   1509 
   1510        /* ignore this region if coords are out of range */
   1511        else if ( NDV[j] <= axis->startCoord ||
   1512                  NDV[j] >= axis->endCoord   )
   1513        {
   1514          blend->BV[master] = 0;
   1515          break;
   1516        }
   1517 
   1518        /* adjust proportionally */
   1519        else if ( NDV[j] < axis->peakCoord )
   1520          blend->BV[master] = FT_MulDiv( blend->BV[master],
   1521                                         NDV[j] - axis->startCoord,
   1522                                         axis->peakCoord - axis->startCoord );
   1523        else   /* NDV[j] > axis->peakCoord ) */
   1524          blend->BV[master] = FT_MulDiv( blend->BV[master],
   1525                                         axis->endCoord - NDV[j],
   1526                                         axis->endCoord - axis->peakCoord );
   1527      }
   1528 
   1529      FT_TRACE4(( ", %f ",
   1530                  blend->BV[master] / 65536.0 ));
   1531    }
   1532 
   1533    FT_TRACE4(( "]\n" ));
   1534 
   1535    /* record the parameters used to build the blend vector */
   1536    blend->lastVsindex = vsindex;
   1537 
   1538    if ( lenNDV != 0 )
   1539    {
   1540      /* user has set a normalized vector */
   1541      if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) )
   1542        goto Exit;
   1543 
   1544      FT_MEM_COPY( blend->lastNDV,
   1545                   NDV,
   1546                   lenNDV * sizeof ( *NDV ) );
   1547    }
   1548 
   1549    blend->lenNDV  = lenNDV;
   1550    blend->builtBV = TRUE;
   1551 
   1552  Exit:
   1553    return error;
   1554  }
   1555 
   1556 
   1557  /* `lenNDV' is zero for default vector;           */
   1558  /* return TRUE if blend vector needs to be built. */
   1559  FT_LOCAL_DEF( FT_Bool )
   1560  cff_blend_check_vector( CFF_Blend  blend,
   1561                          FT_UInt    vsindex,
   1562                          FT_UInt    lenNDV,
   1563                          FT_Fixed*  NDV )
   1564  {
   1565    if ( !blend->builtBV                                ||
   1566         blend->lastVsindex != vsindex                  ||
   1567         blend->lenNDV != lenNDV                        ||
   1568         ( lenNDV                                     &&
   1569           ft_memcmp( NDV,
   1570                      blend->lastNDV,
   1571                      lenNDV * sizeof ( *NDV ) ) != 0 ) )
   1572    {
   1573      /* need to build blend vector */
   1574      return TRUE;
   1575    }
   1576 
   1577    return FALSE;
   1578  }
   1579 
   1580 
   1581 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
   1582 
   1583  FT_LOCAL_DEF( FT_Error )
   1584  cff_get_var_blend( FT_Face      face,             /* CFF_Face */
   1585                     FT_UInt     *num_coords,
   1586                     FT_Fixed*   *coords,
   1587                     FT_Fixed*   *normalizedcoords,
   1588                     FT_MM_Var*  *mm_var )
   1589  {
   1590    CFF_Face                 cffface = (CFF_Face)face;
   1591    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
   1592 
   1593 
   1594    return mm->get_var_blend( face,
   1595                              num_coords,
   1596                              coords,
   1597                              normalizedcoords,
   1598                              mm_var );
   1599  }
   1600 
   1601 
   1602  FT_LOCAL_DEF( void )
   1603  cff_done_blend( FT_Face  face )    /* CFF_Face */
   1604  {
   1605    CFF_Face                 cffface = (CFF_Face)face;
   1606    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
   1607 
   1608 
   1609    if ( mm )
   1610      mm->done_blend( face );
   1611  }
   1612 
   1613 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
   1614 
   1615 
   1616  static void
   1617  cff_encoding_done( CFF_Encoding  encoding )
   1618  {
   1619    encoding->format = 0;
   1620    encoding->offset = 0;
   1621    encoding->count  = 0;
   1622  }
   1623 
   1624 
   1625  static FT_Error
   1626  cff_encoding_load( CFF_Encoding  encoding,
   1627                     CFF_Charset   charset,
   1628                     FT_UInt       num_glyphs,
   1629                     FT_Stream     stream,
   1630                     FT_ULong      base_offset,
   1631                     FT_ULong      offset )
   1632  {
   1633    FT_Error   error = FT_Err_Ok;
   1634    FT_UInt    count;
   1635    FT_UInt    j;
   1636    FT_UShort  glyph_sid;
   1637    FT_UInt    glyph_code;
   1638 
   1639 
   1640    /* Check for charset->sids.  If we do not have this, we fail. */
   1641    if ( !charset->sids )
   1642    {
   1643      error = FT_THROW( Invalid_File_Format );
   1644      goto Exit;
   1645    }
   1646 
   1647    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
   1648    /* the first encoded glyph index is 1.  Hence, we read the character  */
   1649    /* code (`glyph_code') at index j and make the assignment:            */
   1650    /*                                                                    */
   1651    /*    encoding->codes[glyph_code] = j + 1                             */
   1652    /*                                                                    */
   1653    /* We also make the assignment:                                       */
   1654    /*                                                                    */
   1655    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
   1656    /*                                                                    */
   1657    /* This gives us both a code to GID and a code to SID mapping.        */
   1658 
   1659    if ( offset > 1 )
   1660    {
   1661      /* Zero out the code to gid/sid mappings. */
   1662      FT_ARRAY_ZERO( encoding->sids,  256 );
   1663      FT_ARRAY_ZERO( encoding->codes, 256 );
   1664 
   1665      encoding->offset = base_offset + offset;
   1666 
   1667      /* we need to parse the table to determine its size */
   1668      if ( FT_STREAM_SEEK( encoding->offset ) ||
   1669           FT_READ_BYTE( encoding->format )   ||
   1670           FT_READ_BYTE( count )              )
   1671        goto Exit;
   1672 
   1673      switch ( encoding->format & 0x7F )
   1674      {
   1675      case 0:
   1676        {
   1677          FT_Byte*  p;
   1678 
   1679 
   1680          /* By convention, GID 0 is always ".notdef" and is never */
   1681          /* coded in the font.  Hence, the number of codes found  */
   1682          /* in the table is `count+1'.                            */
   1683          /*                                                       */
   1684          encoding->count = count + 1;
   1685 
   1686          if ( FT_FRAME_ENTER( count ) )
   1687            goto Exit;
   1688 
   1689          p = (FT_Byte*)stream->cursor;
   1690 
   1691          for ( j = 1; j <= count; j++ )
   1692          {
   1693            glyph_code = *p++;
   1694 
   1695            /* Make sure j is not too big. */
   1696            if ( j < num_glyphs )
   1697            {
   1698              /* Assign code to GID mapping. */
   1699              encoding->codes[glyph_code] = (FT_UShort)j;
   1700 
   1701              /* Assign code to SID mapping. */
   1702              encoding->sids[glyph_code] = charset->sids[j];
   1703            }
   1704          }
   1705 
   1706          FT_FRAME_EXIT();
   1707        }
   1708        break;
   1709 
   1710      case 1:
   1711        {
   1712          FT_UInt  nleft;
   1713          FT_UInt  i = 1;
   1714          FT_UInt  k;
   1715 
   1716 
   1717          encoding->count = 0;
   1718 
   1719          /* Parse the Format1 ranges. */
   1720          for ( j = 0;  j < count; j++, i += nleft )
   1721          {
   1722            /* Read the first glyph code of the range. */
   1723            if ( FT_READ_BYTE( glyph_code ) )
   1724              goto Exit;
   1725 
   1726            /* Read the number of codes in the range. */
   1727            if ( FT_READ_BYTE( nleft ) )
   1728              goto Exit;
   1729 
   1730            /* Increment nleft, so we read `nleft + 1' codes/sids. */
   1731            nleft++;
   1732 
   1733            /* compute max number of character codes */
   1734            if ( (FT_UInt)nleft > encoding->count )
   1735              encoding->count = nleft;
   1736 
   1737            /* Fill in the range of codes/sids. */
   1738            for ( k = i; k < nleft + i; k++, glyph_code++ )
   1739            {
   1740              /* Make sure k is not too big. */
   1741              if ( k < num_glyphs && glyph_code < 256 )
   1742              {
   1743                /* Assign code to GID mapping. */
   1744                encoding->codes[glyph_code] = (FT_UShort)k;
   1745 
   1746                /* Assign code to SID mapping. */
   1747                encoding->sids[glyph_code] = charset->sids[k];
   1748              }
   1749            }
   1750          }
   1751 
   1752          /* simple check; one never knows what can be found in a font */
   1753          if ( encoding->count > 256 )
   1754            encoding->count = 256;
   1755        }
   1756        break;
   1757 
   1758      default:
   1759        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
   1760        error = FT_THROW( Invalid_File_Format );
   1761        goto Exit;
   1762      }
   1763 
   1764      /* Parse supplemental encodings, if any. */
   1765      if ( encoding->format & 0x80 )
   1766      {
   1767        FT_UInt  gindex;
   1768 
   1769 
   1770        /* count supplements */
   1771        if ( FT_READ_BYTE( count ) )
   1772          goto Exit;
   1773 
   1774        for ( j = 0; j < count; j++ )
   1775        {
   1776          /* Read supplemental glyph code. */
   1777          if ( FT_READ_BYTE( glyph_code ) )
   1778            goto Exit;
   1779 
   1780          /* Read the SID associated with this glyph code. */
   1781          if ( FT_READ_USHORT( glyph_sid ) )
   1782            goto Exit;
   1783 
   1784          /* Assign code to SID mapping. */
   1785          encoding->sids[glyph_code] = glyph_sid;
   1786 
   1787          /* First, look up GID which has been assigned to */
   1788          /* SID glyph_sid.                                */
   1789          for ( gindex = 0; gindex < num_glyphs; gindex++ )
   1790          {
   1791            if ( charset->sids[gindex] == glyph_sid )
   1792            {
   1793              encoding->codes[glyph_code] = (FT_UShort)gindex;
   1794              break;
   1795            }
   1796          }
   1797        }
   1798      }
   1799    }
   1800    else
   1801    {
   1802      /* We take into account the fact a CFF font can use a predefined */
   1803      /* encoding without containing all of the glyphs encoded by this */
   1804      /* encoding (see the note at the end of section 12 in the CFF    */
   1805      /* specification).                                               */
   1806 
   1807      switch ( (FT_UInt)offset )
   1808      {
   1809      case 0:
   1810        /* First, copy the code to SID mapping. */
   1811        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
   1812        goto Populate;
   1813 
   1814      case 1:
   1815        /* First, copy the code to SID mapping. */
   1816        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
   1817 
   1818      Populate:
   1819        /* Construct code to GID mapping from code to SID mapping */
   1820        /* and charset.                                           */
   1821 
   1822        encoding->offset = offset; /* used in cff_face_init */
   1823        encoding->count  = 0;
   1824 
   1825        error = cff_charset_compute_cids( charset, num_glyphs,
   1826                                          stream->memory );
   1827        if ( error )
   1828          goto Exit;
   1829 
   1830        for ( j = 0; j < 256; j++ )
   1831        {
   1832          FT_UInt  sid = encoding->sids[j];
   1833          FT_UInt  gid = 0;
   1834 
   1835 
   1836          if ( sid )
   1837            gid = cff_charset_cid_to_gindex( charset, sid );
   1838 
   1839          if ( gid != 0 )
   1840          {
   1841            encoding->codes[j] = (FT_UShort)gid;
   1842            encoding->count    = j + 1;
   1843          }
   1844          else
   1845          {
   1846            encoding->codes[j] = 0;
   1847            encoding->sids [j] = 0;
   1848          }
   1849        }
   1850        break;
   1851 
   1852      default:
   1853        FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
   1854        error = FT_THROW( Invalid_File_Format );
   1855        goto Exit;
   1856      }
   1857    }
   1858 
   1859  Exit:
   1860 
   1861    /* Clean up if there was an error. */
   1862    return error;
   1863  }
   1864 
   1865 
   1866  /* Parse private dictionary; first call is always from `cff_face_init', */
   1867  /* so NDV has not been set for CFF2 variation.                          */
   1868  /*                                                                      */
   1869  /* `cff_slot_load' must call this function each time NDV changes.       */
   1870  FT_LOCAL_DEF( FT_Error )
   1871  cff_load_private_dict( CFF_Font     font,
   1872                         CFF_SubFont  subfont,
   1873                         FT_UInt      lenNDV,
   1874                         FT_Fixed*    NDV )
   1875  {
   1876    FT_Error         error  = FT_Err_Ok;
   1877    CFF_ParserRec    parser;
   1878    CFF_FontRecDict  top    = &subfont->font_dict;
   1879    CFF_Private      priv   = &subfont->private_dict;
   1880    FT_Stream        stream = font->stream;
   1881    FT_UInt          stackSize;
   1882 
   1883 
   1884    /* store handle needed to access memory, vstore for blend;    */
   1885    /* we need this for clean-up even if there is no private DICT */
   1886    subfont->blend.font   = font;
   1887    subfont->blend.usedBV = FALSE;  /* clear state */
   1888 
   1889    if ( !top->private_offset || !top->private_size )
   1890      goto Exit2;       /* no private DICT, do nothing */
   1891 
   1892    /* set defaults */
   1893    FT_ZERO( priv );
   1894 
   1895    priv->blue_shift       = 7;
   1896    priv->blue_fuzz        = 1;
   1897    priv->lenIV            = -1;
   1898    priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
   1899    priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
   1900 
   1901    /* provide inputs for blend calculations */
   1902    priv->subfont   = subfont;
   1903    subfont->lenNDV = lenNDV;
   1904    subfont->NDV    = NDV;
   1905 
   1906    /* add 1 for the operator */
   1907    stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
   1908                           : CFF_MAX_STACK_DEPTH + 1;
   1909 
   1910    if ( cff_parser_init( &parser,
   1911                          font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
   1912                          priv,
   1913                          font->library,
   1914                          stackSize,
   1915                          top->num_designs,
   1916                          top->num_axes ) )
   1917      goto Exit;
   1918 
   1919    if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
   1920         FT_FRAME_ENTER( top->private_size )                       )
   1921      goto Exit;
   1922 
   1923    FT_TRACE4(( " private dictionary:\n" ));
   1924    error = cff_parser_run( &parser,
   1925                            (FT_Byte*)stream->cursor,
   1926                            (FT_Byte*)stream->limit );
   1927    FT_FRAME_EXIT();
   1928 
   1929    if ( error )
   1930      goto Exit;
   1931 
   1932    /* ensure that `num_blue_values' is even */
   1933    priv->num_blue_values &= ~1;
   1934 
   1935    /* sanitize `initialRandomSeed' to be a positive value, if necessary;  */
   1936    /* this is not mandated by the specification but by our implementation */
   1937    if ( priv->initial_random_seed < 0 )
   1938      priv->initial_random_seed = -priv->initial_random_seed;
   1939    else if ( priv->initial_random_seed == 0 )
   1940      priv->initial_random_seed = 987654321;
   1941 
   1942    /* some sanitizing to avoid overflows later on; */
   1943    /* the upper limits are ad-hoc values           */
   1944    if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
   1945    {
   1946      FT_TRACE2(( "cff_load_private_dict:"
   1947                  " setting unlikely BlueShift value %ld to default (7)\n",
   1948                  priv->blue_shift ));
   1949      priv->blue_shift = 7;
   1950    }
   1951 
   1952    if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
   1953    {
   1954      FT_TRACE2(( "cff_load_private_dict:"
   1955                  " setting unlikely BlueFuzz value %ld to default (1)\n",
   1956                  priv->blue_fuzz ));
   1957      priv->blue_fuzz = 1;
   1958    }
   1959 
   1960  Exit:
   1961    /* clean up */
   1962    cff_blend_clear( subfont ); /* clear blend stack */
   1963    cff_parser_done( &parser ); /* free parser stack */
   1964 
   1965  Exit2:
   1966    /* no clean up (parser not initialized) */
   1967    return error;
   1968  }
   1969 
   1970 
   1971  /* There are 3 ways to call this function, distinguished by code.  */
   1972  /*                                                                 */
   1973  /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
   1974  /* . CFF2_CODE_TOPDICT for CFF2 Top DICT                           */
   1975  /* . CFF2_CODE_FONTDICT for CFF2 Font DICT                         */
   1976 
   1977  static FT_Error
   1978  cff_subfont_load( CFF_SubFont  subfont,
   1979                    CFF_Index    idx,
   1980                    FT_UInt      font_index,
   1981                    FT_Stream    stream,
   1982                    FT_ULong     base_offset,
   1983                    FT_UInt      code,
   1984                    CFF_Font     font,
   1985                    CFF_Face     face )
   1986  {
   1987    FT_Error         error;
   1988    CFF_ParserRec    parser;
   1989    FT_Byte*         dict = NULL;
   1990    FT_ULong         dict_len;
   1991    CFF_FontRecDict  top  = &subfont->font_dict;
   1992    CFF_Private      priv = &subfont->private_dict;
   1993 
   1994    PSAux_Service  psaux = (PSAux_Service)face->psaux;
   1995 
   1996    FT_Bool  cff2      = FT_BOOL( code == CFF2_CODE_TOPDICT  ||
   1997                                  code == CFF2_CODE_FONTDICT );
   1998    FT_UInt  stackSize = cff2 ? CFF2_DEFAULT_STACK
   1999                              : CFF_MAX_STACK_DEPTH;
   2000 
   2001 
   2002    /* Note: We use default stack size for CFF2 Font DICT because        */
   2003    /*       Top and Font DICTs are not allowed to have blend operators. */
   2004    error = cff_parser_init( &parser,
   2005                             code,
   2006                             top,
   2007                             font->library,
   2008                             stackSize,
   2009                             0,
   2010                             0 );
   2011    if ( error )
   2012      goto Exit;
   2013 
   2014    /* set defaults */
   2015    FT_ZERO( top );
   2016 
   2017    top->underline_position  = -( 100L << 16 );
   2018    top->underline_thickness = 50L << 16;
   2019    top->charstring_type     = 2;
   2020    top->font_matrix.xx      = 0x10000L;
   2021    top->font_matrix.yy      = 0x10000L;
   2022    top->cid_count           = 8720;
   2023 
   2024    /* we use the implementation specific SID value 0xFFFF to indicate */
   2025    /* missing entries                                                 */
   2026    top->version             = 0xFFFFU;
   2027    top->notice              = 0xFFFFU;
   2028    top->copyright           = 0xFFFFU;
   2029    top->full_name           = 0xFFFFU;
   2030    top->family_name         = 0xFFFFU;
   2031    top->weight              = 0xFFFFU;
   2032    top->embedded_postscript = 0xFFFFU;
   2033 
   2034    top->cid_registry        = 0xFFFFU;
   2035    top->cid_ordering        = 0xFFFFU;
   2036    top->cid_font_name       = 0xFFFFU;
   2037 
   2038    /* set default stack size */
   2039    top->maxstack            = cff2 ? CFF2_DEFAULT_STACK : 48;
   2040 
   2041    if ( idx->count )   /* count is nonzero for a real index */
   2042      error = cff_index_access_element( idx, font_index, &dict, &dict_len );
   2043    else
   2044    {
   2045      /* CFF2 has a fake top dict index;     */
   2046      /* simulate `cff_index_access_element' */
   2047 
   2048      /* Note: macros implicitly use `stream' and set `error' */
   2049      if ( FT_STREAM_SEEK( idx->data_offset )       ||
   2050           FT_FRAME_EXTRACT( idx->data_size, dict ) )
   2051        goto Exit;
   2052 
   2053      dict_len = idx->data_size;
   2054    }
   2055 
   2056    if ( !error )
   2057    {
   2058      FT_TRACE4(( " top dictionary:\n" ));
   2059      error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
   2060    }
   2061 
   2062    /* clean up regardless of error */
   2063    if ( idx->count )
   2064      cff_index_forget_element( idx, &dict );
   2065    else
   2066      FT_FRAME_RELEASE( dict );
   2067 
   2068    if ( error )
   2069      goto Exit;
   2070 
   2071    /* if it is a CID font, we stop there */
   2072    if ( top->cid_registry != 0xFFFFU )
   2073      goto Exit;
   2074 
   2075    /* Parse the private dictionary, if any.                   */
   2076    /*                                                         */
   2077    /* CFF2 does not have a private dictionary in the Top DICT */
   2078    /* but may have one in a Font DICT.  We need to parse      */
   2079    /* the latter here in order to load any local subrs.       */
   2080    error = cff_load_private_dict( font, subfont, 0, 0 );
   2081    if ( error )
   2082      goto Exit;
   2083 
   2084    if ( !cff2 )
   2085    {
   2086      /*
   2087       * Initialize the random number generator.
   2088       *
   2089       * - If we have a face-specific seed, use it.
   2090       *   If non-zero, update it to a positive value.
   2091       *
   2092       * - Otherwise, use the seed from the CFF driver.
   2093       *   If non-zero, update it to a positive value.
   2094       *
   2095       * - If the random value is zero, use the seed given by the subfont's
   2096       *   `initialRandomSeed' value.
   2097       *
   2098       */
   2099      if ( face->root.internal->random_seed == -1 )
   2100      {
   2101        PS_Driver  driver = (PS_Driver)FT_FACE_DRIVER( face );
   2102 
   2103 
   2104        subfont->random = (FT_UInt32)driver->random_seed;
   2105        if ( driver->random_seed )
   2106        {
   2107          do
   2108          {
   2109            driver->random_seed =
   2110              (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
   2111 
   2112          } while ( driver->random_seed < 0 );
   2113        }
   2114      }
   2115      else
   2116      {
   2117        subfont->random = (FT_UInt32)face->root.internal->random_seed;
   2118        if ( face->root.internal->random_seed )
   2119        {
   2120          do
   2121          {
   2122            face->root.internal->random_seed =
   2123              (FT_Int32)psaux->cff_random(
   2124                (FT_UInt32)face->root.internal->random_seed );
   2125 
   2126          } while ( face->root.internal->random_seed < 0 );
   2127        }
   2128      }
   2129 
   2130      if ( !subfont->random )
   2131        subfont->random = (FT_UInt32)priv->initial_random_seed;
   2132    }
   2133 
   2134    /* read the local subrs, if any */
   2135    if ( priv->local_subrs_offset )
   2136    {
   2137      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
   2138                           priv->local_subrs_offset ) )
   2139        goto Exit;
   2140 
   2141      error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
   2142      if ( error )
   2143        goto Exit;
   2144 
   2145      error = cff_index_get_pointers( &subfont->local_subrs_index,
   2146                                      &subfont->local_subrs, NULL, NULL );
   2147      if ( error )
   2148        goto Exit;
   2149    }
   2150 
   2151  Exit:
   2152    cff_parser_done( &parser ); /* free parser stack */
   2153 
   2154    return error;
   2155  }
   2156 
   2157 
   2158  static void
   2159  cff_subfont_done( FT_Memory    memory,
   2160                    CFF_SubFont  subfont )
   2161  {
   2162    if ( subfont )
   2163    {
   2164      cff_index_done( &subfont->local_subrs_index );
   2165      FT_FREE( subfont->local_subrs );
   2166 
   2167      FT_FREE( subfont->blend.lastNDV );
   2168      FT_FREE( subfont->blend.BV );
   2169      FT_FREE( subfont->blend_stack );
   2170    }
   2171  }
   2172 
   2173 
   2174  FT_LOCAL_DEF( FT_Error )
   2175  cff_font_load( FT_Library library,
   2176                 FT_Stream  stream,
   2177                 FT_Int     face_index,
   2178                 CFF_Font   font,
   2179                 CFF_Face   face,
   2180                 FT_Bool    pure_cff,
   2181                 FT_Bool    cff2 )
   2182  {
   2183    static const FT_Frame_Field  cff_header_fields[] =
   2184    {
   2185 #undef  FT_STRUCTURE
   2186 #define FT_STRUCTURE  CFF_FontRec
   2187 
   2188      FT_FRAME_START( 3 ),
   2189        FT_FRAME_BYTE( version_major ),
   2190        FT_FRAME_BYTE( version_minor ),
   2191        FT_FRAME_BYTE( header_size ),
   2192      FT_FRAME_END
   2193    };
   2194 
   2195    FT_Error         error;
   2196    FT_Memory        memory = stream->memory;
   2197    FT_ULong         base_offset;
   2198    CFF_FontRecDict  dict;
   2199    CFF_IndexRec     string_index;
   2200    FT_UInt          subfont_index;
   2201 
   2202 
   2203    FT_ZERO( font );
   2204    FT_ZERO( &string_index );
   2205 
   2206    dict        = &font->top_font.font_dict;
   2207    base_offset = FT_STREAM_POS();
   2208 
   2209    font->library     = library;
   2210    font->stream      = stream;
   2211    font->memory      = memory;
   2212    font->cff2        = cff2;
   2213    font->base_offset = base_offset;
   2214 
   2215    /* read CFF font header */
   2216    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
   2217      goto Exit;
   2218 
   2219    if ( cff2 )
   2220    {
   2221      if ( font->version_major != 2 ||
   2222           font->header_size < 5    )
   2223      {
   2224        FT_TRACE2(( "  not a CFF2 font header\n" ));
   2225        error = FT_THROW( Unknown_File_Format );
   2226        goto Exit;
   2227      }
   2228 
   2229      if ( FT_READ_USHORT( font->top_dict_length ) )
   2230        goto Exit;
   2231    }
   2232    else
   2233    {
   2234      FT_Byte  absolute_offset;
   2235 
   2236 
   2237      if ( FT_READ_BYTE( absolute_offset ) )
   2238        goto Exit;
   2239 
   2240      if ( font->version_major != 1 ||
   2241           font->header_size < 4    ||
   2242           absolute_offset > 4      )
   2243      {
   2244        FT_TRACE2(( "  not a CFF font header\n" ));
   2245        error = FT_THROW( Unknown_File_Format );
   2246        goto Exit;
   2247      }
   2248    }
   2249 
   2250    /* skip the rest of the header */
   2251    if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
   2252    {
   2253      /* For pure CFFs we have read only four bytes so far.  Contrary to */
   2254      /* other formats like SFNT those bytes doesn't define a signature; */
   2255      /* it is thus possible that the font isn't a CFF at all.           */
   2256      if ( pure_cff )
   2257      {
   2258        FT_TRACE2(( "  not a CFF file\n" ));
   2259        error = FT_THROW( Unknown_File_Format );
   2260      }
   2261      goto Exit;
   2262    }
   2263 
   2264    if ( cff2 )
   2265    {
   2266      /* For CFF2, the top dict data immediately follow the header    */
   2267      /* and the length is stored in the header `offSize' field;      */
   2268      /* there is no index for it.                                    */
   2269      /*                                                              */
   2270      /* Use the `font_dict_index' to save the current position       */
   2271      /* and length of data, but leave count at zero as an indicator. */
   2272      FT_ZERO( &font->font_dict_index );
   2273 
   2274      font->font_dict_index.data_offset = FT_STREAM_POS();
   2275      font->font_dict_index.data_size   = font->top_dict_length;
   2276 
   2277      /* skip the top dict data for now, we will parse it later */
   2278      if ( FT_STREAM_SKIP( font->top_dict_length ) )
   2279        goto Exit;
   2280 
   2281      /* next, read the global subrs index */
   2282      if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
   2283                                         stream, 1, cff2 ) ) )
   2284        goto Exit;
   2285    }
   2286    else
   2287    {
   2288      /* for CFF, read the name, top dict, string and global subrs index */
   2289      if ( FT_SET_ERROR( cff_index_init( &font->name_index,
   2290                                         stream, 0, cff2 ) ) )
   2291      {
   2292        if ( pure_cff )
   2293        {
   2294          FT_TRACE2(( "  not a CFF file\n" ));
   2295          error = FT_THROW( Unknown_File_Format );
   2296        }
   2297        goto Exit;
   2298      }
   2299 
   2300      /* if we have an empty font name,      */
   2301      /* it must be the only font in the CFF */
   2302      if ( font->name_index.count > 1                          &&
   2303           font->name_index.data_size < font->name_index.count )
   2304      {
   2305        /* for pure CFFs, we still haven't checked enough bytes */
   2306        /* to be sure that it is a CFF at all                   */
   2307        error = pure_cff ? FT_THROW( Unknown_File_Format )
   2308                         : FT_THROW( Invalid_File_Format );
   2309        goto Exit;
   2310      }
   2311 
   2312      if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
   2313                                         stream, 0, cff2 ) )                 ||
   2314           FT_SET_ERROR( cff_index_init( &string_index,
   2315                                         stream, 1, cff2 ) )                 ||
   2316           FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
   2317                                         stream, 1, cff2 ) )                 ||
   2318           FT_SET_ERROR( cff_index_get_pointers( &string_index,
   2319                                                 &font->strings,
   2320                                                 &font->string_pool,
   2321                                                 &font->string_pool_size ) ) )
   2322        goto Exit;
   2323 
   2324      /* there must be a Top DICT index entry for each name index entry */
   2325      if ( font->name_index.count > font->font_dict_index.count )
   2326      {
   2327        FT_ERROR(( "cff_font_load:"
   2328                   " not enough entries in Top DICT index\n" ));
   2329        error = FT_THROW( Invalid_File_Format );
   2330        goto Exit;
   2331      }
   2332    }
   2333 
   2334    font->num_strings = string_index.count;
   2335 
   2336    if ( pure_cff )
   2337    {
   2338      /* well, we don't really forget the `disabled' fonts... */
   2339      subfont_index = (FT_UInt)( face_index & 0xFFFF );
   2340 
   2341      if ( face_index > 0 && subfont_index >= font->name_index.count )
   2342      {
   2343        FT_ERROR(( "cff_font_load:"
   2344                   " invalid subfont index for pure CFF font (%u)\n",
   2345                   subfont_index ));
   2346        error = FT_THROW( Invalid_Argument );
   2347        goto Exit;
   2348      }
   2349 
   2350      font->num_faces = font->name_index.count;
   2351    }
   2352    else
   2353    {
   2354      subfont_index = 0;
   2355 
   2356      if ( font->name_index.count > 1 )
   2357      {
   2358        FT_ERROR(( "cff_font_load:"
   2359                   " invalid CFF font with multiple subfonts\n" ));
   2360        FT_ERROR(( "              "
   2361                   " in SFNT wrapper\n" ));
   2362        error = FT_THROW( Invalid_File_Format );
   2363        goto Exit;
   2364      }
   2365    }
   2366 
   2367    /* in case of a font format check, simply exit now */
   2368    if ( face_index < 0 )
   2369      goto Exit;
   2370 
   2371    /* now, parse the top-level font dictionary */
   2372    FT_TRACE4(( "parsing top-level\n" ));
   2373    error = cff_subfont_load( &font->top_font,
   2374                              &font->font_dict_index,
   2375                              subfont_index,
   2376                              stream,
   2377                              base_offset,
   2378                              cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
   2379                              font,
   2380                              face );
   2381    if ( error )
   2382      goto Exit;
   2383 
   2384    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
   2385      goto Exit;
   2386 
   2387    error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
   2388    if ( error )
   2389      goto Exit;
   2390 
   2391    /* now, check for a CID or CFF2 font */
   2392    if ( dict->cid_registry != 0xFFFFU ||
   2393         cff2                          )
   2394    {
   2395      CFF_IndexRec  fd_index;
   2396      CFF_SubFont   sub = NULL;
   2397      FT_UInt       idx;
   2398 
   2399 
   2400      /* for CFF2, read the Variation Store if available;                 */
   2401      /* this must follow the Top DICT parse and precede any Private DICT */
   2402      error = cff_vstore_load( &font->vstore,
   2403                               stream,
   2404                               base_offset,
   2405                               dict->vstore_offset );
   2406      if ( error )
   2407        goto Exit;
   2408 
   2409      /* this is a CID-keyed font, we must now allocate a table of */
   2410      /* sub-fonts, then load each of them separately              */
   2411      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
   2412        goto Exit;
   2413 
   2414      error = cff_index_init( &fd_index, stream, 0, cff2 );
   2415      if ( error )
   2416        goto Exit;
   2417 
   2418      /* Font Dicts are not limited to 256 for CFF2. */
   2419      /* TODO: support this for CFF2                 */
   2420      if ( fd_index.count > CFF_MAX_CID_FONTS )
   2421      {
   2422        FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
   2423        goto Fail_CID;
   2424      }
   2425 
   2426      /* allocate & read each font dict independently */
   2427      font->num_subfonts = fd_index.count;
   2428      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
   2429        goto Fail_CID;
   2430 
   2431      /* set up pointer table */
   2432      for ( idx = 0; idx < fd_index.count; idx++ )
   2433        font->subfonts[idx] = sub + idx;
   2434 
   2435      /* now load each subfont independently */
   2436      for ( idx = 0; idx < fd_index.count; idx++ )
   2437      {
   2438        sub = font->subfonts[idx];
   2439        FT_TRACE4(( "parsing subfont %u\n", idx ));
   2440        error = cff_subfont_load( sub,
   2441                                  &fd_index,
   2442                                  idx,
   2443                                  stream,
   2444                                  base_offset,
   2445                                  cff2 ? CFF2_CODE_FONTDICT
   2446                                       : CFF_CODE_TOPDICT,
   2447                                  font,
   2448                                  face );
   2449        if ( error )
   2450          goto Fail_CID;
   2451      }
   2452 
   2453      /* now load the FD Select array;               */
   2454      /* CFF2 omits FDSelect if there is only one FD */
   2455      if ( !cff2 || fd_index.count > 1 )
   2456        error = CFF_Load_FD_Select( &font->fd_select,
   2457                                    font->charstrings_index.count,
   2458                                    stream,
   2459                                    base_offset + dict->cid_fd_select_offset );
   2460 
   2461    Fail_CID:
   2462      cff_index_done( &fd_index );
   2463 
   2464      if ( error )
   2465        goto Exit;
   2466    }
   2467    else
   2468      font->num_subfonts = 0;
   2469 
   2470    /* read the charstrings index now */
   2471    if ( dict->charstrings_offset == 0 )
   2472    {
   2473      FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
   2474      error = FT_THROW( Invalid_File_Format );
   2475      goto Exit;
   2476    }
   2477 
   2478    font->num_glyphs = font->charstrings_index.count;
   2479 
   2480    error = cff_index_get_pointers( &font->global_subrs_index,
   2481                                    &font->global_subrs, NULL, NULL );
   2482 
   2483    if ( error )
   2484      goto Exit;
   2485 
   2486    /* read the Charset and Encoding tables if available */
   2487    if ( !cff2 && font->num_glyphs > 0 )
   2488    {
   2489      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
   2490 
   2491 
   2492      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
   2493                                base_offset, dict->charset_offset, invert );
   2494      if ( error )
   2495        goto Exit;
   2496 
   2497      /* CID-keyed CFFs don't have an encoding */
   2498      if ( dict->cid_registry == 0xFFFFU )
   2499      {
   2500        error = cff_encoding_load( &font->encoding,
   2501                                   &font->charset,
   2502                                   font->num_glyphs,
   2503                                   stream,
   2504                                   base_offset,
   2505                                   dict->encoding_offset );
   2506        if ( error )
   2507          goto Exit;
   2508      }
   2509    }
   2510 
   2511    /* get the font name (/CIDFontName for CID-keyed fonts, */
   2512    /* /FontName otherwise)                                 */
   2513    font->font_name = cff_index_get_name( font, subfont_index );
   2514 
   2515  Exit:
   2516    cff_index_done( &string_index );
   2517 
   2518    return error;
   2519  }
   2520 
   2521 
   2522  FT_LOCAL_DEF( void )
   2523  cff_font_done( CFF_Font  font )
   2524  {
   2525    FT_Memory  memory = font->memory;
   2526    FT_UInt    idx;
   2527 
   2528 
   2529    cff_index_done( &font->global_subrs_index );
   2530    cff_index_done( &font->font_dict_index );
   2531    cff_index_done( &font->name_index );
   2532    cff_index_done( &font->charstrings_index );
   2533 
   2534    /* release font dictionaries, but only if working with */
   2535    /* a CID keyed CFF font or a CFF2 font                 */
   2536    if ( font->num_subfonts > 0 )
   2537    {
   2538      for ( idx = 0; idx < font->num_subfonts; idx++ )
   2539        cff_subfont_done( memory, font->subfonts[idx] );
   2540 
   2541      /* the subfonts array has been allocated as a single block */
   2542      FT_FREE( font->subfonts[0] );
   2543    }
   2544 
   2545    cff_encoding_done( &font->encoding );
   2546    cff_charset_done( &font->charset, font->stream );
   2547    cff_vstore_done( &font->vstore, memory );
   2548 
   2549    cff_subfont_done( memory, &font->top_font );
   2550 
   2551    CFF_Done_FD_Select( &font->fd_select, font->stream );
   2552 
   2553    FT_FREE( font->font_info );
   2554 
   2555    FT_FREE( font->font_name );
   2556    FT_FREE( font->global_subrs );
   2557    FT_FREE( font->strings );
   2558    FT_FREE( font->string_pool );
   2559 
   2560    if ( font->cf2_instance.finalizer )
   2561    {
   2562      font->cf2_instance.finalizer( font->cf2_instance.data );
   2563      FT_FREE( font->cf2_instance.data );
   2564    }
   2565 
   2566    FT_FREE( font->font_extra );
   2567  }
   2568 
   2569 
   2570 /* END */