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

Last change on this file since 182 was 182, checked in by Eugene Romanenko, 15 years ago

freetype update to version 2.3.0

File size: 45.4 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 by             */
8/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9/*                                                                         */
10/*  This file is part of the FreeType project, and may only be used,       */
11/*  modified, and distributed under the terms of the FreeType project      */
12/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13/*  this file you indicate that you have read the license and              */
14/*  understand and accept it fully.                                        */
15/*                                                                         */
16/***************************************************************************/
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_OBJECTS_H
22#include FT_INTERNAL_STREAM_H
23#include FT_SERVICE_POSTSCRIPT_CMAPS_H
24#include FT_TRUETYPE_TAGS_H
25#include FT_TYPE1_TABLES_H
26
27#include "cffload.h"
28#include "cffparse.h"
29
30#include "cfferrs.h"
31
32
33#if 1
34  static const FT_UShort  cff_isoadobe_charset[229] =
35  {
36      0,   1,   2,   3,   4,   5,   6,   7,
37      8,   9,  10,  11,  12,  13,  14,  15,
38     16,  17,  18,  19,  20,  21,  22,  23,
39     24,  25,  26,  27,  28,  29,  30,  31,
40     32,  33,  34,  35,  36,  37,  38,  39,
41     40,  41,  42,  43,  44,  45,  46,  47,
42     48,  49,  50,  51,  52,  53,  54,  55,
43     56,  57,  58,  59,  60,  61,  62,  63,
44     64,  65,  66,  67,  68,  69,  70,  71,
45     72,  73,  74,  75,  76,  77,  78,  79,
46     80,  81,  82,  83,  84,  85,  86,  87,
47     88,  89,  90,  91,  92,  93,  94,  95,
48     96,  97,  98,  99, 100, 101, 102, 103,
49    104, 105, 106, 107, 108, 109, 110, 111,
50    112, 113, 114, 115, 116, 117, 118, 119,
51    120, 121, 122, 123, 124, 125, 126, 127,
52    128, 129, 130, 131, 132, 133, 134, 135,
53    136, 137, 138, 139, 140, 141, 142, 143,
54    144, 145, 146, 147, 148, 149, 150, 151,
55    152, 153, 154, 155, 156, 157, 158, 159,
56    160, 161, 162, 163, 164, 165, 166, 167,
57    168, 169, 170, 171, 172, 173, 174, 175,
58    176, 177, 178, 179, 180, 181, 182, 183,
59    184, 185, 186, 187, 188, 189, 190, 191,
60    192, 193, 194, 195, 196, 197, 198, 199,
61    200, 201, 202, 203, 204, 205, 206, 207,
62    208, 209, 210, 211, 212, 213, 214, 215,
63    216, 217, 218, 219, 220, 221, 222, 223,
64    224, 225, 226, 227, 228
65  };
66
67  static const FT_UShort  cff_expert_charset[166] =
68  {
69      0,   1, 229, 230, 231, 232, 233, 234,
70    235, 236, 237, 238,  13,  14,  15,  99,
71    239, 240, 241, 242, 243, 244, 245, 246,
72    247, 248,  27,  28, 249, 250, 251, 252,
73    253, 254, 255, 256, 257, 258, 259, 260,
74    261, 262, 263, 264, 265, 266, 109, 110,
75    267, 268, 269, 270, 271, 272, 273, 274,
76    275, 276, 277, 278, 279, 280, 281, 282,
77    283, 284, 285, 286, 287, 288, 289, 290,
78    291, 292, 293, 294, 295, 296, 297, 298,
79    299, 300, 301, 302, 303, 304, 305, 306,
80    307, 308, 309, 310, 311, 312, 313, 314,
81    315, 316, 317, 318, 158, 155, 163, 319,
82    320, 321, 322, 323, 324, 325, 326, 150,
83    164, 169, 327, 328, 329, 330, 331, 332,
84    333, 334, 335, 336, 337, 338, 339, 340,
85    341, 342, 343, 344, 345, 346, 347, 348,
86    349, 350, 351, 352, 353, 354, 355, 356,
87    357, 358, 359, 360, 361, 362, 363, 364,
88    365, 366, 367, 368, 369, 370, 371, 372,
89    373, 374, 375, 376, 377, 378
90  };
91
92  static const FT_UShort  cff_expertsubset_charset[87] =
93  {
94      0,   1, 231, 232, 235, 236, 237, 238,
95     13,  14,  15,  99, 239, 240, 241, 242,
96    243, 244, 245, 246, 247, 248,  27,  28,
97    249, 250, 251, 253, 254, 255, 256, 257,
98    258, 259, 260, 261, 262, 263, 264, 265,
99    266, 109, 110, 267, 268, 269, 270, 272,
100    300, 301, 302, 305, 314, 315, 158, 155,
101    163, 320, 321, 322, 323, 324, 325, 326,
102    150, 164, 169, 327, 328, 329, 330, 331,
103    332, 333, 334, 335, 336, 337, 338, 339,
104    340, 341, 342, 343, 344, 345, 346
105  };
106
107  static const FT_UShort  cff_standard_encoding[256] =
108  {
109      0,   0,   0,   0,   0,   0,   0,   0,
110      0,   0,   0,   0,   0,   0,   0,   0,
111      0,   0,   0,   0,   0,   0,   0,   0,
112      0,   0,   0,   0,   0,   0,   0,   0,
113      1,   2,   3,   4,   5,   6,   7,   8,
114      9,  10,  11,  12,  13,  14,  15,  16,
115     17,  18,  19,  20,  21,  22,  23,  24,
116     25,  26,  27,  28,  29,  30,  31,  32,
117     33,  34,  35,  36,  37,  38,  39,  40,
118     41,  42,  43,  44,  45,  46,  47,  48,
119     49,  50,  51,  52,  53,  54,  55,  56,
120     57,  58,  59,  60,  61,  62,  63,  64,
121     65,  66,  67,  68,  69,  70,  71,  72,
122     73,  74,  75,  76,  77,  78,  79,  80,
123     81,  82,  83,  84,  85,  86,  87,  88,
124     89,  90,  91,  92,  93,  94,  95,   0,
125      0,   0,   0,   0,   0,   0,   0,   0,
126      0,   0,   0,   0,   0,   0,   0,   0,
127      0,   0,   0,   0,   0,   0,   0,   0,
128      0,   0,   0,   0,   0,   0,   0,   0,
129      0,  96,  97,  98,  99, 100, 101, 102,
130    103, 104, 105, 106, 107, 108, 109, 110,
131      0, 111, 112, 113, 114,   0, 115, 116,
132    117, 118, 119, 120, 121, 122,   0, 123,
133      0, 124, 125, 126, 127, 128, 129, 130,
134    131,   0, 132, 133,   0, 134, 135, 136,
135    137,   0,   0,   0,   0,   0,   0,   0,
136      0,   0,   0,   0,   0,   0,   0,   0,
137      0, 138,   0, 139,   0,   0,   0,   0,
138    140, 141, 142, 143,   0,   0,   0,   0,
139      0, 144,   0,   0,   0, 145,   0,   0,
140    146, 147, 148, 149,   0,   0,   0,   0
141  };
142
143  static const FT_UShort  cff_expert_encoding[256] =
144  {
145      0,   0,   0,   0,   0,   0,   0,   0,
146      0,   0,   0,   0,   0,   0,   0,   0,
147      0,   0,   0,   0,   0,   0,   0,   0,
148      0,   0,   0,   0,   0,   0,   0,   0,
149      1, 229, 230,   0, 231, 232, 233, 234,
150    235, 236, 237, 238,  13,  14,  15,  99,
151    239, 240, 241, 242, 243, 244, 245, 246,
152    247, 248,  27,  28, 249, 250, 251, 252,
153      0, 253, 254, 255, 256, 257,   0,   0,
154      0, 258,   0,   0, 259, 260, 261, 262,
155      0,   0, 263, 264, 265,   0, 266, 109,
156    110, 267, 268, 269,   0, 270, 271, 272,
157    273, 274, 275, 276, 277, 278, 279, 280,
158    281, 282, 283, 284, 285, 286, 287, 288,
159    289, 290, 291, 292, 293, 294, 295, 296,
160    297, 298, 299, 300, 301, 302, 303,   0,
161      0,   0,   0,   0,   0,   0,   0,   0,
162      0,   0,   0,   0,   0,   0,   0,   0,
163      0,   0,   0,   0,   0,   0,   0,   0,
164      0,   0,   0,   0,   0,   0,   0,   0,
165      0, 304, 305, 306,   0,   0, 307, 308,
166    309, 310, 311,   0, 312,   0,   0, 312,
167      0,   0, 314, 315,   0,   0, 316, 317,
168    318,   0,   0,   0, 158, 155, 163, 319,
169    320, 321, 322, 323, 324, 325,   0,   0,
170    326, 150, 164, 169, 327, 328, 329, 330,
171    331, 332, 333, 334, 335, 336, 337, 338,
172    339, 340, 341, 342, 343, 344, 345, 346,
173    347, 348, 349, 350, 351, 352, 353, 354,
174    355, 356, 357, 358, 359, 360, 361, 362,
175    363, 364, 365, 366, 367, 368, 369, 370,
176    371, 372, 373, 374, 375, 376, 377, 378
177  };
178#endif
179
180
181  FT_LOCAL_DEF( FT_UShort )
182  cff_get_standard_encoding( FT_UInt  charcode )
183  {
184    return  (FT_UShort)(charcode < 256 ? cff_standard_encoding[charcode] : 0);
185  }
186
187
188  /*************************************************************************/
189  /*                                                                       */
190  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
191  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
192  /* messages during execution.                                            */
193  /*                                                                       */
194#undef  FT_COMPONENT
195#define FT_COMPONENT  trace_cffload
196
197
198  /* read an offset from the index's stream current position */
199  static FT_ULong
200  cff_index_read_offset( CFF_Index  idx,
201                         FT_Error  *errorp )
202  {
203    FT_Error   error;
204    FT_Stream  stream = idx->stream;
205    FT_Byte    tmp[4];
206    FT_ULong   result = 0;
207
208
209    if ( !FT_STREAM_READ( tmp, idx->off_size ) )
210    {
211      FT_Int  nn;
212
213
214      for ( nn = 0; nn < idx->off_size; nn++ )
215        result = ( result << 8 ) | tmp[nn];
216    }
217
218    *errorp = error;
219    return result;
220  }
221
222
223  static FT_Error
224  cff_index_init( CFF_Index  idx,
225                  FT_Stream  stream,
226                  FT_Bool    load )
227  {
228    FT_Error   error;
229    FT_Memory  memory = stream->memory;
230    FT_UShort  count;
231
232
233    FT_MEM_ZERO( idx, sizeof ( *idx ) );
234
235    idx->stream = stream;
236    idx->start  = FT_STREAM_POS();
237    if ( !FT_READ_USHORT( count ) &&
238         count > 0                )
239    {
240      FT_Byte   offsize;
241      FT_ULong  size;
242
243
244      /* there is at least one element; read the offset size,           */
245      /* then access the offset table to compute the index's total size */
246      if ( FT_READ_BYTE( offsize ) )
247        goto Exit;
248
249      if ( offsize < 1 || offsize > 4 )
250      {
251        error = FT_Err_Invalid_Table;
252        goto Exit;
253      }
254
255      idx->count    = count;
256      idx->off_size = offsize;
257      size          = (FT_ULong)( count + 1 ) * offsize;
258
259      idx->data_offset = idx->start + 3 + size;
260
261      if ( FT_STREAM_SKIP( size - offsize ) )
262        goto Exit;
263
264      size = cff_index_read_offset( idx, &error );
265      if ( error )
266        goto Exit;
267
268      if ( size == 0 )
269      {
270        error = CFF_Err_Invalid_Table;
271        goto Exit;
272      }
273
274      idx->data_size = --size;
275
276      if ( load )
277      {
278        /* load the data */
279        if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
280          goto Exit;
281      }
282      else
283      {
284        /* skip the data */
285        if ( FT_STREAM_SKIP( size ) )
286          goto Exit;
287      }
288    }
289
290  Exit:
291    if ( error )
292      FT_FREE( idx->offsets );
293
294    return error;
295  }
296
297
298  static void
299  cff_index_done( CFF_Index  idx )
300  {
301    if ( idx->stream )
302    {
303      FT_Stream  stream = idx->stream;
304      FT_Memory  memory = stream->memory;
305
306
307      if ( idx->bytes )
308        FT_FRAME_RELEASE( idx->bytes );
309
310      FT_FREE( idx->offsets );
311      FT_MEM_ZERO( idx, sizeof ( *idx ) );
312    }
313  }
314
315
316  static FT_Error
317  cff_index_load_offsets( CFF_Index  idx )
318  {
319    FT_Error   error  = 0;
320    FT_Stream  stream = idx->stream;
321    FT_Memory  memory = stream->memory;
322
323
324    if ( idx->count > 0 && idx->offsets == NULL )
325    {
326      FT_Byte    offsize = idx->off_size;
327      FT_ULong   data_size;
328      FT_Byte*   p;
329      FT_Byte*   p_end;
330      FT_ULong*  poff;
331
332
333      data_size = (FT_ULong)( idx->count + 1 ) * offsize;
334
335      if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
336           FT_STREAM_SEEK( idx->start + 3 )             ||
337           FT_FRAME_ENTER( data_size )                  )
338        goto Exit;
339
340      poff   = idx->offsets;
341      p      = (FT_Byte*)stream->cursor;
342      p_end  = p + data_size;
343
344      switch ( offsize )
345      {
346      case 1:
347        for ( ; p < p_end; p++, poff++ )
348          poff[0] = p[0];
349        break;
350
351      case 2:
352        for ( ; p < p_end; p += 2, poff++ )
353          poff[0] = FT_PEEK_USHORT( p );
354        break;
355
356      case 3:
357        for ( ; p < p_end; p += 3, poff++ )
358          poff[0] = FT_PEEK_OFF3( p );
359        break;
360
361      default:
362        for ( ; p < p_end; p += 4, poff++ )
363          poff[0] = FT_PEEK_ULONG( p );
364      }
365
366      FT_FRAME_EXIT();
367    }
368
369  Exit:
370    if ( error )
371      FT_FREE( idx->offsets );
372
373    return error;
374  }
375
376
377  /* allocate a table containing pointers to an index's elements */
378  static FT_Error
379  cff_index_get_pointers( CFF_Index   idx,
380                          FT_Byte***  table )
381  {
382    FT_Error   error  = CFF_Err_Ok;
383    FT_Memory  memory = idx->stream->memory;
384    FT_ULong   n, offset, old_offset;
385    FT_Byte**  t;
386
387
388    *table = 0;
389
390    if ( idx->offsets == NULL )
391    {
392      error = cff_index_load_offsets( idx );
393      if ( error )
394        goto Exit;
395    }
396
397    if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) )
398    {
399      old_offset = 1;
400      for ( n = 0; n <= idx->count; n++ )
401      {
402        offset = idx->offsets[n];
403        if ( !offset )
404          offset = old_offset;
405
406        /* sanity check for invalid offset tables */
407        else if ( offset < old_offset || offset - 1 >= idx->data_size )
408          offset = old_offset;
409
410        t[n] = idx->bytes + offset - 1;
411
412        old_offset = offset;
413      }
414      *table = t;
415    }
416
417  Exit:
418    return error;
419  }
420
421
422  FT_LOCAL_DEF( FT_Error )
423  cff_index_access_element( CFF_Index  idx,
424                            FT_UInt    element,
425                            FT_Byte**  pbytes,
426                            FT_ULong*  pbyte_len )
427  {
428    FT_Error  error = CFF_Err_Ok;
429
430
431    if ( idx && idx->count > element )
432    {
433      /* compute start and end offsets */
434      FT_Stream  stream = idx->stream;
435      FT_ULong   off1, off2 = 0;
436
437
438      /* load offsets from file or the offset table */
439      if ( !idx->offsets )
440      {
441        FT_ULong  pos = element * idx->off_size;
442
443
444        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
445          goto Exit;
446
447        off1 = cff_index_read_offset( idx, &error );
448        if ( error )
449          goto Exit;
450
451        if ( off1 != 0 )
452        {
453          do
454          {
455            element++;
456            off2 = cff_index_read_offset( idx, &error );
457          }
458          while ( off2 == 0 && element < idx->count );
459        }
460      }
461      else   /* use offsets table */
462      {
463        off1 = idx->offsets[element];
464        if ( off1 )
465        {
466          do
467          {
468            element++;
469            off2 = idx->offsets[element];
470
471          } while ( off2 == 0 && element < idx->count );
472        }
473      }
474
475      /* access element */
476      if ( off1 && off2 > off1 )
477      {
478        *pbyte_len = off2 - off1;
479
480        if ( idx->bytes )
481        {
482          /* this index was completely loaded in memory, that's easy */
483          *pbytes = idx->bytes + off1 - 1;
484        }
485        else
486        {
487          /* this index is still on disk/file, access it through a frame */
488          if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
489               FT_FRAME_EXTRACT( off2 - off1, *pbytes )      )
490            goto Exit;
491        }
492      }
493      else
494      {
495        /* empty index element */
496        *pbytes    = 0;
497        *pbyte_len = 0;
498      }
499    }
500    else
501      error = CFF_Err_Invalid_Argument;
502
503  Exit:
504    return error;
505  }
506
507
508  FT_LOCAL_DEF( void )
509  cff_index_forget_element( CFF_Index  idx,
510                            FT_Byte**  pbytes )
511  {
512    if ( idx->bytes == 0 )
513    {
514      FT_Stream  stream = idx->stream;
515
516
517      FT_FRAME_RELEASE( *pbytes );
518    }
519  }
520
521
522  FT_LOCAL_DEF( FT_String* )
523  cff_index_get_name( CFF_Index  idx,
524                      FT_UInt    element )
525  {
526    FT_Memory   memory = idx->stream->memory;
527    FT_Byte*    bytes;
528    FT_ULong    byte_len;
529    FT_Error    error;
530    FT_String*  name = 0;
531
532
533    error = cff_index_access_element( idx, element, &bytes, &byte_len );
534    if ( error )
535      goto Exit;
536
537    if ( !FT_ALLOC( name, byte_len + 1 ) )
538    {
539      FT_MEM_COPY( name, bytes, byte_len );
540      name[byte_len] = 0;
541    }
542    cff_index_forget_element( idx, &bytes );
543
544  Exit:
545    return name;
546  }
547
548
549  FT_LOCAL_DEF( FT_String* )
550  cff_index_get_sid_string( CFF_Index           idx,
551                            FT_UInt             sid,
552                            FT_Service_PsCMaps  psnames )
553  {
554    /* value 0xFFFFU indicates a missing dictionary entry */
555    if ( sid == 0xFFFFU )
556      return 0;
557
558    /* if it is not a standard string, return it */
559    if ( sid > 390 )
560      return cff_index_get_name( idx, sid - 391 );
561
562    /* CID-keyed CFF fonts don't have glyph names */
563    if ( !psnames )
564      return 0;
565
566    /* that's a standard string, fetch a copy from the PSName module */
567    {
568      FT_String*   name       = 0;
569      const char*  adobe_name = psnames->adobe_std_strings( sid );
570      FT_UInt      len;
571
572
573      if ( adobe_name )
574      {
575        FT_Memory  memory = idx->stream->memory;
576        FT_Error   error;
577
578
579        len = (FT_UInt)ft_strlen( adobe_name );
580        if ( !FT_ALLOC( name, len + 1 ) )
581        {
582          FT_MEM_COPY( name, adobe_name, len );
583          name[len] = 0;
584        }
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            cff_parser_run( &parser, dict, dict + dict_len );
1280
1281    cff_index_forget_element( idx, &dict );
1282
1283    if ( error )
1284      goto Exit;
1285
1286    /* if it is a CID font, we stop there */
1287    if ( top->cid_registry != 0xFFFFU )
1288      goto Exit;
1289
1290    /* parse the private dictionary, if any */
1291    if ( top->private_offset && top->private_size )
1292    {
1293      /* set defaults */
1294      FT_MEM_ZERO( priv, sizeof ( *priv ) );
1295
1296      priv->blue_shift       = 7;
1297      priv->blue_fuzz        = 1;
1298      priv->lenIV            = -1;
1299      priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1300      priv->blue_scale       = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1301
1302      cff_parser_init( &parser, CFF_CODE_PRIVATE, priv );
1303
1304      if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1305           FT_FRAME_ENTER( font->font_dict.private_size )                 )
1306        goto Exit;
1307
1308      error = cff_parser_run( &parser,
1309                              (FT_Byte*)stream->cursor,
1310                              (FT_Byte*)stream->limit );
1311      FT_FRAME_EXIT();
1312      if ( error )
1313        goto Exit;
1314
1315      /* ensure that `num_blue_values' is even */
1316      priv->num_blue_values &= ~1;
1317    }
1318
1319    /* read the local subrs, if any */
1320    if ( priv->local_subrs_offset )
1321    {
1322      if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1323                           priv->local_subrs_offset ) )
1324        goto Exit;
1325
1326      error = cff_index_init( &font->local_subrs_index, stream, 1 );
1327      if ( error )
1328        goto Exit;
1329
1330      font->num_local_subrs = font->local_subrs_index.count;
1331      error = cff_index_get_pointers( &font->local_subrs_index,
1332                                      &font->local_subrs );
1333      if ( error )
1334        goto Exit;
1335    }
1336
1337  Exit:
1338    return error;
1339  }
1340
1341
1342  static void
1343  cff_subfont_done( FT_Memory    memory,
1344                    CFF_SubFont  subfont )
1345  {
1346    if ( subfont )
1347    {
1348      cff_index_done( &subfont->local_subrs_index );
1349      FT_FREE( subfont->local_subrs );
1350    }
1351  }
1352
1353
1354  FT_LOCAL_DEF( FT_Error )
1355  cff_font_load( FT_Stream  stream,
1356                 FT_Int     face_index,
1357                 CFF_Font   font )
1358  {
1359    static const FT_Frame_Field  cff_header_fields[] =
1360    {
1361#undef  FT_STRUCTURE
1362#define FT_STRUCTURE  CFF_FontRec
1363
1364      FT_FRAME_START( 4 ),
1365        FT_FRAME_BYTE( version_major ),
1366        FT_FRAME_BYTE( version_minor ),
1367        FT_FRAME_BYTE( header_size ),
1368        FT_FRAME_BYTE( absolute_offsize ),
1369      FT_FRAME_END
1370    };
1371
1372    FT_Error         error;
1373    FT_Memory        memory = stream->memory;
1374    FT_ULong         base_offset;
1375    CFF_FontRecDict  dict;
1376
1377
1378    FT_ZERO( font );
1379
1380    font->stream = stream;
1381    font->memory = memory;
1382    dict         = &font->top_font.font_dict;
1383    base_offset  = FT_STREAM_POS();
1384
1385    /* read CFF font header */
1386    if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1387      goto Exit;
1388
1389    /* check format */
1390    if ( font->version_major   != 1 ||
1391         font->header_size      < 4 ||
1392         font->absolute_offsize > 4 )
1393    {
1394      FT_TRACE2(( "[not a CFF font header!]\n" ));
1395      error = CFF_Err_Unknown_File_Format;
1396      goto Exit;
1397    }
1398
1399    /* skip the rest of the header */
1400    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1401      goto Exit;
1402
1403    /* read the name, top dict, string and global subrs index */
1404    if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1405                                       stream, 0 ) )              ||
1406         FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1407                                       stream, 0 ) )              ||
1408         FT_SET_ERROR( cff_index_init( &font->string_index,
1409                                       stream, 0 ) )              ||
1410         FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1411                                       stream, 1 ) )              )
1412      goto Exit;
1413
1414    /* well, we don't really forget the `disabled' fonts... */
1415    font->num_faces = font->name_index.count;
1416    if ( face_index >= (FT_Int)font->num_faces )
1417    {
1418      FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
1419                 face_index ));
1420      error = CFF_Err_Invalid_Argument;
1421    }
1422
1423    /* in case of a font format check, simply exit now */
1424    if ( face_index < 0 )
1425      goto Exit;
1426
1427    /* now, parse the top-level font dictionary */
1428    error = cff_subfont_load( &font->top_font,
1429                              &font->font_dict_index,
1430                              face_index,
1431                              stream,
1432                              base_offset );
1433    if ( error )
1434      goto Exit;
1435
1436    if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1437      goto Exit;
1438
1439    error = cff_index_init( &font->charstrings_index, stream, 0 );
1440    if ( error )
1441      goto Exit;
1442
1443    /* now, check for a CID font */
1444    if ( dict->cid_registry != 0xFFFFU )
1445    {
1446      CFF_IndexRec  fd_index;
1447      CFF_SubFont   sub;
1448      FT_UInt       idx;
1449
1450
1451      /* this is a CID-keyed font, we must now allocate a table of */
1452      /* sub-fonts, then load each of them separately              */
1453      if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1454        goto Exit;
1455
1456      error = cff_index_init( &fd_index, stream, 0 );
1457      if ( error )
1458        goto Exit;
1459
1460      if ( fd_index.count > CFF_MAX_CID_FONTS )
1461      {
1462        FT_ERROR(( "cff_font_load: FD array too large in CID font\n" ));
1463        goto Fail_CID;
1464      }
1465
1466      /* allocate & read each font dict independently */
1467      font->num_subfonts = fd_index.count;
1468      if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1469        goto Fail_CID;
1470
1471      /* set up pointer table */
1472      for ( idx = 0; idx < fd_index.count; idx++ )
1473        font->subfonts[idx] = sub + idx;
1474
1475      /* now load each subfont independently */
1476      for ( idx = 0; idx < fd_index.count; idx++ )
1477      {
1478        sub = font->subfonts[idx];
1479        error = cff_subfont_load( sub, &fd_index, idx,
1480                                  stream, base_offset );
1481        if ( error )
1482          goto Fail_CID;
1483      }
1484
1485      /* now load the FD Select array */
1486      error = CFF_Load_FD_Select( &font->fd_select,
1487                                  font->charstrings_index.count,
1488                                  stream,
1489                                  base_offset + dict->cid_fd_select_offset );
1490
1491    Fail_CID:
1492      cff_index_done( &fd_index );
1493
1494      if ( error )
1495        goto Exit;
1496    }
1497    else
1498      font->num_subfonts = 0;
1499
1500    /* read the charstrings index now */
1501    if ( dict->charstrings_offset == 0 )
1502    {
1503      FT_ERROR(( "cff_font_load: no charstrings offset!\n" ));
1504      error = CFF_Err_Unknown_File_Format;
1505      goto Exit;
1506    }
1507
1508    /* explicit the global subrs */
1509    font->num_global_subrs = font->global_subrs_index.count;
1510    font->num_glyphs       = font->charstrings_index.count;
1511
1512    error = cff_index_get_pointers( &font->global_subrs_index,
1513                                    &font->global_subrs ) ;
1514
1515    if ( error )
1516      goto Exit;
1517
1518    /* read the Charset and Encoding tables if available */
1519    if ( font->num_glyphs > 0 )
1520    {
1521      FT_Bool  invert = FT_BOOL( dict->cid_registry != 0xFFFFU );
1522
1523
1524      error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1525                                base_offset, dict->charset_offset, invert );
1526      if ( error )
1527        goto Exit;
1528
1529      /* CID-keyed CFFs don't have an encoding */
1530      if ( dict->cid_registry == 0xFFFFU )
1531      {
1532        error = cff_encoding_load( &font->encoding,
1533                                   &font->charset,
1534                                   font->num_glyphs,
1535                                   stream,
1536                                   base_offset,
1537                                   dict->encoding_offset );
1538        if ( error )
1539          goto Exit;
1540      }
1541      else
1542        /* CID-keyed fonts only need CIDs */
1543        FT_FREE( font->charset.sids );
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->global_subrs );
1597    FT_FREE( font->font_name );
1598  }
1599
1600
1601/* END */
Note: See TracBrowser for help on using the repository browser.