26#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
37#define FT_FIXED_ONE ( (FT_Fixed)0x10000 )
42 static const FT_UShort cff_isoadobe_charset[229] =
44 0, 1, 2, 3, 4, 5, 6, 7,
45 8, 9, 10, 11, 12, 13, 14, 15,
46 16, 17, 18, 19, 20, 21, 22, 23,
47 24, 25, 26, 27, 28, 29, 30, 31,
48 32, 33, 34, 35, 36, 37, 38, 39,
49 40, 41, 42, 43, 44, 45, 46, 47,
50 48, 49, 50, 51, 52, 53, 54, 55,
51 56, 57, 58, 59, 60, 61, 62, 63,
52 64, 65, 66, 67, 68, 69, 70, 71,
53 72, 73, 74, 75, 76, 77, 78, 79,
54 80, 81, 82, 83, 84, 85, 86, 87,
55 88, 89, 90, 91, 92, 93, 94, 95,
56 96, 97, 98, 99, 100, 101, 102, 103,
57 104, 105, 106, 107, 108, 109, 110, 111,
58 112, 113, 114, 115, 116, 117, 118, 119,
59 120, 121, 122, 123, 124, 125, 126, 127,
60 128, 129, 130, 131, 132, 133, 134, 135,
61 136, 137, 138, 139, 140, 141, 142, 143,
62 144, 145, 146, 147, 148, 149, 150, 151,
63 152, 153, 154, 155, 156, 157, 158, 159,
64 160, 161, 162, 163, 164, 165, 166, 167,
65 168, 169, 170, 171, 172, 173, 174, 175,
66 176, 177, 178, 179, 180, 181, 182, 183,
67 184, 185, 186, 187, 188, 189, 190, 191,
68 192, 193, 194, 195, 196, 197, 198, 199,
69 200, 201, 202, 203, 204, 205, 206, 207,
70 208, 209, 210, 211, 212, 213, 214, 215,
71 216, 217, 218, 219, 220, 221, 222, 223,
72 224, 225, 226, 227, 228
75 static const FT_UShort cff_expert_charset[166] =
77 0, 1, 229, 230, 231, 232, 233, 234,
78 235, 236, 237, 238, 13, 14, 15, 99,
79 239, 240, 241, 242, 243, 244, 245, 246,
80 247, 248, 27, 28, 249, 250, 251, 252,
81 253, 254, 255, 256, 257, 258, 259, 260,
82 261, 262, 263, 264, 265, 266, 109, 110,
83 267, 268, 269, 270, 271, 272, 273, 274,
84 275, 276, 277, 278, 279, 280, 281, 282,
85 283, 284, 285, 286, 287, 288, 289, 290,
86 291, 292, 293, 294, 295, 296, 297, 298,
87 299, 300, 301, 302, 303, 304, 305, 306,
88 307, 308, 309, 310, 311, 312, 313, 314,
89 315, 316, 317, 318, 158, 155, 163, 319,
90 320, 321, 322, 323, 324, 325, 326, 150,
91 164, 169, 327, 328, 329, 330, 331, 332,
92 333, 334, 335, 336, 337, 338, 339, 340,
93 341, 342, 343, 344, 345, 346, 347, 348,
94 349, 350, 351, 352, 353, 354, 355, 356,
95 357, 358, 359, 360, 361, 362, 363, 364,
96 365, 366, 367, 368, 369, 370, 371, 372,
97 373, 374, 375, 376, 377, 378
100 static const FT_UShort cff_expertsubset_charset[87] =
102 0, 1, 231, 232, 235, 236, 237, 238,
103 13, 14, 15, 99, 239, 240, 241, 242,
104 243, 244, 245, 246, 247, 248, 27, 28,
105 249, 250, 251, 253, 254, 255, 256, 257,
106 258, 259, 260, 261, 262, 263, 264, 265,
107 266, 109, 110, 267, 268, 269, 270, 272,
108 300, 301, 302, 305, 314, 315, 158, 155,
109 163, 320, 321, 322, 323, 324, 325, 326,
110 150, 164, 169, 327, 328, 329, 330, 331,
111 332, 333, 334, 335, 336, 337, 338, 339,
112 340, 341, 342, 343, 344, 345, 346
115 static const FT_UShort cff_standard_encoding[256] =
117 0, 0, 0, 0, 0, 0, 0, 0,
118 0, 0, 0, 0, 0, 0, 0, 0,
119 0, 0, 0, 0, 0, 0, 0, 0,
120 0, 0, 0, 0, 0, 0, 0, 0,
121 1, 2, 3, 4, 5, 6, 7, 8,
122 9, 10, 11, 12, 13, 14, 15, 16,
123 17, 18, 19, 20, 21, 22, 23, 24,
124 25, 26, 27, 28, 29, 30, 31, 32,
125 33, 34, 35, 36, 37, 38, 39, 40,
126 41, 42, 43, 44, 45, 46, 47, 48,
127 49, 50, 51, 52, 53, 54, 55, 56,
128 57, 58, 59, 60, 61, 62, 63, 64,
129 65, 66, 67, 68, 69, 70, 71, 72,
130 73, 74, 75, 76, 77, 78, 79, 80,
131 81, 82, 83, 84, 85, 86, 87, 88,
132 89, 90, 91, 92, 93, 94, 95, 0,
133 0, 0, 0, 0, 0, 0, 0, 0,
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 96, 97, 98, 99, 100, 101, 102,
138 103, 104, 105, 106, 107, 108, 109, 110,
139 0, 111, 112, 113, 114, 0, 115, 116,
140 117, 118, 119, 120, 121, 122, 0, 123,
141 0, 124, 125, 126, 127, 128, 129, 130,
142 131, 0, 132, 133, 0, 134, 135, 136,
143 137, 0, 0, 0, 0, 0, 0, 0,
144 0, 0, 0, 0, 0, 0, 0, 0,
145 0, 138, 0, 139, 0, 0, 0, 0,
146 140, 141, 142, 143, 0, 0, 0, 0,
147 0, 144, 0, 0, 0, 145, 0, 0,
148 146, 147, 148, 149, 0, 0, 0, 0
151 static const FT_UShort cff_expert_encoding[256] =
153 0, 0, 0, 0, 0, 0, 0, 0,
154 0, 0, 0, 0, 0, 0, 0, 0,
155 0, 0, 0, 0, 0, 0, 0, 0,
156 0, 0, 0, 0, 0, 0, 0, 0,
157 1, 229, 230, 0, 231, 232, 233, 234,
158 235, 236, 237, 238, 13, 14, 15, 99,
159 239, 240, 241, 242, 243, 244, 245, 246,
160 247, 248, 27, 28, 249, 250, 251, 252,
161 0, 253, 254, 255, 256, 257, 0, 0,
162 0, 258, 0, 0, 259, 260, 261, 262,
163 0, 0, 263, 264, 265, 0, 266, 109,
164 110, 267, 268, 269, 0, 270, 271, 272,
165 273, 274, 275, 276, 277, 278, 279, 280,
166 281, 282, 283, 284, 285, 286, 287, 288,
167 289, 290, 291, 292, 293, 294, 295, 296,
168 297, 298, 299, 300, 301, 302, 303, 0,
169 0, 0, 0, 0, 0, 0, 0, 0,
170 0, 0, 0, 0, 0, 0, 0, 0,
171 0, 0, 0, 0, 0, 0, 0, 0,
172 0, 0, 0, 0, 0, 0, 0, 0,
173 0, 304, 305, 306, 0, 0, 307, 308,
174 309, 310, 311, 0, 312, 0, 0, 312,
175 0, 0, 314, 315, 0, 0, 316, 317,
176 318, 0, 0, 0, 158, 155, 163, 319,
177 320, 321, 322, 323, 324, 325, 0, 0,
178 326, 150, 164, 169, 327, 328, 329, 330,
179 331, 332, 333, 334, 335, 336, 337, 338,
180 339, 340, 341, 342, 343, 344, 345, 346,
181 347, 348, 349, 350, 351, 352, 353, 354,
182 355, 356, 357, 358, 359, 360, 361, 362,
183 363, 364, 365, 366, 367, 368, 369, 370,
184 371, 372, 373, 374, 375, 376, 377, 378
190 FT_LOCAL_DEF( FT_UShort )
191 cff_get_standard_encoding( FT_UInt charcode )
193 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
205#define FT_COMPONENT cffload
210 cff_index_read_offset( CFF_Index idx,
214 FT_Stream stream = idx->stream;
219 if ( !FT_STREAM_READ( tmp, idx->off_size ) )
224 for ( nn = 0; nn < idx->off_size; nn++ )
225 result = ( result << 8 ) | tmp[nn];
234 cff_index_init( CFF_Index idx,
240 FT_Memory memory = stream->memory;
246 idx->stream = stream;
247 idx->start = FT_STREAM_POS();
251 if ( FT_READ_ULONG( count ) )
257 if ( FT_READ_USHORT( count ) )
270 if ( FT_READ_BYTE( offsize ) )
273 if ( offsize < 1 || offsize > 4 )
275 error = FT_THROW( Invalid_Table );
280 idx->off_size = offsize;
281 size = (FT_ULong)( count + 1 ) * offsize;
283 idx->data_offset = idx->start + idx->hdr_size + size;
285 if ( FT_STREAM_SKIP( size - offsize ) )
288 size = cff_index_read_offset( idx, &error );
294 error = FT_THROW( Invalid_Table );
298 idx->data_size = --size;
303 if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
309 if ( FT_STREAM_SKIP( size ) )
316 FT_FREE( idx->offsets );
323 cff_index_done( CFF_Index idx )
327 FT_Stream stream = idx->stream;
328 FT_Memory memory = stream->memory;
332 FT_FRAME_RELEASE( idx->bytes );
334 FT_FREE( idx->offsets );
341 cff_index_load_offsets( CFF_Index idx )
343 FT_Error error = FT_Err_Ok;
344 FT_Stream stream = idx->stream;
345 FT_Memory memory = stream->memory;
348 if ( idx->count > 0 && !idx->offsets )
350 FT_Byte offsize = idx->off_size;
357 data_size = (FT_ULong)( idx->count + 1 ) * offsize;
359 if ( FT_QNEW_ARRAY( idx->offsets, idx->count + 1 ) ||
360 FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
361 FT_FRAME_ENTER( data_size ) )
365 p = (FT_Byte*)stream->cursor;
366 p_end = p + data_size;
371 for ( ; p < p_end; p++, poff++ )
376 for ( ; p < p_end; p += 2, poff++ )
377 poff[0] = FT_PEEK_USHORT( p );
381 for ( ; p < p_end; p += 3, poff++ )
382 poff[0] = FT_PEEK_UOFF3( p );
386 for ( ; p < p_end; p += 4, poff++ )
387 poff[0] = FT_PEEK_ULONG( p );
395 FT_FREE( idx->offsets );
405 cff_index_get_pointers( CFF_Index idx,
408 FT_ULong* pool_size )
410 FT_Error error = FT_Err_Ok;
411 FT_Memory memory = idx->stream->memory;
413 FT_Byte** tbl = NULL;
414 FT_Byte* new_bytes = NULL;
422 error = cff_index_load_offsets( idx );
427 new_size = idx->data_size + idx->count;
429 if ( idx->count > 0 &&
430 !FT_QNEW_ARRAY( tbl, idx->count + 1 ) &&
431 ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
433 FT_ULong n, cur_offset;
435 FT_Byte* org_bytes = idx->bytes;
439 cur_offset = idx->offsets[0] - 1;
442 if ( cur_offset != 0 )
444 FT_TRACE0((
"cff_index_get_pointers:"
445 " invalid first offset value %lu set to zero\n",
451 tbl[0] = org_bytes + cur_offset;
453 tbl[0] = new_bytes + cur_offset;
455 for ( n = 1; n <= idx->count; n++ )
457 FT_ULong next_offset = idx->offsets[n] - 1;
461 if ( next_offset < cur_offset )
462 next_offset = cur_offset;
463 else if ( next_offset > idx->data_size )
464 next_offset = idx->data_size;
467 tbl[n] = org_bytes + next_offset;
470 tbl[n] = new_bytes + next_offset + extra;
472 if ( next_offset != cur_offset )
474 FT_MEM_COPY( tbl[n - 1],
475 org_bytes + cur_offset,
476 tbl[n] - tbl[n - 1] );
483 cur_offset = next_offset;
490 *pool_size = new_size;
494 if ( error && new_bytes )
495 FT_FREE( new_bytes );
503 FT_LOCAL_DEF( FT_Error )
504 cff_index_access_element( CFF_Index idx,
507 FT_ULong* pbyte_len )
509 FT_Error error = FT_Err_Ok;
512 if ( idx && idx->count > element )
515 FT_Stream stream = idx->stream;
516 FT_ULong off1, off2 = 0;
522 FT_ULong pos = element * idx->off_size;
525 if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
528 off1 = cff_index_read_offset( idx, &error );
537 off2 = cff_index_read_offset( idx, &error );
539 }
while ( off2 == 0 && element < idx->count );
544 off1 = idx->offsets[element];
550 off2 = idx->offsets[element];
552 }
while ( off2 == 0 && element < idx->count );
558 if ( off2 > stream->size + 1 ||
559 idx->data_offset > stream->size - off2 + 1 )
561 FT_ERROR((
"cff_index_access_element:"
562 " offset to next entry (%lu)"
563 " exceeds the end of stream (%lu)\n",
564 off2, stream->size - idx->data_offset + 1 ));
565 off2 = stream->size - idx->data_offset + 1;
569 if ( off1 && off2 > off1 )
571 *pbyte_len = off2 - off1;
576 *pbytes = idx->bytes + off1 - 1;
581 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
582 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
594 error = FT_THROW( Invalid_Argument );
602 cff_index_forget_element( CFF_Index idx,
605 if ( idx->bytes == 0 )
607 FT_Stream stream = idx->stream;
610 FT_FRAME_RELEASE( *pbytes );
616 FT_LOCAL_DEF( FT_String* )
617 cff_index_get_name( CFF_Font font,
620 CFF_Index idx = &font->name_index;
625 FT_String* name = NULL;
631 memory = idx->stream->memory;
633 error = cff_index_access_element( idx, element, &bytes, &byte_len );
637 if ( !FT_QALLOC( name, byte_len + 1 ) )
639 FT_MEM_COPY( name, bytes, byte_len );
642 cff_index_forget_element( idx, &bytes );
650 FT_LOCAL_DEF( FT_String* )
651 cff_index_get_string( CFF_Font font,
654 return ( element < font->num_strings )
655 ? (FT_String*)font->strings[element]
660 FT_LOCAL_DEF( FT_String* )
661 cff_index_get_sid_string( CFF_Font font,
665 if ( sid == 0xFFFFU )
670 return cff_index_get_string( font, sid - 391 );
673 if ( !font->psnames )
677 return (FT_String *)font->psnames->adobe_std_strings( sid );
691 CFF_Done_FD_Select( CFF_FDSelect fdselect,
694 if ( fdselect->data )
695 FT_FRAME_RELEASE( fdselect->data );
697 fdselect->data_size = 0;
698 fdselect->format = 0;
699 fdselect->range_count = 0;
704 CFF_Load_FD_Select( CFF_FDSelect fdselect,
715 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
718 fdselect->format = format;
719 fdselect->cache_count = 0;
724 fdselect->data_size = num_glyphs;
728 if ( FT_READ_USHORT( num_ranges ) )
733 FT_TRACE0((
"CFF_Load_FD_Select: empty FDSelect array\n" ));
734 error = FT_THROW( Invalid_File_Format );
738 fdselect->data_size = num_ranges * 3 + 2;
741 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
746 error = FT_THROW( Invalid_File_Format );
754 FT_LOCAL_DEF( FT_Byte )
755 cff_fd_select_get( CFF_FDSelect fdselect,
756 FT_UInt glyph_index )
763 if ( !fdselect->data )
766 switch ( fdselect->format )
769 fd = fdselect->data[glyph_index];
774 if ( glyph_index - fdselect->cache_first < fdselect->cache_count )
776 fd = fdselect->cache_fd;
782 FT_Byte* p = fdselect->data;
783 FT_Byte* p_limit = p + fdselect->data_size;
785 FT_UInt first, limit;
788 first = FT_NEXT_USHORT( p );
791 if ( glyph_index < first )
795 limit = FT_NEXT_USHORT( p );
797 if ( glyph_index < limit )
802 fdselect->cache_first = first;
803 fdselect->cache_count = limit - first;
804 fdselect->cache_fd = fd2;
809 }
while ( p < p_limit );
831 cff_charset_compute_cids( CFF_Charset charset,
835 FT_Error error = FT_Err_Ok;
837 FT_UShort max_cid = 0;
840 if ( charset->max_cid > 0 )
843 for ( i = 0; i < num_glyphs; i++ )
845 if ( charset->sids[i] > max_cid )
846 max_cid = charset->sids[i];
849 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
856 for ( i = num_glyphs - 1; i < num_glyphs; i-- )
857 charset->cids[charset->sids[i]] = (FT_UShort)i;
859 charset->max_cid = max_cid;
860 charset->num_glyphs = num_glyphs;
867 FT_LOCAL_DEF( FT_UInt )
868 cff_charset_cid_to_gindex( CFF_Charset charset,
874 if ( cid <= charset->max_cid )
875 result = charset->cids[cid];
882 cff_charset_free_cids( CFF_Charset charset,
885 FT_FREE( charset->cids );
886 charset->max_cid = 0;
891 cff_charset_done( CFF_Charset charset,
894 FT_Memory memory = stream->memory;
897 cff_charset_free_cids( charset, memory );
899 FT_FREE( charset->sids );
906 cff_charset_load( CFF_Charset charset,
909 FT_ULong base_offset,
913 FT_Memory memory = stream->memory;
914 FT_Error error = FT_Err_Ok;
925 charset->offset = base_offset + offset;
928 if ( FT_STREAM_SEEK( charset->offset ) ||
929 FT_READ_BYTE( charset->format ) )
933 if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
937 charset->sids[0] = 0;
939 switch ( charset->format )
942 if ( num_glyphs > 0 )
944 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
947 for ( j = 1; j < num_glyphs; j++ )
948 charset->sids[j] = FT_GET_USHORT();
963 while ( j < num_glyphs )
966 if ( FT_READ_USHORT( glyph_sid ) )
970 if ( charset->format == 2 )
972 if ( FT_READ_USHORT( nleft ) )
977 if ( FT_READ_BYTE( nleft ) )
982 if ( glyph_sid > 0xFFFFL - nleft )
984 FT_ERROR((
"cff_charset_load: invalid SID range trimmed"
985 " nleft=%u -> %ld\n", nleft, 0xFFFFL - glyph_sid ));
986 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
990 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
991 charset->sids[j] = glyph_sid;
997 FT_ERROR((
"cff_charset_load: invalid table format\n" ));
998 error = FT_THROW( Invalid_File_Format );
1012 charset->offset = offset;
1014 switch ( (FT_UInt)offset )
1017 if ( num_glyphs > 229 )
1019 FT_ERROR((
"cff_charset_load: implicit charset larger than\n" ));
1020 FT_ERROR((
"predefined charset (Adobe ISO-Latin)\n" ));
1021 error = FT_THROW( Invalid_File_Format );
1026 if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1030 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
1035 if ( num_glyphs > 166 )
1037 FT_ERROR((
"cff_charset_load: implicit charset larger than\n" ));
1038 FT_ERROR((
"predefined charset (Adobe Expert)\n" ));
1039 error = FT_THROW( Invalid_File_Format );
1044 if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1048 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
1053 if ( num_glyphs > 87 )
1055 FT_ERROR((
"cff_charset_load: implicit charset larger than\n" ));
1056 FT_ERROR((
"predefined charset (Adobe Expert Subset)\n" ));
1057 error = FT_THROW( Invalid_File_Format );
1062 if ( FT_QNEW_ARRAY( charset->sids, num_glyphs ) )
1066 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1071 error = FT_THROW( Invalid_File_Format );
1078 error = cff_charset_compute_cids( charset, num_glyphs, memory );
1084 FT_FREE( charset->sids );
1085 FT_FREE( charset->cids );
1086 charset->format = 0;
1087 charset->offset = 0;
1095 cff_vstore_done( CFF_VStoreRec* vstore,
1102 if ( vstore->varRegionList )
1104 for ( i = 0; i < vstore->regionCount; i++ )
1105 FT_FREE( vstore->varRegionList[i].axisList );
1107 FT_FREE( vstore->varRegionList );
1110 if ( vstore->varData )
1112 for ( i = 0; i < vstore->dataCount; i++ )
1113 FT_FREE( vstore->varData[i].regionIndices );
1115 FT_FREE( vstore->varData );
1120 #define FT_fdot14ToFixed( x ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
1124 cff_vstore_load( CFF_VStoreRec* vstore,
1126 FT_ULong base_offset,
1129 FT_Memory memory = stream->memory;
1130 FT_Error error = FT_ERR( Invalid_File_Format );
1132 FT_ULong* dataOffsetArray = NULL;
1142 FT_UInt regionCount;
1143 FT_ULong regionListOffset;
1148 if ( FT_STREAM_SEEK( base_offset + offset ) ||
1149 FT_STREAM_SKIP( 2 ) )
1153 vsOffset = FT_STREAM_POS();
1156 if ( FT_READ_USHORT( format ) )
1160 error = FT_THROW( Invalid_File_Format );
1165 if ( FT_READ_ULONG( regionListOffset ) ||
1166 FT_READ_USHORT( dataCount ) )
1171 if ( FT_QNEW_ARRAY( dataOffsetArray, dataCount ) )
1174 for ( i = 0; i < dataCount; i++ )
1176 if ( FT_READ_ULONG( dataOffsetArray[i] ) )
1181 if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
1182 FT_READ_USHORT( vstore->axisCount ) ||
1183 FT_READ_USHORT( regionCount ) )
1186 vstore->regionCount = 0;
1187 if ( FT_QNEW_ARRAY( vstore->varRegionList, regionCount ) )
1190 for ( i = 0; i < regionCount; i++ )
1192 CFF_VarRegion* region = &vstore->varRegionList[i];
1195 if ( FT_QNEW_ARRAY( region->axisList, vstore->axisCount ) )
1199 vstore->regionCount++;
1201 for ( j = 0; j < vstore->axisCount; j++ )
1203 CFF_AxisCoords* axis = ®ion->axisList[j];
1205 FT_Int start, peak, end;
1208 if ( FT_READ_SHORT( start ) ||
1209 FT_READ_SHORT( peak ) ||
1210 FT_READ_SHORT( end ) )
1214 if ( ( start < 0 && end > 0 ) || start > peak || peak > end )
1217 axis->startCoord = FT_fdot14ToFixed( start );
1218 axis->peakCoord = FT_fdot14ToFixed( peak );
1219 axis->endCoord = FT_fdot14ToFixed( end );
1224 vstore->dataCount = 0;
1225 if ( FT_QNEW_ARRAY( vstore->varData, dataCount ) )
1228 for ( i = 0; i < dataCount; i++ )
1230 CFF_VarData* data = &vstore->varData[i];
1233 if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
1238 if ( FT_STREAM_SKIP( 4 ) )
1244 if ( FT_READ_USHORT( data->regionIdxCount ) )
1247 if ( FT_QNEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
1251 vstore->dataCount++;
1253 for ( j = 0; j < data->regionIdxCount; j++ )
1255 if ( FT_READ_USHORT( data->regionIndices[j] ) )
1264 FT_FREE( dataOffsetArray );
1266 cff_vstore_done( vstore, memory );
1278 FT_LOCAL_DEF(
void )
1279 cff_blend_clear( CFF_SubFont subFont )
1281 subFont->blend_top = subFont->blend_stack;
1282 subFont->blend_used = 0;
1296 FT_LOCAL_DEF( FT_Error )
1297 cff_blend_doBlend( CFF_SubFont subFont,
1306 CFF_Blend blend = &subFont->blend;
1308 FT_Memory memory = subFont->blend.font->memory;
1309 FT_Error error = FT_Err_Ok;
1312 FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV );
1313 FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack );
1316 if ( numOperands > count )
1318 FT_TRACE4((
" cff_blend_doBlend: Stack underflow %u argument%s\n",
1320 count == 1 ?
"" :
"s" ));
1322 error = FT_THROW( Stack_Underflow );
1327 size = 5 * numBlends;
1328 if ( subFont->blend_used + size > subFont->blend_alloc )
1330 FT_Byte* blend_stack_old = subFont->blend_stack;
1331 FT_Byte* blend_top_old = subFont->blend_top;
1336 if ( FT_QREALLOC( subFont->blend_stack,
1337 subFont->blend_alloc,
1338 subFont->blend_alloc + size ) )
1341 subFont->blend_top = subFont->blend_stack + subFont->blend_used;
1342 subFont->blend_alloc += size;
1346 if ( blend_stack_old &&
1347 subFont->blend_stack != blend_stack_old )
1349 FT_PtrDist offset = subFont->blend_stack - blend_stack_old;
1353 for ( p = parser->stack; p < parser->top; p++ )
1355 if ( *p >= blend_stack_old && *p < blend_top_old )
1360 subFont->blend_used += size;
1362 base = count - numOperands;
1363 delta = base + numBlends;
1365 for ( i = 0; i < numBlends; i++ )
1367 const FT_Int32* weight = &blend->BV[1];
1372 sum = cff_parse_fixed( parser, &parser->stack[i + base] );
1374 for ( j = 1; j < blend->lenBV; j++ )
1375 sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ),
1379 parser->stack[i + base] = subFont->blend_top;
1385 *subFont->blend_top++ = 255;
1386 *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 24 );
1387 *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 16 );
1388 *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum >> 8 );
1389 *subFont->blend_top++ = (FT_Byte)( (FT_UInt32)sum );
1393 parser->top = &parser->stack[base + numBlends];
1404 FT_LOCAL_DEF( FT_Error )
1405 cff_blend_build_vector( CFF_Blend blend,
1410 FT_Error error = FT_Err_Ok;
1411 FT_Memory memory = blend->font->memory;
1415 CFF_VarData* varData;
1420 if ( !( lenNDV == 0 || NDV ) )
1422 FT_TRACE4((
" cff_blend_build_vector:"
1423 " Malformed Normalize Design Vector data\n" ));
1424 error = FT_THROW( Invalid_File_Format );
1428 blend->builtBV = FALSE;
1430 vs = &blend->font->vstore;
1433 if ( lenNDV != 0 && lenNDV != vs->axisCount )
1435 FT_TRACE4((
" cff_blend_build_vector: Axis count mismatch\n" ));
1436 error = FT_THROW( Invalid_File_Format );
1440 if ( vsindex >= vs->dataCount )
1442 FT_TRACE4((
" cff_blend_build_vector: vsindex out of range\n" ));
1443 error = FT_THROW( Invalid_File_Format );
1448 varData = &vs->varData[vsindex];
1451 len = varData->regionIdxCount + 1;
1452 if ( FT_QRENEW_ARRAY( blend->BV, blend->lenBV, len ) )
1458 for ( master = 0; master < len; master++ )
1462 CFF_VarRegion* varRegion;
1468 blend->BV[master] = FT_FIXED_ONE;
1469 FT_TRACE4((
" build blend vector len %u\n", len ));
1470 FT_TRACE4((
" [ %f ", blend->BV[master] / 65536.0 ));
1475 idx = varData->regionIndices[master - 1];
1476 varRegion = &vs->varRegionList[idx];
1478 if ( idx >= vs->regionCount )
1480 FT_TRACE4((
" cff_blend_build_vector:"
1481 " region index out of range\n" ));
1482 error = FT_THROW( Invalid_File_Format );
1490 blend->BV[master] = 0;
1496 blend->BV[master] = FT_FIXED_ONE;
1499 for ( j = 0; j < lenNDV; j++ )
1501 CFF_AxisCoords* axis = &varRegion->axisList[j];
1506 if ( axis->peakCoord == NDV[j] ||
1507 axis->peakCoord == 0 )
1511 else if ( NDV[j] <= axis->startCoord ||
1512 NDV[j] >= axis->endCoord )
1514 blend->BV[master] = 0;
1519 else if ( NDV[j] < axis->peakCoord )
1520 blend->BV[master] = FT_MulDiv( blend->BV[master],
1521 NDV[j] - axis->startCoord,
1522 axis->peakCoord - axis->startCoord );
1524 blend->BV[master] = FT_MulDiv( blend->BV[master],
1525 axis->endCoord - NDV[j],
1526 axis->endCoord - axis->peakCoord );
1529 FT_TRACE4((
", %f ",
1530 blend->BV[master] / 65536.0 ));
1533 FT_TRACE4((
"]\n" ));
1536 blend->lastVsindex = vsindex;
1541 if ( FT_QRENEW_ARRAY( blend->lastNDV, blend->lenNDV, lenNDV ) )
1544 FT_MEM_COPY( blend->lastNDV,
1546 lenNDV * sizeof ( *NDV ) );
1549 blend->lenNDV = lenNDV;
1550 blend->builtBV = TRUE;
1559 FT_LOCAL_DEF( FT_Bool )
1560 cff_blend_check_vector( CFF_Blend blend,
1565 if ( !blend->builtBV ||
1566 blend->lastVsindex != vsindex ||
1567 blend->lenNDV != lenNDV ||
1571 lenNDV * sizeof ( *NDV ) ) != 0 ) )
1581#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1583 FT_LOCAL_DEF( FT_Error )
1584 cff_get_var_blend( FT_Face face,
1585 FT_UInt *num_coords,
1587 FT_Fixed* *normalizedcoords,
1588 FT_MM_Var* *mm_var )
1590 CFF_Face cffface = (CFF_Face)face;
1591 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm;
1594 return mm->get_var_blend( face,
1602 FT_LOCAL_DEF(
void )
1603 cff_done_blend( FT_Face face )
1605 CFF_Face cffface = (CFF_Face)face;
1606 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)cffface->mm;
1610 mm->done_blend( face );
1617 cff_encoding_done( CFF_Encoding encoding )
1619 encoding->format = 0;
1620 encoding->offset = 0;
1621 encoding->count = 0;
1626 cff_encoding_load( CFF_Encoding encoding,
1627 CFF_Charset charset,
1630 FT_ULong base_offset,
1633 FT_Error error = FT_Err_Ok;
1636 FT_UShort glyph_sid;
1641 if ( !charset->sids )
1643 error = FT_THROW( Invalid_File_Format );
1662 FT_ARRAY_ZERO( encoding->sids, 256 );
1663 FT_ARRAY_ZERO( encoding->codes, 256 );
1665 encoding->offset = base_offset + offset;
1668 if ( FT_STREAM_SEEK( encoding->offset ) ||
1669 FT_READ_BYTE( encoding->format ) ||
1670 FT_READ_BYTE( count ) )
1673 switch ( encoding->format & 0x7F )
1684 encoding->count = count + 1;
1686 if ( FT_FRAME_ENTER( count ) )
1689 p = (FT_Byte*)stream->cursor;
1691 for ( j = 1; j <= count; j++ )
1696 if ( j < num_glyphs )
1699 encoding->codes[glyph_code] = (FT_UShort)j;
1702 encoding->sids[glyph_code] = charset->sids[j];
1717 encoding->count = 0;
1720 for ( j = 0; j < count; j++, i += nleft )
1723 if ( FT_READ_BYTE( glyph_code ) )
1727 if ( FT_READ_BYTE( nleft ) )
1734 if ( (FT_UInt)nleft > encoding->count )
1735 encoding->count = nleft;
1738 for ( k = i; k < nleft + i; k++, glyph_code++ )
1741 if ( k < num_glyphs && glyph_code < 256 )
1744 encoding->codes[glyph_code] = (FT_UShort)k;
1747 encoding->sids[glyph_code] = charset->sids[k];
1753 if ( encoding->count > 256 )
1754 encoding->count = 256;
1759 FT_ERROR((
"cff_encoding_load: invalid table format\n" ));
1760 error = FT_THROW( Invalid_File_Format );
1765 if ( encoding->format & 0x80 )
1771 if ( FT_READ_BYTE( count ) )
1774 for ( j = 0; j < count; j++ )
1777 if ( FT_READ_BYTE( glyph_code ) )
1781 if ( FT_READ_USHORT( glyph_sid ) )
1785 encoding->sids[glyph_code] = glyph_sid;
1789 for ( gindex = 0; gindex < num_glyphs; gindex++ )
1791 if ( charset->sids[gindex] == glyph_sid )
1793 encoding->codes[glyph_code] = (FT_UShort)gindex;
1807 switch ( (FT_UInt)offset )
1811 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1816 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1822 encoding->offset = offset;
1823 encoding->count = 0;
1825 error = cff_charset_compute_cids( charset, num_glyphs,
1830 for ( j = 0; j < 256; j++ )
1832 FT_UInt sid = encoding->sids[j];
1837 gid = cff_charset_cid_to_gindex( charset, sid );
1841 encoding->codes[j] = (FT_UShort)gid;
1842 encoding->count = j + 1;
1846 encoding->codes[j] = 0;
1847 encoding->sids [j] = 0;
1853 FT_ERROR((
"cff_encoding_load: invalid table format\n" ));
1854 error = FT_THROW( Invalid_File_Format );
1870 FT_LOCAL_DEF( FT_Error )
1871 cff_load_private_dict( CFF_Font font,
1872 CFF_SubFont subfont,
1876 FT_Error error = FT_Err_Ok;
1877 CFF_ParserRec parser;
1878 CFF_FontRecDict top = &subfont->font_dict;
1879 CFF_Private priv = &subfont->private_dict;
1880 FT_Stream stream = font->stream;
1886 subfont->blend.font = font;
1887 subfont->blend.usedBV = FALSE;
1889 if ( !top->private_offset || !top->private_size )
1895 priv->blue_shift = 7;
1896 priv->blue_fuzz = 1;
1898 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1899 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1902 priv->subfont = subfont;
1903 subfont->lenNDV = lenNDV;
1907 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
1908 : CFF_MAX_STACK_DEPTH + 1;
1910 if ( cff_parser_init( &parser,
1911 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
1919 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
1920 FT_FRAME_ENTER( top->private_size ) )
1923 FT_TRACE4((
" private dictionary:\n" ));
1924 error = cff_parser_run( &parser,
1925 (FT_Byte*)stream->cursor,
1926 (FT_Byte*)stream->limit );
1933 priv->num_blue_values &= ~1;
1937 if ( priv->initial_random_seed < 0 )
1938 priv->initial_random_seed = -priv->initial_random_seed;
1939 else if ( priv->initial_random_seed == 0 )
1940 priv->initial_random_seed = 987654321;
1944 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
1946 FT_TRACE2((
"cff_load_private_dict:"
1947 " setting unlikely BlueShift value %ld to default (7)\n",
1948 priv->blue_shift ));
1949 priv->blue_shift = 7;
1952 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
1954 FT_TRACE2((
"cff_load_private_dict:"
1955 " setting unlikely BlueFuzz value %ld to default (1)\n",
1957 priv->blue_fuzz = 1;
1962 cff_blend_clear( subfont );
1963 cff_parser_done( &parser );
1978 cff_subfont_load( CFF_SubFont subfont,
1982 FT_ULong base_offset,
1988 CFF_ParserRec parser;
1989 FT_Byte* dict = NULL;
1991 CFF_FontRecDict top = &subfont->font_dict;
1992 CFF_Private priv = &subfont->private_dict;
1994 PSAux_Service psaux = (PSAux_Service)face->psaux;
1996 FT_Bool cff2 = FT_BOOL(
code == CFF2_CODE_TOPDICT ||
1997 code == CFF2_CODE_FONTDICT );
1998 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK
1999 : CFF_MAX_STACK_DEPTH;
2004 error = cff_parser_init( &parser,
2017 top->underline_position = -( 100L << 16 );
2018 top->underline_thickness = 50L << 16;
2019 top->charstring_type = 2;
2020 top->font_matrix.xx = 0x10000L;
2021 top->font_matrix.yy = 0x10000L;
2022 top->cid_count = 8720;
2026 top->version = 0xFFFFU;
2027 top->notice = 0xFFFFU;
2028 top->copyright = 0xFFFFU;
2029 top->full_name = 0xFFFFU;
2030 top->family_name = 0xFFFFU;
2031 top->weight = 0xFFFFU;
2032 top->embedded_postscript = 0xFFFFU;
2034 top->cid_registry = 0xFFFFU;
2035 top->cid_ordering = 0xFFFFU;
2036 top->cid_font_name = 0xFFFFU;
2039 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48;
2042 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2049 if ( FT_STREAM_SEEK( idx->data_offset ) ||
2050 FT_FRAME_EXTRACT( idx->data_size, dict ) )
2053 dict_len = idx->data_size;
2058 FT_TRACE4((
" top dictionary:\n" ));
2059 error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
2064 cff_index_forget_element( idx, &dict );
2066 FT_FRAME_RELEASE( dict );
2072 if ( top->cid_registry != 0xFFFFU )
2080 error = cff_load_private_dict( font, subfont, 0, 0 );
2099 if ( face->root.internal->random_seed == -1 )
2101 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
2104 subfont->random = (FT_UInt32)driver->random_seed;
2105 if ( driver->random_seed )
2109 driver->random_seed =
2110 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2112 }
while ( driver->random_seed < 0 );
2117 subfont->random = (FT_UInt32)face->root.internal->random_seed;
2118 if ( face->root.internal->random_seed )
2122 face->root.internal->random_seed =
2123 (FT_Int32)psaux->cff_random(
2124 (FT_UInt32)face->root.internal->random_seed );
2126 }
while ( face->root.internal->random_seed < 0 );
2130 if ( !subfont->random )
2131 subfont->random = (FT_UInt32)priv->initial_random_seed;
2135 if ( priv->local_subrs_offset )
2137 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2138 priv->local_subrs_offset ) )
2141 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2145 error = cff_index_get_pointers( &subfont->local_subrs_index,
2146 &subfont->local_subrs, NULL, NULL );
2152 cff_parser_done( &parser );
2159 cff_subfont_done( FT_Memory memory,
2160 CFF_SubFont subfont )
2164 cff_index_done( &subfont->local_subrs_index );
2165 FT_FREE( subfont->local_subrs );
2167 FT_FREE( subfont->blend.lastNDV );
2168 FT_FREE( subfont->blend.BV );
2169 FT_FREE( subfont->blend_stack );
2174 FT_LOCAL_DEF( FT_Error )
2175 cff_font_load( FT_Library library,
2183 static const FT_Frame_Field cff_header_fields[] =
2186#define FT_STRUCTURE CFF_FontRec
2188 FT_FRAME_START( 3 ),
2189 FT_FRAME_BYTE( version_major ),
2190 FT_FRAME_BYTE( version_minor ),
2191 FT_FRAME_BYTE( header_size ),
2196 FT_Memory memory = stream->memory;
2197 FT_ULong base_offset;
2198 CFF_FontRecDict dict;
2199 CFF_IndexRec string_index;
2200 FT_UInt subfont_index;
2204 FT_ZERO( &string_index );
2206 dict = &font->top_font.font_dict;
2207 base_offset = FT_STREAM_POS();
2209 font->library = library;
2210 font->stream = stream;
2211 font->memory = memory;
2213 font->base_offset = base_offset;
2216 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2221 if ( font->version_major != 2 ||
2222 font->header_size < 5 )
2224 FT_TRACE2((
" not a CFF2 font header\n" ));
2225 error = FT_THROW( Unknown_File_Format );
2229 if ( FT_READ_USHORT( font->top_dict_length ) )
2234 FT_Byte absolute_offset;
2237 if ( FT_READ_BYTE( absolute_offset ) )
2240 if ( font->version_major != 1 ||
2241 font->header_size < 4 ||
2242 absolute_offset > 4 )
2244 FT_TRACE2((
" not a CFF font header\n" ));
2245 error = FT_THROW( Unknown_File_Format );
2251 if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2258 FT_TRACE2((
" not a CFF file\n" ));
2259 error = FT_THROW( Unknown_File_Format );
2272 FT_ZERO( &font->font_dict_index );
2274 font->font_dict_index.data_offset = FT_STREAM_POS();
2275 font->font_dict_index.data_size = font->top_dict_length;
2278 if ( FT_STREAM_SKIP( font->top_dict_length ) )
2282 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2283 stream, 1, cff2 ) ) )
2289 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2290 stream, 0, cff2 ) ) )
2294 FT_TRACE2((
" not a CFF file\n" ));
2295 error = FT_THROW( Unknown_File_Format );
2302 if ( font->name_index.count > 1 &&
2303 font->name_index.data_size < font->name_index.count )
2307 error = pure_cff ? FT_THROW( Unknown_File_Format )
2308 : FT_THROW( Invalid_File_Format );
2312 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2313 stream, 0, cff2 ) ) ||
2314 FT_SET_ERROR( cff_index_init( &string_index,
2315 stream, 1, cff2 ) ) ||
2316 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2317 stream, 1, cff2 ) ) ||
2318 FT_SET_ERROR( cff_index_get_pointers( &string_index,
2321 &font->string_pool_size ) ) )
2325 if ( font->name_index.count > font->font_dict_index.count )
2327 FT_ERROR((
"cff_font_load:"
2328 " not enough entries in Top DICT index\n" ));
2329 error = FT_THROW( Invalid_File_Format );
2334 font->num_strings = string_index.count;
2339 subfont_index = (FT_UInt)( face_index & 0xFFFF );
2341 if ( face_index > 0 && subfont_index >= font->name_index.count )
2343 FT_ERROR((
"cff_font_load:"
2344 " invalid subfont index for pure CFF font (%u)\n",
2346 error = FT_THROW( Invalid_Argument );
2350 font->num_faces = font->name_index.count;
2356 if ( font->name_index.count > 1 )
2358 FT_ERROR((
"cff_font_load:"
2359 " invalid CFF font with multiple subfonts\n" ));
2361 " in SFNT wrapper\n" ));
2362 error = FT_THROW( Invalid_File_Format );
2368 if ( face_index < 0 )
2372 FT_TRACE4((
"parsing top-level\n" ));
2373 error = cff_subfont_load( &font->top_font,
2374 &font->font_dict_index,
2378 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
2384 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2387 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2392 if ( dict->cid_registry != 0xFFFFU ||
2395 CFF_IndexRec fd_index;
2396 CFF_SubFont sub = NULL;
2402 error = cff_vstore_load( &font->vstore,
2405 dict->vstore_offset );
2411 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2414 error = cff_index_init( &fd_index, stream, 0, cff2 );
2420 if ( fd_index.count > CFF_MAX_CID_FONTS )
2422 FT_TRACE0((
"cff_font_load: FD array too large in CID font\n" ));
2427 font->num_subfonts = fd_index.count;
2428 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2432 for ( idx = 0; idx < fd_index.count; idx++ )
2433 font->subfonts[idx] = sub + idx;
2436 for ( idx = 0; idx < fd_index.count; idx++ )
2438 sub = font->subfonts[idx];
2439 FT_TRACE4((
"parsing subfont %u\n", idx ));
2440 error = cff_subfont_load( sub,
2445 cff2 ? CFF2_CODE_FONTDICT
2455 if ( !cff2 || fd_index.count > 1 )
2456 error = CFF_Load_FD_Select( &font->fd_select,
2457 font->charstrings_index.count,
2459 base_offset + dict->cid_fd_select_offset );
2462 cff_index_done( &fd_index );
2468 font->num_subfonts = 0;
2471 if ( dict->charstrings_offset == 0 )
2473 FT_ERROR((
"cff_font_load: no charstrings offset\n" ));
2474 error = FT_THROW( Invalid_File_Format );
2478 font->num_glyphs = font->charstrings_index.count;
2480 error = cff_index_get_pointers( &font->global_subrs_index,
2481 &font->global_subrs, NULL, NULL );
2487 if ( !cff2 && font->num_glyphs > 0 )
2489 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2492 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2493 base_offset, dict->charset_offset, invert );
2498 if ( dict->cid_registry == 0xFFFFU )
2500 error = cff_encoding_load( &font->encoding,
2505 dict->encoding_offset );
2513 font->font_name = cff_index_get_name( font, subfont_index );
2516 cff_index_done( &string_index );
2522 FT_LOCAL_DEF(
void )
2523 cff_font_done( CFF_Font font )
2525 FT_Memory memory = font->memory;
2529 cff_index_done( &font->global_subrs_index );
2530 cff_index_done( &font->font_dict_index );
2531 cff_index_done( &font->name_index );
2532 cff_index_done( &font->charstrings_index );
2536 if ( font->num_subfonts > 0 )
2538 for ( idx = 0; idx < font->num_subfonts; idx++ )
2539 cff_subfont_done( memory, font->subfonts[idx] );
2542 FT_FREE( font->subfonts[0] );
2545 cff_encoding_done( &font->encoding );
2546 cff_charset_done( &font->charset, font->stream );
2547 cff_vstore_done( &font->vstore, memory );
2549 cff_subfont_done( memory, &font->top_font );
2551 CFF_Done_FD_Select( &font->fd_select, font->stream );
2553 FT_FREE( font->font_info );
2555 FT_FREE( font->font_name );
2556 FT_FREE( font->global_subrs );
2557 FT_FREE( font->strings );
2558 FT_FREE( font->string_pool );
2560 if ( font->cf2_instance.finalizer )
2562 font->cf2_instance.finalizer( font->cf2_instance.data );
2563 FT_FREE( font->cf2_instance.data );
2566 FT_FREE( font->font_extra );