Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  cffload.c                                                              */
  4. /*                                                                         */
  5. /*    OpenType and CFF data/program tables loader (body).                  */
  6. /*                                                                         */
  7. /*  Copyright 1996-2013 by                                                 */
  8. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  9. /*                                                                         */
  10. /*  This file is part of the FreeType project, and may only be used,       */
  11. /*  modified, and distributed under the terms of the FreeType project      */
  12. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  13. /*  this file you indicate that you have read the license and              */
  14. /*  understand and accept it fully.                                        */
  15. /*                                                                         */
  16. /***************************************************************************/
  17.  
  18.  
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_INTERNAL_OBJECTS_H
  22. #include FT_INTERNAL_STREAM_H
  23. #include FT_TRUETYPE_TAGS_H
  24. #include FT_TYPE1_TABLES_H
  25.  
  26. #include "cffload.h"
  27. #include "cffparse.h"
  28.  
  29. #include "cfferrs.h"
  30.  
  31.  
  32. #if 1
  33.  
  34.   static const FT_UShort  cff_isoadobe_charset[229] =
  35.   {
  36.       0,   1,   2,   3,   4,   5,   6,   7,
  37.       8,   9,  10,  11,  12,  13,  14,  15,
  38.      16,  17,  18,  19,  20,  21,  22,  23,
  39.      24,  25,  26,  27,  28,  29,  30,  31,
  40.      32,  33,  34,  35,  36,  37,  38,  39,
  41.      40,  41,  42,  43,  44,  45,  46,  47,
  42.      48,  49,  50,  51,  52,  53,  54,  55,
  43.      56,  57,  58,  59,  60,  61,  62,  63,
  44.      64,  65,  66,  67,  68,  69,  70,  71,
  45.      72,  73,  74,  75,  76,  77,  78,  79,
  46.      80,  81,  82,  83,  84,  85,  86,  87,
  47.      88,  89,  90,  91,  92,  93,  94,  95,
  48.      96,  97,  98,  99, 100, 101, 102, 103,
  49.     104, 105, 106, 107, 108, 109, 110, 111,
  50.     112, 113, 114, 115, 116, 117, 118, 119,
  51.     120, 121, 122, 123, 124, 125, 126, 127,
  52.     128, 129, 130, 131, 132, 133, 134, 135,
  53.     136, 137, 138, 139, 140, 141, 142, 143,
  54.     144, 145, 146, 147, 148, 149, 150, 151,
  55.     152, 153, 154, 155, 156, 157, 158, 159,
  56.     160, 161, 162, 163, 164, 165, 166, 167,
  57.     168, 169, 170, 171, 172, 173, 174, 175,
  58.     176, 177, 178, 179, 180, 181, 182, 183,
  59.     184, 185, 186, 187, 188, 189, 190, 191,
  60.     192, 193, 194, 195, 196, 197, 198, 199,
  61.     200, 201, 202, 203, 204, 205, 206, 207,
  62.     208, 209, 210, 211, 212, 213, 214, 215,
  63.     216, 217, 218, 219, 220, 221, 222, 223,
  64.     224, 225, 226, 227, 228
  65.   };
  66.  
  67.   static const FT_UShort  cff_expert_charset[166] =
  68.   {
  69.       0,   1, 229, 230, 231, 232, 233, 234,
  70.     235, 236, 237, 238,  13,  14,  15,  99,
  71.     239, 240, 241, 242, 243, 244, 245, 246,
  72.     247, 248,  27,  28, 249, 250, 251, 252,
  73.     253, 254, 255, 256, 257, 258, 259, 260,
  74.     261, 262, 263, 264, 265, 266, 109, 110,
  75.     267, 268, 269, 270, 271, 272, 273, 274,
  76.     275, 276, 277, 278, 279, 280, 281, 282,
  77.     283, 284, 285, 286, 287, 288, 289, 290,
  78.     291, 292, 293, 294, 295, 296, 297, 298,
  79.     299, 300, 301, 302, 303, 304, 305, 306,
  80.     307, 308, 309, 310, 311, 312, 313, 314,
  81.     315, 316, 317, 318, 158, 155, 163, 319,
  82.     320, 321, 322, 323, 324, 325, 326, 150,
  83.     164, 169, 327, 328, 329, 330, 331, 332,
  84.     333, 334, 335, 336, 337, 338, 339, 340,
  85.     341, 342, 343, 344, 345, 346, 347, 348,
  86.     349, 350, 351, 352, 353, 354, 355, 356,
  87.     357, 358, 359, 360, 361, 362, 363, 364,
  88.     365, 366, 367, 368, 369, 370, 371, 372,
  89.     373, 374, 375, 376, 377, 378
  90.   };
  91.  
  92.   static const FT_UShort  cff_expertsubset_charset[87] =
  93.   {
  94.       0,   1, 231, 232, 235, 236, 237, 238,
  95.      13,  14,  15,  99, 239, 240, 241, 242,
  96.     243, 244, 245, 246, 247, 248,  27,  28,
  97.     249, 250, 251, 253, 254, 255, 256, 257,
  98.     258, 259, 260, 261, 262, 263, 264, 265,
  99.     266, 109, 110, 267, 268, 269, 270, 272,
  100.     300, 301, 302, 305, 314, 315, 158, 155,
  101.     163, 320, 321, 322, 323, 324, 325, 326,
  102.     150, 164, 169, 327, 328, 329, 330, 331,
  103.     332, 333, 334, 335, 336, 337, 338, 339,
  104.     340, 341, 342, 343, 344, 345, 346
  105.   };
  106.  
  107.   static const FT_UShort  cff_standard_encoding[256] =
  108.   {
  109.       0,   0,   0,   0,   0,   0,   0,   0,
  110.       0,   0,   0,   0,   0,   0,   0,   0,
  111.       0,   0,   0,   0,   0,   0,   0,   0,
  112.       0,   0,   0,   0,   0,   0,   0,   0,
  113.       1,   2,   3,   4,   5,   6,   7,   8,
  114.       9,  10,  11,  12,  13,  14,  15,  16,
  115.      17,  18,  19,  20,  21,  22,  23,  24,
  116.      25,  26,  27,  28,  29,  30,  31,  32,
  117.      33,  34,  35,  36,  37,  38,  39,  40,
  118.      41,  42,  43,  44,  45,  46,  47,  48,
  119.      49,  50,  51,  52,  53,  54,  55,  56,
  120.      57,  58,  59,  60,  61,  62,  63,  64,
  121.      65,  66,  67,  68,  69,  70,  71,  72,
  122.      73,  74,  75,  76,  77,  78,  79,  80,
  123.      81,  82,  83,  84,  85,  86,  87,  88,
  124.      89,  90,  91,  92,  93,  94,  95,   0,
  125.       0,   0,   0,   0,   0,   0,   0,   0,
  126.       0,   0,   0,   0,   0,   0,   0,   0,
  127.       0,   0,   0,   0,   0,   0,   0,   0,
  128.       0,   0,   0,   0,   0,   0,   0,   0,
  129.       0,  96,  97,  98,  99, 100, 101, 102,
  130.     103, 104, 105, 106, 107, 108, 109, 110,
  131.       0, 111, 112, 113, 114,   0, 115, 116,
  132.     117, 118, 119, 120, 121, 122,   0, 123,
  133.       0, 124, 125, 126, 127, 128, 129, 130,
  134.     131,   0, 132, 133,   0, 134, 135, 136,
  135.     137,   0,   0,   0,   0,   0,   0,   0,
  136.       0,   0,   0,   0,   0,   0,   0,   0,
  137.       0, 138,   0, 139,   0,   0,   0,   0,
  138.     140, 141, 142, 143,   0,   0,   0,   0,
  139.       0, 144,   0,   0,   0, 145,   0,   0,
  140.     146, 147, 148, 149,   0,   0,   0,   0
  141.   };
  142.  
  143.   static const FT_UShort  cff_expert_encoding[256] =
  144.   {
  145.       0,   0,   0,   0,   0,   0,   0,   0,
  146.       0,   0,   0,   0,   0,   0,   0,   0,
  147.       0,   0,   0,   0,   0,   0,   0,   0,
  148.       0,   0,   0,   0,   0,   0,   0,   0,
  149.       1, 229, 230,   0, 231, 232, 233, 234,
  150.     235, 236, 237, 238,  13,  14,  15,  99,
  151.     239, 240, 241, 242, 243, 244, 245, 246,
  152.     247, 248,  27,  28, 249, 250, 251, 252,
  153.       0, 253, 254, 255, 256, 257,   0,   0,
  154.       0, 258,   0,   0, 259, 260, 261, 262,
  155.       0,   0, 263, 264, 265,   0, 266, 109,
  156.     110, 267, 268, 269,   0, 270, 271, 272,
  157.     273, 274, 275, 276, 277, 278, 279, 280,
  158.     281, 282, 283, 284, 285, 286, 287, 288,
  159.     289, 290, 291, 292, 293, 294, 295, 296,
  160.     297, 298, 299, 300, 301, 302, 303,   0,
  161.       0,   0,   0,   0,   0,   0,   0,   0,
  162.       0,   0,   0,   0,   0,   0,   0,   0,
  163.       0,   0,   0,   0,   0,   0,   0,   0,
  164.       0,   0,   0,   0,   0,   0,   0,   0,
  165.       0, 304, 305, 306,   0,   0, 307, 308,
  166.     309, 310, 311,   0, 312,   0,   0, 312,
  167.       0,   0, 314, 315,   0,   0, 316, 317,
  168.     318,   0,   0,   0, 158, 155, 163, 319,
  169.     320, 321, 322, 323, 324, 325,   0,   0,
  170.     326, 150, 164, 169, 327, 328, 329, 330,
  171.     331, 332, 333, 334, 335, 336, 337, 338,
  172.     339, 340, 341, 342, 343, 344, 345, 346,
  173.     347, 348, 349, 350, 351, 352, 353, 354,
  174.     355, 356, 357, 358, 359, 360, 361, 362,
  175.     363, 364, 365, 366, 367, 368, 369, 370,
  176.     371, 372, 373, 374, 375, 376, 377, 378
  177.   };
  178.  
  179. #endif /* 1 */
  180.  
  181.  
  182.   FT_LOCAL_DEF( FT_UShort )
  183.   cff_get_standard_encoding( FT_UInt  charcode )
  184.   {
  185.     return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
  186.                                        : 0 );
  187.   }
  188.  
  189.  
  190.   /*************************************************************************/
  191.   /*                                                                       */
  192.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  193.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  194.   /* messages during execution.                                            */
  195.   /*                                                                       */
  196. #undef  FT_COMPONENT
  197. #define FT_COMPONENT  trace_cffload
  198.  
  199.  
  200.   /* read an offset from the index's stream current position */
  201.   static FT_ULong
  202.   cff_index_read_offset( CFF_Index  idx,
  203.                          FT_Error  *errorp )
  204.   {
  205.     FT_Error   error;
  206.     FT_Stream  stream = idx->stream;
  207.     FT_Byte    tmp[4];
  208.     FT_ULong   result = 0;
  209.  
  210.  
  211.     if ( !FT_STREAM_READ( tmp, idx->off_size ) )
  212.     {
  213.       FT_Int  nn;
  214.  
  215.  
  216.       for ( nn = 0; nn < idx->off_size; nn++ )
  217.         result = ( result << 8 ) | tmp[nn];
  218.     }
  219.  
  220.     *errorp = error;
  221.     return result;
  222.   }
  223.  
  224.  
  225.   static FT_Error
  226.   cff_index_init( CFF_Index  idx,
  227.                   FT_Stream  stream,
  228.                   FT_Bool    load )
  229.   {
  230.     FT_Error   error;
  231.     FT_Memory  memory = stream->memory;
  232.     FT_UShort  count;
  233.  
  234.  
  235.     FT_MEM_ZERO( idx, sizeof ( *idx ) );
  236.  
  237.     idx->stream = stream;
  238.     idx->start  = FT_STREAM_POS();
  239.     if ( !FT_READ_USHORT( count ) &&
  240.          count > 0                )
  241.     {
  242.       FT_Byte   offsize;
  243.       FT_ULong  size;
  244.  
  245.  
  246.       /* there is at least one element; read the offset size,           */
  247.       /* then access the offset table to compute the index's total size */
  248.       if ( FT_READ_BYTE( offsize ) )
  249.         goto Exit;
  250.  
  251.       if ( offsize < 1 || offsize > 4 )
  252.       {
  253.         error = FT_THROW( Invalid_Table );
  254.         goto Exit;
  255.       }
  256.  
  257.       idx->count    = count;
  258.       idx->off_size = offsize;
  259.       size          = (FT_ULong)( count + 1 ) * offsize;
  260.  
  261.       idx->data_offset = idx->start + 3 + size;
  262.  
  263.       if ( FT_STREAM_SKIP( size - offsize ) )
  264.         goto Exit;
  265.  
  266.       size = cff_index_read_offset( idx, &error );
  267.       if ( error )
  268.         goto Exit;
  269.  
  270.       if ( size == 0 )
  271.       {
  272.         error = FT_THROW( Invalid_Table );
  273.         goto Exit;
  274.       }
  275.  
  276.       idx->data_size = --size;
  277.  
  278.       if ( load )
  279.       {
  280.         /* load the data */
  281.         if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
  282.           goto Exit;
  283.       }
  284.       else
  285.       {
  286.         /* skip the data */
  287.         if ( FT_STREAM_SKIP( size ) )
  288.           goto Exit;
  289.       }
  290.     }
  291.  
  292.   Exit:
  293.     if ( error )
  294.       FT_FREE( idx->offsets );
  295.  
  296.     return error;
  297.   }
  298.  
  299.  
  300.   static void
  301.   cff_index_done( CFF_Index  idx )
  302.   {
  303.     if ( idx->stream )
  304.     {
  305.       FT_Stream  stream = idx->stream;
  306.       FT_Memory  memory = stream->memory;
  307.  
  308.  
  309.       if ( idx->bytes )
  310.         FT_FRAME_RELEASE( idx->bytes );
  311.  
  312.       FT_FREE( idx->offsets );
  313.       FT_MEM_ZERO( idx, sizeof ( *idx ) );
  314.     }
  315.   }
  316.  
  317.  
  318.   static FT_Error
  319.   cff_index_load_offsets( CFF_Index  idx )
  320.   {
  321.     FT_Error   error  = FT_Err_Ok;
  322.     FT_Stream  stream = idx->stream;
  323.     FT_Memory  memory = stream->memory;
  324.  
  325.  
  326.     if ( idx->count > 0 && idx->offsets == NULL )
  327.     {
  328.       FT_Byte    offsize = idx->off_size;
  329.       FT_ULong   data_size;
  330.       FT_Byte*   p;
  331.       FT_Byte*   p_end;
  332.       FT_ULong*  poff;
  333.  
  334.  
  335.       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
  336.  
  337.       if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
  338.            FT_STREAM_SEEK( idx->start + 3 )             ||
  339.            FT_FRAME_ENTER( data_size )                  )
  340.         goto Exit;
  341.  
  342.       poff   = idx->offsets;
  343.       p      = (FT_Byte*)stream->cursor;
  344.       p_end  = p + data_size;
  345.  
  346.       switch ( offsize )
  347.       {
  348.       case 1:
  349.         for ( ; p < p_end; p++, poff++ )
  350.           poff[0] = p[0];
  351.         break;
  352.  
  353.       case 2:
  354.         for ( ; p < p_end; p += 2, poff++ )
  355.           poff[0] = FT_PEEK_USHORT( p );
  356.         break;
  357.  
  358.       case 3:
  359.         for ( ; p < p_end; p += 3, poff++ )
  360.           poff[0] = FT_PEEK_OFF3( p );
  361.         break;
  362.  
  363.       default:
  364.         for ( ; p < p_end; p += 4, poff++ )
  365.           poff[0] = FT_PEEK_ULONG( p );
  366.       }
  367.  
  368.       FT_FRAME_EXIT();
  369.     }
  370.  
  371.   Exit:
  372.     if ( error )
  373.       FT_FREE( idx->offsets );
  374.  
  375.     return error;
  376.   }
  377.  
  378.  
  379.   /* Allocate a table containing pointers to an index's elements. */
  380.   /* The `pool' argument makes this function convert the index    */
  381.   /* entries to C-style strings (this is, NULL-terminated).       */
  382.   static FT_Error
  383.   cff_index_get_pointers( CFF_Index   idx,
  384.                           FT_Byte***  table,
  385.                           FT_Byte**   pool )
  386.   {
  387.     FT_Error   error     = FT_Err_Ok;
  388.     FT_Memory  memory    = idx->stream->memory;
  389.  
  390.     FT_Byte**  t         = NULL;
  391.     FT_Byte*   new_bytes = NULL;
  392.  
  393.  
  394.     *table = NULL;
  395.  
  396.     if ( idx->offsets == NULL )
  397.     {
  398.       error = cff_index_load_offsets( idx );
  399.       if ( error )
  400.         goto Exit;
  401.     }
  402.  
  403.     if ( idx->count > 0                                        &&
  404.          !FT_NEW_ARRAY( t, idx->count + 1 )                    &&
  405.          ( !pool || !FT_ALLOC( new_bytes,
  406.                                idx->data_size + idx->count ) ) )
  407.     {
  408.       FT_ULong  n, cur_offset;
  409.       FT_ULong  extra = 0;
  410.       FT_Byte*  org_bytes = idx->bytes;
  411.  
  412.  
  413.       /* at this point, `idx->offsets' can't be NULL */
  414.       cur_offset = idx->offsets[0] - 1;
  415.  
  416.       /* sanity check */
  417.       if ( cur_offset >= 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 = FT_Err_Ok;
  476.  
  477.  
  478.     if ( idx && idx->count > element )
  479.     {
  480.       /* compute start and end offsets */
  481.       FT_Stream  stream = idx->stream;
  482.       FT_ULong   off1, off2 = 0;
  483.  
  484.  
  485.       /* load offsets from file or the offset table */
  486.       if ( !idx->offsets )
  487.       {
  488.         FT_ULong  pos = element * idx->off_size;
  489.  
  490.  
  491.         if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
  492.           goto Exit;
  493.  
  494.         off1 = cff_index_read_offset( idx, &error );
  495.         if ( error )
  496.           goto Exit;
  497.  
  498.         if ( off1 != 0 )
  499.         {
  500.           do
  501.           {
  502.             element++;
  503.             off2 = cff_index_read_offset( idx, &error );
  504.           }
  505.           while ( off2 == 0 && element < idx->count );
  506.         }
  507.       }
  508.       else   /* use offsets table */
  509.       {
  510.         off1 = idx->offsets[element];
  511.         if ( off1 )
  512.         {
  513.           do
  514.           {
  515.             element++;
  516.             off2 = idx->offsets[element];
  517.  
  518.           } while ( off2 == 0 && element < idx->count );
  519.         }
  520.       }
  521.  
  522.       /* XXX: should check off2 does not exceed the end of this entry; */
  523.       /*      at present, only truncate off2 at the end of this stream */
  524.       if ( off2 > stream->size + 1                    ||
  525.            idx->data_offset > stream->size - off2 + 1 )
  526.       {
  527.         FT_ERROR(( "cff_index_access_element:"
  528.                    " offset to next entry (%d)"
  529.                    " exceeds the end of stream (%d)\n",
  530.                    off2, stream->size - idx->data_offset + 1 ));
  531.         off2 = stream->size - idx->data_offset + 1;
  532.       }
  533.  
  534.       /* access element */
  535.       if ( off1 && off2 > off1 )
  536.       {
  537.         *pbyte_len = off2 - off1;
  538.  
  539.         if ( idx->bytes )
  540.         {
  541.           /* this index was completely loaded in memory, that's easy */
  542.           *pbytes = idx->bytes + off1 - 1;
  543.         }
  544.         else
  545.         {
  546.           /* this index is still on disk/file, access it through a frame */
  547.           if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
  548.                FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
  549.             goto Exit;
  550.         }
  551.       }
  552.       else
  553.       {
  554.         /* empty index element */
  555.         *pbytes    = 0;
  556.         *pbyte_len = 0;
  557.       }
  558.     }
  559.     else
  560.       error = FT_THROW( Invalid_Argument );
  561.  
  562.   Exit:
  563.     return error;
  564.   }
  565.  
  566.  
  567.   FT_LOCAL_DEF( void )
  568.   cff_index_forget_element( CFF_Index  idx,
  569.                             FT_Byte**  pbytes )
  570.   {
  571.     if ( idx->bytes == 0 )
  572.     {
  573.       FT_Stream  stream = idx->stream;
  574.  
  575.  
  576.       FT_FRAME_RELEASE( *pbytes );
  577.     }
  578.   }
  579.  
  580.  
  581.   /* get an entry from Name INDEX */
  582.   FT_LOCAL_DEF( FT_String* )
  583.   cff_index_get_name( CFF_Font  font,
  584.                       FT_UInt   element )
  585.   {
  586.     CFF_Index   idx = &font->name_index;
  587.     FT_Memory   memory = idx->stream->memory;
  588.     FT_Byte*    bytes;
  589.     FT_ULong    byte_len;
  590.     FT_Error    error;
  591.     FT_String*  name = 0;
  592.  
  593.  
  594.     error = cff_index_access_element( idx, element, &bytes, &byte_len );
  595.     if ( error )
  596.       goto Exit;
  597.  
  598.     if ( !FT_ALLOC( name, byte_len + 1 ) )
  599.     {
  600.       FT_MEM_COPY( name, bytes, byte_len );
  601.       name[byte_len] = 0;
  602.     }
  603.     cff_index_forget_element( idx, &bytes );
  604.  
  605.   Exit:
  606.     return name;
  607.   }
  608.  
  609.  
  610.   /* get an entry from String INDEX */
  611.   FT_LOCAL_DEF( FT_String* )
  612.   cff_index_get_string( CFF_Font  font,
  613.                         FT_UInt   element )
  614.   {
  615.     return ( element < font->num_strings )
  616.              ? (FT_String*)font->strings[element]
  617.              : NULL;
  618.   }
  619.  
  620.  
  621.   FT_LOCAL_DEF( FT_String* )
  622.   cff_index_get_sid_string( CFF_Font  font,
  623.                             FT_UInt   sid )
  624.   {
  625.     /* value 0xFFFFU indicates a missing dictionary entry */
  626.     if ( sid == 0xFFFFU )
  627.       return NULL;
  628.  
  629.     /* if it is not a standard string, return it */
  630.     if ( sid > 390 )
  631.       return cff_index_get_string( font, sid - 391 );
  632.  
  633.     /* CID-keyed CFF fonts don't have glyph names */
  634.     if ( !font->psnames )
  635.       return NULL;
  636.  
  637.     /* this is a standard string */
  638.     return (FT_String *)font->psnames->adobe_std_strings( sid );
  639.   }
  640.  
  641.  
  642.   /*************************************************************************/
  643.   /*************************************************************************/
  644.   /***                                                                   ***/
  645.   /***   FD Select table support                                         ***/
  646.   /***                                                                   ***/
  647.   /*************************************************************************/
  648.   /*************************************************************************/
  649.  
  650.  
  651.   static void
  652.   CFF_Done_FD_Select( CFF_FDSelect  fdselect,
  653.                       FT_Stream     stream )
  654.   {
  655.     if ( fdselect->data )
  656.       FT_FRAME_RELEASE( fdselect->data );
  657.  
  658.     fdselect->data_size   = 0;
  659.     fdselect->format      = 0;
  660.     fdselect->range_count = 0;
  661.   }
  662.  
  663.  
  664.   static FT_Error
  665.   CFF_Load_FD_Select( CFF_FDSelect  fdselect,
  666.                       FT_UInt       num_glyphs,
  667.                       FT_Stream     stream,
  668.                       FT_ULong      offset )
  669.   {
  670.     FT_Error  error;
  671.     FT_Byte   format;
  672.     FT_UInt   num_ranges;
  673.  
  674.  
  675.     /* read format */
  676.     if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
  677.       goto Exit;
  678.  
  679.     fdselect->format      = format;
  680.     fdselect->cache_count = 0;   /* clear cache */
  681.  
  682.     switch ( format )
  683.     {
  684.     case 0:     /* format 0, that's simple */
  685.       fdselect->data_size = num_glyphs;
  686.       goto Load_Data;
  687.  
  688.     case 3:     /* format 3, a tad more complex */
  689.       if ( FT_READ_USHORT( num_ranges ) )
  690.         goto Exit;
  691.  
  692.       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 = FT_THROW( 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   = FT_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  = FT_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 = FT_THROW( 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 = FT_THROW( 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 = FT_THROW( 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 = FT_THROW( 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 = FT_THROW( 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 = FT_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 = FT_THROW( 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 = FT_THROW( 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 = FT_THROW( 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.     {
  1341.       FT_TRACE4(( " top dictionary:\n" ));
  1342.       error = cff_parser_run( &parser, dict, dict + dict_len );
  1343.     }
  1344.  
  1345.     cff_index_forget_element( idx, &dict );
  1346.  
  1347.     if ( error )
  1348.       goto Exit;
  1349.  
  1350.     /* if it is a CID font, we stop there */
  1351.     if ( top->cid_registry != 0xFFFFU )
  1352.       goto Exit;
  1353.  
  1354.     /* parse the private dictionary, if any */
  1355.     if ( top->private_offset && top->private_size )
  1356.     {
  1357.       /* set defaults */
  1358.       FT_MEM_ZERO( priv, sizeof ( *priv ) );
  1359.  
  1360.       priv->blue_shift       = 7;
  1361.       priv->blue_fuzz        = 1;
  1362.       priv->lenIV            = -1;
  1363.       priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
  1364.       priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
  1365.  
  1366.       cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
  1367.  
  1368.       if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
  1369.            FT_FRAME_ENTER( font->font_dict.private_size )                 )
  1370.         goto Exit;
  1371.  
  1372.       FT_TRACE4(( " private dictionary:\n" ));
  1373.       error = cff_parser_run( &parser,
  1374.                               (FT_Byte*)stream->cursor,
  1375.                               (FT_Byte*)stream->limit );
  1376.       FT_FRAME_EXIT();
  1377.       if ( error )
  1378.         goto Exit;
  1379.  
  1380.       /* ensure that `num_blue_values' is even */
  1381.       priv->num_blue_values &= ~1;
  1382.     }
  1383.  
  1384.     /* read the local subrs, if any */
  1385.     if ( priv->local_subrs_offset )
  1386.     {
  1387.       if ( FT_STREAM_SEEK( base_offset + top->private_offset +
  1388.                            priv->local_subrs_offset ) )
  1389.         goto Exit;
  1390.  
  1391.       error = cff_index_init( &font->local_subrs_index, stream, 1 );
  1392.       if ( error )
  1393.         goto Exit;
  1394.  
  1395.       error = cff_index_get_pointers( &font->local_subrs_index,
  1396.                                       &font->local_subrs, NULL );
  1397.       if ( error )
  1398.         goto Exit;
  1399.     }
  1400.  
  1401.   Exit:
  1402.     return error;
  1403.   }
  1404.  
  1405.  
  1406.   static void
  1407.   cff_subfont_done( FT_Memory    memory,
  1408.                     CFF_SubFont  subfont )
  1409.   {
  1410.     if ( subfont )
  1411.     {
  1412.       cff_index_done( &subfont->local_subrs_index );
  1413.       FT_FREE( subfont->local_subrs );
  1414.     }
  1415.   }
  1416.  
  1417.  
  1418.   FT_LOCAL_DEF( FT_Error )
  1419.   cff_font_load( FT_Library library,
  1420.                  FT_Stream  stream,
  1421.                  FT_Int     face_index,
  1422.                  CFF_Font   font,
  1423.                  FT_Bool    pure_cff )
  1424.   {
  1425.     static const FT_Frame_Field  cff_header_fields[] =
  1426.     {
  1427. #undef  FT_STRUCTURE
  1428. #define FT_STRUCTURE  CFF_FontRec
  1429.  
  1430.       FT_FRAME_START( 4 ),
  1431.         FT_FRAME_BYTE( version_major ),
  1432.         FT_FRAME_BYTE( version_minor ),
  1433.         FT_FRAME_BYTE( header_size ),
  1434.         FT_FRAME_BYTE( absolute_offsize ),
  1435.       FT_FRAME_END
  1436.     };
  1437.  
  1438.     FT_Error         error;
  1439.     FT_Memory        memory = stream->memory;
  1440.     FT_ULong         base_offset;
  1441.     CFF_FontRecDict  dict;
  1442.     CFF_IndexRec     string_index;
  1443.     FT_Int           subfont_index;
  1444.  
  1445.  
  1446.     FT_ZERO( font );
  1447.     FT_ZERO( &string_index );
  1448.  
  1449.     font->stream = stream;
  1450.     font->memory = memory;
  1451.     dict         = &font->top_font.font_dict;
  1452.     base_offset  = FT_STREAM_POS();
  1453.  
  1454.     /* read CFF font header */
  1455.     if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
  1456.       goto Exit;
  1457.  
  1458.     /* check format */
  1459.     if ( font->version_major   != 1 ||
  1460.          font->header_size      < 4 ||
  1461.          font->absolute_offsize > 4 )
  1462.     {
  1463.       FT_TRACE2(( "  not a CFF font header\n" ));
  1464.       error = FT_THROW( Unknown_File_Format );
  1465.       goto Exit;
  1466.     }
  1467.  
  1468.     /* skip the rest of the header */
  1469.     if ( FT_STREAM_SKIP( font->header_size - 4 ) )
  1470.       goto Exit;
  1471.  
  1472.     /* read the name, top dict, string and global subrs index */
  1473.     if ( FT_SET_ERROR( cff_index_init( &font->name_index,
  1474.                                        stream, 0 ) )                  ||
  1475.          FT_SET_ERROR( cff_index_init( &font->font_dict_index,
  1476.                                        stream, 0 ) )                  ||
  1477.          FT_SET_ERROR( cff_index_init( &string_index,
  1478.                                        stream, 1 ) )                  ||
  1479.          FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
  1480.                                        stream, 1 ) )                  ||
  1481.          FT_SET_ERROR( cff_index_get_pointers( &string_index,
  1482.                                                &font->strings,
  1483.                                                &font->string_pool ) ) )
  1484.       goto Exit;
  1485.  
  1486.     font->num_strings = string_index.count;
  1487.  
  1488.     if ( pure_cff )
  1489.     {
  1490.       /* well, we don't really forget the `disabled' fonts... */
  1491.       subfont_index = face_index;
  1492.  
  1493.       if ( subfont_index >= (FT_Int)font->name_index.count )
  1494.       {
  1495.         FT_ERROR(( "cff_font_load:"
  1496.                    " invalid subfont index for pure CFF font (%d)\n",
  1497.                    subfont_index ));
  1498.         error = FT_THROW( Invalid_Argument );
  1499.         goto Exit;
  1500.       }
  1501.  
  1502.       font->num_faces = font->name_index.count;
  1503.     }
  1504.     else
  1505.     {
  1506.       subfont_index = 0;
  1507.  
  1508.       if ( font->name_index.count > 1 )
  1509.       {
  1510.         FT_ERROR(( "cff_font_load:"
  1511.                    " invalid CFF font with multiple subfonts\n"
  1512.                    "              "
  1513.                    " in SFNT wrapper\n" ));
  1514.         error = FT_THROW( Invalid_File_Format );
  1515.         goto Exit;
  1516.       }
  1517.     }
  1518.  
  1519.     /* in case of a font format check, simply exit now */
  1520.     if ( face_index < 0 )
  1521.       goto Exit;
  1522.  
  1523.     /* now, parse the top-level font dictionary */
  1524.     FT_TRACE4(( "parsing top-level\n" ));
  1525.     error = cff_subfont_load( &font->top_font,
  1526.                               &font->font_dict_index,
  1527.                               subfont_index,
  1528.                               stream,
  1529.                               base_offset,
  1530.                               library );
  1531.     if ( error )
  1532.       goto Exit;
  1533.  
  1534.     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
  1535.       goto Exit;
  1536.  
  1537.     error = cff_index_init( &font->charstrings_index, stream, 0 );
  1538.     if ( error )
  1539.       goto Exit;
  1540.  
  1541.     /* now, check for a CID font */
  1542.     if ( dict->cid_registry != 0xFFFFU )
  1543.     {
  1544.       CFF_IndexRec  fd_index;
  1545.       CFF_SubFont   sub = NULL;
  1546.       FT_UInt       idx;
  1547.  
  1548.  
  1549.       /* this is a CID-keyed font, we must now allocate a table of */
  1550.       /* sub-fonts, then load each of them separately              */
  1551.       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
  1552.         goto Exit;
  1553.  
  1554.       error = cff_index_init( &fd_index, stream, 0 );
  1555.       if ( error )
  1556.         goto Exit;
  1557.  
  1558.       if ( fd_index.count > CFF_MAX_CID_FONTS )
  1559.       {
  1560.         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
  1561.         goto Fail_CID;
  1562.       }
  1563.  
  1564.       /* allocate & read each font dict independently */
  1565.       font->num_subfonts = fd_index.count;
  1566.       if ( FT_NEW_ARRAY( sub, fd_index.count ) )
  1567.         goto Fail_CID;
  1568.  
  1569.       /* set up pointer table */
  1570.       for ( idx = 0; idx < fd_index.count; idx++ )
  1571.         font->subfonts[idx] = sub + idx;
  1572.  
  1573.       /* now load each subfont independently */
  1574.       for ( idx = 0; idx < fd_index.count; idx++ )
  1575.       {
  1576.         sub = font->subfonts[idx];
  1577.         FT_TRACE4(( "parsing subfont %u\n", idx ));
  1578.         error = cff_subfont_load( sub, &fd_index, idx,
  1579.                                   stream, base_offset, library );
  1580.         if ( error )
  1581.           goto Fail_CID;
  1582.       }
  1583.  
  1584.       /* now load the FD Select array */
  1585.       error = CFF_Load_FD_Select( &font->fd_select,
  1586.                                   font->charstrings_index.count,
  1587.                                   stream,
  1588.                                   base_offset + dict->cid_fd_select_offset );
  1589.  
  1590.     Fail_CID:
  1591.       cff_index_done( &fd_index );
  1592.  
  1593.       if ( error )
  1594.         goto Exit;
  1595.     }
  1596.     else
  1597.       font->num_subfonts = 0;
  1598.  
  1599.     /* read the charstrings index now */
  1600.     if ( dict->charstrings_offset == 0 )
  1601.     {
  1602.       FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
  1603.       error = FT_THROW( Invalid_File_Format );
  1604.       goto Exit;
  1605.     }
  1606.  
  1607.     font->num_glyphs = font->charstrings_index.count;
  1608.  
  1609.     error = cff_index_get_pointers( &font->global_subrs_index,
  1610.                                     &font->global_subrs, NULL );
  1611.  
  1612.     if ( error )
  1613.       goto Exit;
  1614.  
  1615.     /* read the Charset and Encoding tables if available */
  1616.     if ( font->num_glyphs > 0 )
  1617.     {
  1618.       FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
  1619.  
  1620.  
  1621.       error = cff_charset_load( &font->charset, font->num_glyphs, stream,
  1622.                                 base_offset, dict->charset_offset, invert );
  1623.       if ( error )
  1624.         goto Exit;
  1625.  
  1626.       /* CID-keyed CFFs don't have an encoding */
  1627.       if ( dict->cid_registry == 0xFFFFU )
  1628.       {
  1629.         error = cff_encoding_load( &font->encoding,
  1630.                                    &font->charset,
  1631.                                    font->num_glyphs,
  1632.                                    stream,
  1633.                                    base_offset,
  1634.                                    dict->encoding_offset );
  1635.         if ( error )
  1636.           goto Exit;
  1637.       }
  1638.     }
  1639.  
  1640.     /* get the font name (/CIDFontName for CID-keyed fonts, */
  1641.     /* /FontName otherwise)                                 */
  1642.     font->font_name = cff_index_get_name( font, subfont_index );
  1643.  
  1644.   Exit:
  1645.     cff_index_done( &string_index );
  1646.  
  1647.     return error;
  1648.   }
  1649.  
  1650.  
  1651.   FT_LOCAL_DEF( void )
  1652.   cff_font_done( CFF_Font  font )
  1653.   {
  1654.     FT_Memory  memory = font->memory;
  1655.     FT_UInt    idx;
  1656.  
  1657.  
  1658.     cff_index_done( &font->global_subrs_index );
  1659.     cff_index_done( &font->font_dict_index );
  1660.     cff_index_done( &font->name_index );
  1661.     cff_index_done( &font->charstrings_index );
  1662.  
  1663.     /* release font dictionaries, but only if working with */
  1664.     /* a CID keyed CFF font                                */
  1665.     if ( font->num_subfonts > 0 )
  1666.     {
  1667.       for ( idx = 0; idx < font->num_subfonts; idx++ )
  1668.         cff_subfont_done( memory, font->subfonts[idx] );
  1669.  
  1670.       /* the subfonts array has been allocated as a single block */
  1671.       FT_FREE( font->subfonts[0] );
  1672.     }
  1673.  
  1674.     cff_encoding_done( &font->encoding );
  1675.     cff_charset_done( &font->charset, font->stream );
  1676.  
  1677.     cff_subfont_done( memory, &font->top_font );
  1678.  
  1679.     CFF_Done_FD_Select( &font->fd_select, font->stream );
  1680.  
  1681.     FT_FREE( font->font_info );
  1682.  
  1683.     FT_FREE( font->font_name );
  1684.     FT_FREE( font->global_subrs );
  1685.     FT_FREE( font->strings );
  1686.     FT_FREE( font->string_pool );
  1687.  
  1688.     if ( font->cf2_instance.finalizer )
  1689.     {
  1690.       font->cf2_instance.finalizer( font->cf2_instance.data );
  1691.       FT_FREE( font->cf2_instance.data );
  1692.     }
  1693.   }
  1694.  
  1695.  
  1696. /* END */
  1697.