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