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