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

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

PDF plugin: freetype library updated to version 2.3.9

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, 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_UShort  max_cid = 0;
740
741
742    if ( charset->max_cid > 0 )
743      goto Exit;
744
745    for ( i = 0; i < num_glyphs; i++ )
746      if ( charset->sids[i] > max_cid )
747        max_cid = charset->sids[i];
748    max_cid++;
749
750    if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
751      goto Exit;
752
753    for ( i = 0; i < num_glyphs; i++ )
754      charset->cids[charset->sids[i]] = (FT_UShort)i;
755
756    charset->max_cid    = max_cid;
757    charset->num_glyphs = num_glyphs;
758
759  Exit:
760    return error;
761  }
762
763
764  FT_LOCAL_DEF( FT_UInt )
765  cff_charset_cid_to_gindex( CFF_Charset  charset,
766                             FT_UInt      cid )
767  {
768    FT_UInt  result = 0;
769
770
771    if ( cid < charset->max_cid )
772      result = charset->cids[cid];
773
774    return result;
775  }
776
777
778  static void
779  cff_charset_free_cids( CFF_Charset  charset,
780                         FT_Memory    memory )
781  {
782    FT_FREE( charset->cids );
783    charset->max_cid = 0;
784  }
785
786
787  static void
788  cff_charset_done( CFF_Charset  charset,
789                    FT_Stream    stream )
790  {
791    FT_Memory  memory = stream->memory;
792
793
794    cff_charset_free_cids( charset, memory );
795
796    FT_FREE( charset->sids );
797    charset->format = 0;
798    charset->offset = 0;
799  }
800
801
802  static FT_Error
803  cff_charset_load( CFF_Charset  charset,
804                    FT_UInt      num_glyphs,
805                    FT_Stream    stream,
806                    FT_ULong     base_offset,
807                    FT_ULong     offset,
808                    FT_Bool      invert )
809  {
810    FT_Memory  memory = stream->memory;
811    FT_Error   error  = CFF_Err_Ok;
812    FT_UShort  glyph_sid;
813
814
815    /* If the the offset is greater than 2, we have to parse the */
816    /* charset table.                                            */
817    if ( offset > 2 )
818    {
819      FT_UInt  j;
820
821
822      charset->offset = base_offset + offset;
823
824      /* Get the format of the table. */
825      if ( FT_STREAM_SEEK( charset->offset ) ||
826           FT_READ_BYTE( charset->format )   )
827        goto Exit;
828
829      /* Allocate memory for sids. */
830      if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
831        goto Exit;
832
833      /* assign the .notdef glyph */
834      charset->sids[0] = 0;
835
836      switch ( charset->format )
837      {
838      case 0:
839        if ( num_glyphs > 0 )
840        {
841          if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
842            goto Exit;
843
844          for ( j = 1; j < num_glyphs; j++ )
845            charset->sids[j] = FT_GET_USHORT();
846
847          FT_FRAME_EXIT();
848        }
849        break;
850
851      case 1:
852      case 2:
853        {
854          FT_UInt  nleft;
855          FT_UInt  i;
856
857
858          j = 1;
859
860          while ( j < num_glyphs )
861          {
862            /* Read the first glyph sid of the range. */
863            if ( FT_READ_USHORT( glyph_sid ) )
864              goto Exit;
865
866            /* Read the number of glyphs in the range.  */
867            if ( charset->format == 2 )
868            {
869              if ( FT_READ_USHORT( nleft ) )
870                goto Exit;
871            }
872            else
873            {
874              if ( FT_READ_BYTE( nleft ) )
875                goto Exit;
876            }
877
878            /* Fill in the range of sids -- `nleft + 1' glyphs. */
879            for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
880              charset->sids[j] = glyph_sid;
881          }
882        }
883        break;
884
885      default:
886        FT_ERROR(( "cff_charset_load: invalid table format!\n" ));
887        error = CFF_Err_Invalid_File_Format;
888        goto Exit;
889      }
890    }
891    else
892    {
893      /* Parse default tables corresponding to offset == 0, 1, or 2.  */
894      /* CFF specification intimates the following:                   */
895      /*                                                              */
896      /* In order to use a predefined charset, the following must be  */
897      /* true: The charset constructed for the glyphs in the font's   */
898      /* charstrings dictionary must match the predefined charset in  */
899      /* the first num_glyphs.                                        */
900
901      charset->offset = offset;  /* record charset type */
902
903      switch ( (FT_UInt)offset )
904      {
905      case 0:
906        if ( num_glyphs > 229 )
907        {
908          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
909                     "predefined charset (Adobe ISO-Latin)!\n" ));
910          error = CFF_Err_Invalid_File_Format;
911          goto Exit;
912        }
913
914        /* Allocate memory for sids. */
915        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
916          goto Exit;
917
918        /* Copy the predefined charset into the allocated memory. */
919        FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
920
921        break;
922
923      case 1:
924        if ( num_glyphs > 166 )
925        {
926          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
927                     "predefined charset (Adobe Expert)!\n" ));
928          error = CFF_Err_Invalid_File_Format;
929          goto Exit;
930        }
931
932        /* Allocate memory for sids. */
933        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
934          goto Exit;
935
936        /* Copy the predefined charset into the allocated memory.     */
937        FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
938
939        break;
940
941      case 2:
942        if ( num_glyphs > 87 )
943        {
944          FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
945                     "predefined charset (Adobe Expert Subset)!\n" ));
946          error = CFF_Err_Invalid_File_Format;
947          goto Exit;
948        }
949
950        /* Allocate memory for sids. */
951        if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
952          goto Exit;
953
954        /* Copy the predefined charset into the allocated memory.     */
955        FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
956
957        break;
958
959      default:
960        error = CFF_Err_Invalid_File_Format;
961        goto Exit;
962      }
963    }
964
965    /* we have to invert the `sids' array for subsetted CID-keyed fonts */
966    if ( invert )
967      error = cff_charset_compute_cids( charset, num_glyphs, memory );
968
969  Exit:
970    /* Clean up if there was an error. */
971    if ( error )
972    {
973      FT_FREE( charset->sids );
974      FT_FREE( charset->cids );
975      charset->format = 0;
976      charset->offset = 0;
977      charset->sids   = 0;
978    }
979
980    return error;
981  }
982
983
984  static void
985  cff_encoding_done( CFF_Encoding  encoding )
986  {
987    encoding->format = 0;
988    encoding->offset = 0;
989    encoding->count  = 0;
990  }
991
992
993  static FT_Error
994  cff_encoding_load( CFF_Encoding  encoding,
995                     CFF_Charset   charset,
996                     FT_UInt       num_glyphs,
997                     FT_Stream     stream,
998                     FT_ULong      base_offset,
999                     FT_ULong      offset )
1000  {
1001    FT_Error   error = CFF_Err_Ok;
1002    FT_UInt    count;
1003    FT_UInt    j;
1004    FT_UShort  glyph_sid;
1005    FT_UInt    glyph_code;
1006
1007
1008    /* Check for charset->sids.  If we do not have this, we fail. */
1009    if ( !charset->sids )
1010    {
1011      error = CFF_Err_Invalid_File_Format;
1012      goto Exit;
1013    }
1014
1015    /* Zero out the code to gid/sid mappings. */
1016    for ( j = 0; j < 256; j++ )
1017    {
1018      encoding->sids [j] = 0;
1019      encoding->codes[j] = 0;
1020    }
1021
1022    /* Note: The encoding table in a CFF font is indexed by glyph index;  */
1023    /* the first encoded glyph index is 1.  Hence, we read the character  */
1024    /* code (`glyph_code') at index j and make the assignment:            */
1025    /*                                                                    */
1026    /*    encoding->codes[glyph_code] = j + 1                             */
1027    /*                                                                    */
1028    /* We also make the assignment:                                       */
1029    /*                                                                    */
1030    /*    encoding->sids[glyph_code] = charset->sids[j + 1]               */
1031    /*                                                                    */
1032    /* This gives us both a code to GID and a code to SID mapping.        */
1033
1034    if ( offset > 1 )
1035    {
1036      encoding->offset = base_offset + offset;
1037
1038      /* we need to parse the table to determine its size */
1039      if ( FT_STREAM_SEEK( encoding->offset ) ||
1040           FT_READ_BYTE( encoding->format )   ||
1041           FT_READ_BYTE( count )              )
1042        goto Exit;
1043
1044      switch ( encoding->format & 0x7F )
1045      {
1046      case 0:
1047        {
1048          FT_Byte*  p;
1049
1050
1051          /* By convention, GID 0 is always ".notdef" and is never */
1052          /* coded in the font.  Hence, the number of codes found  */
1053          /* in the table is `count+1'.                            */
1054          /*                                                       */
1055          encoding->count = count + 1;
1056
1057          if ( FT_FRAME_ENTER( count ) )
1058            goto Exit;
1059
1060          p = (FT_Byte*)stream->cursor;
1061
1062          for ( j = 1; j <= count; j++ )
1063          {
1064            glyph_code = *p++;
1065
1066            /* Make sure j is not too big. */
1067            if ( j < num_glyphs )
1068            {
1069              /* Assign code to GID mapping. */
1070              encoding->codes[glyph_code] = (FT_UShort)j;
1071
1072              /* Assign code to SID mapping. */
1073              encoding->sids[glyph_code] = charset->sids[j];
1074            }
1075          }
1076
1077          FT_FRAME_EXIT();
1078        }
1079        break;
1080
1081      case 1:
1082        {
1083          FT_UInt  nleft;
1084          FT_UInt  i = 1;
1085          FT_UInt  k;
1086
1087
1088          encoding->count = 0;
1089
1090          /* Parse the Format1 ranges. */
1091          for ( j = 0;  j < count; j++, i += nleft )
1092          {
1093            /* Read the first glyph code of the range. */
1094            if ( FT_READ_BYTE( glyph_code ) )
1095              goto Exit;
1096
1097            /* Read the number of codes in the range. */
1098            if ( FT_READ_BYTE( nleft ) )
1099              goto Exit;
1100
1101            /* Increment nleft, so we read `nleft + 1' codes/sids. */
1102            nleft++;
1103
1104            /* compute max number of character codes */
1105            if ( (FT_UInt)nleft > encoding->count )
1106              encoding->count = nleft;
1107
1108            /* Fill in the range of codes/sids. */
1109            for ( k = i; k < nleft + i; k++, glyph_code++ )
1110            {
1111              /* Make sure k is not too big. */
1112              if ( k < num_glyphs && glyph_code < 256 )
1113              {
1114                /* Assign code to GID mapping. */
1115                encoding->codes[glyph_code] = (FT_UShort)k;
1116
1117                /* Assign code to SID mapping. */
1118                encoding->sids[glyph_code] = charset->sids[k];
1119              }
1120            }
1121          }
1122
1123          /* simple check; one never knows what can be found in a font */
1124          if ( encoding->count > 256 )
1125            encoding->count = 256;
1126        }
1127        break;
1128
1129      default:
1130        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
1131        error = CFF_Err_Invalid_File_Format;
1132        goto Exit;
1133      }
1134
1135      /* Parse supplemental encodings, if any. */
1136      if ( encoding->format & 0x80 )
1137      {
1138        FT_UInt  gindex;
1139
1140
1141        /* count supplements */
1142        if ( FT_READ_BYTE( count ) )
1143          goto Exit;
1144
1145        for ( j = 0; j < count; j++ )
1146        {
1147          /* Read supplemental glyph code. */
1148          if ( FT_READ_BYTE( glyph_code ) )
1149            goto Exit;
1150
1151          /* Read the SID associated with this glyph code. */
1152          if ( FT_READ_USHORT( glyph_sid ) )
1153            goto Exit;
1154
1155          /* Assign code to SID mapping. */
1156          encoding->sids[glyph_code] = glyph_sid;
1157
1158          /* First, look up GID which has been assigned to */
1159          /* SID glyph_sid.                                */
1160          for ( gindex = 0; gindex < num_glyphs; gindex++ )
1161          {
1162            if ( charset->sids[gindex] == glyph_sid )
1163            {
1164              encoding->codes[glyph_code] = (FT_UShort)gindex;
1165              break;
1166            }
1167          }
1168        }
1169      }
1170    }
1171    else
1172    {
1173      /* We take into account the fact a CFF font can use a predefined */
1174      /* encoding without containing all of the glyphs encoded by this */
1175      /* encoding (see the note at the end of section 12 in the CFF    */
1176      /* specification).                                               */
1177
1178      switch ( (FT_UInt)offset )
1179      {
1180      case 0:
1181        /* First, copy the code to SID mapping. */
1182        FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1183        goto Populate;
1184
1185      case 1:
1186        /* First, copy the code to SID mapping. */
1187        FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1188
1189      Populate:
1190        /* Construct code to GID mapping from code to SID mapping */
1191        /* and charset.                                           */
1192
1193        encoding->count = 0;
1194
1195        error = cff_charset_compute_cids( charset, num_glyphs,
1196                                          stream->memory );
1197        if ( error )
1198          goto Exit;
1199
1200        for ( j = 0; j < 256; j++ )
1201        {
1202          FT_UInt  sid = encoding->sids[j];
1203          FT_UInt  gid = 0;
1204
1205
1206          if ( sid )
1207            gid = cff_charset_cid_to_gindex( charset, sid );
1208
1209          if ( gid != 0 )
1210          {
1211            encoding->codes[j] = (FT_UShort)gid;
1212
1213            if ( encoding->count < j + 1 )
1214              encoding->count = j + 1;
1215          }
1216          else
1217          {
1218            encoding->codes[j] = 0;
1219            encoding->sids [j] = 0;
1220          }
1221        }
1222        break;
1223
1224      default:
1225        FT_ERROR(( "cff_encoding_load: invalid table format!\n" ));
1226        error = CFF_Err_Invalid_File_Format;
1227        goto Exit;
1228      }
1229    }
1230
1231  Exit:
1232
1233    /* Clean up if there was an error. */
1234    return error;
1235  }
1236
1237
1238  static FT_Error
1239  cff_subfont_load( CFF_SubFont  font,
1240                    CFF_Index    idx,
1241                    FT_UInt      font_index,
1242                    FT_Stream    stream,
1243                    FT_ULong     base_offset )
1244  {
1245    FT_Error         error;
1246    CFF_ParserRec    parser;
1247    FT_Byte*         dict = NULL;
1248    FT_ULong         dict_len;
1249    CFF_FontRecDict  top  = &font->font_dict;
1250    CFF_Private      priv = &font->private_dict;
1251
1252
1253    cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict );
1254
1255    /* set defaults */
1256    FT_MEM_ZERO( top, sizeof ( *top ) );
1257
1258    top->underline_position  = -100L << 16;
1259    top->underline_thickness = 50L << 16;
1260    top->charstring_type     = 2;
1261    top->font_matrix.xx      = 0x10000L;
1262    top->font_matrix.yy      = 0x10000L;
1263    top->cid_count           = 8720;
1264
1265    /* we use the implementation specific SID value 0xFFFF to indicate */
1266    /* missing entries                                                 */
1267    top->version             = 0xFFFFU;
1268    top->notice              = 0xFFFFU;
1269    top->copyright           = 0xFFFFU;
1270    top->full_name           = 0xFFFFU;
1271    top->family_name         = 0xFFFFU;
1272    top->weight              = 0xFFFFU;
1273    top->embedded_postscript = 0xFFFFU;
1274
1275    top->cid_registry        = 0xFFFFU;
1276    top->cid_ordering        = 0xFFFFU;
1277    top->cid_font_name       = 0xFFFFU;
1278
1279    error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1280    if ( !error )
1281      error = cff_parser_run( &parser, dict, dict + dict_len );
1282
1283    cff_index_forget_element( idx, &dict );
1284
1285    if ( error )
1286      goto Exit;
1287
1288    /* if it is a CID font, we stop there */
1289    if ( top->cid_registry != 0xFFFFU )
1290      goto Exit;
1291
1292    /* parse the private dictionary, if any */
1293    if ( top->private_offset && top->private_size )
1294    {
1295      /* set defaults */
1296      FT_MEM_ZERO( priv, sizeof ( *priv ) );
1297
1298      priv->blue_shift       = 7;
1299      priv->blue_fuzz        = 1;
1300      priv->lenIV            = -1;
1301      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1302      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1303
1304      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
1305
1306      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1307           FT_FRAME_ENTER( font->font_dict.private_size )                 )
1308        goto Exit;
1309
1310      error = cff_parser_run( &parser,
1311                              (FT_Byte*)stream->cursor,
1312                              (FT_Byte*)stream->limit );
1313      FT_FRAME_EXIT();
1314      if ( error )
1315        goto Exit;
1316
1317      /* ensure that `num_blue_values' is even */
1318      priv->num_blue_values &= ~1;
1319    }
1320
1321    /* read the local subrs, if any */
1322    if ( priv->local_subrs_offset )
1323    {
1324      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1325                           priv->local_subrs_offset ) )
1326        goto Exit;
1327
1328      error = cff_index_init( &font->local_subrs_index, stream, 1 );
1329      if ( error )
1330        goto Exit;
1331
1332      font->num_local_subrs = font->local_subrs_index.count;
1333      error = cff_index_get_pointers( &font->local_subrs_index,
1334                                      &font->local_subrs );
1335      if ( error )
1336        goto Exit;
1337    }
1338
1339  Exit:
1340    return error;
1341  }
1342
1343
1344  static void
1345  cff_subfont_done( FT_Memory    memory,
1346                    CFF_SubFont  subfont )
1347  {
1348    if ( subfont )
1349    {
1350      cff_index_done( &subfont->local_subrs_index );
1351      FT_FREE( subfont->local_subrs );
1352    }
1353  }
1354
1355
1356  FT_LOCAL_DEF( FT_Error )
1357  cff_font_load( FT_Stream  stream,
1358                 FT_Int     face_index,
1359                 CFF_Font   font,
1360                 FT_Bool    pure_cff )
1361  {
1362    static const FT_Frame_Field  cff_header_fields[] =
1363    {
1364#undef  FT_STRUCTURE
1365#define FT_STRUCTURE  CFF_FontRec
1366
1367      FT_FRAME_START( 4 ),
1368        FT_FRAME_BYTE( version_major ),
1369        FT_FRAME_BYTE( version_minor ),
1370        FT_FRAME_BYTE( header_size ),
1371        FT_FRAME_BYTE( absolute_offsize ),
1372      FT_FRAME_END
1373    };
1374
1375    FT_Error         error;
1376    FT_Memory        memory = stream->memory;
1377    FT_ULong         base_offset;
1378    CFF_FontRecDict  dict;
1379
1380
1381    FT_ZERO( font );
1382
1383    font->stream = stream;
1384    font->memory = memory;
1385    dict         = &font->top_font.font_dict;
1386    base_offset  = FT_STREAM_POS();
1387
1388    /* read CFF font header */
1389    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1390      goto Exit;
1391
1392    /* check format */
1393    if ( font->version_major   != 1 ||
1394         font->header_size      < 4 ||
1395         font->absolute_offsize > 4 )
1396    {
1397      FT_TRACE2(( "[not a CFF font header!]\n" ));
1398      error = CFF_Err_Unknown_File_Format;
1399      goto Exit;
1400    }
1401
1402    /* skip the rest of the header */
1403    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1404      goto Exit;
1405
1406    /* read the name, top dict, string and global subrs index */
1407    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1408                                       stream, 0 ) )              ||
1409         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1410                                       stream, 0 ) )              ||
1411         FT_SET_ERROR( cff_index_init( &font->string_index,
1412                                       stream, 0 ) )              ||
1413         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1414                                       stream, 1 ) )              )
1415      goto Exit;
1416
1417    /* well, we don't really forget the `disabled' fonts... */
1418    font->num_faces = font->name_index.count;
1419    if ( face_index >= (FT_Int)font->num_faces )
1420    {
1421      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
1422                 face_index ));
1423      error = CFF_Err_Invalid_Argument;
1424    }
1425
1426    /* in case of a font format check, simply exit now */
1427    if ( face_index < 0 )
1428      goto Exit;
1429
1430    /* now, parse the top-level font dictionary */
1431    error = cff_subfont_load( &font->top_font,
1432                              &font->font_dict_index,
1433                              face_index,
1434                              stream,
1435                              base_offset );
1436    if ( error )
1437      goto Exit;
1438
1439    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1440      goto Exit;
1441
1442    error = cff_index_init( &font->charstrings_index, stream, 0 );
1443    if ( error )
1444      goto Exit;
1445
1446    /* now, check for a CID font */
1447    if ( dict->cid_registry != 0xFFFFU )
1448    {
1449      CFF_IndexRec  fd_index;
1450      CFF_SubFont   sub;
1451      FT_UInt       idx;
1452
1453
1454      /* this is a CID-keyed font, we must now allocate a table of */
1455      /* sub-fonts, then load each of them separately              */
1456      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1457        goto Exit;
1458
1459      error = cff_index_init( &fd_index, stream, 0 );
1460      if ( error )
1461        goto Exit;
1462
1463      if ( fd_index.count > CFF_MAX_CID_FONTS )
1464      {
1465        FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
1466        goto Fail_CID;
1467      }
1468
1469      /* allocate & read each font dict independently */
1470      font->num_subfonts = fd_index.count;
1471      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1472        goto Fail_CID;
1473
1474      /* set up pointer table */
1475      for ( idx = 0; idx < fd_index.count; idx++ )
1476        font->subfonts[idx] = sub + idx;
1477
1478      /* now load each subfont independently */
1479      for ( idx = 0; idx < fd_index.count; idx++ )
1480      {
1481        sub = font->subfonts[idx];
1482        error = cff_subfont_load( sub, &fd_index, idx,
1483                                  stream, base_offset );
1484        if ( error )
1485          goto Fail_CID;
1486      }
1487
1488      /* now load the FD Select array */
1489      error = CFF_Load_FD_Select( &font->fd_select,
1490                                  font->charstrings_index.count,
1491                                  stream,
1492                                  base_offset + dict->cid_fd_select_offset );
1493
1494    Fail_CID:
1495      cff_index_done( &fd_index );
1496
1497      if ( error )
1498        goto Exit;
1499    }
1500    else
1501      font->num_subfonts = 0;
1502
1503    /* read the charstrings index now */
1504    if ( dict->charstrings_offset == 0 )
1505    {
1506      FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
1507      error = CFF_Err_Unknown_File_Format;
1508      goto Exit;
1509    }
1510
1511    /* explicit the global subrs */
1512    font->num_global_subrs = font->global_subrs_index.count;
1513    font->num_glyphs       = font->charstrings_index.count;
1514
1515    error = cff_index_get_pointers( &font->global_subrs_index,
1516                                    &font->global_subrs ) ;
1517
1518    if ( error )
1519      goto Exit;
1520
1521    /* read the Charset and Encoding tables if available */
1522    if ( font->num_glyphs > 0 )
1523    {
1524      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1525
1526
1527      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1528                                base_offset, dict->charset_offset, invert );
1529      if ( error )
1530        goto Exit;
1531
1532      /* CID-keyed CFFs don't have an encoding */
1533      if ( dict->cid_registry == 0xFFFFU )
1534      {
1535        error = cff_encoding_load( &font->encoding,
1536                                   &font->charset,
1537                                   font->num_glyphs,
1538                                   stream,
1539                                   base_offset,
1540                                   dict->encoding_offset );
1541        if ( error )
1542          goto Exit;
1543      }
1544    }
1545
1546    /* get the font name (/CIDFontName for CID-keyed fonts, */
1547    /* /FontName otherwise)                                 */
1548    font->font_name = cff_index_get_name( &font->name_index, face_index );
1549
1550  Exit:
1551    return error;
1552  }
1553
1554
1555  FT_LOCAL_DEF( void )
1556  cff_font_done( CFF_Font  font )
1557  {
1558    FT_Memory  memory = font->memory;
1559    FT_UInt    idx;
1560
1561
1562    cff_index_done( &font->global_subrs_index );
1563    cff_index_done( &font->string_index );
1564    cff_index_done( &font->font_dict_index );
1565    cff_index_done( &font->name_index );
1566    cff_index_done( &font->charstrings_index );
1567
1568    /* release font dictionaries, but only if working with */
1569    /* a CID keyed CFF font                                */
1570    if ( font->num_subfonts > 0 )
1571    {
1572      for ( idx = 0; idx < font->num_subfonts; idx++ )
1573        cff_subfont_done( memory, font->subfonts[idx] );
1574
1575      /* the subfonts array has been allocated as a single block */
1576      FT_FREE( font->subfonts[0] );
1577    }
1578
1579    cff_encoding_done( &font->encoding );
1580    cff_charset_done( &font->charset, font->stream );
1581
1582    cff_subfont_done( memory, &font->top_font );
1583
1584    CFF_Done_FD_Select( &font->fd_select, font->stream );
1585
1586    if (font->font_info != NULL)
1587    {
1588      FT_FREE( font->font_info->version );
1589      FT_FREE( font->font_info->notice );
1590      FT_FREE( font->font_info->full_name );
1591      FT_FREE( font->font_info->family_name );
1592      FT_FREE( font->font_info->weight );
1593      FT_FREE( font->font_info );
1594    }
1595
1596    FT_FREE( font->registry );
1597    FT_FREE( font->ordering );
1598
1599    FT_FREE( font->global_subrs );
1600    FT_FREE( font->font_name );
1601  }
1602
1603
1604/* END */
Note: See TracBrowser for help on using the repository browser.