ReactOS 0.4.16-dev-2332-g4cba65d
cffload.c
Go to the documentation of this file.
1/****************************************************************************
2 *
3 * cffload.c
4 *
5 * OpenType and CFF data/program tables loader (body).
6 *
7 * Copyright (C) 1996-2020 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
22#include <freetype/tttags.h>
23#include <freetype/t1tables.h>
25
26#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
27#include <freetype/ftmm.h>
29#endif
30
31#include "cffload.h"
32#include "cffparse.h"
33
34#include "cfferrs.h"
35
36
37#define FT_FIXED_ONE ( (FT_Fixed)0x10000 )
38
39
40#if 1
41
42 static const FT_UShort cff_isoadobe_charset[229] =
43 {
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
73 };
74
75 static const FT_UShort cff_expert_charset[166] =
76 {
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
98 };
99
101 {
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
113 };
114
116 {
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
149 };
150
151 static const FT_UShort cff_expert_encoding[256] =
152 {
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
185 };
186
187#endif /* 1 */
188
189
192 {
193 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
194 : 0 );
195 }
196
197
198 /**************************************************************************
199 *
200 * The macro FT_COMPONENT is used in trace mode. It is an implicit
201 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
202 * messages during execution.
203 */
204#undef FT_COMPONENT
205#define FT_COMPONENT cffload
206
207
208 /* read an offset from the index's stream current position */
209 static FT_ULong
211 FT_Error *errorp )
212 {
214 FT_Stream stream = idx->stream;
215 FT_Byte tmp[4];
216 FT_ULong result = 0;
217
218
219 if ( !FT_STREAM_READ( tmp, idx->off_size ) )
220 {
221 FT_Int nn;
222
223
224 for ( nn = 0; nn < idx->off_size; nn++ )
225 result = ( result << 8 ) | tmp[nn];
226 }
227
228 *errorp = error;
229 return result;
230 }
231
232
233 static FT_Error
237 FT_Bool cff2 )
238 {
240 FT_Memory memory = stream->memory;
242
243
244 FT_ZERO( idx );
245
246 idx->stream = stream;
247 idx->start = FT_STREAM_POS();
248
249 if ( cff2 )
250 {
251 if ( FT_READ_ULONG( count ) )
252 goto Exit;
253 idx->hdr_size = 5;
254 }
255 else
256 {
257 if ( FT_READ_USHORT( count ) )
258 goto Exit;
259 idx->hdr_size = 3;
260 }
261
262 if ( count > 0 )
263 {
264 FT_Byte offsize;
266
267
268 /* there is at least one element; read the offset size, */
269 /* then access the offset table to compute the index's total size */
270 if ( FT_READ_BYTE( offsize ) )
271 goto Exit;
272
273 if ( offsize < 1 || offsize > 4 )
274 {
275 error = FT_THROW( Invalid_Table );
276 goto Exit;
277 }
278
279 idx->count = count;
280 idx->off_size = offsize;
281 size = (FT_ULong)( count + 1 ) * offsize;
282
283 idx->data_offset = idx->start + idx->hdr_size + size;
284
285 if ( FT_STREAM_SKIP( size - offsize ) )
286 goto Exit;
287
289 if ( error )
290 goto Exit;
291
292 if ( size == 0 )
293 {
294 error = FT_THROW( Invalid_Table );
295 goto Exit;
296 }
297
298 idx->data_size = --size;
299
300 if ( load )
301 {
302 /* load the data */
303 if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
304 goto Exit;
305 }
306 else
307 {
308 /* skip the data */
309 if ( FT_STREAM_SKIP( size ) )
310 goto Exit;
311 }
312 }
313
314 Exit:
315 if ( error )
316 FT_FREE( idx->offsets );
317
318 return error;
319 }
320
321
322 static void
324 {
325 if ( idx->stream )
326 {
327 FT_Stream stream = idx->stream;
328 FT_Memory memory = stream->memory;
329
330
331 if ( idx->bytes )
332 FT_FRAME_RELEASE( idx->bytes );
333
334 FT_FREE( idx->offsets );
335 FT_ZERO( idx );
336 }
337 }
338
339
340 static FT_Error
342 {
344 FT_Stream stream = idx->stream;
345 FT_Memory memory = stream->memory;
346
347
348 if ( idx->count > 0 && !idx->offsets )
349 {
350 FT_Byte offsize = idx->off_size;
351 FT_ULong data_size;
352 FT_Byte* p;
353 FT_Byte* p_end;
354 FT_ULong* poff;
355
356
357 data_size = (FT_ULong)( idx->count + 1 ) * offsize;
358
359 if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
360 FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
361 FT_FRAME_ENTER( data_size ) )
362 goto Exit;
363
364 poff = idx->offsets;
365 p = (FT_Byte*)stream->cursor;
366 p_end = p + data_size;
367
368 switch ( offsize )
369 {
370 case 1:
371 for ( ; p < p_end; p++, poff++ )
372 poff[0] = p[0];
373 break;
374
375 case 2:
376 for ( ; p < p_end; p += 2, poff++ )
377 poff[0] = FT_PEEK_USHORT( p );
378 break;
379
380 case 3:
381 for ( ; p < p_end; p += 3, poff++ )
382 poff[0] = FT_PEEK_UOFF3( p );
383 break;
384
385 default:
386 for ( ; p < p_end; p += 4, poff++ )
387 poff[0] = FT_PEEK_ULONG( p );
388 }
389
391 }
392
393 Exit:
394 if ( error )
395 FT_FREE( idx->offsets );
396
397 return error;
398 }
399
400
401 /* Allocate a table containing pointers to an index's elements. */
402 /* The `pool' argument makes this function convert the index */
403 /* entries to C-style strings (this is, NULL-terminated). */
404 static FT_Error
406 FT_Byte*** table,
407 FT_Byte** pool,
408 FT_ULong* pool_size )
409 {
411 FT_Memory memory = idx->stream->memory;
412
413 FT_Byte** tbl = NULL;
414 FT_Byte* new_bytes = NULL;
416
417
418 *table = NULL;
419
420 if ( !idx->offsets )
421 {
423 if ( error )
424 goto Exit;
425 }
426
427 new_size = idx->data_size + idx->count;
428
429 if ( idx->count > 0 &&
430 !FT_NEW_ARRAY( tbl, idx->count + 1 ) &&
431 ( !pool || !FT_ALLOC( new_bytes, new_size ) ) )
432 {
433 FT_ULong n, cur_offset;
434 FT_ULong extra = 0;
435 FT_Byte* org_bytes = idx->bytes;
436
437
438 /* at this point, `idx->offsets' can't be NULL */
439 cur_offset = idx->offsets[0] - 1;
440
441 /* sanity check */
442 if ( cur_offset != 0 )
443 {
444 FT_TRACE0(( "cff_index_get_pointers:"
445 " invalid first offset value %ld set to zero\n",
446 cur_offset ));
447 cur_offset = 0;
448 }
449
450 if ( !pool )
451 tbl[0] = org_bytes + cur_offset;
452 else
453 tbl[0] = new_bytes + cur_offset;
454
455 for ( n = 1; n <= idx->count; n++ )
456 {
457 FT_ULong next_offset = idx->offsets[n] - 1;
458
459
460 /* two sanity checks for invalid offset tables */
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;
465
466 if ( !pool )
467 tbl[n] = org_bytes + next_offset;
468 else
469 {
470 tbl[n] = new_bytes + next_offset + extra;
471
472 if ( next_offset != cur_offset )
473 {
474 FT_MEM_COPY( tbl[n - 1],
475 org_bytes + cur_offset,
476 tbl[n] - tbl[n - 1] );
477 tbl[n][0] = '\0';
478 tbl[n] += 1;
479 extra++;
480 }
481 }
482
483 cur_offset = next_offset;
484 }
485 *table = tbl;
486
487 if ( pool )
488 *pool = new_bytes;
489 if ( pool_size )
490 *pool_size = new_size;
491 }
492
493 Exit:
494 if ( error && new_bytes )
495 FT_FREE( new_bytes );
496 if ( error && tbl )
497 FT_FREE( tbl );
498
499 return error;
500 }
501
502
506 FT_Byte** pbytes,
507 FT_ULong* pbyte_len )
508 {
510
511
512 if ( idx && idx->count > element )
513 {
514 /* compute start and end offsets */
515 FT_Stream stream = idx->stream;
516 FT_ULong off1, off2 = 0;
517
518
519 /* load offsets from file or the offset table */
520 if ( !idx->offsets )
521 {
522 FT_ULong pos = element * idx->off_size;
523
524
525 if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
526 goto Exit;
527
528 off1 = cff_index_read_offset( idx, &error );
529 if ( error )
530 goto Exit;
531
532 if ( off1 != 0 )
533 {
534 do
535 {
536 element++;
537 off2 = cff_index_read_offset( idx, &error );
538
539 } while ( off2 == 0 && element < idx->count );
540 }
541 }
542 else /* use offsets table */
543 {
544 off1 = idx->offsets[element];
545 if ( off1 )
546 {
547 do
548 {
549 element++;
550 off2 = idx->offsets[element];
551
552 } while ( off2 == 0 && element < idx->count );
553 }
554 }
555
556 /* XXX: should check off2 does not exceed the end of this entry; */
557 /* at present, only truncate off2 at the end of this stream */
558 if ( off2 > stream->size + 1 ||
559 idx->data_offset > stream->size - off2 + 1 )
560 {
561 FT_ERROR(( "cff_index_access_element:"
562 " offset to next entry (%ld)"
563 " exceeds the end of stream (%ld)\n",
564 off2, stream->size - idx->data_offset + 1 ));
565 off2 = stream->size - idx->data_offset + 1;
566 }
567
568 /* access element */
569 if ( off1 && off2 > off1 )
570 {
571 *pbyte_len = off2 - off1;
572
573 if ( idx->bytes )
574 {
575 /* this index was completely loaded in memory, that's easy */
576 *pbytes = idx->bytes + off1 - 1;
577 }
578 else
579 {
580 /* this index is still on disk/file, access it through a frame */
581 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
582 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
583 goto Exit;
584 }
585 }
586 else
587 {
588 /* empty index element */
589 *pbytes = 0;
590 *pbyte_len = 0;
591 }
592 }
593 else
594 error = FT_THROW( Invalid_Argument );
595
596 Exit:
597 return error;
598 }
599
600
601 FT_LOCAL_DEF( void )
603 FT_Byte** pbytes )
604 {
605 if ( idx->bytes == 0 )
606 {
607 FT_Stream stream = idx->stream;
608
609
610 FT_FRAME_RELEASE( *pbytes );
611 }
612 }
613
614
615 /* get an entry from Name INDEX */
619 {
620 CFF_Index idx = &font->name_index;
622 FT_Byte* bytes;
623 FT_ULong byte_len;
625 FT_String* name = 0;
626
627
628 if ( !idx->stream ) /* CFF2 does not include a name index */
629 goto Exit;
630
631 memory = idx->stream->memory;
632
634 if ( error )
635 goto Exit;
636
637 if ( !FT_ALLOC( name, byte_len + 1 ) )
638 {
639 if ( byte_len )
640 FT_MEM_COPY( name, bytes, byte_len );
641 name[byte_len] = 0;
642 }
644
645 Exit:
646 return name;
647 }
648
649
650 /* get an entry from String INDEX */
654 {
655 return ( element < font->num_strings )
656 ? (FT_String*)font->strings[element]
657 : NULL;
658 }
659
660
663 FT_UInt sid )
664 {
665 /* value 0xFFFFU indicates a missing dictionary entry */
666 if ( sid == 0xFFFFU )
667 return NULL;
668
669 /* if it is not a standard string, return it */
670 if ( sid > 390 )
671 return cff_index_get_string( font, sid - 391 );
672
673 /* CID-keyed CFF fonts don't have glyph names */
674 if ( !font->psnames )
675 return NULL;
676
677 /* this is a standard string */
678 return (FT_String *)font->psnames->adobe_std_strings( sid );
679 }
680
681
682 /*************************************************************************/
683 /*************************************************************************/
684 /*** ***/
685 /*** FD Select table support ***/
686 /*** ***/
687 /*************************************************************************/
688 /*************************************************************************/
689
690
691 static void
694 {
695 if ( fdselect->data )
696 FT_FRAME_RELEASE( fdselect->data );
697
698 fdselect->data_size = 0;
699 fdselect->format = 0;
700 fdselect->range_count = 0;
701 }
702
703
704 static FT_Error
706 FT_UInt num_glyphs,
709 {
712 FT_UInt num_ranges;
713
714
715 /* read format */
717 goto Exit;
718
719 fdselect->format = format;
720 fdselect->cache_count = 0; /* clear cache */
721
722 switch ( format )
723 {
724 case 0: /* format 0, that's simple */
725 fdselect->data_size = num_glyphs;
726 goto Load_Data;
727
728 case 3: /* format 3, a tad more complex */
729 if ( FT_READ_USHORT( num_ranges ) )
730 goto Exit;
731
732 if ( !num_ranges )
733 {
734 FT_TRACE0(( "CFF_Load_FD_Select: empty FDSelect array\n" ));
735 error = FT_THROW( Invalid_File_Format );
736 goto Exit;
737 }
738
739 fdselect->data_size = num_ranges * 3 + 2;
740
741 Load_Data:
742 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
743 goto Exit;
744 break;
745
746 default: /* hmm... that's wrong */
747 error = FT_THROW( Invalid_File_Format );
748 }
749
750 Exit:
751 return error;
752 }
753
754
757 FT_UInt glyph_index )
758 {
759 FT_Byte fd = 0;
760
761
762 /* if there is no FDSelect, return zero */
763 /* Note: CFF2 with just one Font Dict has no FDSelect */
764 if ( !fdselect->data )
765 goto Exit;
766
767 switch ( fdselect->format )
768 {
769 case 0:
770 fd = fdselect->data[glyph_index];
771 break;
772
773 case 3:
774 /* first, compare to the cache */
775 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
776 fdselect->cache_count )
777 {
778 fd = fdselect->cache_fd;
779 break;
780 }
781
782 /* then, look up the ranges array */
783 {
784 FT_Byte* p = fdselect->data;
785 FT_Byte* p_limit = p + fdselect->data_size;
786 FT_Byte fd2;
788
789
791 do
792 {
793 if ( glyph_index < first )
794 break;
795
796 fd2 = *p++;
798
799 if ( glyph_index < limit )
800 {
801 fd = fd2;
802
803 /* update cache */
804 fdselect->cache_first = first;
805 fdselect->cache_count = limit - first;
806 fdselect->cache_fd = fd2;
807 break;
808 }
809 first = limit;
810
811 } while ( p < p_limit );
812 }
813 break;
814
815 default:
816 ;
817 }
818
819 Exit:
820 return fd;
821 }
822
823
824 /*************************************************************************/
825 /*************************************************************************/
826 /*** ***/
827 /*** CFF font support ***/
828 /*** ***/
829 /*************************************************************************/
830 /*************************************************************************/
831
832 static FT_Error
834 FT_UInt num_glyphs,
836 {
838 FT_UInt i;
839 FT_Long j;
840 FT_UShort max_cid = 0;
841
842
843 if ( charset->max_cid > 0 )
844 goto Exit;
845
846 for ( i = 0; i < num_glyphs; i++ )
847 {
848 if ( charset->sids[i] > max_cid )
849 max_cid = charset->sids[i];
850 }
851
852 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
853 goto Exit;
854
855 /* When multiple GIDs map to the same CID, we choose the lowest */
856 /* GID. This is not described in any spec, but it matches the */
857 /* behaviour of recent Acroread versions. */
858 for ( j = (FT_Long)num_glyphs - 1; j >= 0; j-- )
860
861 charset->max_cid = max_cid;
862 charset->num_glyphs = num_glyphs;
863
864 Exit:
865 return error;
866 }
867
868
871 FT_UInt cid )
872 {
873 FT_UInt result = 0;
874
875
876 if ( cid <= charset->max_cid )
878
879 return result;
880 }
881
882
883 static void
886 {
887 FT_FREE( charset->cids );
888 charset->max_cid = 0;
889 }
890
891
892 static void
895 {
896 FT_Memory memory = stream->memory;
897
898
900
901 FT_FREE( charset->sids );
902 charset->format = 0;
903 charset->offset = 0;
904 }
905
906
907 static FT_Error
909 FT_UInt num_glyphs,
911 FT_ULong base_offset,
914 {
915 FT_Memory memory = stream->memory;
917 FT_UShort glyph_sid;
918
919
920 /* If the offset is greater than 2, we have to parse the charset */
921 /* table. */
922 if ( offset > 2 )
923 {
924 FT_UInt j;
925
926
927 charset->offset = base_offset + offset;
928
929 /* Get the format of the table. */
930 if ( FT_STREAM_SEEK( charset->offset ) ||
932 goto Exit;
933
934 /* Allocate memory for sids. */
935 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
936 goto Exit;
937
938 /* assign the .notdef glyph */
939 charset->sids[0] = 0;
940
941 switch ( charset->format )
942 {
943 case 0:
944 if ( num_glyphs > 0 )
945 {
946 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
947 goto Exit;
948
949 for ( j = 1; j < num_glyphs; j++ )
951
953 }
954 break;
955
956 case 1:
957 case 2:
958 {
959 FT_UInt nleft;
960 FT_UInt i;
961
962
963 j = 1;
964
965 while ( j < num_glyphs )
966 {
967 /* Read the first glyph sid of the range. */
968 if ( FT_READ_USHORT( glyph_sid ) )
969 goto Exit;
970
971 /* Read the number of glyphs in the range. */
972 if ( charset->format == 2 )
973 {
974 if ( FT_READ_USHORT( nleft ) )
975 goto Exit;
976 }
977 else
978 {
979 if ( FT_READ_BYTE( nleft ) )
980 goto Exit;
981 }
982
983 /* try to rescue some of the SIDs if `nleft' is too large */
984 if ( glyph_sid > 0xFFFFL - nleft )
985 {
986 FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
987 " nleft=%d -> %ld\n", nleft, 0xFFFFL - glyph_sid ));
988 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
989 }
990
991 /* Fill in the range of sids -- `nleft + 1' glyphs. */
992 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
993 charset->sids[j] = glyph_sid;
994 }
995 }
996 break;
997
998 default:
999 FT_ERROR(( "cff_charset_load: invalid table format\n" ));
1000 error = FT_THROW( Invalid_File_Format );
1001 goto Exit;
1002 }
1003 }
1004 else
1005 {
1006 /* Parse default tables corresponding to offset == 0, 1, or 2. */
1007 /* CFF specification intimates the following: */
1008 /* */
1009 /* In order to use a predefined charset, the following must be */
1010 /* true: The charset constructed for the glyphs in the font's */
1011 /* charstrings dictionary must match the predefined charset in */
1012 /* the first num_glyphs. */
1013
1014 charset->offset = offset; /* record charset type */
1015
1016 switch ( (FT_UInt)offset )
1017 {
1018 case 0:
1019 if ( num_glyphs > 229 )
1020 {
1021 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1022 "predefined charset (Adobe ISO-Latin)\n" ));
1023 error = FT_THROW( Invalid_File_Format );
1024 goto Exit;
1025 }
1026
1027 /* Allocate memory for sids. */
1028 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1029 goto Exit;
1030
1031 /* Copy the predefined charset into the allocated memory. */
1033
1034 break;
1035
1036 case 1:
1037 if ( num_glyphs > 166 )
1038 {
1039 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1040 "predefined charset (Adobe Expert)\n" ));
1041 error = FT_THROW( Invalid_File_Format );
1042 goto Exit;
1043 }
1044
1045 /* Allocate memory for sids. */
1046 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1047 goto Exit;
1048
1049 /* Copy the predefined charset into the allocated memory. */
1051
1052 break;
1053
1054 case 2:
1055 if ( num_glyphs > 87 )
1056 {
1057 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1058 "predefined charset (Adobe Expert Subset)\n" ));
1059 error = FT_THROW( Invalid_File_Format );
1060 goto Exit;
1061 }
1062
1063 /* Allocate memory for sids. */
1064 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1065 goto Exit;
1066
1067 /* Copy the predefined charset into the allocated memory. */
1069
1070 break;
1071
1072 default:
1073 error = FT_THROW( Invalid_File_Format );
1074 goto Exit;
1075 }
1076 }
1077
1078 /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1079 if ( invert )
1080 error = cff_charset_compute_cids( charset, num_glyphs, memory );
1081
1082 Exit:
1083 /* Clean up if there was an error. */
1084 if ( error )
1085 {
1086 FT_FREE( charset->sids );
1087 FT_FREE( charset->cids );
1088 charset->format = 0;
1089 charset->offset = 0;
1090 charset->sids = 0;
1091 }
1092
1093 return error;
1094 }
1095
1096
1097 static void
1100 {
1101 FT_UInt i;
1102
1103
1104 /* free regionList and axisLists */
1105 if ( vstore->varRegionList )
1106 {
1107 for ( i = 0; i < vstore->regionCount; i++ )
1108 FT_FREE( vstore->varRegionList[i].axisList );
1109 }
1110 FT_FREE( vstore->varRegionList );
1111
1112 /* free varData and indices */
1113 if ( vstore->varData )
1114 {
1115 for ( i = 0; i < vstore->dataCount; i++ )
1116 FT_FREE( vstore->varData[i].regionIndices );
1117 }
1118 FT_FREE( vstore->varData );
1119 }
1120
1121
1122 /* convert 2.14 to Fixed */
1123 #define FT_fdot14ToFixed( x ) ( (FT_Fixed)( (FT_ULong)(x) << 2 ) )
1124
1125
1126 static FT_Error
1129 FT_ULong base_offset,
1131 {
1132 FT_Memory memory = stream->memory;
1133 FT_Error error = FT_ERR( Invalid_File_Format );
1134
1135 FT_ULong* dataOffsetArray = NULL;
1136 FT_UInt i, j;
1137
1138
1139 /* no offset means no vstore to parse */
1140 if ( offset )
1141 {
1142 FT_UInt vsOffset;
1144 FT_ULong regionListOffset;
1145
1146
1147 /* we need to parse the table to determine its size; */
1148 /* skip table length */
1149 if ( FT_STREAM_SEEK( base_offset + offset ) ||
1150 FT_STREAM_SKIP( 2 ) )
1151 goto Exit;
1152
1153 /* actual variation store begins after the length */
1154 vsOffset = FT_STREAM_POS();
1155
1156 /* check the header */
1157 if ( FT_READ_USHORT( format ) )
1158 goto Exit;
1159 if ( format != 1 )
1160 {
1161 error = FT_THROW( Invalid_File_Format );
1162 goto Exit;
1163 }
1164
1165 /* read top level fields */
1166 if ( FT_READ_ULONG( regionListOffset ) ||
1167 FT_READ_USHORT( vstore->dataCount ) )
1168 goto Exit;
1169
1170 /* make temporary copy of item variation data offsets; */
1171 /* we'll parse region list first, then come back */
1172 if ( FT_NEW_ARRAY( dataOffsetArray, vstore->dataCount ) )
1173 goto Exit;
1174
1175 for ( i = 0; i < vstore->dataCount; i++ )
1176 {
1177 if ( FT_READ_ULONG( dataOffsetArray[i] ) )
1178 goto Exit;
1179 }
1180
1181 /* parse regionList and axisLists */
1182 if ( FT_STREAM_SEEK( vsOffset + regionListOffset ) ||
1183 FT_READ_USHORT( vstore->axisCount ) ||
1184 FT_READ_USHORT( vstore->regionCount ) )
1185 goto Exit;
1186
1187 if ( FT_NEW_ARRAY( vstore->varRegionList, vstore->regionCount ) )
1188 goto Exit;
1189
1190 for ( i = 0; i < vstore->regionCount; i++ )
1191 {
1192 CFF_VarRegion* region = &vstore->varRegionList[i];
1193
1194
1195 if ( FT_NEW_ARRAY( region->axisList, vstore->axisCount ) )
1196 goto Exit;
1197
1198 for ( j = 0; j < vstore->axisCount; j++ )
1199 {
1200 CFF_AxisCoords* axis = &region->axisList[j];
1201
1202 FT_Int16 start14, peak14, end14;
1203
1204
1205 if ( FT_READ_SHORT( start14 ) ||
1206 FT_READ_SHORT( peak14 ) ||
1207 FT_READ_SHORT( end14 ) )
1208 goto Exit;
1209
1210 axis->startCoord = FT_fdot14ToFixed( start14 );
1211 axis->peakCoord = FT_fdot14ToFixed( peak14 );
1212 axis->endCoord = FT_fdot14ToFixed( end14 );
1213 }
1214 }
1215
1216 /* use dataOffsetArray now to parse varData items */
1217 if ( FT_NEW_ARRAY( vstore->varData, vstore->dataCount ) )
1218 goto Exit;
1219
1220 for ( i = 0; i < vstore->dataCount; i++ )
1221 {
1222 CFF_VarData* data = &vstore->varData[i];
1223
1224
1225 if ( FT_STREAM_SEEK( vsOffset + dataOffsetArray[i] ) )
1226 goto Exit;
1227
1228 /* ignore `itemCount' and `shortDeltaCount' */
1229 /* because CFF2 has no delta sets */
1230 if ( FT_STREAM_SKIP( 4 ) )
1231 goto Exit;
1232
1233 /* Note: just record values; consistency is checked later */
1234 /* by cff_blend_build_vector when it consumes `vstore' */
1235
1236 if ( FT_READ_USHORT( data->regionIdxCount ) )
1237 goto Exit;
1238
1239 if ( FT_NEW_ARRAY( data->regionIndices, data->regionIdxCount ) )
1240 goto Exit;
1241
1242 for ( j = 0; j < data->regionIdxCount; j++ )
1243 {
1244 if ( FT_READ_USHORT( data->regionIndices[j] ) )
1245 goto Exit;
1246 }
1247 }
1248 }
1249
1250 error = FT_Err_Ok;
1251
1252 Exit:
1253 FT_FREE( dataOffsetArray );
1254 if ( error )
1255 cff_vstore_done( vstore, memory );
1256
1257 return error;
1258 }
1259
1260
1261 /* Clear blend stack (after blend values are consumed). */
1262 /* */
1263 /* TODO: Should do this in cff_run_parse, but subFont */
1264 /* ref is not available there. */
1265 /* */
1266 /* Allocation is not changed when stack is cleared. */
1267 FT_LOCAL_DEF( void )
1269 {
1270 subFont->blend_top = subFont->blend_stack;
1271 subFont->blend_used = 0;
1272 }
1273
1274
1275 /* Blend numOperands on the stack, */
1276 /* store results into the first numBlends values, */
1277 /* then pop remaining arguments. */
1278 /* */
1279 /* This is comparable to `cf2_doBlend' but */
1280 /* the cffparse stack is different and can't be written. */
1281 /* Blended values are written to a different buffer, */
1282 /* using reserved operator 255. */
1283 /* */
1284 /* Blend calculation is done in 16.16 fixed point. */
1288 FT_UInt numBlends )
1289 {
1290 FT_UInt delta;
1291 FT_UInt base;
1292 FT_UInt i, j;
1293 FT_UInt size;
1294
1295 CFF_Blend blend = &subFont->blend;
1296
1297 FT_Memory memory = subFont->blend.font->memory; /* for FT_REALLOC */
1298 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
1299
1300 /* compute expected number of operands for this blend */
1301 FT_UInt numOperands = (FT_UInt)( numBlends * blend->lenBV );
1302 FT_UInt count = (FT_UInt)( parser->top - 1 - parser->stack );
1303
1304
1305 if ( numOperands > count )
1306 {
1307 FT_TRACE4(( " cff_blend_doBlend: Stack underflow %d argument%s\n",
1308 count,
1309 count == 1 ? "" : "s" ));
1310
1311 error = FT_THROW( Stack_Underflow );
1312 goto Exit;
1313 }
1314
1315 /* check whether we have room for `numBlends' values at `blend_top' */
1316 size = 5 * numBlends; /* add 5 bytes per entry */
1317 if ( subFont->blend_used + size > subFont->blend_alloc )
1318 {
1319 FT_Byte* blend_stack_old = subFont->blend_stack;
1320 FT_Byte* blend_top_old = subFont->blend_top;
1321
1322
1323 /* increase or allocate `blend_stack' and reset `blend_top'; */
1324 /* prepare to append `numBlends' values to the buffer */
1325 if ( FT_REALLOC( subFont->blend_stack,
1326 subFont->blend_alloc,
1327 subFont->blend_alloc + size ) )
1328 goto Exit;
1329
1330 subFont->blend_top = subFont->blend_stack + subFont->blend_used;
1331 subFont->blend_alloc += size;
1332
1333 /* iterate over the parser stack and adjust pointers */
1334 /* if the reallocated buffer has a different address */
1335 if ( blend_stack_old &&
1336 subFont->blend_stack != blend_stack_old )
1337 {
1338 FT_PtrDist offset = subFont->blend_stack - blend_stack_old;
1339 FT_Byte** p;
1340
1341
1342 for ( p = parser->stack; p < parser->top; p++ )
1343 {
1344 if ( *p >= blend_stack_old && *p < blend_top_old )
1345 *p += offset;
1346 }
1347 }
1348 }
1349 subFont->blend_used += size;
1350
1351 base = count - numOperands; /* index of first blend arg */
1352 delta = base + numBlends; /* index of first delta arg */
1353
1354 for ( i = 0; i < numBlends; i++ )
1355 {
1356 const FT_Int32* weight = &blend->BV[1];
1357 FT_UInt32 sum;
1358
1359
1360 /* convert inputs to 16.16 fixed point */
1361 sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
1362
1363 for ( j = 1; j < blend->lenBV; j++ )
1364 sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
1365
1366 /* point parser stack to new value on blend_stack */
1367 parser->stack[i + base] = subFont->blend_top;
1368
1369 /* Push blended result as Type 2 5-byte fixed point number. This */
1370 /* will not conflict with actual DICTs because 255 is a reserved */
1371 /* opcode in both CFF and CFF2 DICTs. See `cff_parse_num' for */
1372 /* decode of this, which rounds to an integer. */
1373 *subFont->blend_top++ = 255;
1374 *subFont->blend_top++ = (FT_Byte)( sum >> 24 );
1375 *subFont->blend_top++ = (FT_Byte)( sum >> 16 );
1376 *subFont->blend_top++ = (FT_Byte)( sum >> 8 );
1377 *subFont->blend_top++ = (FT_Byte)sum;
1378 }
1379
1380 /* leave only numBlends results on parser stack */
1381 parser->top = &parser->stack[base + numBlends];
1382
1383 Exit:
1384 return error;
1385 }
1386
1387
1388 /* Compute a blend vector from variation store index and normalized */
1389 /* vector based on pseudo-code in OpenType Font Variations Overview. */
1390 /* */
1391 /* Note: lenNDV == 0 produces a default blend vector, (1,0,0,...). */
1394 FT_UInt vsindex,
1395 FT_UInt lenNDV,
1396 FT_Fixed* NDV )
1397 {
1398 FT_Error error = FT_Err_Ok; /* for FT_REALLOC */
1399 FT_Memory memory = blend->font->memory; /* for FT_REALLOC */
1400
1401 FT_UInt len;
1402 CFF_VStore vs;
1403 CFF_VarData* varData;
1404 FT_UInt master;
1405
1406
1407 /* protect against malformed fonts */
1408 if ( !( lenNDV == 0 || NDV ) )
1409 {
1410 FT_TRACE4(( " cff_blend_build_vector:"
1411 " Malformed Normalize Design Vector data\n" ));
1412 error = FT_THROW( Invalid_File_Format );
1413 goto Exit;
1414 }
1415
1416 blend->builtBV = FALSE;
1417
1418 vs = &blend->font->vstore;
1419
1420 /* VStore and fvar must be consistent */
1421 if ( lenNDV != 0 && lenNDV != vs->axisCount )
1422 {
1423 FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
1424 error = FT_THROW( Invalid_File_Format );
1425 goto Exit;
1426 }
1427
1428 if ( vsindex >= vs->dataCount )
1429 {
1430 FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
1431 error = FT_THROW( Invalid_File_Format );
1432 goto Exit;
1433 }
1434
1435 /* select the item variation data structure */
1436 varData = &vs->varData[vsindex];
1437
1438 /* prepare buffer for the blend vector */
1439 len = varData->regionIdxCount + 1; /* add 1 for default component */
1440 if ( FT_REALLOC( blend->BV,
1441 blend->lenBV * sizeof( *blend->BV ),
1442 len * sizeof( *blend->BV ) ) )
1443 goto Exit;
1444
1445 blend->lenBV = len;
1446
1447 /* outer loop steps through master designs to be blended */
1448 for ( master = 0; master < len; master++ )
1449 {
1450 FT_UInt j;
1451 FT_UInt idx;
1452 CFF_VarRegion* varRegion;
1453
1454
1455 /* default factor is always one */
1456 if ( master == 0 )
1457 {
1458 blend->BV[master] = FT_FIXED_ONE;
1459 FT_TRACE4(( " build blend vector len %d\n"
1460 " [ %f ",
1461 len,
1462 blend->BV[master] / 65536.0 ));
1463 continue;
1464 }
1465
1466 /* VStore array does not include default master, so subtract one */
1467 idx = varData->regionIndices[master - 1];
1468 varRegion = &vs->varRegionList[idx];
1469
1470 if ( idx >= vs->regionCount )
1471 {
1472 FT_TRACE4(( " cff_blend_build_vector:"
1473 " region index out of range\n" ));
1474 error = FT_THROW( Invalid_File_Format );
1475 goto Exit;
1476 }
1477
1478 /* Note: `lenNDV' could be zero. */
1479 /* In that case, build default blend vector (1,0,0...). */
1480 if ( !lenNDV )
1481 {
1482 blend->BV[master] = 0;
1483 continue;
1484 }
1485
1486 /* In the normal case, initialize each component to 1 */
1487 /* before inner loop. */
1488 blend->BV[master] = FT_FIXED_ONE; /* default */
1489
1490 /* inner loop steps through axes in this region */
1491 for ( j = 0; j < lenNDV; j++ )
1492 {
1493 CFF_AxisCoords* axis = &varRegion->axisList[j];
1494 FT_Fixed axisScalar;
1495
1496
1497 /* compute the scalar contribution of this axis; */
1498 /* ignore invalid ranges */
1499 if ( axis->startCoord > axis->peakCoord ||
1500 axis->peakCoord > axis->endCoord )
1501 axisScalar = FT_FIXED_ONE;
1502
1503 else if ( axis->startCoord < 0 &&
1504 axis->endCoord > 0 &&
1505 axis->peakCoord != 0 )
1506 axisScalar = FT_FIXED_ONE;
1507
1508 /* peak of 0 means ignore this axis */
1509 else if ( axis->peakCoord == 0 )
1510 axisScalar = FT_FIXED_ONE;
1511
1512 /* ignore this region if coords are out of range */
1513 else if ( NDV[j] < axis->startCoord ||
1514 NDV[j] > axis->endCoord )
1515 axisScalar = 0;
1516
1517 /* calculate a proportional factor */
1518 else
1519 {
1520 if ( NDV[j] == axis->peakCoord )
1521 axisScalar = FT_FIXED_ONE;
1522 else if ( NDV[j] < axis->peakCoord )
1523 axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
1524 axis->peakCoord - axis->startCoord );
1525 else
1526 axisScalar = FT_DivFix( axis->endCoord - NDV[j],
1527 axis->endCoord - axis->peakCoord );
1528 }
1529
1530 /* take product of all the axis scalars */
1531 blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
1532 }
1533
1534 FT_TRACE4(( ", %f ",
1535 blend->BV[master] / 65536.0 ));
1536 }
1537
1538 FT_TRACE4(( "]\n" ));
1539
1540 /* record the parameters used to build the blend vector */
1541 blend->lastVsindex = vsindex;
1542
1543 if ( lenNDV != 0 )
1544 {
1545 /* user has set a normalized vector */
1546 if ( FT_REALLOC( blend->lastNDV,
1547 blend->lenNDV * sizeof ( *NDV ),
1548 lenNDV * sizeof ( *NDV ) ) )
1549 goto Exit;
1550
1551 FT_MEM_COPY( blend->lastNDV,
1552 NDV,
1553 lenNDV * sizeof ( *NDV ) );
1554 }
1555
1556 blend->lenNDV = lenNDV;
1557 blend->builtBV = TRUE;
1558
1559 Exit:
1560 return error;
1561 }
1562
1563
1564 /* `lenNDV' is zero for default vector; */
1565 /* return TRUE if blend vector needs to be built. */
1568 FT_UInt vsindex,
1569 FT_UInt lenNDV,
1570 FT_Fixed* NDV )
1571 {
1572 if ( !blend->builtBV ||
1573 blend->lastVsindex != vsindex ||
1574 blend->lenNDV != lenNDV ||
1575 ( lenNDV &&
1576 ft_memcmp( NDV,
1577 blend->lastNDV,
1578 lenNDV * sizeof ( *NDV ) ) != 0 ) )
1579 {
1580 /* need to build blend vector */
1581 return TRUE;
1582 }
1583
1584 return FALSE;
1585 }
1586
1587
1588#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1589
1591 cff_get_var_blend( CFF_Face face,
1592 FT_UInt *num_coords,
1593 FT_Fixed* *coords,
1594 FT_Fixed* *normalizedcoords,
1595 FT_MM_Var* *mm_var )
1596 {
1597 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
1598
1599
1600 return mm->get_var_blend( FT_FACE( face ),
1601 num_coords,
1602 coords,
1603 normalizedcoords,
1604 mm_var );
1605 }
1606
1607
1608 FT_LOCAL_DEF( void )
1609 cff_done_blend( CFF_Face face )
1610 {
1611 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
1612
1613
1614 if (mm)
1615 mm->done_blend( FT_FACE( face ) );
1616 }
1617
1618#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1619
1620
1621 static void
1623 {
1624 encoding->format = 0;
1625 encoding->offset = 0;
1626 encoding->count = 0;
1627 }
1628
1629
1630 static FT_Error
1633 FT_UInt num_glyphs,
1635 FT_ULong base_offset,
1637 {
1639 FT_UInt count;
1640 FT_UInt j;
1641 FT_UShort glyph_sid;
1642 FT_UInt glyph_code;
1643
1644
1645 /* Check for charset->sids. If we do not have this, we fail. */
1646 if ( !charset->sids )
1647 {
1648 error = FT_THROW( Invalid_File_Format );
1649 goto Exit;
1650 }
1651
1652 /* Zero out the code to gid/sid mappings. */
1653 for ( j = 0; j < 256; j++ )
1654 {
1655 encoding->sids [j] = 0;
1656 encoding->codes[j] = 0;
1657 }
1658
1659 /* Note: The encoding table in a CFF font is indexed by glyph index; */
1660 /* the first encoded glyph index is 1. Hence, we read the character */
1661 /* code (`glyph_code') at index j and make the assignment: */
1662 /* */
1663 /* encoding->codes[glyph_code] = j + 1 */
1664 /* */
1665 /* We also make the assignment: */
1666 /* */
1667 /* encoding->sids[glyph_code] = charset->sids[j + 1] */
1668 /* */
1669 /* This gives us both a code to GID and a code to SID mapping. */
1670
1671 if ( offset > 1 )
1672 {
1673 encoding->offset = base_offset + offset;
1674
1675 /* we need to parse the table to determine its size */
1676 if ( FT_STREAM_SEEK( encoding->offset ) ||
1677 FT_READ_BYTE( encoding->format ) ||
1678 FT_READ_BYTE( count ) )
1679 goto Exit;
1680
1681 switch ( encoding->format & 0x7F )
1682 {
1683 case 0:
1684 {
1685 FT_Byte* p;
1686
1687
1688 /* By convention, GID 0 is always ".notdef" and is never */
1689 /* coded in the font. Hence, the number of codes found */
1690 /* in the table is `count+1'. */
1691 /* */
1692 encoding->count = count + 1;
1693
1694 if ( FT_FRAME_ENTER( count ) )
1695 goto Exit;
1696
1697 p = (FT_Byte*)stream->cursor;
1698
1699 for ( j = 1; j <= count; j++ )
1700 {
1701 glyph_code = *p++;
1702
1703 /* Make sure j is not too big. */
1704 if ( j < num_glyphs )
1705 {
1706 /* Assign code to GID mapping. */
1707 encoding->codes[glyph_code] = (FT_UShort)j;
1708
1709 /* Assign code to SID mapping. */
1710 encoding->sids[glyph_code] = charset->sids[j];
1711 }
1712 }
1713
1714 FT_FRAME_EXIT();
1715 }
1716 break;
1717
1718 case 1:
1719 {
1720 FT_UInt nleft;
1721 FT_UInt i = 1;
1722 FT_UInt k;
1723
1724
1725 encoding->count = 0;
1726
1727 /* Parse the Format1 ranges. */
1728 for ( j = 0; j < count; j++, i += nleft )
1729 {
1730 /* Read the first glyph code of the range. */
1731 if ( FT_READ_BYTE( glyph_code ) )
1732 goto Exit;
1733
1734 /* Read the number of codes in the range. */
1735 if ( FT_READ_BYTE( nleft ) )
1736 goto Exit;
1737
1738 /* Increment nleft, so we read `nleft + 1' codes/sids. */
1739 nleft++;
1740
1741 /* compute max number of character codes */
1742 if ( (FT_UInt)nleft > encoding->count )
1743 encoding->count = nleft;
1744
1745 /* Fill in the range of codes/sids. */
1746 for ( k = i; k < nleft + i; k++, glyph_code++ )
1747 {
1748 /* Make sure k is not too big. */
1749 if ( k < num_glyphs && glyph_code < 256 )
1750 {
1751 /* Assign code to GID mapping. */
1752 encoding->codes[glyph_code] = (FT_UShort)k;
1753
1754 /* Assign code to SID mapping. */
1755 encoding->sids[glyph_code] = charset->sids[k];
1756 }
1757 }
1758 }
1759
1760 /* simple check; one never knows what can be found in a font */
1761 if ( encoding->count > 256 )
1762 encoding->count = 256;
1763 }
1764 break;
1765
1766 default:
1767 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1768 error = FT_THROW( Invalid_File_Format );
1769 goto Exit;
1770 }
1771
1772 /* Parse supplemental encodings, if any. */
1773 if ( encoding->format & 0x80 )
1774 {
1775 FT_UInt gindex;
1776
1777
1778 /* count supplements */
1779 if ( FT_READ_BYTE( count ) )
1780 goto Exit;
1781
1782 for ( j = 0; j < count; j++ )
1783 {
1784 /* Read supplemental glyph code. */
1785 if ( FT_READ_BYTE( glyph_code ) )
1786 goto Exit;
1787
1788 /* Read the SID associated with this glyph code. */
1789 if ( FT_READ_USHORT( glyph_sid ) )
1790 goto Exit;
1791
1792 /* Assign code to SID mapping. */
1793 encoding->sids[glyph_code] = glyph_sid;
1794
1795 /* First, look up GID which has been assigned to */
1796 /* SID glyph_sid. */
1797 for ( gindex = 0; gindex < num_glyphs; gindex++ )
1798 {
1799 if ( charset->sids[gindex] == glyph_sid )
1800 {
1801 encoding->codes[glyph_code] = (FT_UShort)gindex;
1802 break;
1803 }
1804 }
1805 }
1806 }
1807 }
1808 else
1809 {
1810 /* We take into account the fact a CFF font can use a predefined */
1811 /* encoding without containing all of the glyphs encoded by this */
1812 /* encoding (see the note at the end of section 12 in the CFF */
1813 /* specification). */
1814
1815 switch ( (FT_UInt)offset )
1816 {
1817 case 0:
1818 /* First, copy the code to SID mapping. */
1819 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1820 goto Populate;
1821
1822 case 1:
1823 /* First, copy the code to SID mapping. */
1824 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1825
1826 Populate:
1827 /* Construct code to GID mapping from code to SID mapping */
1828 /* and charset. */
1829
1830 encoding->count = 0;
1831
1832 error = cff_charset_compute_cids( charset, num_glyphs,
1833 stream->memory );
1834 if ( error )
1835 goto Exit;
1836
1837 for ( j = 0; j < 256; j++ )
1838 {
1839 FT_UInt sid = encoding->sids[j];
1840 FT_UInt gid = 0;
1841
1842
1843 if ( sid )
1845
1846 if ( gid != 0 )
1847 {
1848 encoding->codes[j] = (FT_UShort)gid;
1849 encoding->count = j + 1;
1850 }
1851 else
1852 {
1853 encoding->codes[j] = 0;
1854 encoding->sids [j] = 0;
1855 }
1856 }
1857 break;
1858
1859 default:
1860 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1861 error = FT_THROW( Invalid_File_Format );
1862 goto Exit;
1863 }
1864 }
1865
1866 Exit:
1867
1868 /* Clean up if there was an error. */
1869 return error;
1870 }
1871
1872
1873 /* Parse private dictionary; first call is always from `cff_face_init', */
1874 /* so NDV has not been set for CFF2 variation. */
1875 /* */
1876 /* `cff_slot_load' must call this function each time NDV changes. */
1879 CFF_SubFont subfont,
1880 FT_UInt lenNDV,
1881 FT_Fixed* NDV )
1882 {
1885 CFF_FontRecDict top = &subfont->font_dict;
1886 CFF_Private priv = &subfont->private_dict;
1887 FT_Stream stream = font->stream;
1888 FT_UInt stackSize;
1889
1890
1891 /* store handle needed to access memory, vstore for blend; */
1892 /* we need this for clean-up even if there is no private DICT */
1893 subfont->blend.font = font;
1894 subfont->blend.usedBV = FALSE; /* clear state */
1895
1896 if ( !top->private_offset || !top->private_size )
1897 goto Exit2; /* no private DICT, do nothing */
1898
1899 /* set defaults */
1900 FT_ZERO( priv );
1901
1902 priv->blue_shift = 7;
1903 priv->blue_fuzz = 1;
1904 priv->lenIV = -1;
1905 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1906 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1907
1908 /* provide inputs for blend calculations */
1909 priv->subfont = subfont;
1910 subfont->lenNDV = lenNDV;
1911 subfont->NDV = NDV;
1912
1913 /* add 1 for the operator */
1914 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
1915 : CFF_MAX_STACK_DEPTH + 1;
1916
1917 if ( cff_parser_init( &parser,
1919 priv,
1920 font->library,
1921 stackSize,
1922 top->num_designs,
1923 top->num_axes ) )
1924 goto Exit;
1925
1926 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
1927 FT_FRAME_ENTER( top->private_size ) )
1928 goto Exit;
1929
1930 FT_TRACE4(( " private dictionary:\n" ));
1932 (FT_Byte*)stream->cursor,
1933 (FT_Byte*)stream->limit );
1934 FT_FRAME_EXIT();
1935
1936 if ( error )
1937 goto Exit;
1938
1939 /* ensure that `num_blue_values' is even */
1940 priv->num_blue_values &= ~1;
1941
1942 /* sanitize `initialRandomSeed' to be a positive value, if necessary; */
1943 /* this is not mandated by the specification but by our implementation */
1944 if ( priv->initial_random_seed < 0 )
1946 else if ( priv->initial_random_seed == 0 )
1947 priv->initial_random_seed = 987654321;
1948
1949 /* some sanitizing to avoid overflows later on; */
1950 /* the upper limits are ad-hoc values */
1951 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
1952 {
1953 FT_TRACE2(( "cff_load_private_dict:"
1954 " setting unlikely BlueShift value %ld to default (7)\n",
1955 priv->blue_shift ));
1956 priv->blue_shift = 7;
1957 }
1958
1959 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
1960 {
1961 FT_TRACE2(( "cff_load_private_dict:"
1962 " setting unlikely BlueFuzz value %ld to default (1)\n",
1963 priv->blue_fuzz ));
1964 priv->blue_fuzz = 1;
1965 }
1966
1967 Exit:
1968 /* clean up */
1969 cff_blend_clear( subfont ); /* clear blend stack */
1970 cff_parser_done( &parser ); /* free parser stack */
1971
1972 Exit2:
1973 /* no clean up (parser not initialized) */
1974 return error;
1975 }
1976
1977
1978 /* There are 3 ways to call this function, distinguished by code. */
1979 /* */
1980 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
1981 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */
1982 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */
1983
1984 static FT_Error
1986 CFF_Index idx,
1987 FT_UInt font_index,
1989 FT_ULong base_offset,
1990 FT_UInt code,
1991 CFF_Font font,
1992 CFF_Face face )
1993 {
1996 FT_Byte* dict = NULL;
1997 FT_ULong dict_len;
1998 CFF_FontRecDict top = &subfont->font_dict;
1999 CFF_Private priv = &subfont->private_dict;
2000
2001 PSAux_Service psaux = (PSAux_Service)face->psaux;
2002
2005 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK
2007
2008
2009 /* Note: We use default stack size for CFF2 Font DICT because */
2010 /* Top and Font DICTs are not allowed to have blend operators. */
2012 code,
2013 &subfont->font_dict,
2014 font->library,
2015 stackSize,
2016 0,
2017 0 );
2018 if ( error )
2019 goto Exit;
2020
2021 /* set defaults */
2022 FT_ZERO( top );
2023
2024 top->underline_position = -( 100L << 16 );
2025 top->underline_thickness = 50L << 16;
2026 top->charstring_type = 2;
2027 top->font_matrix.xx = 0x10000L;
2028 top->font_matrix.yy = 0x10000L;
2029 top->cid_count = 8720;
2030
2031 /* we use the implementation specific SID value 0xFFFF to indicate */
2032 /* missing entries */
2033 top->version = 0xFFFFU;
2034 top->notice = 0xFFFFU;
2035 top->copyright = 0xFFFFU;
2036 top->full_name = 0xFFFFU;
2037 top->family_name = 0xFFFFU;
2038 top->weight = 0xFFFFU;
2039 top->embedded_postscript = 0xFFFFU;
2040
2041 top->cid_registry = 0xFFFFU;
2042 top->cid_ordering = 0xFFFFU;
2043 top->cid_font_name = 0xFFFFU;
2044
2045 /* set default stack size */
2046 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48;
2047
2048 if ( idx->count ) /* count is nonzero for a real index */
2049 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2050 else
2051 {
2052 /* CFF2 has a fake top dict index; */
2053 /* simulate `cff_index_access_element' */
2054
2055 /* Note: macros implicitly use `stream' and set `error' */
2056 if ( FT_STREAM_SEEK( idx->data_offset ) ||
2057 FT_FRAME_EXTRACT( idx->data_size, dict ) )
2058 goto Exit;
2059
2060 dict_len = idx->data_size;
2061 }
2062
2063 if ( !error )
2064 {
2065 FT_TRACE4(( " top dictionary:\n" ));
2066 error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
2067 }
2068
2069 /* clean up regardless of error */
2070 if ( idx->count )
2071 cff_index_forget_element( idx, &dict );
2072 else
2073 FT_FRAME_RELEASE( dict );
2074
2075 if ( error )
2076 goto Exit;
2077
2078 /* if it is a CID font, we stop there */
2079 if ( top->cid_registry != 0xFFFFU )
2080 goto Exit;
2081
2082 /* Parse the private dictionary, if any. */
2083 /* */
2084 /* CFF2 does not have a private dictionary in the Top DICT */
2085 /* but may have one in a Font DICT. We need to parse */
2086 /* the latter here in order to load any local subrs. */
2087 error = cff_load_private_dict( font, subfont, 0, 0 );
2088 if ( error )
2089 goto Exit;
2090
2091 if ( !cff2 )
2092 {
2093 /*
2094 * Initialize the random number generator.
2095 *
2096 * - If we have a face-specific seed, use it.
2097 * If non-zero, update it to a positive value.
2098 *
2099 * - Otherwise, use the seed from the CFF driver.
2100 * If non-zero, update it to a positive value.
2101 *
2102 * - If the random value is zero, use the seed given by the subfont's
2103 * `initialRandomSeed' value.
2104 *
2105 */
2106 if ( face->root.internal->random_seed == -1 )
2107 {
2109
2110
2111 subfont->random = (FT_UInt32)driver->random_seed;
2112 if ( driver->random_seed )
2113 {
2114 do
2115 {
2116 driver->random_seed =
2117 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2118
2119 } while ( driver->random_seed < 0 );
2120 }
2121 }
2122 else
2123 {
2124 subfont->random = (FT_UInt32)face->root.internal->random_seed;
2125 if ( face->root.internal->random_seed )
2126 {
2127 do
2128 {
2129 face->root.internal->random_seed =
2130 (FT_Int32)psaux->cff_random(
2131 (FT_UInt32)face->root.internal->random_seed );
2132
2133 } while ( face->root.internal->random_seed < 0 );
2134 }
2135 }
2136
2137 if ( !subfont->random )
2138 subfont->random = (FT_UInt32)priv->initial_random_seed;
2139 }
2140
2141 /* read the local subrs, if any */
2142 if ( priv->local_subrs_offset )
2143 {
2144 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2145 priv->local_subrs_offset ) )
2146 goto Exit;
2147
2148 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2149 if ( error )
2150 goto Exit;
2151
2153 &subfont->local_subrs, NULL, NULL );
2154 if ( error )
2155 goto Exit;
2156 }
2157
2158 Exit:
2159 cff_parser_done( &parser ); /* free parser stack */
2160
2161 return error;
2162 }
2163
2164
2165 static void
2167 CFF_SubFont subfont )
2168 {
2169 if ( subfont )
2170 {
2171 cff_index_done( &subfont->local_subrs_index );
2172 FT_FREE( subfont->local_subrs );
2173
2174 FT_FREE( subfont->blend.lastNDV );
2175 FT_FREE( subfont->blend.BV );
2176 FT_FREE( subfont->blend_stack );
2177 }
2178 }
2179
2180
2184 FT_Int face_index,
2185 CFF_Font font,
2186 CFF_Face face,
2187 FT_Bool pure_cff,
2188 FT_Bool cff2 )
2189 {
2190 static const FT_Frame_Field cff_header_fields[] =
2191 {
2192#undef FT_STRUCTURE
2193#define FT_STRUCTURE CFF_FontRec
2194
2195 FT_FRAME_START( 3 ),
2196 FT_FRAME_BYTE( version_major ),
2197 FT_FRAME_BYTE( version_minor ),
2198 FT_FRAME_BYTE( header_size ),
2200 };
2201
2203 FT_Memory memory = stream->memory;
2204 FT_ULong base_offset;
2205 CFF_FontRecDict dict;
2207 FT_UInt subfont_index;
2208
2209
2210 FT_ZERO( font );
2212
2213 dict = &font->top_font.font_dict;
2214 base_offset = FT_STREAM_POS();
2215
2216 font->library = library;
2217 font->stream = stream;
2218 font->memory = memory;
2219 font->cff2 = cff2;
2220 font->base_offset = base_offset;
2221
2222 /* read CFF font header */
2223 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2224 goto Exit;
2225
2226 if ( cff2 )
2227 {
2228 if ( font->version_major != 2 ||
2229 font->header_size < 5 )
2230 {
2231 FT_TRACE2(( " not a CFF2 font header\n" ));
2232 error = FT_THROW( Unknown_File_Format );
2233 goto Exit;
2234 }
2235
2236 if ( FT_READ_USHORT( font->top_dict_length ) )
2237 goto Exit;
2238 }
2239 else
2240 {
2241 FT_Byte absolute_offset;
2242
2243
2244 if ( FT_READ_BYTE( absolute_offset ) )
2245 goto Exit;
2246
2247 if ( font->version_major != 1 ||
2248 font->header_size < 4 ||
2249 absolute_offset > 4 )
2250 {
2251 FT_TRACE2(( " not a CFF font header\n" ));
2252 error = FT_THROW( Unknown_File_Format );
2253 goto Exit;
2254 }
2255 }
2256
2257 /* skip the rest of the header */
2258 if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2259 {
2260 /* For pure CFFs we have read only four bytes so far. Contrary to */
2261 /* other formats like SFNT those bytes doesn't define a signature; */
2262 /* it is thus possible that the font isn't a CFF at all. */
2263 if ( pure_cff )
2264 {
2265 FT_TRACE2(( " not a CFF file\n" ));
2266 error = FT_THROW( Unknown_File_Format );
2267 }
2268 goto Exit;
2269 }
2270
2271 if ( cff2 )
2272 {
2273 /* For CFF2, the top dict data immediately follow the header */
2274 /* and the length is stored in the header `offSize' field; */
2275 /* there is no index for it. */
2276 /* */
2277 /* Use the `font_dict_index' to save the current position */
2278 /* and length of data, but leave count at zero as an indicator. */
2279 FT_ZERO( &font->font_dict_index );
2280
2281 font->font_dict_index.data_offset = FT_STREAM_POS();
2282 font->font_dict_index.data_size = font->top_dict_length;
2283
2284 /* skip the top dict data for now, we will parse it later */
2285 if ( FT_STREAM_SKIP( font->top_dict_length ) )
2286 goto Exit;
2287
2288 /* next, read the global subrs index */
2289 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2290 stream, 1, cff2 ) ) )
2291 goto Exit;
2292 }
2293 else
2294 {
2295 /* for CFF, read the name, top dict, string and global subrs index */
2296 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2297 stream, 0, cff2 ) ) )
2298 {
2299 if ( pure_cff )
2300 {
2301 FT_TRACE2(( " not a CFF file\n" ));
2302 error = FT_THROW( Unknown_File_Format );
2303 }
2304 goto Exit;
2305 }
2306
2307 /* if we have an empty font name, */
2308 /* it must be the only font in the CFF */
2309 if ( font->name_index.count > 1 &&
2310 font->name_index.data_size < font->name_index.count )
2311 {
2312 /* for pure CFFs, we still haven't checked enough bytes */
2313 /* to be sure that it is a CFF at all */
2314 error = pure_cff ? FT_THROW( Unknown_File_Format )
2315 : FT_THROW( Invalid_File_Format );
2316 goto Exit;
2317 }
2318
2319 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2320 stream, 0, cff2 ) ) ||
2322 stream, 1, cff2 ) ) ||
2323 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2324 stream, 1, cff2 ) ) ||
2326 &font->strings,
2327 &font->string_pool,
2328 &font->string_pool_size ) ) )
2329 goto Exit;
2330
2331 /* there must be a Top DICT index entry for each name index entry */
2332 if ( font->name_index.count > font->font_dict_index.count )
2333 {
2334 FT_ERROR(( "cff_font_load:"
2335 " not enough entries in Top DICT index\n" ));
2336 error = FT_THROW( Invalid_File_Format );
2337 goto Exit;
2338 }
2339 }
2340
2341 font->num_strings = string_index.count;
2342
2343 if ( pure_cff )
2344 {
2345 /* well, we don't really forget the `disabled' fonts... */
2346 subfont_index = (FT_UInt)( face_index & 0xFFFF );
2347
2348 if ( face_index > 0 && subfont_index >= font->name_index.count )
2349 {
2350 FT_ERROR(( "cff_font_load:"
2351 " invalid subfont index for pure CFF font (%d)\n",
2352 subfont_index ));
2353 error = FT_THROW( Invalid_Argument );
2354 goto Exit;
2355 }
2356
2357 font->num_faces = font->name_index.count;
2358 }
2359 else
2360 {
2361 subfont_index = 0;
2362
2363 if ( font->name_index.count > 1 )
2364 {
2365 FT_ERROR(( "cff_font_load:"
2366 " invalid CFF font with multiple subfonts\n"
2367 " "
2368 " in SFNT wrapper\n" ));
2369 error = FT_THROW( Invalid_File_Format );
2370 goto Exit;
2371 }
2372 }
2373
2374 /* in case of a font format check, simply exit now */
2375 if ( face_index < 0 )
2376 goto Exit;
2377
2378 /* now, parse the top-level font dictionary */
2379 FT_TRACE4(( "parsing top-level\n" ));
2380 error = cff_subfont_load( &font->top_font,
2381 &font->font_dict_index,
2382 subfont_index,
2383 stream,
2384 base_offset,
2386 font,
2387 face );
2388 if ( error )
2389 goto Exit;
2390
2391 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2392 goto Exit;
2393
2394 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2395 if ( error )
2396 goto Exit;
2397
2398 /* now, check for a CID or CFF2 font */
2399 if ( dict->cid_registry != 0xFFFFU ||
2400 cff2 )
2401 {
2402 CFF_IndexRec fd_index;
2403 CFF_SubFont sub = NULL;
2404 FT_UInt idx;
2405
2406
2407 /* for CFF2, read the Variation Store if available; */
2408 /* this must follow the Top DICT parse and precede any Private DICT */
2409 error = cff_vstore_load( &font->vstore,
2410 stream,
2411 base_offset,
2412 dict->vstore_offset );
2413 if ( error )
2414 goto Exit;
2415
2416 /* this is a CID-keyed font, we must now allocate a table of */
2417 /* sub-fonts, then load each of them separately */
2418 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2419 goto Exit;
2420
2421 error = cff_index_init( &fd_index, stream, 0, cff2 );
2422 if ( error )
2423 goto Exit;
2424
2425 /* Font Dicts are not limited to 256 for CFF2. */
2426 /* TODO: support this for CFF2 */
2427 if ( fd_index.count > CFF_MAX_CID_FONTS )
2428 {
2429 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
2430 goto Fail_CID;
2431 }
2432
2433 /* allocate & read each font dict independently */
2434 font->num_subfonts = fd_index.count;
2435 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2436 goto Fail_CID;
2437
2438 /* set up pointer table */
2439 for ( idx = 0; idx < fd_index.count; idx++ )
2440 font->subfonts[idx] = sub + idx;
2441
2442 /* now load each subfont independently */
2443 for ( idx = 0; idx < fd_index.count; idx++ )
2444 {
2445 sub = font->subfonts[idx];
2446 FT_TRACE4(( "parsing subfont %u\n", idx ));
2447 error = cff_subfont_load( sub,
2448 &fd_index,
2449 idx,
2450 stream,
2451 base_offset,
2452 cff2 ? CFF2_CODE_FONTDICT
2454 font,
2455 face );
2456 if ( error )
2457 goto Fail_CID;
2458 }
2459
2460 /* now load the FD Select array; */
2461 /* CFF2 omits FDSelect if there is only one FD */
2462 if ( !cff2 || fd_index.count > 1 )
2463 error = CFF_Load_FD_Select( &font->fd_select,
2464 font->charstrings_index.count,
2465 stream,
2466 base_offset + dict->cid_fd_select_offset );
2467
2468 Fail_CID:
2469 cff_index_done( &fd_index );
2470
2471 if ( error )
2472 goto Exit;
2473 }
2474 else
2475 font->num_subfonts = 0;
2476
2477 /* read the charstrings index now */
2478 if ( dict->charstrings_offset == 0 )
2479 {
2480 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
2481 error = FT_THROW( Invalid_File_Format );
2482 goto Exit;
2483 }
2484
2485 font->num_glyphs = font->charstrings_index.count;
2486
2487 error = cff_index_get_pointers( &font->global_subrs_index,
2488 &font->global_subrs, NULL, NULL );
2489
2490 if ( error )
2491 goto Exit;
2492
2493 /* read the Charset and Encoding tables if available */
2494 if ( !cff2 && font->num_glyphs > 0 )
2495 {
2496 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2497
2498
2499 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2500 base_offset, dict->charset_offset, invert );
2501 if ( error )
2502 goto Exit;
2503
2504 /* CID-keyed CFFs don't have an encoding */
2505 if ( dict->cid_registry == 0xFFFFU )
2506 {
2507 error = cff_encoding_load( &font->encoding,
2508 &font->charset,
2509 font->num_glyphs,
2510 stream,
2511 base_offset,
2512 dict->encoding_offset );
2513 if ( error )
2514 goto Exit;
2515 }
2516 }
2517
2518 /* get the font name (/CIDFontName for CID-keyed fonts, */
2519 /* /FontName otherwise) */
2520 font->font_name = cff_index_get_name( font, subfont_index );
2521
2522 Exit:
2524
2525 return error;
2526 }
2527
2528
2529 FT_LOCAL_DEF( void )
2531 {
2532 FT_Memory memory = font->memory;
2533 FT_UInt idx;
2534
2535
2536 cff_index_done( &font->global_subrs_index );
2537 cff_index_done( &font->font_dict_index );
2538 cff_index_done( &font->name_index );
2539 cff_index_done( &font->charstrings_index );
2540
2541 /* release font dictionaries, but only if working with */
2542 /* a CID keyed CFF font or a CFF2 font */
2543 if ( font->num_subfonts > 0 )
2544 {
2545 for ( idx = 0; idx < font->num_subfonts; idx++ )
2546 cff_subfont_done( memory, font->subfonts[idx] );
2547
2548 /* the subfonts array has been allocated as a single block */
2549 FT_FREE( font->subfonts[0] );
2550 }
2551
2552 cff_encoding_done( &font->encoding );
2553 cff_charset_done( &font->charset, font->stream );
2554 cff_vstore_done( &font->vstore, memory );
2555
2556 cff_subfont_done( memory, &font->top_font );
2557
2558 CFF_Done_FD_Select( &font->fd_select, font->stream );
2559
2560 FT_FREE( font->font_info );
2561
2562 FT_FREE( font->font_name );
2563 FT_FREE( font->global_subrs );
2564 FT_FREE( font->strings );
2565 FT_FREE( font->string_pool );
2566
2567 if ( font->cf2_instance.finalizer )
2568 {
2569 font->cf2_instance.finalizer( font->cf2_instance.data );
2570 FT_FREE( font->cf2_instance.data );
2571 }
2572
2573 FT_FREE( font->font_extra );
2574 }
2575
2576
2577/* END */
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
FT_UInt sid
Definition: cffcmap.c:138
CFF_Charset charset
Definition: cffcmap.c:137
FT_Library library
Definition: cffdrivr.c:660
static FT_ULong cff_index_read_offset(CFF_Index idx, FT_Error *errorp)
Definition: cffload.c:210
static FT_Error cff_index_load_offsets(CFF_Index idx)
Definition: cffload.c:341
static FT_Error cff_charset_load(CFF_Charset charset, FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, FT_ULong offset, FT_Bool invert)
Definition: cffload.c:908
cff_get_standard_encoding(FT_UInt charcode)
Definition: cffload.c:191
static void cff_subfont_done(FT_Memory memory, CFF_SubFont subfont)
Definition: cffload.c:2166
cff_blend_clear(CFF_SubFont subFont)
Definition: cffload.c:1268
cff_blend_build_vector(CFF_Blend blend, FT_UInt vsindex, FT_UInt lenNDV, FT_Fixed *NDV)
Definition: cffload.c:1393
static void cff_charset_free_cids(CFF_Charset charset, FT_Memory memory)
Definition: cffload.c:884
static FT_Error cff_encoding_load(CFF_Encoding encoding, CFF_Charset charset, FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, FT_ULong offset)
Definition: cffload.c:1631
cff_charset_cid_to_gindex(CFF_Charset charset, FT_UInt cid)
Definition: cffload.c:870
cff_index_forget_element(CFF_Index idx, FT_Byte **pbytes)
Definition: cffload.c:602
static void cff_index_done(CFF_Index idx)
Definition: cffload.c:323
cff_font_done(CFF_Font font)
Definition: cffload.c:2530
static const FT_UShort cff_expertsubset_charset[87]
Definition: cffload.c:100
static const FT_UShort cff_expert_encoding[256]
Definition: cffload.c:151
#define FT_fdot14ToFixed(x)
Definition: cffload.c:1123
#define FT_FIXED_ONE
Definition: cffload.c:37
static void CFF_Done_FD_Select(CFF_FDSelect fdselect, FT_Stream stream)
Definition: cffload.c:692
static FT_Error cff_subfont_load(CFF_SubFont subfont, CFF_Index idx, FT_UInt font_index, FT_Stream stream, FT_ULong base_offset, FT_UInt code, CFF_Font font, CFF_Face face)
Definition: cffload.c:1985
cff_fd_select_get(CFF_FDSelect fdselect, FT_UInt glyph_index)
Definition: cffload.c:756
static FT_Error cff_charset_compute_cids(CFF_Charset charset, FT_UInt num_glyphs, FT_Memory memory)
Definition: cffload.c:833
static const FT_UShort cff_expert_charset[166]
Definition: cffload.c:75
cff_blend_doBlend(CFF_SubFont subFont, CFF_Parser parser, FT_UInt numBlends)
Definition: cffload.c:1286
static void cff_vstore_done(CFF_VStoreRec *vstore, FT_Memory memory)
Definition: cffload.c:1098
static FT_Error cff_index_init(CFF_Index idx, FT_Stream stream, FT_Bool load, FT_Bool cff2)
Definition: cffload.c:234
static const FT_UShort cff_standard_encoding[256]
Definition: cffload.c:115
cff_index_access_element(CFF_Index idx, FT_UInt element, FT_Byte **pbytes, FT_ULong *pbyte_len)
Definition: cffload.c:504
cff_index_get_string(CFF_Font font, FT_UInt element)
Definition: cffload.c:652
cff_font_load(FT_Library library, FT_Stream stream, FT_Int face_index, CFF_Font font, CFF_Face face, FT_Bool pure_cff, FT_Bool cff2)
Definition: cffload.c:2182
cff_load_private_dict(CFF_Font font, CFF_SubFont subfont, FT_UInt lenNDV, FT_Fixed *NDV)
Definition: cffload.c:1878
cff_index_get_sid_string(CFF_Font font, FT_UInt sid)
Definition: cffload.c:662
static void cff_encoding_done(CFF_Encoding encoding)
Definition: cffload.c:1622
cff_blend_check_vector(CFF_Blend blend, FT_UInt vsindex, FT_UInt lenNDV, FT_Fixed *NDV)
Definition: cffload.c:1567
static const FT_UShort cff_isoadobe_charset[229]
Definition: cffload.c:42
static FT_Error CFF_Load_FD_Select(CFF_FDSelect fdselect, FT_UInt num_glyphs, FT_Stream stream, FT_ULong offset)
Definition: cffload.c:705
static FT_Error cff_vstore_load(CFF_VStoreRec *vstore, FT_Stream stream, FT_ULong base_offset, FT_ULong offset)
Definition: cffload.c:1127
static void cff_charset_done(CFF_Charset charset, FT_Stream stream)
Definition: cffload.c:893
cff_index_get_name(CFF_Font font, FT_UInt element)
Definition: cffload.c:617
static FT_Error cff_index_get_pointers(CFF_Index idx, FT_Byte ***table, FT_Byte **pool, FT_ULong *pool_size)
Definition: cffload.c:405
FT_BEGIN_HEADER typedef TT_Face CFF_Face
Definition: cffotypes.h:32
cff_parser_init(CFF_Parser parser, FT_UInt code, void *object, FT_Library library, FT_UInt stackSize, FT_UShort num_designs, FT_UShort num_axes)
Definition: cffparse.c:41
cff_parse_num(CFF_Parser parser, FT_Byte **d)
Definition: cffparse.c:522
cff_parser_done(CFF_Parser parser)
Definition: cffparse.c:97
cff_parser_run(CFF_Parser parser, FT_Byte *start, FT_Byte *limit)
Definition: cffparse.c:1194
#define CFF2_DEFAULT_STACK
Definition: cffparse.h:42
#define CFF_CODE_TOPDICT
Definition: cffparse.h:44
#define CFF2_CODE_PRIVATE
Definition: cffparse.h:48
#define CFF_CODE_PRIVATE
Definition: cffparse.h:45
#define CFF2_CODE_FONTDICT
Definition: cffparse.h:47
#define CFF_MAX_STACK_DEPTH
Definition: cffparse.h:32
#define CFF2_CODE_TOPDICT
Definition: cffparse.h:46
FT_BEGIN_HEADER struct CFF_IndexRec_ * CFF_Index
FT_BEGIN_HEADER struct CFF_IndexRec_ CFF_IndexRec
#define CFF_MAX_CID_FONTS
Definition: cfftypes.h:334
#define FT_LOCAL_DEF(x)
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
switch(r->id)
Definition: btrfs.c:3046
size_t const new_size
Definition: expand.cpp:66
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:607
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:508
return FT_Err_Ok
Definition: ftbbox.c:526
#define FT_TRACE0(varformat)
Definition: ftdebug.h:187
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE2(varformat)
Definition: ftdebug.h:189
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
#define FT_REALLOC(ptr, cursz, newsz)
Definition: ftmemory.h:314
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:341
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:43
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:311
#define FT_FREE(ptr)
Definition: ftmemory.h:337
#define FT_OFFSET(base, count)
Definition: ftmemory.h:66
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:253
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:237
#define FT_FACE(x)
Definition: ftobjs.h:597
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:601
#define ft_memcmp
Definition: ftstdlib.h:81
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:548
#define FT_READ_USHORT(var)
Definition: ftstream.h:339
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:562
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:525
#define FT_READ_ULONG(var)
Definition: ftstream.h:343
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:244
#define FT_STREAM_POS()
Definition: ftstream.h:522
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:186
#define FT_READ_BYTE(var)
Definition: ftstream.h:336
#define FT_FRAME_EXIT()
Definition: ftstream.h:553
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:556
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:544
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:529
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:533
#define FT_FRAME_START(size)
Definition: ftstream.h:117
#define FT_PEEK_UOFF3(p)
Definition: ftstream.h:203
#define FT_PEEK_ULONG(p)
Definition: ftstream.h:194
#define FT_READ_SHORT(var)
Definition: ftstream.h:338
#define FT_GET_USHORT()
Definition: ftstream.h:311
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:64
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:336
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
signed long FT_Long
Definition: fttypes.h:242
#define FT_ERR(e)
Definition: fttypes.h:599
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:591
signed int FT_Int
Definition: fttypes.h:220
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLboolean invert
Definition: gl.h:1949
GLdouble n
Definition: glext.h:7729
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint coords
Definition: glext.h:7368
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLint limit
Definition: glext.h:10326
const GLint * first
Definition: glext.h:5794
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
@ extra
Definition: id3.c:95
static TfClientId cid
signed short FT_Int16
Definition: integer-types.h:79
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
#define for
Definition: utility.h:88
static char memory[1024 *256]
Definition: process.c:122
static vector_t * vs
Definition: server.c:146
int k
Definition: mpi.c:3369
int load
Definition: msacm.c:1365
struct @1789::@1790 driver
Definition: mk_font.cpp:20
FT_BEGIN_HEADER struct PS_DriverRec_ * PS_Driver
struct PSAux_ServiceRec_ * PSAux_Service
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
static int fd
Definition: io.c:51
weight
Definition: sortkey.c:157
static void Exit(void)
Definition: sock.c:1330
FT_Fixed startCoord
Definition: cfftypes.h:129
FT_Fixed peakCoord
Definition: cfftypes.h:130
FT_Fixed endCoord
Definition: cfftypes.h:131
FT_UInt lenBV
Definition: cfftypes.h:178
FT_Fixed * lastNDV
Definition: cfftypes.h:177
FT_Int32 * BV
Definition: cfftypes.h:179
FT_UShort * sids
Definition: cfftypes.h:102
FT_UInt num_glyphs
Definition: cfftypes.h:106
FT_UShort * cids
Definition: cfftypes.h:103
FT_UInt format
Definition: cfftypes.h:99
FT_ULong offset
Definition: cfftypes.h:100
FT_UInt max_cid
Definition: cfftypes.h:105
FT_UShort sids[256]
Definition: cfftypes.h:90
FT_UShort codes[256]
Definition: cfftypes.h:91
FT_UInt count
Definition: cfftypes.h:89
FT_ULong offset
Definition: cfftypes.h:87
FT_UInt format
Definition: cfftypes.h:86
FT_UInt cache_count
Definition: cfftypes.h:294
FT_Byte * data
Definition: cfftypes.h:289
FT_Byte format
Definition: cfftypes.h:285
FT_UInt range_count
Definition: cfftypes.h:286
FT_UInt data_size
Definition: cfftypes.h:290
FT_ULong cid_fd_array_offset
Definition: cfftypes.h:223
FT_ULong charset_offset
Definition: cfftypes.h:205
FT_ULong cid_fd_select_offset
Definition: cfftypes.h:224
FT_UInt cid_registry
Definition: cfftypes.h:214
FT_ULong charstrings_offset
Definition: cfftypes.h:207
FT_ULong encoding_offset
Definition: cfftypes.h:206
FT_ULong vstore_offset
Definition: cfftypes.h:234
FT_Byte num_blue_values
Definition: cfftypes.h:246
CFF_SubFont subfont
Definition: cfftypes.h:278
FT_Int lenIV
Definition: cfftypes.h:268
FT_Long initial_random_seed
Definition: cfftypes.h:271
FT_Fixed blue_scale
Definition: cfftypes.h:256
FT_Pos blue_fuzz
Definition: cfftypes.h:258
FT_Fixed expansion_factor
Definition: cfftypes.h:270
FT_Pos blue_shift
Definition: cfftypes.h:257
FT_ULong local_subrs_offset
Definition: cfftypes.h:272
FT_UInt lenNDV
Definition: cfftypes.h:309
FT_Byte ** local_subrs
Definition: cfftypes.h:326
FT_Byte * blend_stack
Definition: cfftypes.h:320
CFF_IndexRec local_subrs_index
Definition: cfftypes.h:325
FT_UInt32 random
Definition: cfftypes.h:329
CFF_PrivateRec private_dict
Definition: cfftypes.h:305
CFF_BlendRec blend
Definition: cfftypes.h:308
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:304
FT_UInt dataCount
Definition: cfftypes.h:145
CFF_VarRegion * varRegionList
Definition: cfftypes.h:150
CFF_VarData * varData
Definition: cfftypes.h:146
FT_UShort axisCount
Definition: cfftypes.h:148
FT_UInt regionCount
Definition: cfftypes.h:149
FT_UInt * regionIndices
Definition: cfftypes.h:121
FT_UInt regionIdxCount
Definition: cfftypes.h:120
CFF_AxisCoords * axisList
Definition: cfftypes.h:138
FT_UInt32(* cff_random)(FT_UInt32 r)
Definition: psaux.h:1358
Definition: inflate.c:139
Definition: format.c:58
Definition: name.c:39
Definition: import.c:81
enum parser_state stack[4]
Definition: inffile.c:91
Definition: parse.h:23
unsigned int size
Definition: parse.h:27
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList