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