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