XFA: merge patch from CL 817753002
[pdfium.git] / core / src / fxge / fx_freetype / fxft2.5.01 / src / cff / cffload.c
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 "../../include/ft2build.h"
20 #include "../../include/freetype/internal/ftdebug.h"
21 #include "../../include/freetype/internal/ftobjs.h"
22 #include "../../include/freetype/internal/ftstream.h"
23 #include "../../include/freetype/tttags.h"
24 #include "../../include/freetype/t1tables.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 */