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