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