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