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