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-2016 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include <ft2build.h>
     20 #include FT_INTERNAL_DEBUG_H
     21 #include FT_INTERNAL_OBJECTS_H
     22 #include FT_INTERNAL_STREAM_H
     23 #include FT_TRUETYPE_TAGS_H
     24 #include FT_TYPE1_TABLES_H
     25 
     26 #include "cffload.h"
     27 #include "cffparse.h"
     28 
     29 #include "cfferrs.h"
     30 
     31 
     32 #if 1
     33 
     34   static const FT_UShort  cff_isoadobe_charset[229] =
     35   {
     36       0,   1,   2,   3,   4,   5,   6,   7,
     37       8,   9,  10,  11,  12,  13,  14,  15,
     38      16,  17,  18,  19,  20,  21,  22,  23,
     39      24,  25,  26,  27,  28,  29,  30,  31,
     40      32,  33,  34,  35,  36,  37,  38,  39,
     41      40,  41,  42,  43,  44,  45,  46,  47,
     42      48,  49,  50,  51,  52,  53,  54,  55,
     43      56,  57,  58,  59,  60,  61,  62,  63,
     44      64,  65,  66,  67,  68,  69,  70,  71,
     45      72,  73,  74,  75,  76,  77,  78,  79,
     46      80,  81,  82,  83,  84,  85,  86,  87,
     47      88,  89,  90,  91,  92,  93,  94,  95,
     48      96,  97,  98,  99, 100, 101, 102, 103,
     49     104, 105, 106, 107, 108, 109, 110, 111,
     50     112, 113, 114, 115, 116, 117, 118, 119,
     51     120, 121, 122, 123, 124, 125, 126, 127,
     52     128, 129, 130, 131, 132, 133, 134, 135,
     53     136, 137, 138, 139, 140, 141, 142, 143,
     54     144, 145, 146, 147, 148, 149, 150, 151,
     55     152, 153, 154, 155, 156, 157, 158, 159,
     56     160, 161, 162, 163, 164, 165, 166, 167,
     57     168, 169, 170, 171, 172, 173, 174, 175,
     58     176, 177, 178, 179, 180, 181, 182, 183,
     59     184, 185, 186, 187, 188, 189, 190, 191,
     60     192, 193, 194, 195, 196, 197, 198, 199,
     61     200, 201, 202, 203, 204, 205, 206, 207,
     62     208, 209, 210, 211, 212, 213, 214, 215,
     63     216, 217, 218, 219, 220, 221, 222, 223,
     64     224, 225, 226, 227, 228
     65   };
     66 
     67   static const FT_UShort  cff_expert_charset[166] =
     68   {
     69       0,   1, 229, 230, 231, 232, 233, 234,
     70     235, 236, 237, 238,  13,  14,  15,  99,
     71     239, 240, 241, 242, 243, 244, 245, 246,
     72     247, 248,  27,  28, 249, 250, 251, 252,
     73     253, 254, 255, 256, 257, 258, 259, 260,
     74     261, 262, 263, 264, 265, 266, 109, 110,
     75     267, 268, 269, 270, 271, 272, 273, 274,
     76     275, 276, 277, 278, 279, 280, 281, 282,
     77     283, 284, 285, 286, 287, 288, 289, 290,
     78     291, 292, 293, 294, 295, 296, 297, 298,
     79     299, 300, 301, 302, 303, 304, 305, 306,
     80     307, 308, 309, 310, 311, 312, 313, 314,
     81     315, 316, 317, 318, 158, 155, 163, 319,
     82     320, 321, 322, 323, 324, 325, 326, 150,
     83     164, 169, 327, 328, 329, 330, 331, 332,
     84     333, 334, 335, 336, 337, 338, 339, 340,
     85     341, 342, 343, 344, 345, 346, 347, 348,
     86     349, 350, 351, 352, 353, 354, 355, 356,
     87     357, 358, 359, 360, 361, 362, 363, 364,
     88     365, 366, 367, 368, 369, 370, 371, 372,
     89     373, 374, 375, 376, 377, 378
     90   };
     91 
     92   static const FT_UShort  cff_expertsubset_charset[87] =
     93   {
     94       0,   1, 231, 232, 235, 236, 237, 238,
     95      13,  14,  15,  99, 239, 240, 241, 242,
     96     243, 244, 245, 246, 247, 248,  27,  28,
     97     249, 250, 251, 253, 254, 255, 256, 257,
     98     258, 259, 260, 261, 262, 263, 264, 265,
     99     266, 109, 110, 267, 268, 269, 270, 272,
    100     300, 301, 302, 305, 314, 315, 158, 155,
    101     163, 320, 321, 322, 323, 324, 325, 326,
    102     150, 164, 169, 327, 328, 329, 330, 331,
    103     332, 333, 334, 335, 336, 337, 338, 339,
    104     340, 341, 342, 343, 344, 345, 346
    105   };
    106 
    107   static const FT_UShort  cff_standard_encoding[256] =
    108   {
    109       0,   0,   0,   0,   0,   0,   0,   0,
    110       0,   0,   0,   0,   0,   0,   0,   0,
    111       0,   0,   0,   0,   0,   0,   0,   0,
    112       0,   0,   0,   0,   0,   0,   0,   0,
    113       1,   2,   3,   4,   5,   6,   7,   8,
    114       9,  10,  11,  12,  13,  14,  15,  16,
    115      17,  18,  19,  20,  21,  22,  23,  24,
    116      25,  26,  27,  28,  29,  30,  31,  32,
    117      33,  34,  35,  36,  37,  38,  39,  40,
    118      41,  42,  43,  44,  45,  46,  47,  48,
    119      49,  50,  51,  52,  53,  54,  55,  56,
    120      57,  58,  59,  60,  61,  62,  63,  64,
    121      65,  66,  67,  68,  69,  70,  71,  72,
    122      73,  74,  75,  76,  77,  78,  79,  80,
    123      81,  82,  83,  84,  85,  86,  87,  88,
    124      89,  90,  91,  92,  93,  94,  95,   0,
    125       0,   0,   0,   0,   0,   0,   0,   0,
    126       0,   0,   0,   0,   0,   0,   0,   0,
    127       0,   0,   0,   0,   0,   0,   0,   0,
    128       0,   0,   0,   0,   0,   0,   0,   0,
    129       0,  96,  97,  98,  99, 100, 101, 102,
    130     103, 104, 105, 106, 107, 108, 109, 110,
    131       0, 111, 112, 113, 114,   0, 115, 116,
    132     117, 118, 119, 120, 121, 122,   0, 123,
    133       0, 124, 125, 126, 127, 128, 129, 130,
    134     131,   0, 132, 133,   0, 134, 135, 136,
    135     137,   0,   0,   0,   0,   0,   0,   0,
    136       0,   0,   0,   0,   0,   0,   0,   0,
    137       0, 138,   0, 139,   0,   0,   0,   0,
    138     140, 141, 142, 143,   0,   0,   0,   0,
    139       0, 144,   0,   0,   0, 145,   0,   0,
    140     146, 147, 148, 149,   0,   0,   0,   0
    141   };
    142 
    143   static const FT_UShort  cff_expert_encoding[256] =
    144   {
    145       0,   0,   0,   0,   0,   0,   0,   0,
    146       0,   0,   0,   0,   0,   0,   0,   0,
    147       0,   0,   0,   0,   0,   0,   0,   0,
    148       0,   0,   0,   0,   0,   0,   0,   0,
    149       1, 229, 230,   0, 231, 232, 233, 234,
    150     235, 236, 237, 238,  13,  14,  15,  99,
    151     239, 240, 241, 242, 243, 244, 245, 246,
    152     247, 248,  27,  28, 249, 250, 251, 252,
    153       0, 253, 254, 255, 256, 257,   0,   0,
    154       0, 258,   0,   0, 259, 260, 261, 262,
    155       0,   0, 263, 264, 265,   0, 266, 109,
    156     110, 267, 268, 269,   0, 270, 271, 272,
    157     273, 274, 275, 276, 277, 278, 279, 280,
    158     281, 282, 283, 284, 285, 286, 287, 288,
    159     289, 290, 291, 292, 293, 294, 295, 296,
    160     297, 298, 299, 300, 301, 302, 303,   0,
    161       0,   0,   0,   0,   0,   0,   0,   0,
    162       0,   0,   0,   0,   0,   0,   0,   0,
    163       0,   0,   0,   0,   0,   0,   0,   0,
    164       0,   0,   0,   0,   0,   0,   0,   0,
    165       0, 304, 305, 306,   0,   0, 307, 308,
    166     309, 310, 311,   0, 312,   0,   0, 312,
    167       0,   0, 314, 315,   0,   0, 316, 317,
    168     318,   0,   0,   0, 158, 155, 163, 319,
    169     320, 321, 322, 323, 324, 325,   0,   0,
    170     326, 150, 164, 169, 327, 328, 329, 330,
    171     331, 332, 333, 334, 335, 336, 337, 338,
    172     339, 340, 341, 342, 343, 344, 345, 346,
    173     347, 348, 349, 350, 351, 352, 353, 354,
    174     355, 356, 357, 358, 359, 360, 361, 362,
    175     363, 364, 365, 366, 367, 368, 369, 370,
    176     371, 372, 373, 374, 375, 376, 377, 378
    177   };
    178 
    179 #endif /* 1 */
    180 
    181 
    182   FT_LOCAL_DEF( FT_UShort )
    183   cff_get_standard_encoding( FT_UInt  charcode )
    184   {
    185     return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
    186                                        : 0 );
    187   }
    188 
    189 
    190   /*************************************************************************/
    191   /*                                                                       */
    192   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
    193   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
    194   /* messages during execution.                                            */
    195   /*                                                                       */
    196 #undef  FT_COMPONENT
    197 #define FT_COMPONENT  trace_cffload
    198 
    199 
    200   /* read an offset from the index's stream current position */
    201   static FT_ULong
    202   cff_index_read_offset( CFF_Index  idx,
    203                          FT_Error  *errorp )
    204   {
    205     FT_Error   error;
    206     FT_Stream  stream = idx->stream;
    207     FT_Byte    tmp[4];
    208     FT_ULong   result = 0;
    209 
    210 
    211     if ( !FT_STREAM_READ( tmp, idx->off_size ) )
    212     {
    213       FT_Int  nn;
    214 
    215 
    216       for ( nn = 0; nn < idx->off_size; nn++ )
    217         result = ( result << 8 ) | tmp[nn];
    218     }
    219 
    220     *errorp = error;
    221     return result;
    222   }
    223 
    224 
    225   static FT_Error
    226   cff_index_init( CFF_Index  idx,
    227                   FT_Stream  stream,
    228                   FT_Bool    load )
    229   {
    230     FT_Error   error;
    231     FT_Memory  memory = stream->memory;
    232     FT_UShort  count;
    233 
    234 
    235     FT_MEM_ZERO( idx, sizeof ( *idx ) );
    236 
    237     idx->stream = stream;
    238     idx->start  = FT_STREAM_POS();
    239     if ( !FT_READ_USHORT( count ) &&
    240          count > 0                )
    241     {
    242       FT_Byte   offsize;
    243       FT_ULong  size;
    244 
    245 
    246       /* there is at least one element; read the offset size,           */
    247       /* then access the offset table to compute the index's total size */
    248       if ( FT_READ_BYTE( offsize ) )
    249         goto Exit;
    250 
    251       if ( offsize < 1 || offsize > 4 )
    252       {
    253         error = FT_THROW( Invalid_Table );
    254         goto Exit;
    255       }
    256 
    257       idx->count    = count;
    258       idx->off_size = offsize;
    259       size          = (FT_ULong)( count + 1 ) * offsize;
    260 
    261       idx->data_offset = idx->start + 3 + size;
    262 
    263       if ( FT_STREAM_SKIP( size - offsize ) )
    264         goto Exit;
    265 
    266       size = cff_index_read_offset( idx, &error );
    267       if ( error )
    268         goto Exit;
    269 
    270       if ( size == 0 )
    271       {
    272         error = FT_THROW( Invalid_Table );
    273         goto Exit;
    274       }
    275 
    276       idx->data_size = --size;
    277 
    278       if ( load )
    279       {
    280         /* load the data */
    281         if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
    282           goto Exit;
    283       }
    284       else
    285       {
    286         /* skip the data */
    287         if ( FT_STREAM_SKIP( size ) )
    288           goto Exit;
    289       }
    290     }
    291 
    292   Exit:
    293     if ( error )
    294       FT_FREE( idx->offsets );
    295 
    296     return error;
    297   }
    298 
    299 
    300   static void
    301   cff_index_done( CFF_Index  idx )
    302   {
    303     if ( idx->stream )
    304     {
    305       FT_Stream  stream = idx->stream;
    306       FT_Memory  memory = stream->memory;
    307 
    308 
    309       if ( idx->bytes )
    310         FT_FRAME_RELEASE( idx->bytes );
    311 
    312       FT_FREE( idx->offsets );
    313       FT_MEM_ZERO( idx, sizeof ( *idx ) );
    314     }
    315   }
    316 
    317 
    318   static FT_Error
    319   cff_index_load_offsets( CFF_Index  idx )
    320   {
    321     FT_Error   error  = FT_Err_Ok;
    322     FT_Stream  stream = idx->stream;
    323     FT_Memory  memory = stream->memory;
    324 
    325 
    326     if ( idx->count > 0 && idx->offsets == NULL )
    327     {
    328       FT_Byte    offsize = idx->off_size;
    329       FT_ULong   data_size;
    330       FT_Byte*   p;
    331       FT_Byte*   p_end;
    332       FT_ULong*  poff;
    333 
    334 
    335       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
    336 
    337       if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
    338            FT_STREAM_SEEK( idx->start + 3 )             ||
    339            FT_FRAME_ENTER( data_size )                  )
    340         goto Exit;
    341 
    342       poff   = idx->offsets;
    343       p      = (FT_Byte*)stream->cursor;
    344       p_end  = p + data_size;
    345 
    346       switch ( offsize )
    347       {
    348       case 1:
    349         for ( ; p < p_end; p++, poff++ )
    350           poff[0] = p[0];
    351         break;
    352 
    353       case 2:
    354         for ( ; p < p_end; p += 2, poff++ )
    355           poff[0] = FT_PEEK_USHORT( p );
    356         break;
    357 
    358       case 3:
    359         for ( ; p < p_end; p += 3, poff++ )
    360           poff[0] = FT_PEEK_UOFF3( p );
    361         break;
    362 
    363       default:
    364         for ( ; p < p_end; p += 4, poff++ )
    365           poff[0] = FT_PEEK_ULONG( p );
    366       }
    367 
    368       FT_FRAME_EXIT();
    369     }
    370 
    371   Exit:
    372     if ( error )
    373       FT_FREE( idx->offsets );
    374 
    375     return error;
    376   }
    377 
    378 
    379   /* Allocate a table containing pointers to an index's elements. */
    380   /* The `pool' argument makes this function convert the index    */
    381   /* entries to C-style strings (this is, NULL-terminated).       */
    382   static FT_Error
    383   cff_index_get_pointers( CFF_Index   idx,
    384                           FT_Byte***  table,
    385                           FT_Byte**   pool,
    386                           FT_ULong*   pool_size )
    387   {
    388     FT_Error   error     = FT_Err_Ok;
    389     FT_Memory  memory    = idx->stream->memory;
    390 
    391     FT_Byte**  t         = NULL;
    392     FT_Byte*   new_bytes = NULL;
    393     FT_ULong   new_size;
    394 
    395 
    396     *table = NULL;
    397 
    398     if ( idx->offsets == NULL )
    399     {
    400       error = cff_index_load_offsets( idx );
    401       if ( error )
    402         goto Exit;
    403     }
    404 
    405     new_size = idx->data_size + idx->count;
    406 
    407     if ( idx->count > 0                                &&
    408          !FT_NEW_ARRAY( t, idx->count + 1 )            &&
    409          ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
    410     {
    411       FT_ULong  n, cur_offset;
    412       FT_ULong  extra = 0;
    413       FT_Byte*  org_bytes = idx->bytes;
    414 
    415 
    416       /* at this point, `idx->offsets' can't be NULL */
    417       cur_offset = idx->offsets[0] - 1;
    418 
    419       /* sanity check */
    420       if ( cur_offset != 0 )
    421       {
    422         FT_TRACE0(( "cff_index_get_pointers:"
    423                     " invalid first offset value %d set to zero\n",
    424                     cur_offset ));
    425         cur_offset = 0;
    426       }
    427 
    428       if ( !pool )
    429         t[0] = org_bytes + cur_offset;
    430       else
    431         t[0] = new_bytes + cur_offset;
    432 
    433       for ( n = 1; n <= idx->count; n++ )
    434       {
    435         FT_ULong  next_offset = idx->offsets[n] - 1;
    436 
    437 
    438         /* two sanity checks for invalid offset tables */
    439         if ( next_offset < cur_offset )
    440           next_offset = cur_offset;
    441         else if ( next_offset > idx->data_size )
    442           next_offset = idx->data_size;
    443 
    444         if ( !pool )
    445           t[n] = org_bytes + next_offset;
    446         else
    447         {
    448           t[n] = new_bytes + next_offset + extra;
    449 
    450           if ( next_offset != cur_offset )
    451           {
    452             FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
    453             t[n][0] = '\0';
    454             t[n]   += 1;
    455             extra++;
    456           }
    457         }
    458 
    459         cur_offset = next_offset;
    460       }
    461       *table = t;
    462 
    463       if ( pool )
    464         *pool = new_bytes;
    465       if ( pool_size )
    466         *pool_size = new_size;
    467     }
    468 
    469   Exit:
    470     return error;
    471   }
    472 
    473 
    474   FT_LOCAL_DEF( FT_Error )
    475   cff_index_access_element( CFF_Index  idx,
    476                             FT_UInt    element,
    477                             FT_Byte**  pbytes,
    478                             FT_ULong*  pbyte_len )
    479   {
    480     FT_Error  error = FT_Err_Ok;
    481 
    482 
    483     if ( idx && idx->count > element )
    484     {
    485       /* compute start and end offsets */
    486       FT_Stream  stream = idx->stream;
    487       FT_ULong   off1, off2 = 0;
    488 
    489 
    490       /* load offsets from file or the offset table */
    491       if ( !idx->offsets )
    492       {
    493         FT_ULong  pos = element * idx->off_size;
    494 
    495 
    496         if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
    497           goto Exit;
    498 
    499         off1 = cff_index_read_offset( idx, &error );
    500         if ( error )
    501           goto Exit;
    502 
    503         if ( off1 != 0 )
    504         {
    505           do
    506           {
    507             element++;
    508             off2 = cff_index_read_offset( idx, &error );
    509 
    510           } while ( off2 == 0 && element < idx->count );
    511         }
    512       }
    513       else   /* use offsets table */
    514       {
    515         off1 = idx->offsets[element];
    516         if ( off1 )
    517         {
    518           do
    519           {
    520             element++;
    521             off2 = idx->offsets[element];
    522 
    523           } while ( off2 == 0 && element < idx->count );
    524         }
    525       }
    526 
    527       /* XXX: should check off2 does not exceed the end of this entry; */
    528       /*      at present, only truncate off2 at the end of this stream */
    529       if ( off2 > stream->size + 1                    ||
    530            idx->data_offset > stream->size - off2 + 1 )
    531       {
    532         FT_ERROR(( "cff_index_access_element:"
    533                    " offset to next entry (%d)"
    534                    " exceeds the end of stream (%d)\n",
    535                    off2, stream->size - idx->data_offset + 1 ));
    536         off2 = stream->size - idx->data_offset + 1;
    537       }
    538 
    539       /* access element */
    540       if ( off1 && off2 > off1 )
    541       {
    542         *pbyte_len = off2 - off1;
    543 
    544         if ( idx->bytes )
    545         {
    546           /* this index was completely loaded in memory, that's easy */
    547           *pbytes = idx->bytes + off1 - 1;
    548         }
    549         else
    550         {
    551           /* this index is still on disk/file, access it through a frame */
    552           if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
    553                FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
    554             goto Exit;
    555         }
    556       }
    557       else
    558       {
    559         /* empty index element */
    560         *pbytes    = 0;
    561         *pbyte_len = 0;
    562       }
    563     }
    564     else
    565       error = FT_THROW( Invalid_Argument );
    566 
    567   Exit:
    568     return error;
    569   }
    570 
    571 
    572   FT_LOCAL_DEF( void )
    573   cff_index_forget_element( CFF_Index  idx,
    574                             FT_Byte**  pbytes )
    575   {
    576     if ( idx->bytes == 0 )
    577     {
    578       FT_Stream  stream = idx->stream;
    579 
    580 
    581       FT_FRAME_RELEASE( *pbytes );
    582     }
    583   }
    584 
    585 
    586   /* get an entry from Name INDEX */
    587   FT_LOCAL_DEF( FT_String* )
    588   cff_index_get_name( CFF_Font  font,
    589                       FT_UInt   element )
    590   {
    591     CFF_Index   idx = &font->name_index;
    592     FT_Memory   memory = idx->stream->memory;
    593     FT_Byte*    bytes;
    594     FT_ULong    byte_len;
    595     FT_Error    error;
    596     FT_String*  name = 0;
    597 
    598 
    599     error = cff_index_access_element( idx, element, &bytes, &byte_len );
    600     if ( error )
    601       goto Exit;
    602 
    603     if ( !FT_ALLOC( name, byte_len + 1 ) )
    604     {
    605       if ( byte_len )
    606         FT_MEM_COPY( name, bytes, byte_len );
    607       name[byte_len] = 0;
    608     }
    609     cff_index_forget_element( idx, &bytes );
    610 
    611   Exit:
    612     return name;
    613   }
    614 
    615 
    616   /* get an entry from String INDEX */
    617   FT_LOCAL_DEF( FT_String* )
    618   cff_index_get_string( CFF_Font  font,
    619                         FT_UInt   element )
    620   {
    621     return ( element < font->num_strings )
    622              ? (FT_String*)font->strings[element]
    623              : NULL;
    624   }
    625 
    626 
    627   FT_LOCAL_DEF( FT_String* )
    628   cff_index_get_sid_string( CFF_Font  font,
    629                             FT_UInt   sid )
    630   {
    631     /* value 0xFFFFU indicates a missing dictionary entry */
    632     if ( sid == 0xFFFFU )
    633       return NULL;
    634 
    635     /* if it is not a standard string, return it */
    636     if ( sid > 390 )
    637       return cff_index_get_string( font, sid - 391 );
    638 
    639     /* CID-keyed CFF fonts don't have glyph names */
    640     if ( !font->psnames )
    641       return NULL;
    642 
    643     /* this is a standard string */
    644     return (FT_String *)font->psnames->adobe_std_strings( sid );
    645   }
    646 
    647 
    648   /*************************************************************************/
    649   /*************************************************************************/
    650   /***                                                                   ***/
    651   /***   FD Select table support                                         ***/
    652   /***                                                                   ***/
    653   /*************************************************************************/
    654   /*************************************************************************/
    655 
    656 
    657   static void
    658   CFF_Done_FD_Select( CFF_FDSelect  fdselect,
    659                       FT_Stream     stream )
    660   {
    661     if ( fdselect->data )
    662       FT_FRAME_RELEASE( fdselect->data );
    663 
    664     fdselect->data_size   = 0;
    665     fdselect->format      = 0;
    666     fdselect->range_count = 0;
    667   }
    668 
    669 
    670   static FT_Error
    671   CFF_Load_FD_Select( CFF_FDSelect  fdselect,
    672                       FT_UInt       num_glyphs,
    673                       FT_Stream     stream,
    674                       FT_ULong      offset )
    675   {
    676     FT_Error  error;
    677     FT_Byte   format;
    678     FT_UInt   num_ranges;
    679 
    680 
    681     /* read format */
    682     if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
    683       goto Exit;
    684 
    685     fdselect->format      = format;
    686     fdselect->cache_count = 0;   /* clear cache */
    687 
    688     switch ( format )
    689     {
    690     case 0:     /* format 0, that's simple */
    691       fdselect->data_size = num_glyphs;
    692       goto Load_Data;
    693 
    694     case 3:     /* format 3, a tad more complex */
    695       if ( FT_READ_USHORT( num_ranges ) )
    696         goto Exit;
    697 
    698       if ( !num_ranges )
    699       {
    700         FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
    701         error = FT_THROW( Invalid_File_Format );
    702         goto Exit;
    703       }
    704 
    705       fdselect->data_size = num_ranges * 3 + 2;
    706 
    707     Load_Data:
    708       if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
    709         goto Exit;
    710       break;
    711 
    712     default:    /* hmm... that's wrong */
    713       error = FT_THROW( Invalid_File_Format );
    714     }
    715 
    716   Exit:
    717     return error;
    718   }
    719 
    720 
    721   FT_LOCAL_DEF( FT_Byte )
    722   cff_fd_select_get( CFF_FDSelect  fdselect,
    723                      FT_UInt       glyph_index )
    724   {
    725     FT_Byte  fd = 0;
    726 
    727 
    728     switch ( fdselect->format )
    729     {
    730     case 0:
    731       fd = fdselect->data[glyph_index];
    732       break;
    733 
    734     case 3:
    735       /* first, compare to the cache */
    736       if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
    737                         fdselect->cache_count )
    738       {
    739         fd = fdselect->cache_fd;
    740         break;
    741       }
    742 
    743       /* then, look up the ranges array */
    744       {
    745         FT_Byte*  p       = fdselect->data;
    746         FT_Byte*  p_limit = p + fdselect->data_size;
    747         FT_Byte   fd2;
    748         FT_UInt   first, limit;
    749 
    750 
    751         first = FT_NEXT_USHORT( p );
    752         do
    753         {
    754           if ( glyph_index < first )
    755             break;
    756 
    757           fd2   = *p++;
    758           limit = FT_NEXT_USHORT( p );
    759 
    760           if ( glyph_index < limit )
    761           {
    762             fd = fd2;
    763 
    764             /* update cache */
    765             fdselect->cache_first = first;
    766             fdselect->cache_count = limit - first;
    767             fdselect->cache_fd    = fd2;
    768             break;
    769           }
    770           first = limit;
    771 
    772         } while ( p < p_limit );
    773       }
    774       break;
    775 
    776     default:
    777       ;
    778     }
    779 
    780     return fd;
    781   }
    782 
    783 
    784   /*************************************************************************/
    785   /*************************************************************************/
    786   /***                                                                   ***/
    787   /***   CFF font support                                                ***/
    788   /***                                                                   ***/
    789   /*************************************************************************/
    790   /*************************************************************************/
    791 
    792   static FT_Error
    793   cff_charset_compute_cids( CFF_Charset  charset,
    794                             FT_UInt      num_glyphs,
    795                             FT_Memory    memory )
    796   {
    797     FT_Error   error   = FT_Err_Ok;
    798     FT_UInt    i;
    799     FT_Long    j;
    800     FT_UShort  max_cid = 0;
    801 
    802 
    803     if ( charset->max_cid > 0 )
    804       goto Exit;
    805 
    806     for ( i = 0; i < num_glyphs; i++ )
    807     {
    808       if ( charset->sids[i] > max_cid )
    809         max_cid = charset->sids[i];
    810     }
    811 
    812     if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
    813       goto Exit;
    814 
    815     /* When multiple GIDs map to the same CID, we choose the lowest */
    816     /* GID.  This is not described in any spec, but it matches the  */
    817     /* behaviour of recent Acroread versions.                       */
    818     for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
    819       charset->cids[charset->sids[j]] = (FT_UShort)j;
    820 
    821     charset->max_cid    = max_cid;
    822     charset->num_glyphs = num_glyphs;
    823 
    824   Exit:
    825     return error;
    826   }
    827 
    828 
    829   FT_LOCAL_DEF( FT_UInt )
    830   cff_charset_cid_to_gindex( CFF_Charset  charset,
    831                              FT_UInt      cid )
    832   {
    833     FT_UInt  result = 0;
    834 
    835 
    836     if ( cid <= charset->max_cid )
    837       result = charset->cids[cid];
    838 
    839     return result;
    840   }
    841 
    842 
    843   static void
    844   cff_charset_free_cids( CFF_Charset  charset,
    845                          FT_Memory    memory )
    846   {
    847     FT_FREE( charset->cids );
    848     charset->max_cid = 0;
    849   }
    850 
    851 
    852   static void
    853   cff_charset_done( CFF_Charset  charset,
    854                     FT_Stream    stream )
    855   {
    856     FT_Memory  memory = stream->memory;
    857 
    858 
    859     cff_charset_free_cids( charset, memory );
    860 
    861     FT_FREE( charset->sids );
    862     charset->format = 0;
    863     charset->offset = 0;
    864   }
    865 
    866 
    867   static FT_Error
    868   cff_charset_load( CFF_Charset  charset,
    869                     FT_UInt      num_glyphs,
    870                     FT_Stream    stream,
    871                     FT_ULong     base_offset,
    872                     FT_ULong     offset,
    873                     FT_Bool      invert )
    874   {
    875     FT_Memory  memory = stream->memory;
    876     FT_Error   error  = FT_Err_Ok;
    877     FT_UShort  glyph_sid;
    878 
    879 
    880     /* If the offset is greater than 2, we have to parse the charset */
    881     /* table.                                                        */
    882     if ( offset > 2 )
    883     {
    884       FT_UInt  j;
    885 
    886 
    887       charset->offset = base_offset + offset;
    888 
    889       /* Get the format of the table. */
    890       if ( FT_STREAM_SEEK( charset->offset ) ||
    891            FT_READ_BYTE( charset->format )   )
    892         goto Exit;
    893 
    894       /* Allocate memory for sids. */
    895       if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
    896         goto Exit;
    897 
    898       /* assign the .notdef glyph */
    899       charset->sids[0] = 0;
    900 
    901       switch ( charset->format )
    902       {
    903       case 0:
    904         if ( num_glyphs > 0 )
    905         {
    906           if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
    907             goto Exit;
    908 
    909           for ( j = 1; j < num_glyphs; j++ )
    910             charset->sids[j] = FT_GET_USHORT();
    911 
    912           FT_FRAME_EXIT();
    913         }
    914         break;
    915 
    916       case 1:
    917       case 2:
    918         {
    919           FT_UInt  nleft;
    920           FT_UInt  i;
    921 
    922 
    923           j = 1;
    924 
    925           while ( j < num_glyphs )
    926           {
    927             /* Read the first glyph sid of the range. */
    928             if ( FT_READ_USHORT( glyph_sid ) )
    929               goto Exit;
    930 
    931             /* Read the number of glyphs in the range.  */
    932             if ( charset->format == 2 )
    933             {
    934               if ( FT_READ_USHORT( nleft ) )
    935                 goto Exit;
    936             }
    937             else
    938             {
    939               if ( FT_READ_BYTE( nleft ) )
    940                 goto Exit;
    941             }
    942 
    943             /* try to rescue some of the SIDs if `nleft' is too large */
    944             if ( glyph_sid > 0xFFFFL - nleft )
    945             {
    946               FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
    947                          " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
    948               nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
    949             }
    950 
    951             /* Fill in the range of sids -- `nleft + 1' glyphs. */
    952             for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
    953               charset->sids[j] = glyph_sid;
    954           }
    955         }
    956         break;
    957 
    958       default:
    959         FT_ERROR(( "cff_charset_load: invalid table format\n" ));
    960         error = FT_THROW( Invalid_File_Format );
    961         goto Exit;
    962       }
    963     }
    964     else
    965     {
    966       /* Parse default tables corresponding to offset == 0, 1, or 2.  */
    967       /* CFF specification intimates the following:                   */
    968       /*                                                              */
    969       /* In order to use a predefined charset, the following must be  */
    970       /* true: The charset constructed for the glyphs in the font's   */
    971       /* charstrings dictionary must match the predefined charset in  */
    972       /* the first num_glyphs.                                        */
    973 
    974       charset->offset = offset;  /* record charset type */
    975 
    976       switch ( (FT_UInt)offset )
    977       {
    978       case 0:
    979         if ( num_glyphs > 229 )
    980         {
    981           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
    982                      "predefined charset (Adobe ISO-Latin)\n" ));
    983           error = FT_THROW( Invalid_File_Format );
    984           goto Exit;
    985         }
    986 
    987         /* Allocate memory for sids. */
    988         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
    989           goto Exit;
    990 
    991         /* Copy the predefined charset into the allocated memory. */
    992         FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
    993 
    994         break;
    995 
    996       case 1:
    997         if ( num_glyphs > 166 )
    998         {
    999           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
   1000                      "predefined charset (Adobe Expert)\n" ));
   1001           error = FT_THROW( Invalid_File_Format );
   1002           goto Exit;
   1003         }
   1004 
   1005         /* Allocate memory for sids. */
   1006         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
   1007           goto Exit;
   1008 
   1009         /* Copy the predefined charset into the allocated memory.     */
   1010         FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
   1011 
   1012         break;
   1013 
   1014       case 2:
   1015         if ( num_glyphs > 87 )
   1016         {
   1017           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
   1018                      "predefined charset (Adobe Expert Subset)\n" ));
   1019           error = FT_THROW( Invalid_File_Format );
   1020           goto Exit;
   1021         }
   1022 
   1023         /* Allocate memory for sids. */
   1024         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
   1025           goto Exit;
   1026 
   1027         /* Copy the predefined charset into the allocated memory.     */
   1028         FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
   1029 
   1030         break;
   1031 
   1032       default:
   1033         error = FT_THROW( Invalid_File_Format );
   1034         goto Exit;
   1035       }
   1036     }
   1037 
   1038     /* we have to invert the `sids' array for subsetted CID-keyed fonts */
   1039     if ( invert )
   1040       error = cff_charset_compute_cids( charset, num_glyphs, memory );
   1041 
   1042   Exit:
   1043     /* Clean up if there was an error. */
   1044     if ( error )
   1045     {
   1046       FT_FREE( charset->sids );
   1047       FT_FREE( charset->cids );
   1048       charset->format = 0;
   1049       charset->offset = 0;
   1050       charset->sids   = 0;
   1051     }
   1052 
   1053     return error;
   1054   }
   1055 
   1056 
   1057   static void
   1058   cff_encoding_done( CFF_Encoding  encoding )
   1059   {
   1060     encoding->format = 0;
   1061     encoding->offset = 0;
   1062     encoding->count  = 0;
   1063   }
   1064 
   1065 
   1066   static FT_Error
   1067   cff_encoding_load( CFF_Encoding  encoding,
   1068                      CFF_Charset   charset,
   1069                      FT_UInt       num_glyphs,
   1070                      FT_Stream     stream,
   1071                      FT_ULong      base_offset,
   1072                      FT_ULong      offset )
   1073   {
   1074     FT_Error   error = FT_Err_Ok;
   1075     FT_UInt    count;
   1076     FT_UInt    j;
   1077     FT_UShort  glyph_sid;
   1078     FT_UInt    glyph_code;
   1079 
   1080 
   1081     /* Check for charset->sids.  If we do not have this, we fail. */
   1082     if ( !charset->sids )
   1083     {
   1084       error = FT_THROW( Invalid_File_Format );
   1085       goto Exit;
   1086     }
   1087 
   1088     /* Zero out the code to gid/sid mappings. */
   1089     for ( j = 0; j < 256; j++ )
   1090     {
   1091       encoding->sids [j] = 0;
   1092       encoding->codes[j] = 0;
   1093     }
   1094 
   1095     /* Note: The encoding table in a CFF font is indexed by glyph index;  */
   1096     /* the first encoded glyph index is 1.  Hence, we read the character  */
   1097     /* code (`glyph_code') at index j and make the assignment:            */
   1098     /*                                                                    */
   1099     /*    encoding->codes[glyph_code] = j + 1                             */
   1100     /*                                                                    */
   1101     /* We also make the assignment:                                       */
   1102     /*                                                                    */
   1103     /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
   1104     /*                                                                    */
   1105     /* This gives us both a code to GID and a code to SID mapping.        */
   1106 
   1107     if ( offset > 1 )
   1108     {
   1109       encoding->offset = base_offset + offset;
   1110 
   1111       /* we need to parse the table to determine its size */
   1112       if ( FT_STREAM_SEEK( encoding->offset ) ||
   1113            FT_READ_BYTE( encoding->format )   ||
   1114            FT_READ_BYTE( count )              )
   1115         goto Exit;
   1116 
   1117       switch ( encoding->format & 0x7F )
   1118       {
   1119       case 0:
   1120         {
   1121           FT_Byte*  p;
   1122 
   1123 
   1124           /* By convention, GID 0 is always ".notdef" and is never */
   1125           /* coded in the font.  Hence, the number of codes found  */
   1126           /* in the table is `count+1'.                            */
   1127           /*                                                       */
   1128           encoding->count = count + 1;
   1129 
   1130           if ( FT_FRAME_ENTER( count ) )
   1131             goto Exit;
   1132 
   1133           p = (FT_Byte*)stream->cursor;
   1134 
   1135           for ( j = 1; j <= count; j++ )
   1136           {
   1137             glyph_code = *p++;
   1138 
   1139             /* Make sure j is not too big. */
   1140             if ( j < num_glyphs )
   1141             {
   1142               /* Assign code to GID mapping. */
   1143               encoding->codes[glyph_code] = (FT_UShort)j;
   1144 
   1145               /* Assign code to SID mapping. */
   1146               encoding->sids[glyph_code] = charset->sids[j];
   1147             }
   1148           }
   1149 
   1150           FT_FRAME_EXIT();
   1151         }
   1152         break;
   1153 
   1154       case 1:
   1155         {
   1156           FT_UInt  nleft;
   1157           FT_UInt  i = 1;
   1158           FT_UInt  k;
   1159 
   1160 
   1161           encoding->count = 0;
   1162 
   1163           /* Parse the Format1 ranges. */
   1164           for ( j = 0;  j < count; j++, i += nleft )
   1165           {
   1166             /* Read the first glyph code of the range. */
   1167             if ( FT_READ_BYTE( glyph_code ) )
   1168               goto Exit;
   1169 
   1170             /* Read the number of codes in the range. */
   1171             if ( FT_READ_BYTE( nleft ) )
   1172               goto Exit;
   1173 
   1174             /* Increment nleft, so we read `nleft + 1' codes/sids. */
   1175             nleft++;
   1176 
   1177             /* compute max number of character codes */
   1178             if ( (FT_UInt)nleft > encoding->count )
   1179               encoding->count = nleft;
   1180 
   1181             /* Fill in the range of codes/sids. */
   1182             for ( k = i; k < nleft + i; k++, glyph_code++ )
   1183             {
   1184               /* Make sure k is not too big. */
   1185               if ( k < num_glyphs && glyph_code < 256 )
   1186               {
   1187                 /* Assign code to GID mapping. */
   1188                 encoding->codes[glyph_code] = (FT_UShort)k;
   1189 
   1190                 /* Assign code to SID mapping. */
   1191                 encoding->sids[glyph_code] = charset->sids[k];
   1192               }
   1193             }
   1194           }
   1195 
   1196           /* simple check; one never knows what can be found in a font */
   1197           if ( encoding->count > 256 )
   1198             encoding->count = 256;
   1199         }
   1200         break;
   1201 
   1202       default:
   1203         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
   1204         error = FT_THROW( Invalid_File_Format );
   1205         goto Exit;
   1206       }
   1207 
   1208       /* Parse supplemental encodings, if any. */
   1209       if ( encoding->format & 0x80 )
   1210       {
   1211         FT_UInt  gindex;
   1212 
   1213 
   1214         /* count supplements */
   1215         if ( FT_READ_BYTE( count ) )
   1216           goto Exit;
   1217 
   1218         for ( j = 0; j < count; j++ )
   1219         {
   1220           /* Read supplemental glyph code. */
   1221           if ( FT_READ_BYTE( glyph_code ) )
   1222             goto Exit;
   1223 
   1224           /* Read the SID associated with this glyph code. */
   1225           if ( FT_READ_USHORT( glyph_sid ) )
   1226             goto Exit;
   1227 
   1228           /* Assign code to SID mapping. */
   1229           encoding->sids[glyph_code] = glyph_sid;
   1230 
   1231           /* First, look up GID which has been assigned to */
   1232           /* SID glyph_sid.                                */
   1233           for ( gindex = 0; gindex < num_glyphs; gindex++ )
   1234           {
   1235             if ( charset->sids[gindex] == glyph_sid )
   1236             {
   1237               encoding->codes[glyph_code] = (FT_UShort)gindex;
   1238               break;
   1239             }
   1240           }
   1241         }
   1242       }
   1243     }
   1244     else
   1245     {
   1246       /* We take into account the fact a CFF font can use a predefined */
   1247       /* encoding without containing all of the glyphs encoded by this */
   1248       /* encoding (see the note at the end of section 12 in the CFF    */
   1249       /* specification).                                               */
   1250 
   1251       switch ( (FT_UInt)offset )
   1252       {
   1253       case 0:
   1254         /* First, copy the code to SID mapping. */
   1255         FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
   1256         goto Populate;
   1257 
   1258       case 1:
   1259         /* First, copy the code to SID mapping. */
   1260         FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
   1261 
   1262       Populate:
   1263         /* Construct code to GID mapping from code to SID mapping */
   1264         /* and charset.                                           */
   1265 
   1266         encoding->count = 0;
   1267 
   1268         error = cff_charset_compute_cids( charset, num_glyphs,
   1269                                           stream->memory );
   1270         if ( error )
   1271           goto Exit;
   1272 
   1273         for ( j = 0; j < 256; j++ )
   1274         {
   1275           FT_UInt  sid = encoding->sids[j];
   1276           FT_UInt  gid = 0;
   1277 
   1278 
   1279           if ( sid )
   1280             gid = cff_charset_cid_to_gindex( charset, sid );
   1281 
   1282           if ( gid != 0 )
   1283           {
   1284             encoding->codes[j] = (FT_UShort)gid;
   1285             encoding->count    = j + 1;
   1286           }
   1287           else
   1288           {
   1289             encoding->codes[j] = 0;
   1290             encoding->sids [j] = 0;
   1291           }
   1292         }
   1293         break;
   1294 
   1295       default:
   1296         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
   1297         error = FT_THROW( Invalid_File_Format );
   1298         goto Exit;
   1299       }
   1300     }
   1301 
   1302   Exit:
   1303 
   1304     /* Clean up if there was an error. */
   1305     return error;
   1306   }
   1307 
   1308 
   1309   static FT_Error
   1310   cff_subfont_load( CFF_SubFont  font,
   1311                     CFF_Index    idx,
   1312                     FT_UInt      font_index,
   1313                     FT_Stream    stream,
   1314                     FT_ULong     base_offset,
   1315                     FT_Library   library )
   1316   {
   1317     FT_Error         error;
   1318     CFF_ParserRec    parser;
   1319     FT_Byte*         dict = NULL;
   1320     FT_ULong         dict_len;
   1321     CFF_FontRecDict  top  = &font->font_dict;
   1322     CFF_Private      priv = &font->private_dict;
   1323 
   1324 
   1325     cff_parser_init( &parser,
   1326                      CFF_CODE_TOPDICT,
   1327                      &font->font_dict,
   1328                      library,
   1329                      0,
   1330                      0 );
   1331 
   1332     /* set defaults */
   1333     FT_MEM_ZERO( top, sizeof ( *top ) );
   1334 
   1335     top->underline_position  = -( 100L << 16 );
   1336     top->underline_thickness = 50L << 16;
   1337     top->charstring_type     = 2;
   1338     top->font_matrix.xx      = 0x10000L;
   1339     top->font_matrix.yy      = 0x10000L;
   1340     top->cid_count           = 8720;
   1341 
   1342     /* we use the implementation specific SID value 0xFFFF to indicate */
   1343     /* missing entries                                                 */
   1344     top->version             = 0xFFFFU;
   1345     top->notice              = 0xFFFFU;
   1346     top->copyright           = 0xFFFFU;
   1347     top->full_name           = 0xFFFFU;
   1348     top->family_name         = 0xFFFFU;
   1349     top->weight              = 0xFFFFU;
   1350     top->embedded_postscript = 0xFFFFU;
   1351 
   1352     top->cid_registry        = 0xFFFFU;
   1353     top->cid_ordering        = 0xFFFFU;
   1354     top->cid_font_name       = 0xFFFFU;
   1355 
   1356     error = cff_index_access_element( idx, font_index, &dict, &dict_len );
   1357     if ( !error )
   1358     {
   1359       FT_TRACE4(( " top dictionary:\n" ));
   1360       error = cff_parser_run( &parser, dict, dict + dict_len );
   1361     }
   1362 
   1363     cff_index_forget_element( idx, &dict );
   1364 
   1365     if ( error )
   1366       goto Exit;
   1367 
   1368     /* if it is a CID font, we stop there */
   1369     if ( top->cid_registry != 0xFFFFU )
   1370       goto Exit;
   1371 
   1372     /* parse the private dictionary, if any */
   1373     if ( top->private_offset && top->private_size )
   1374     {
   1375       /* set defaults */
   1376       FT_MEM_ZERO( priv, sizeof ( *priv ) );
   1377 
   1378       priv->blue_shift       = 7;
   1379       priv->blue_fuzz        = 1;
   1380       priv->lenIV            = -1;
   1381       priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
   1382       priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
   1383 
   1384       cff_parser_init( &parser,
   1385                        CFF_CODE_PRIVATE,
   1386                        priv,
   1387                        library,
   1388                        top->num_designs,
   1389                        top->num_axes );
   1390 
   1391       if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
   1392            FT_FRAME_ENTER( font->font_dict.private_size )                 )
   1393         goto Exit;
   1394 
   1395       FT_TRACE4(( " private dictionary:\n" ));
   1396       error = cff_parser_run( &parser,
   1397                               (FT_Byte*)stream->cursor,
   1398                               (FT_Byte*)stream->limit );
   1399       FT_FRAME_EXIT();
   1400       if ( error )
   1401         goto Exit;
   1402 
   1403       /* ensure that `num_blue_values' is even */
   1404       priv->num_blue_values &= ~1;
   1405     }
   1406 
   1407     /* read the local subrs, if any */
   1408     if ( priv->local_subrs_offset )
   1409     {
   1410       if ( FT_STREAM_SEEK( base_offset + top->private_offset +
   1411                            priv->local_subrs_offset ) )
   1412         goto Exit;
   1413 
   1414       error = cff_index_init( &font->local_subrs_index, stream, 1 );
   1415       if ( error )
   1416         goto Exit;
   1417 
   1418       error = cff_index_get_pointers( &font->local_subrs_index,
   1419                                       &font->local_subrs, NULL, NULL );
   1420       if ( error )
   1421         goto Exit;
   1422     }
   1423 
   1424   Exit:
   1425     return error;
   1426   }
   1427 
   1428 
   1429   static void
   1430   cff_subfont_done( FT_Memory    memory,
   1431                     CFF_SubFont  subfont )
   1432   {
   1433     if ( subfont )
   1434     {
   1435       cff_index_done( &subfont->local_subrs_index );
   1436       FT_FREE( subfont->local_subrs );
   1437     }
   1438   }
   1439 
   1440 
   1441   FT_LOCAL_DEF( FT_Error )
   1442   cff_font_load( FT_Library library,
   1443                  FT_Stream  stream,
   1444                  FT_Int     face_index,
   1445                  CFF_Font   font,
   1446                  FT_Bool    pure_cff )
   1447   {
   1448     static const FT_Frame_Field  cff_header_fields[] =
   1449     {
   1450 #undef  FT_STRUCTURE
   1451 #define FT_STRUCTURE  CFF_FontRec
   1452 
   1453       FT_FRAME_START( 4 ),
   1454         FT_FRAME_BYTE( version_major ),
   1455         FT_FRAME_BYTE( version_minor ),
   1456         FT_FRAME_BYTE( header_size ),
   1457         FT_FRAME_BYTE( absolute_offsize ),
   1458       FT_FRAME_END
   1459     };
   1460 
   1461     FT_Error         error;
   1462     FT_Memory        memory = stream->memory;
   1463     FT_ULong         base_offset;
   1464     CFF_FontRecDict  dict;
   1465     CFF_IndexRec     string_index;
   1466     FT_UInt          subfont_index;
   1467 
   1468 
   1469     FT_ZERO( font );
   1470     FT_ZERO( &string_index );
   1471 
   1472     font->stream = stream;
   1473     font->memory = memory;
   1474     dict         = &font->top_font.font_dict;
   1475     base_offset  = FT_STREAM_POS();
   1476 
   1477     /* read CFF font header */
   1478     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
   1479       goto Exit;
   1480 
   1481     /* check format */
   1482     if ( font->version_major   != 1 ||
   1483          font->header_size      < 4 ||
   1484          font->absolute_offsize > 4 )
   1485     {
   1486       FT_TRACE2(( "  not a CFF font header\n" ));
   1487       error = FT_THROW( Unknown_File_Format );
   1488       goto Exit;
   1489     }
   1490 
   1491     /* skip the rest of the header */
   1492     if ( FT_STREAM_SKIP( font->header_size - 4 ) )
   1493       goto Exit;
   1494 
   1495     /* read the name, top dict, string and global subrs index */
   1496     if ( FT_SET_ERROR( cff_index_init( &font->name_index,
   1497                                        stream, 0 ) )                       ||
   1498          FT_SET_ERROR( cff_index_init( &font->font_dict_index,
   1499                                        stream, 0 ) )                       ||
   1500          FT_SET_ERROR( cff_index_init( &string_index,
   1501                                        stream, 1 ) )                       ||
   1502          FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
   1503                                        stream, 1 ) )                       ||
   1504          FT_SET_ERROR( cff_index_get_pointers( &string_index,
   1505                                                &font->strings,
   1506                                                &font->string_pool,
   1507                                                &font->string_pool_size ) ) )
   1508       goto Exit;
   1509 
   1510     font->num_strings = string_index.count;
   1511 
   1512     if ( pure_cff )
   1513     {
   1514       /* well, we don't really forget the `disabled' fonts... */
   1515       subfont_index = (FT_UInt)( face_index & 0xFFFF );
   1516 
   1517       if ( face_index > 0 && subfont_index >= font->name_index.count )
   1518       {
   1519         FT_ERROR(( "cff_font_load:"
   1520                    " invalid subfont index for pure CFF font (%d)\n",
   1521                    subfont_index ));
   1522         error = FT_THROW( Invalid_Argument );
   1523         goto Exit;
   1524       }
   1525 
   1526       font->num_faces = font->name_index.count;
   1527     }
   1528     else
   1529     {
   1530       subfont_index = 0;
   1531 
   1532       if ( font->name_index.count > 1 )
   1533       {
   1534         FT_ERROR(( "cff_font_load:"
   1535                    " invalid CFF font with multiple subfonts\n"
   1536                    "              "
   1537                    " in SFNT wrapper\n" ));
   1538         error = FT_THROW( Invalid_File_Format );
   1539         goto Exit;
   1540       }
   1541     }
   1542 
   1543     /* in case of a font format check, simply exit now */
   1544     if ( face_index < 0 )
   1545       goto Exit;
   1546 
   1547     /* now, parse the top-level font dictionary */
   1548     FT_TRACE4(( "parsing top-level\n" ));
   1549     error = cff_subfont_load( &font->top_font,
   1550                               &font->font_dict_index,
   1551                               subfont_index,
   1552                               stream,
   1553                               base_offset,
   1554                               library );
   1555     if ( error )
   1556       goto Exit;
   1557 
   1558     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
   1559       goto Exit;
   1560 
   1561     error = cff_index_init( &font->charstrings_index, stream, 0 );
   1562     if ( error )
   1563       goto Exit;
   1564 
   1565     /* now, check for a CID font */
   1566     if ( dict->cid_registry != 0xFFFFU )
   1567     {
   1568       CFF_IndexRec  fd_index;
   1569       CFF_SubFont   sub = NULL;
   1570       FT_UInt       idx;
   1571 
   1572 
   1573       /* this is a CID-keyed font, we must now allocate a table of */
   1574       /* sub-fonts, then load each of them separately              */
   1575       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
   1576         goto Exit;
   1577 
   1578       error = cff_index_init( &fd_index, stream, 0 );
   1579       if ( error )
   1580         goto Exit;
   1581 
   1582       if ( fd_index.count > CFF_MAX_CID_FONTS )
   1583       {
   1584         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
   1585         goto Fail_CID;
   1586       }
   1587 
   1588       /* allocate & read each font dict independently */
   1589       font->num_subfonts = fd_index.count;
   1590       if ( FT_NEW_ARRAY( sub, fd_index.count ) )
   1591         goto Fail_CID;
   1592 
   1593       /* set up pointer table */
   1594       for ( idx = 0; idx < fd_index.count; idx++ )
   1595         font->subfonts[idx] = sub + idx;
   1596 
   1597       /* now load each subfont independently */
   1598       for ( idx = 0; idx < fd_index.count; idx++ )
   1599       {
   1600         sub = font->subfonts[idx];
   1601         FT_TRACE4(( "parsing subfont %u\n", idx ));
   1602         error = cff_subfont_load( sub, &fd_index, idx,
   1603                                   stream, base_offset, library );
   1604         if ( error )
   1605           goto Fail_CID;
   1606       }
   1607 
   1608       /* now load the FD Select array */
   1609       error = CFF_Load_FD_Select( &font->fd_select,
   1610                                   font->charstrings_index.count,
   1611                                   stream,
   1612                                   base_offset + dict->cid_fd_select_offset );
   1613 
   1614     Fail_CID:
   1615       cff_index_done( &fd_index );
   1616 
   1617       if ( error )
   1618         goto Exit;
   1619     }
   1620     else
   1621       font->num_subfonts = 0;
   1622 
   1623     /* read the charstrings index now */
   1624     if ( dict->charstrings_offset == 0 )
   1625     {
   1626       FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
   1627       error = FT_THROW( Invalid_File_Format );
   1628       goto Exit;
   1629     }
   1630 
   1631     font->num_glyphs = font->charstrings_index.count;
   1632 
   1633     error = cff_index_get_pointers( &font->global_subrs_index,
   1634                                     &font->global_subrs, NULL, NULL );
   1635 
   1636     if ( error )
   1637       goto Exit;
   1638 
   1639     /* read the Charset and Encoding tables if available */
   1640     if ( font->num_glyphs > 0 )
   1641     {
   1642       FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
   1643 
   1644 
   1645       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
   1646                                 base_offset, dict->charset_offset, invert );
   1647       if ( error )
   1648         goto Exit;
   1649 
   1650       /* CID-keyed CFFs don't have an encoding */
   1651       if ( dict->cid_registry == 0xFFFFU )
   1652       {
   1653         error = cff_encoding_load( &font->encoding,
   1654                                    &font->charset,
   1655                                    font->num_glyphs,
   1656                                    stream,
   1657                                    base_offset,
   1658                                    dict->encoding_offset );
   1659         if ( error )
   1660           goto Exit;
   1661       }
   1662     }
   1663 
   1664     /* get the font name (/CIDFontName for CID-keyed fonts, */
   1665     /* /FontName otherwise)                                 */
   1666     font->font_name = cff_index_get_name( font, subfont_index );
   1667 
   1668   Exit:
   1669     cff_index_done( &string_index );
   1670 
   1671     return error;
   1672   }
   1673 
   1674 
   1675   FT_LOCAL_DEF( void )
   1676   cff_font_done( CFF_Font  font )
   1677   {
   1678     FT_Memory  memory = font->memory;
   1679     FT_UInt    idx;
   1680 
   1681 
   1682     cff_index_done( &font->global_subrs_index );
   1683     cff_index_done( &font->font_dict_index );
   1684     cff_index_done( &font->name_index );
   1685     cff_index_done( &font->charstrings_index );
   1686 
   1687     /* release font dictionaries, but only if working with */
   1688     /* a CID keyed CFF font                                */
   1689     if ( font->num_subfonts > 0 )
   1690     {
   1691       for ( idx = 0; idx < font->num_subfonts; idx++ )
   1692         cff_subfont_done( memory, font->subfonts[idx] );
   1693 
   1694       /* the subfonts array has been allocated as a single block */
   1695       FT_FREE( font->subfonts[0] );
   1696     }
   1697 
   1698     cff_encoding_done( &font->encoding );
   1699     cff_charset_done( &font->charset, font->stream );
   1700 
   1701     cff_subfont_done( memory, &font->top_font );
   1702 
   1703     CFF_Done_FD_Select( &font->fd_select, font->stream );
   1704 
   1705     FT_FREE( font->font_info );
   1706 
   1707     FT_FREE( font->font_name );
   1708     FT_FREE( font->global_subrs );
   1709     FT_FREE( font->strings );
   1710     FT_FREE( font->string_pool );
   1711 
   1712     if ( font->cf2_instance.finalizer )
   1713     {
   1714       font->cf2_instance.finalizer( font->cf2_instance.data );
   1715       FT_FREE( font->cf2_instance.data );
   1716     }
   1717   }
   1718 
   1719 
   1720 /* END */
   1721