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