cffload.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  cffload.c                                                              */
00004 /*                                                                         */
00005 /*    OpenType and CFF data/program tables loader (body).                  */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_OBJECTS_H
00022 #include FT_INTERNAL_STREAM_H
00023 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
00024 #include FT_TRUETYPE_TAGS_H
00025 #include FT_TYPE1_TABLES_H
00026 
00027 #include "cffload.h"
00028 #include "cffparse.h"
00029 
00030 #include "cfferrs.h"
00031 
00032 
00033 #if 1
00034 
00035   static const FT_UShort  cff_isoadobe_charset[229] =
00036   {
00037       0,   1,   2,   3,   4,   5,   6,   7,
00038       8,   9,  10,  11,  12,  13,  14,  15,
00039      16,  17,  18,  19,  20,  21,  22,  23,
00040      24,  25,  26,  27,  28,  29,  30,  31,
00041      32,  33,  34,  35,  36,  37,  38,  39,
00042      40,  41,  42,  43,  44,  45,  46,  47,
00043      48,  49,  50,  51,  52,  53,  54,  55,
00044      56,  57,  58,  59,  60,  61,  62,  63,
00045      64,  65,  66,  67,  68,  69,  70,  71,
00046      72,  73,  74,  75,  76,  77,  78,  79,
00047      80,  81,  82,  83,  84,  85,  86,  87,
00048      88,  89,  90,  91,  92,  93,  94,  95,
00049      96,  97,  98,  99, 100, 101, 102, 103,
00050     104, 105, 106, 107, 108, 109, 110, 111,
00051     112, 113, 114, 115, 116, 117, 118, 119,
00052     120, 121, 122, 123, 124, 125, 126, 127,
00053     128, 129, 130, 131, 132, 133, 134, 135,
00054     136, 137, 138, 139, 140, 141, 142, 143,
00055     144, 145, 146, 147, 148, 149, 150, 151,
00056     152, 153, 154, 155, 156, 157, 158, 159,
00057     160, 161, 162, 163, 164, 165, 166, 167,
00058     168, 169, 170, 171, 172, 173, 174, 175,
00059     176, 177, 178, 179, 180, 181, 182, 183,
00060     184, 185, 186, 187, 188, 189, 190, 191,
00061     192, 193, 194, 195, 196, 197, 198, 199,
00062     200, 201, 202, 203, 204, 205, 206, 207,
00063     208, 209, 210, 211, 212, 213, 214, 215,
00064     216, 217, 218, 219, 220, 221, 222, 223,
00065     224, 225, 226, 227, 228
00066   };
00067 
00068   static const FT_UShort  cff_expert_charset[166] =
00069   {
00070       0,   1, 229, 230, 231, 232, 233, 234,
00071     235, 236, 237, 238,  13,  14,  15,  99,
00072     239, 240, 241, 242, 243, 244, 245, 246,
00073     247, 248,  27,  28, 249, 250, 251, 252,
00074     253, 254, 255, 256, 257, 258, 259, 260,
00075     261, 262, 263, 264, 265, 266, 109, 110,
00076     267, 268, 269, 270, 271, 272, 273, 274,
00077     275, 276, 277, 278, 279, 280, 281, 282,
00078     283, 284, 285, 286, 287, 288, 289, 290,
00079     291, 292, 293, 294, 295, 296, 297, 298,
00080     299, 300, 301, 302, 303, 304, 305, 306,
00081     307, 308, 309, 310, 311, 312, 313, 314,
00082     315, 316, 317, 318, 158, 155, 163, 319,
00083     320, 321, 322, 323, 324, 325, 326, 150,
00084     164, 169, 327, 328, 329, 330, 331, 332,
00085     333, 334, 335, 336, 337, 338, 339, 340,
00086     341, 342, 343, 344, 345, 346, 347, 348,
00087     349, 350, 351, 352, 353, 354, 355, 356,
00088     357, 358, 359, 360, 361, 362, 363, 364,
00089     365, 366, 367, 368, 369, 370, 371, 372,
00090     373, 374, 375, 376, 377, 378
00091   };
00092 
00093   static const FT_UShort  cff_expertsubset_charset[87] =
00094   {
00095       0,   1, 231, 232, 235, 236, 237, 238,
00096      13,  14,  15,  99, 239, 240, 241, 242,
00097     243, 244, 245, 246, 247, 248,  27,  28,
00098     249, 250, 251, 253, 254, 255, 256, 257,
00099     258, 259, 260, 261, 262, 263, 264, 265,
00100     266, 109, 110, 267, 268, 269, 270, 272,
00101     300, 301, 302, 305, 314, 315, 158, 155,
00102     163, 320, 321, 322, 323, 324, 325, 326,
00103     150, 164, 169, 327, 328, 329, 330, 331,
00104     332, 333, 334, 335, 336, 337, 338, 339,
00105     340, 341, 342, 343, 344, 345, 346
00106   };
00107 
00108   static const FT_UShort  cff_standard_encoding[256] =
00109   {
00110       0,   0,   0,   0,   0,   0,   0,   0,
00111       0,   0,   0,   0,   0,   0,   0,   0,
00112       0,   0,   0,   0,   0,   0,   0,   0,
00113       0,   0,   0,   0,   0,   0,   0,   0,
00114       1,   2,   3,   4,   5,   6,   7,   8,
00115       9,  10,  11,  12,  13,  14,  15,  16,
00116      17,  18,  19,  20,  21,  22,  23,  24,
00117      25,  26,  27,  28,  29,  30,  31,  32,
00118      33,  34,  35,  36,  37,  38,  39,  40,
00119      41,  42,  43,  44,  45,  46,  47,  48,
00120      49,  50,  51,  52,  53,  54,  55,  56,
00121      57,  58,  59,  60,  61,  62,  63,  64,
00122      65,  66,  67,  68,  69,  70,  71,  72,
00123      73,  74,  75,  76,  77,  78,  79,  80,
00124      81,  82,  83,  84,  85,  86,  87,  88,
00125      89,  90,  91,  92,  93,  94,  95,   0,
00126       0,   0,   0,   0,   0,   0,   0,   0,
00127       0,   0,   0,   0,   0,   0,   0,   0,
00128       0,   0,   0,   0,   0,   0,   0,   0,
00129       0,   0,   0,   0,   0,   0,   0,   0,
00130       0,  96,  97,  98,  99, 100, 101, 102,
00131     103, 104, 105, 106, 107, 108, 109, 110,
00132       0, 111, 112, 113, 114,   0, 115, 116,
00133     117, 118, 119, 120, 121, 122,   0, 123,
00134       0, 124, 125, 126, 127, 128, 129, 130,
00135     131,   0, 132, 133,   0, 134, 135, 136,
00136     137,   0,   0,   0,   0,   0,   0,   0,
00137       0,   0,   0,   0,   0,   0,   0,   0,
00138       0, 138,   0, 139,   0,   0,   0,   0,
00139     140, 141, 142, 143,   0,   0,   0,   0,
00140       0, 144,   0,   0,   0, 145,   0,   0,
00141     146, 147, 148, 149,   0,   0,   0,   0
00142   };
00143 
00144   static const FT_UShort  cff_expert_encoding[256] =
00145   {
00146       0,   0,   0,   0,   0,   0,   0,   0,
00147       0,   0,   0,   0,   0,   0,   0,   0,
00148       0,   0,   0,   0,   0,   0,   0,   0,
00149       0,   0,   0,   0,   0,   0,   0,   0,
00150       1, 229, 230,   0, 231, 232, 233, 234,
00151     235, 236, 237, 238,  13,  14,  15,  99,
00152     239, 240, 241, 242, 243, 244, 245, 246,
00153     247, 248,  27,  28, 249, 250, 251, 252,
00154       0, 253, 254, 255, 256, 257,   0,   0,
00155       0, 258,   0,   0, 259, 260, 261, 262,
00156       0,   0, 263, 264, 265,   0, 266, 109,
00157     110, 267, 268, 269,   0, 270, 271, 272,
00158     273, 274, 275, 276, 277, 278, 279, 280,
00159     281, 282, 283, 284, 285, 286, 287, 288,
00160     289, 290, 291, 292, 293, 294, 295, 296,
00161     297, 298, 299, 300, 301, 302, 303,   0,
00162       0,   0,   0,   0,   0,   0,   0,   0,
00163       0,   0,   0,   0,   0,   0,   0,   0,
00164       0,   0,   0,   0,   0,   0,   0,   0,
00165       0,   0,   0,   0,   0,   0,   0,   0,
00166       0, 304, 305, 306,   0,   0, 307, 308,
00167     309, 310, 311,   0, 312,   0,   0, 312,
00168       0,   0, 314, 315,   0,   0, 316, 317,
00169     318,   0,   0,   0, 158, 155, 163, 319,
00170     320, 321, 322, 323, 324, 325,   0,   0,
00171     326, 150, 164, 169, 327, 328, 329, 330,
00172     331, 332, 333, 334, 335, 336, 337, 338,
00173     339, 340, 341, 342, 343, 344, 345, 346,
00174     347, 348, 349, 350, 351, 352, 353, 354,
00175     355, 356, 357, 358, 359, 360, 361, 362,
00176     363, 364, 365, 366, 367, 368, 369, 370,
00177     371, 372, 373, 374, 375, 376, 377, 378
00178   };
00179 
00180 #endif /* 1 */
00181 
00182 
00183   FT_LOCAL_DEF( FT_UShort )
00184   cff_get_standard_encoding( FT_UInt  charcode )
00185   {
00186     return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
00187                                        : 0 );
00188   }
00189 
00190 
00191   /*************************************************************************/
00192   /*                                                                       */
00193   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00194   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00195   /* messages during execution.                                            */
00196   /*                                                                       */
00197 #undef  FT_COMPONENT
00198 #define FT_COMPONENT  trace_cffload
00199 
00200 
00201   /* read an offset from the index's stream current position */
00202   static FT_ULong
00203   cff_index_read_offset( CFF_Index  idx,
00204                          FT_Error  *errorp )
00205   {
00206     FT_Error   error;
00207     FT_Stream  stream = idx->stream;
00208     FT_Byte    tmp[4];
00209     FT_ULong   result = 0;
00210 
00211 
00212     if ( !FT_STREAM_READ( tmp, idx->off_size ) )
00213     {
00214       FT_Int  nn;
00215 
00216 
00217       for ( nn = 0; nn < idx->off_size; nn++ )
00218         result = ( result << 8 ) | tmp[nn];
00219     }
00220 
00221     *errorp = error;
00222     return result;
00223   }
00224 
00225 
00226   static FT_Error
00227   cff_index_init( CFF_Index  idx,
00228                   FT_Stream  stream,
00229                   FT_Bool    load )
00230   {
00231     FT_Error   error;
00232     FT_Memory  memory = stream->memory;
00233     FT_UShort  count;
00234 
00235 
00236     FT_MEM_ZERO( idx, sizeof ( *idx ) );
00237 
00238     idx->stream = stream;
00239     idx->start  = FT_STREAM_POS();
00240     if ( !FT_READ_USHORT( count ) &&
00241          count > 0                )
00242     {
00243       FT_Byte   offsize;
00244       FT_ULong  size;
00245 
00246 
00247       /* there is at least one element; read the offset size,           */
00248       /* then access the offset table to compute the index's total size */
00249       if ( FT_READ_BYTE( offsize ) )
00250         goto Exit;
00251 
00252       if ( offsize < 1 || offsize > 4 )
00253       {
00254         error = FT_Err_Invalid_Table;
00255         goto Exit;
00256       }
00257 
00258       idx->count    = count;
00259       idx->off_size = offsize;
00260       size          = (FT_ULong)( count + 1 ) * offsize;
00261 
00262       idx->data_offset = idx->start + 3 + size;
00263 
00264       if ( FT_STREAM_SKIP( size - offsize ) )
00265         goto Exit;
00266 
00267       size = cff_index_read_offset( idx, &error );
00268       if ( error )
00269         goto Exit;
00270 
00271       if ( size == 0 )
00272       {
00273         error = CFF_Err_Invalid_Table;
00274         goto Exit;
00275       }
00276 
00277       idx->data_size = --size;
00278 
00279       if ( load )
00280       {
00281         /* load the data */
00282         if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
00283           goto Exit;
00284       }
00285       else
00286       {
00287         /* skip the data */
00288         if ( FT_STREAM_SKIP( size ) )
00289           goto Exit;
00290       }
00291     }
00292 
00293   Exit:
00294     if ( error )
00295       FT_FREE( idx->offsets );
00296 
00297     return error;
00298   }
00299 
00300 
00301   static void
00302   cff_index_done( CFF_Index  idx )
00303   {
00304     if ( idx->stream )
00305     {
00306       FT_Stream  stream = idx->stream;
00307       FT_Memory  memory = stream->memory;
00308 
00309 
00310       if ( idx->bytes )
00311         FT_FRAME_RELEASE( idx->bytes );
00312 
00313       FT_FREE( idx->offsets );
00314       FT_MEM_ZERO( idx, sizeof ( *idx ) );
00315     }
00316   }
00317 
00318 
00319   static FT_Error
00320   cff_index_load_offsets( CFF_Index  idx )
00321   {
00322     FT_Error   error  = CFF_Err_Ok;
00323     FT_Stream  stream = idx->stream;
00324     FT_Memory  memory = stream->memory;
00325 
00326 
00327     if ( idx->count > 0 && idx->offsets == NULL )
00328     {
00329       FT_Byte    offsize = idx->off_size;
00330       FT_ULong   data_size;
00331       FT_Byte*   p;
00332       FT_Byte*   p_end;
00333       FT_ULong*  poff;
00334 
00335 
00336       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
00337 
00338       if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
00339            FT_STREAM_SEEK( idx->start + 3 )             ||
00340            FT_FRAME_ENTER( data_size )                  )
00341         goto Exit;
00342 
00343       poff   = idx->offsets;
00344       p      = (FT_Byte*)stream->cursor;
00345       p_end  = p + data_size;
00346 
00347       switch ( offsize )
00348       {
00349       case 1:
00350         for ( ; p < p_end; p++, poff++ )
00351           poff[0] = p[0];
00352         break;
00353 
00354       case 2:
00355         for ( ; p < p_end; p += 2, poff++ )
00356           poff[0] = FT_PEEK_USHORT( p );
00357         break;
00358 
00359       case 3:
00360         for ( ; p < p_end; p += 3, poff++ )
00361           poff[0] = FT_PEEK_OFF3( p );
00362         break;
00363 
00364       default:
00365         for ( ; p < p_end; p += 4, poff++ )
00366           poff[0] = FT_PEEK_ULONG( p );
00367       }
00368 
00369       FT_FRAME_EXIT();
00370     }
00371 
00372   Exit:
00373     if ( error )
00374       FT_FREE( idx->offsets );
00375 
00376     return error;
00377   }
00378 
00379 
00380   /* allocate a table containing pointers to an index's elements */
00381   static FT_Error
00382   cff_index_get_pointers( CFF_Index   idx,
00383                           FT_Byte***  table )
00384   {
00385     FT_Error   error  = CFF_Err_Ok;
00386     FT_Memory  memory = idx->stream->memory;
00387     FT_ULong   n, offset, old_offset;
00388     FT_Byte**  t;
00389 
00390 
00391     *table = 0;
00392 
00393     if ( idx->offsets == NULL )
00394     {
00395       error = cff_index_load_offsets( idx );
00396       if ( error )
00397         goto Exit;
00398     }
00399 
00400     if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
00401     {
00402       old_offset = 1;
00403       for ( n = 0; n <= idx->count; n++ )
00404       {
00405         /* at this point, `idx->offsets' can't be NULL */
00406         offset = idx->offsets[n];
00407         if ( !offset )
00408           offset = old_offset;
00409 
00410         /* two sanity checks for invalid offset tables */
00411         else if ( offset < old_offset )
00412           offset = old_offset;
00413 
00414         else if ( offset - 1 >= idx->data_size && n < idx->count )
00415           offset = old_offset;
00416 
00417         t[n] = idx->bytes + offset - 1;
00418 
00419         old_offset = offset;
00420       }
00421       *table = t;
00422     }
00423 
00424   Exit:
00425     return error;
00426   }
00427 
00428 
00429   FT_LOCAL_DEF( FT_Error )
00430   cff_index_access_element( CFF_Index  idx,
00431                             FT_UInt    element,
00432                             FT_Byte**  pbytes,
00433                             FT_ULong*  pbyte_len )
00434   {
00435     FT_Error  error = CFF_Err_Ok;
00436 
00437 
00438     if ( idx && idx->count > element )
00439     {
00440       /* compute start and end offsets */
00441       FT_Stream  stream = idx->stream;
00442       FT_ULong   off1, off2 = 0;
00443 
00444 
00445       /* load offsets from file or the offset table */
00446       if ( !idx->offsets )
00447       {
00448         FT_ULong  pos = element * idx->off_size;
00449 
00450 
00451         if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
00452           goto Exit;
00453 
00454         off1 = cff_index_read_offset( idx, &error );
00455         if ( error )
00456           goto Exit;
00457 
00458         if ( off1 != 0 )
00459         {
00460           do
00461           {
00462             element++;
00463             off2 = cff_index_read_offset( idx, &error );
00464           }
00465           while ( off2 == 0 && element < idx->count );
00466         }
00467       }
00468       else   /* use offsets table */
00469       {
00470         off1 = idx->offsets[element];
00471         if ( off1 )
00472         {
00473           do
00474           {
00475             element++;
00476             off2 = idx->offsets[element];
00477 
00478           } while ( off2 == 0 && element < idx->count );
00479         }
00480       }
00481 
00482       /* access element */
00483       if ( off1 && off2 > off1 )
00484       {
00485         *pbyte_len = off2 - off1;
00486 
00487         if ( idx->bytes )
00488         {
00489           /* this index was completely loaded in memory, that's easy */
00490           *pbytes = idx->bytes + off1 - 1;
00491         }
00492         else
00493         {
00494           /* this index is still on disk/file, access it through a frame */
00495           if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
00496                FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
00497             goto Exit;
00498         }
00499       }
00500       else
00501       {
00502         /* empty index element */
00503         *pbytes    = 0;
00504         *pbyte_len = 0;
00505       }
00506     }
00507     else
00508       error = CFF_Err_Invalid_Argument;
00509 
00510   Exit:
00511     return error;
00512   }
00513 
00514 
00515   FT_LOCAL_DEF( void )
00516   cff_index_forget_element( CFF_Index  idx,
00517                             FT_Byte**  pbytes )
00518   {
00519     if ( idx->bytes == 0 )
00520     {
00521       FT_Stream  stream = idx->stream;
00522 
00523 
00524       FT_FRAME_RELEASE( *pbytes );
00525     }
00526   }
00527 
00528 
00529   FT_LOCAL_DEF( FT_String* )
00530   cff_index_get_name( CFF_Index  idx,
00531                       FT_UInt    element )
00532   {
00533     FT_Memory   memory = idx->stream->memory;
00534     FT_Byte*    bytes;
00535     FT_ULong    byte_len;
00536     FT_Error    error;
00537     FT_String*  name = 0;
00538 
00539 
00540     error = cff_index_access_element( idx, element, &bytes, &byte_len );
00541     if ( error )
00542       goto Exit;
00543 
00544     if ( !FT_ALLOC( name, byte_len + 1 ) )
00545     {
00546       FT_MEM_COPY( name, bytes, byte_len );
00547       name[byte_len] = 0;
00548     }
00549     cff_index_forget_element( idx, &bytes );
00550 
00551   Exit:
00552     return name;
00553   }
00554 
00555 
00556   FT_LOCAL_DEF( FT_String* )
00557   cff_index_get_sid_string( CFF_Index           idx,
00558                             FT_UInt             sid,
00559                             FT_Service_PsCMaps  psnames )
00560   {
00561     /* value 0xFFFFU indicates a missing dictionary entry */
00562     if ( sid == 0xFFFFU )
00563       return 0;
00564 
00565     /* if it is not a standard string, return it */
00566     if ( sid > 390 )
00567       return cff_index_get_name( idx, sid - 391 );
00568 
00569     /* CID-keyed CFF fonts don't have glyph names */
00570     if ( !psnames )
00571       return 0;
00572 
00573     /* that's a standard string, fetch a copy from the PSName module */
00574     {
00575       FT_String*   name       = 0;
00576       const char*  adobe_name = psnames->adobe_std_strings( sid );
00577 
00578 
00579       if ( adobe_name )
00580       {
00581         FT_Memory  memory = idx->stream->memory;
00582         FT_Error   error;
00583 
00584 
00585         (void)FT_STRDUP( name, adobe_name );
00586 
00587         FT_UNUSED( error );
00588       }
00589 
00590       return name;
00591     }
00592   }
00593 
00594 
00595   /*************************************************************************/
00596   /*************************************************************************/
00597   /***                                                                   ***/
00598   /***   FD Select table support                                         ***/
00599   /***                                                                   ***/
00600   /*************************************************************************/
00601   /*************************************************************************/
00602 
00603 
00604   static void
00605   CFF_Done_FD_Select( CFF_FDSelect  fdselect,
00606                       FT_Stream     stream )
00607   {
00608     if ( fdselect->data )
00609       FT_FRAME_RELEASE( fdselect->data );
00610 
00611     fdselect->data_size   = 0;
00612     fdselect->format      = 0;
00613     fdselect->range_count = 0;
00614   }
00615 
00616 
00617   static FT_Error
00618   CFF_Load_FD_Select( CFF_FDSelect  fdselect,
00619                       FT_UInt       num_glyphs,
00620                       FT_Stream     stream,
00621                       FT_ULong      offset )
00622   {
00623     FT_Error  error;
00624     FT_Byte   format;
00625     FT_UInt   num_ranges;
00626 
00627 
00628     /* read format */
00629     if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
00630       goto Exit;
00631 
00632     fdselect->format      = format;
00633     fdselect->cache_count = 0;   /* clear cache */
00634 
00635     switch ( format )
00636     {
00637     case 0:     /* format 0, that's simple */
00638       fdselect->data_size = num_glyphs;
00639       goto Load_Data;
00640 
00641     case 3:     /* format 3, a tad more complex */
00642       if ( FT_READ_USHORT( num_ranges ) )
00643         goto Exit;
00644 
00645       fdselect->data_size = num_ranges * 3 + 2;
00646 
00647     Load_Data:
00648       if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
00649         goto Exit;
00650       break;
00651 
00652     default:    /* hmm... that's wrong */
00653       error = CFF_Err_Invalid_File_Format;
00654     }
00655 
00656   Exit:
00657     return error;
00658   }
00659 
00660 
00661   FT_LOCAL_DEF( FT_Byte )
00662   cff_fd_select_get( CFF_FDSelect  fdselect,
00663                      FT_UInt       glyph_index )
00664   {
00665     FT_Byte  fd = 0;
00666 
00667 
00668     switch ( fdselect->format )
00669     {
00670     case 0:
00671       fd = fdselect->data[glyph_index];
00672       break;
00673 
00674     case 3:
00675       /* first, compare to cache */
00676       if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
00677                         fdselect->cache_count )
00678       {
00679         fd = fdselect->cache_fd;
00680         break;
00681       }
00682 
00683       /* then, lookup the ranges array */
00684       {
00685         FT_Byte*  p       = fdselect->data;
00686         FT_Byte*  p_limit = p + fdselect->data_size;
00687         FT_Byte   fd2;
00688         FT_UInt   first, limit;
00689 
00690 
00691         first = FT_NEXT_USHORT( p );
00692         do
00693         {
00694           if ( glyph_index < first )
00695             break;
00696 
00697           fd2   = *p++;
00698           limit = FT_NEXT_USHORT( p );
00699 
00700           if ( glyph_index < limit )
00701           {
00702             fd = fd2;
00703 
00704             /* update cache */
00705             fdselect->cache_first = first;
00706             fdselect->cache_count = limit-first;
00707             fdselect->cache_fd    = fd2;
00708             break;
00709           }
00710           first = limit;
00711 
00712         } while ( p < p_limit );
00713       }
00714       break;
00715 
00716     default:
00717       ;
00718     }
00719 
00720     return fd;
00721   }
00722 
00723 
00724   /*************************************************************************/
00725   /*************************************************************************/
00726   /***                                                                   ***/
00727   /***   CFF font support                                                ***/
00728   /***                                                                   ***/
00729   /*************************************************************************/
00730   /*************************************************************************/
00731 
00732   static FT_Error
00733   cff_charset_compute_cids( CFF_Charset  charset,
00734                             FT_UInt      num_glyphs,
00735                             FT_Memory    memory )
00736   {
00737     FT_Error   error   = FT_Err_Ok;
00738     FT_UInt    i;
00739     FT_Long    j;
00740     FT_UShort  max_cid = 0;
00741 
00742 
00743     if ( charset->max_cid > 0 )
00744       goto Exit;
00745 
00746     for ( i = 0; i < num_glyphs; i++ )
00747       if ( charset->sids[i] > max_cid )
00748         max_cid = charset->sids[i];
00749     max_cid++;
00750 
00751     if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
00752       goto Exit;
00753 
00754     /* When multiple GIDs map to the same CID, we choose the lowest */
00755     /* GID.  This is not described in any spec, but it matches the  */
00756     /* behaviour of recent Acroread versions.                       */
00757     for ( j = num_glyphs - 1; j >= 0 ; j-- )
00758       charset->cids[charset->sids[j]] = (FT_UShort)j;
00759 
00760     charset->max_cid    = max_cid;
00761     charset->num_glyphs = num_glyphs;
00762 
00763   Exit:
00764     return error;
00765   }
00766 
00767 
00768   FT_LOCAL_DEF( FT_UInt )
00769   cff_charset_cid_to_gindex( CFF_Charset  charset,
00770                              FT_UInt      cid )
00771   {
00772     FT_UInt  result = 0;
00773 
00774 
00775     if ( cid < charset->max_cid )
00776       result = charset->cids[cid];
00777 
00778     return result;
00779   }
00780 
00781 
00782   static void
00783   cff_charset_free_cids( CFF_Charset  charset,
00784                          FT_Memory    memory )
00785   {
00786     FT_FREE( charset->cids );
00787     charset->max_cid = 0;
00788   }
00789 
00790 
00791   static void
00792   cff_charset_done( CFF_Charset  charset,
00793                     FT_Stream    stream )
00794   {
00795     FT_Memory  memory = stream->memory;
00796 
00797 
00798     cff_charset_free_cids( charset, memory );
00799 
00800     FT_FREE( charset->sids );
00801     charset->format = 0;
00802     charset->offset = 0;
00803   }
00804 
00805 
00806   static FT_Error
00807   cff_charset_load( CFF_Charset  charset,
00808                     FT_UInt      num_glyphs,
00809                     FT_Stream    stream,
00810                     FT_ULong     base_offset,
00811                     FT_ULong     offset,
00812                     FT_Bool      invert )
00813   {
00814     FT_Memory  memory = stream->memory;
00815     FT_Error   error  = CFF_Err_Ok;
00816     FT_UShort  glyph_sid;
00817 
00818 
00819     /* If the the offset is greater than 2, we have to parse the */
00820     /* charset table.                                            */
00821     if ( offset > 2 )
00822     {
00823       FT_UInt  j;
00824 
00825 
00826       charset->offset = base_offset + offset;
00827 
00828       /* Get the format of the table. */
00829       if ( FT_STREAM_SEEK( charset->offset ) ||
00830            FT_READ_BYTE( charset->format )   )
00831         goto Exit;
00832 
00833       /* Allocate memory for sids. */
00834       if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00835         goto Exit;
00836 
00837       /* assign the .notdef glyph */
00838       charset->sids[0] = 0;
00839 
00840       switch ( charset->format )
00841       {
00842       case 0:
00843         if ( num_glyphs > 0 )
00844         {
00845           if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
00846             goto Exit;
00847 
00848           for ( j = 1; j < num_glyphs; j++ )
00849           {
00850             FT_UShort sid = FT_GET_USHORT();
00851 
00852 
00853             /* this constant is given in the CFF specification */
00854             if ( sid < 65000L )
00855               charset->sids[j] = sid;
00856             else
00857             {
00858               FT_TRACE0(( "cff_charset_load:"
00859                           " invalid SID value %d set to zero\n", sid ));
00860               charset->sids[j] = 0;
00861             }
00862           }
00863 
00864           FT_FRAME_EXIT();
00865         }
00866         break;
00867 
00868       case 1:
00869       case 2:
00870         {
00871           FT_UInt  nleft;
00872           FT_UInt  i;
00873 
00874 
00875           j = 1;
00876 
00877           while ( j < num_glyphs )
00878           {
00879             /* Read the first glyph sid of the range. */
00880             if ( FT_READ_USHORT( glyph_sid ) )
00881               goto Exit;
00882 
00883             /* Read the number of glyphs in the range.  */
00884             if ( charset->format == 2 )
00885             {
00886               if ( FT_READ_USHORT( nleft ) )
00887                 goto Exit;
00888             }
00889             else
00890             {
00891               if ( FT_READ_BYTE( nleft ) )
00892                 goto Exit;
00893             }
00894 
00895             /* check whether the range contains at least one valid glyph; */
00896             /* the constant is given in the CFF specification             */
00897             if ( glyph_sid >= 65000L ) {
00898               FT_ERROR(( "cff_charset_load: invalid SID range\n" ));
00899               error = CFF_Err_Invalid_File_Format;
00900               goto Exit;
00901             }
00902 
00903             /* try to rescue some of the SIDs if `nleft' is too large */
00904             if ( nleft > 65000L - 1L || glyph_sid >= 65000L - nleft ) {
00905               FT_ERROR(( "cff_charset_load: invalid SID range trimmed\n" ));
00906               nleft = ( FT_UInt )( 65000L - 1L - glyph_sid );
00907             }
00908 
00909             /* Fill in the range of sids -- `nleft + 1' glyphs. */
00910             for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
00911               charset->sids[j] = glyph_sid;
00912           }
00913         }
00914         break;
00915 
00916       default:
00917         FT_ERROR(( "cff_charset_load: invalid table format\n" ));
00918         error = CFF_Err_Invalid_File_Format;
00919         goto Exit;
00920       }
00921     }
00922     else
00923     {
00924       /* Parse default tables corresponding to offset == 0, 1, or 2.  */
00925       /* CFF specification intimates the following:                   */
00926       /*                                                              */
00927       /* In order to use a predefined charset, the following must be  */
00928       /* true: The charset constructed for the glyphs in the font's   */
00929       /* charstrings dictionary must match the predefined charset in  */
00930       /* the first num_glyphs.                                        */
00931 
00932       charset->offset = offset;  /* record charset type */
00933 
00934       switch ( (FT_UInt)offset )
00935       {
00936       case 0:
00937         if ( num_glyphs > 229 )
00938         {
00939           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00940                      "predefined charset (Adobe ISO-Latin)\n" ));
00941           error = CFF_Err_Invalid_File_Format;
00942           goto Exit;
00943         }
00944 
00945         /* Allocate memory for sids. */
00946         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00947           goto Exit;
00948 
00949         /* Copy the predefined charset into the allocated memory. */
00950         FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
00951 
00952         break;
00953 
00954       case 1:
00955         if ( num_glyphs > 166 )
00956         {
00957           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00958                      "predefined charset (Adobe Expert)\n" ));
00959           error = CFF_Err_Invalid_File_Format;
00960           goto Exit;
00961         }
00962 
00963         /* Allocate memory for sids. */
00964         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00965           goto Exit;
00966 
00967         /* Copy the predefined charset into the allocated memory.     */
00968         FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
00969 
00970         break;
00971 
00972       case 2:
00973         if ( num_glyphs > 87 )
00974         {
00975           FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
00976                      "predefined charset (Adobe Expert Subset)\n" ));
00977           error = CFF_Err_Invalid_File_Format;
00978           goto Exit;
00979         }
00980 
00981         /* Allocate memory for sids. */
00982         if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
00983           goto Exit;
00984 
00985         /* Copy the predefined charset into the allocated memory.     */
00986         FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
00987 
00988         break;
00989 
00990       default:
00991         error = CFF_Err_Invalid_File_Format;
00992         goto Exit;
00993       }
00994     }
00995 
00996     /* we have to invert the `sids' array for subsetted CID-keyed fonts */
00997     if ( invert )
00998       error = cff_charset_compute_cids( charset, num_glyphs, memory );
00999 
01000   Exit:
01001     /* Clean up if there was an error. */
01002     if ( error )
01003     {
01004       FT_FREE( charset->sids );
01005       FT_FREE( charset->cids );
01006       charset->format = 0;
01007       charset->offset = 0;
01008       charset->sids   = 0;
01009     }
01010 
01011     return error;
01012   }
01013 
01014 
01015   static void
01016   cff_encoding_done( CFF_Encoding  encoding )
01017   {
01018     encoding->format = 0;
01019     encoding->offset = 0;
01020     encoding->count  = 0;
01021   }
01022 
01023 
01024   static FT_Error
01025   cff_encoding_load( CFF_Encoding  encoding,
01026                      CFF_Charset   charset,
01027                      FT_UInt       num_glyphs,
01028                      FT_Stream     stream,
01029                      FT_ULong      base_offset,
01030                      FT_ULong      offset )
01031   {
01032     FT_Error   error = CFF_Err_Ok;
01033     FT_UInt    count;
01034     FT_UInt    j;
01035     FT_UShort  glyph_sid;
01036     FT_UInt    glyph_code;
01037 
01038 
01039     /* Check for charset->sids.  If we do not have this, we fail. */
01040     if ( !charset->sids )
01041     {
01042       error = CFF_Err_Invalid_File_Format;
01043       goto Exit;
01044     }
01045 
01046     /* Zero out the code to gid/sid mappings. */
01047     for ( j = 0; j < 256; j++ )
01048     {
01049       encoding->sids [j] = 0;
01050       encoding->codes[j] = 0;
01051     }
01052 
01053     /* Note: The encoding table in a CFF font is indexed by glyph index;  */
01054     /* the first encoded glyph index is 1.  Hence, we read the character  */
01055     /* code (`glyph_code') at index j and make the assignment:            */
01056     /*                                                                    */
01057     /*    encoding->codes[glyph_code] = j + 1                             */
01058     /*                                                                    */
01059     /* We also make the assignment:                                       */
01060     /*                                                                    */
01061     /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
01062     /*                                                                    */
01063     /* This gives us both a code to GID and a code to SID mapping.        */
01064 
01065     if ( offset > 1 )
01066     {
01067       encoding->offset = base_offset + offset;
01068 
01069       /* we need to parse the table to determine its size */
01070       if ( FT_STREAM_SEEK( encoding->offset ) ||
01071            FT_READ_BYTE( encoding->format )   ||
01072            FT_READ_BYTE( count )              )
01073         goto Exit;
01074 
01075       switch ( encoding->format & 0x7F )
01076       {
01077       case 0:
01078         {
01079           FT_Byte*  p;
01080 
01081 
01082           /* By convention, GID 0 is always ".notdef" and is never */
01083           /* coded in the font.  Hence, the number of codes found  */
01084           /* in the table is `count+1'.                            */
01085           /*                                                       */
01086           encoding->count = count + 1;
01087 
01088           if ( FT_FRAME_ENTER( count ) )
01089             goto Exit;
01090 
01091           p = (FT_Byte*)stream->cursor;
01092 
01093           for ( j = 1; j <= count; j++ )
01094           {
01095             glyph_code = *p++;
01096 
01097             /* Make sure j is not too big. */
01098             if ( j < num_glyphs )
01099             {
01100               /* Assign code to GID mapping. */
01101               encoding->codes[glyph_code] = (FT_UShort)j;
01102 
01103               /* Assign code to SID mapping. */
01104               encoding->sids[glyph_code] = charset->sids[j];
01105             }
01106           }
01107 
01108           FT_FRAME_EXIT();
01109         }
01110         break;
01111 
01112       case 1:
01113         {
01114           FT_UInt  nleft;
01115           FT_UInt  i = 1;
01116           FT_UInt  k;
01117 
01118 
01119           encoding->count = 0;
01120 
01121           /* Parse the Format1 ranges. */
01122           for ( j = 0;  j < count; j++, i += nleft )
01123           {
01124             /* Read the first glyph code of the range. */
01125             if ( FT_READ_BYTE( glyph_code ) )
01126               goto Exit;
01127 
01128             /* Read the number of codes in the range. */
01129             if ( FT_READ_BYTE( nleft ) )
01130               goto Exit;
01131 
01132             /* Increment nleft, so we read `nleft + 1' codes/sids. */
01133             nleft++;
01134 
01135             /* compute max number of character codes */
01136             if ( (FT_UInt)nleft > encoding->count )
01137               encoding->count = nleft;
01138 
01139             /* Fill in the range of codes/sids. */
01140             for ( k = i; k < nleft + i; k++, glyph_code++ )
01141             {
01142               /* Make sure k is not too big. */
01143               if ( k < num_glyphs && glyph_code < 256 )
01144               {
01145                 /* Assign code to GID mapping. */
01146                 encoding->codes[glyph_code] = (FT_UShort)k;
01147 
01148                 /* Assign code to SID mapping. */
01149                 encoding->sids[glyph_code] = charset->sids[k];
01150               }
01151             }
01152           }
01153 
01154           /* simple check; one never knows what can be found in a font */
01155           if ( encoding->count > 256 )
01156             encoding->count = 256;
01157         }
01158         break;
01159 
01160       default:
01161         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
01162         error = CFF_Err_Invalid_File_Format;
01163         goto Exit;
01164       }
01165 
01166       /* Parse supplemental encodings, if any. */
01167       if ( encoding->format & 0x80 )
01168       {
01169         FT_UInt  gindex;
01170 
01171 
01172         /* count supplements */
01173         if ( FT_READ_BYTE( count ) )
01174           goto Exit;
01175 
01176         for ( j = 0; j < count; j++ )
01177         {
01178           /* Read supplemental glyph code. */
01179           if ( FT_READ_BYTE( glyph_code ) )
01180             goto Exit;
01181 
01182           /* Read the SID associated with this glyph code. */
01183           if ( FT_READ_USHORT( glyph_sid ) )
01184             goto Exit;
01185 
01186           /* Assign code to SID mapping. */
01187           encoding->sids[glyph_code] = glyph_sid;
01188 
01189           /* First, look up GID which has been assigned to */
01190           /* SID glyph_sid.                                */
01191           for ( gindex = 0; gindex < num_glyphs; gindex++ )
01192           {
01193             if ( charset->sids[gindex] == glyph_sid )
01194             {
01195               encoding->codes[glyph_code] = (FT_UShort)gindex;
01196               break;
01197             }
01198           }
01199         }
01200       }
01201     }
01202     else
01203     {
01204       /* We take into account the fact a CFF font can use a predefined */
01205       /* encoding without containing all of the glyphs encoded by this */
01206       /* encoding (see the note at the end of section 12 in the CFF    */
01207       /* specification).                                               */
01208 
01209       switch ( (FT_UInt)offset )
01210       {
01211       case 0:
01212         /* First, copy the code to SID mapping. */
01213         FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
01214         goto Populate;
01215 
01216       case 1:
01217         /* First, copy the code to SID mapping. */
01218         FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
01219 
01220       Populate:
01221         /* Construct code to GID mapping from code to SID mapping */
01222         /* and charset.                                           */
01223 
01224         encoding->count = 0;
01225 
01226         error = cff_charset_compute_cids( charset, num_glyphs,
01227                                           stream->memory );
01228         if ( error )
01229           goto Exit;
01230 
01231         for ( j = 0; j < 256; j++ )
01232         {
01233           FT_UInt  sid = encoding->sids[j];
01234           FT_UInt  gid = 0;
01235 
01236 
01237           if ( sid )
01238             gid = cff_charset_cid_to_gindex( charset, sid );
01239 
01240           if ( gid != 0 )
01241           {
01242             encoding->codes[j] = (FT_UShort)gid;
01243 
01244             if ( encoding->count < j + 1 )
01245               encoding->count = j + 1;
01246           }
01247           else
01248           {
01249             encoding->codes[j] = 0;
01250             encoding->sids [j] = 0;
01251           }
01252         }
01253         break;
01254 
01255       default:
01256         FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
01257         error = CFF_Err_Invalid_File_Format;
01258         goto Exit;
01259       }
01260     }
01261 
01262   Exit:
01263 
01264     /* Clean up if there was an error. */
01265     return error;
01266   }
01267 
01268 
01269   static FT_Error
01270   cff_subfont_load( CFF_SubFont  font,
01271                     CFF_Index    idx,
01272                     FT_UInt      font_index,
01273                     FT_Stream    stream,
01274                     FT_ULong     base_offset,
01275                     FT_Library   library )
01276   {
01277     FT_Error         error;
01278     CFF_ParserRec    parser;
01279     FT_Byte*         dict = NULL;
01280     FT_ULong         dict_len;
01281     CFF_FontRecDict  top  = &font->font_dict;
01282     CFF_Private      priv = &font->private_dict;
01283 
01284 
01285     cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
01286 
01287     /* set defaults */
01288     FT_MEM_ZERO( top, sizeof ( *top ) );
01289 
01290     top->underline_position  = -100L << 16;
01291     top->underline_thickness = 50L << 16;
01292     top->charstring_type     = 2;
01293     top->font_matrix.xx      = 0x10000L;
01294     top->font_matrix.yy      = 0x10000L;
01295     top->cid_count           = 8720;
01296 
01297     /* we use the implementation specific SID value 0xFFFF to indicate */
01298     /* missing entries                                                 */
01299     top->version             = 0xFFFFU;
01300     top->notice              = 0xFFFFU;
01301     top->copyright           = 0xFFFFU;
01302     top->full_name           = 0xFFFFU;
01303     top->family_name         = 0xFFFFU;
01304     top->weight              = 0xFFFFU;
01305     top->embedded_postscript = 0xFFFFU;
01306 
01307     top->cid_registry        = 0xFFFFU;
01308     top->cid_ordering        = 0xFFFFU;
01309     top->cid_font_name       = 0xFFFFU;
01310 
01311     error = cff_index_access_element( idx, font_index, &dict, &dict_len );
01312     if ( !error )
01313       error = cff_parser_run( &parser, dict, dict + dict_len );
01314 
01315     cff_index_forget_element( idx, &dict );
01316 
01317     if ( error )
01318       goto Exit;
01319 
01320     /* if it is a CID font, we stop there */
01321     if ( top->cid_registry != 0xFFFFU )
01322       goto Exit;
01323 
01324     /* parse the private dictionary, if any */
01325     if ( top->private_offset && top->private_size )
01326     {
01327       /* set defaults */
01328       FT_MEM_ZERO( priv, sizeof ( *priv ) );
01329 
01330       priv->blue_shift       = 7;
01331       priv->blue_fuzz        = 1;
01332       priv->lenIV            = -1;
01333       priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
01334       priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
01335 
01336       cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
01337 
01338       if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
01339            FT_FRAME_ENTER( font->font_dict.private_size )                 )
01340         goto Exit;
01341 
01342       error = cff_parser_run( &parser,
01343                               (FT_Byte*)stream->cursor,
01344                               (FT_Byte*)stream->limit );
01345       FT_FRAME_EXIT();
01346       if ( error )
01347         goto Exit;
01348 
01349       /* ensure that `num_blue_values' is even */
01350       priv->num_blue_values &= ~1;
01351     }
01352 
01353     /* read the local subrs, if any */
01354     if ( priv->local_subrs_offset )
01355     {
01356       if ( FT_STREAM_SEEK( base_offset + top->private_offset +
01357                            priv->local_subrs_offset ) )
01358         goto Exit;
01359 
01360       error = cff_index_init( &font->local_subrs_index, stream, 1 );
01361       if ( error )
01362         goto Exit;
01363 
01364       font->num_local_subrs = font->local_subrs_index.count;
01365       error = cff_index_get_pointers( &font->local_subrs_index,
01366                                       &font->local_subrs );
01367       if ( error )
01368         goto Exit;
01369     }
01370 
01371   Exit:
01372     return error;
01373   }
01374 
01375 
01376   static void
01377   cff_subfont_done( FT_Memory    memory,
01378                     CFF_SubFont  subfont )
01379   {
01380     if ( subfont )
01381     {
01382       cff_index_done( &subfont->local_subrs_index );
01383       FT_FREE( subfont->local_subrs );
01384     }
01385   }
01386 
01387 
01388   FT_LOCAL_DEF( FT_Error )
01389   cff_font_load( FT_Library library,
01390                  FT_Stream  stream,
01391                  FT_Int     face_index,
01392                  CFF_Font   font,
01393                  FT_Bool    pure_cff )
01394   {
01395     static const FT_Frame_Field  cff_header_fields[] =
01396     {
01397 #undef  FT_STRUCTURE
01398 #define FT_STRUCTURE  CFF_FontRec
01399 
01400       FT_FRAME_START( 4 ),
01401         FT_FRAME_BYTE( version_major ),
01402         FT_FRAME_BYTE( version_minor ),
01403         FT_FRAME_BYTE( header_size ),
01404         FT_FRAME_BYTE( absolute_offsize ),
01405       FT_FRAME_END
01406     };
01407 
01408     FT_Error         error;
01409     FT_Memory        memory = stream->memory;
01410     FT_ULong         base_offset;
01411     CFF_FontRecDict  dict;
01412 
01413 
01414     FT_ZERO( font );
01415 
01416     font->stream = stream;
01417     font->memory = memory;
01418     dict         = &font->top_font.font_dict;
01419     base_offset  = FT_STREAM_POS();
01420 
01421     /* read CFF font header */
01422     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
01423       goto Exit;
01424 
01425     /* check format */
01426     if ( font->version_major   != 1 ||
01427          font->header_size      < 4 ||
01428          font->absolute_offsize > 4 )
01429     {
01430       FT_TRACE2(( "[not a CFF font header]\n" ));
01431       error = CFF_Err_Unknown_File_Format;
01432       goto Exit;
01433     }
01434 
01435     /* skip the rest of the header */
01436     if ( FT_STREAM_SKIP( font->header_size - 4 ) )
01437       goto Exit;
01438 
01439     /* read the name, top dict, string and global subrs index */
01440     if ( FT_SET_ERROR( cff_index_init( &font->name_index,
01441                                        stream, 0 ) )              ||
01442          FT_SET_ERROR( cff_index_init( &font->font_dict_index,
01443                                        stream, 0 ) )              ||
01444          FT_SET_ERROR( cff_index_init( &font->string_index,
01445                                        stream, 0 ) )              ||
01446          FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
01447                                        stream, 1 ) )              )
01448       goto Exit;
01449 
01450     /* well, we don't really forget the `disabled' fonts... */
01451     font->num_faces = font->name_index.count;
01452     if ( face_index >= (FT_Int)font->num_faces )
01453     {
01454       FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
01455                  face_index ));
01456       error = CFF_Err_Invalid_Argument;
01457     }
01458 
01459     /* in case of a font format check, simply exit now */
01460     if ( face_index < 0 )
01461       goto Exit;
01462 
01463     /* now, parse the top-level font dictionary */
01464     error = cff_subfont_load( &font->top_font,
01465                               &font->font_dict_index,
01466                               face_index,
01467                               stream,
01468                               base_offset,
01469                               library );
01470     if ( error )
01471       goto Exit;
01472 
01473     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
01474       goto Exit;
01475 
01476     error = cff_index_init( &font->charstrings_index, stream, 0 );
01477     if ( error )
01478       goto Exit;
01479 
01480     /* now, check for a CID font */
01481     if ( dict->cid_registry != 0xFFFFU )
01482     {
01483       CFF_IndexRec  fd_index;
01484       CFF_SubFont   sub;
01485       FT_UInt       idx;
01486 
01487 
01488       /* this is a CID-keyed font, we must now allocate a table of */
01489       /* sub-fonts, then load each of them separately              */
01490       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
01491         goto Exit;
01492 
01493       error = cff_index_init( &fd_index, stream, 0 );
01494       if ( error )
01495         goto Exit;
01496 
01497       if ( fd_index.count > CFF_MAX_CID_FONTS )
01498       {
01499         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
01500         goto Fail_CID;
01501       }
01502 
01503       /* allocate & read each font dict independently */
01504       font->num_subfonts = fd_index.count;
01505       if ( FT_NEW_ARRAY( sub, fd_index.count ) )
01506         goto Fail_CID;
01507 
01508       /* set up pointer table */
01509       for ( idx = 0; idx < fd_index.count; idx++ )
01510         font->subfonts[idx] = sub + idx;
01511 
01512       /* now load each subfont independently */
01513       for ( idx = 0; idx < fd_index.count; idx++ )
01514       {
01515         sub = font->subfonts[idx];
01516         error = cff_subfont_load( sub, &fd_index, idx,
01517                                   stream, base_offset, library );
01518         if ( error )
01519           goto Fail_CID;
01520       }
01521 
01522       /* now load the FD Select array */
01523       error = CFF_Load_FD_Select( &font->fd_select,
01524                                   font->charstrings_index.count,
01525                                   stream,
01526                                   base_offset + dict->cid_fd_select_offset );
01527 
01528     Fail_CID:
01529       cff_index_done( &fd_index );
01530 
01531       if ( error )
01532         goto Exit;
01533     }
01534     else
01535       font->num_subfonts = 0;
01536 
01537     /* read the charstrings index now */
01538     if ( dict->charstrings_offset == 0 )
01539     {
01540       FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
01541       error = CFF_Err_Unknown_File_Format;
01542       goto Exit;
01543     }
01544 
01545     /* explicit the global subrs */
01546     font->num_global_subrs = font->global_subrs_index.count;
01547     font->num_glyphs       = font->charstrings_index.count;
01548 
01549     error = cff_index_get_pointers( &font->global_subrs_index,
01550                                     &font->global_subrs ) ;
01551 
01552     if ( error )
01553       goto Exit;
01554 
01555     /* read the Charset and Encoding tables if available */
01556     if ( font->num_glyphs > 0 )
01557     {
01558       FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
01559 
01560 
01561       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
01562                                 base_offset, dict->charset_offset, invert );
01563       if ( error )
01564         goto Exit;
01565 
01566       /* CID-keyed CFFs don't have an encoding */
01567       if ( dict->cid_registry == 0xFFFFU )
01568       {
01569         error = cff_encoding_load( &font->encoding,
01570                                    &font->charset,
01571                                    font->num_glyphs,
01572                                    stream,
01573                                    base_offset,
01574                                    dict->encoding_offset );
01575         if ( error )
01576           goto Exit;
01577       }
01578     }
01579 
01580     /* get the font name (/CIDFontName for CID-keyed fonts, */
01581     /* /FontName otherwise)                                 */
01582     font->font_name = cff_index_get_name( &font->name_index, face_index );
01583 
01584   Exit:
01585     return error;
01586   }
01587 
01588 
01589   FT_LOCAL_DEF( void )
01590   cff_font_done( CFF_Font  font )
01591   {
01592     FT_Memory  memory = font->memory;
01593     FT_UInt    idx;
01594 
01595 
01596     cff_index_done( &font->global_subrs_index );
01597     cff_index_done( &font->string_index );
01598     cff_index_done( &font->font_dict_index );
01599     cff_index_done( &font->name_index );
01600     cff_index_done( &font->charstrings_index );
01601 
01602     /* release font dictionaries, but only if working with */
01603     /* a CID keyed CFF font                                */
01604     if ( font->num_subfonts > 0 )
01605     {
01606       for ( idx = 0; idx < font->num_subfonts; idx++ )
01607         cff_subfont_done( memory, font->subfonts[idx] );
01608 
01609       /* the subfonts array has been allocated as a single block */
01610       FT_FREE( font->subfonts[0] );
01611     }
01612 
01613     cff_encoding_done( &font->encoding );
01614     cff_charset_done( &font->charset, font->stream );
01615 
01616     cff_subfont_done( memory, &font->top_font );
01617 
01618     CFF_Done_FD_Select( &font->fd_select, font->stream );
01619 
01620     if (font->font_info != NULL)
01621     {
01622       FT_FREE( font->font_info->version );
01623       FT_FREE( font->font_info->notice );
01624       FT_FREE( font->font_info->full_name );
01625       FT_FREE( font->font_info->family_name );
01626       FT_FREE( font->font_info->weight );
01627       FT_FREE( font->font_info );
01628     }
01629 
01630     FT_FREE( font->registry );
01631     FT_FREE( font->ordering );
01632 
01633     FT_FREE( font->global_subrs );
01634     FT_FREE( font->font_name );
01635   }
01636 
01637 
01638 /* END */

Generated on Tue Jul 5 14:13:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1