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