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