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