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