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