source: trunk/poppler/freetype2/src/cff/cffload.c @ 262

Last change on this file since 262 was 262, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.8

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