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
101 static const FT_UShort cff_expertsubset_charset[87] =
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
116 static const FT_UShort cff_standard_encoding[256] =
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
191 FT_LOCAL_DEF( FT_UShort )
192 cff_get_standard_encoding( FT_UInt charcode )
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
211 cff_index_read_offset( CFF_Index idx,
212 FT_Error *errorp )
213 {
214 FT_Error error;
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
235 cff_index_init( CFF_Index idx,
236 FT_Stream stream,
237 FT_Bool load,
238 FT_Bool cff2 )
239 {
240 FT_Error error;
241 FT_Memory memory = stream->memory;
242 FT_UInt count;
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;
266 FT_ULong size;
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
289 size = cff_index_read_offset( idx, &error );
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
324 cff_index_done( CFF_Index idx )
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
342 cff_index_load_offsets( CFF_Index idx )
343 {
344 FT_Error error = FT_Err_Ok;
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
391 FT_FRAME_EXIT();
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
406 cff_index_get_pointers( CFF_Index idx,
407 FT_Byte*** table,
408 FT_Byte** pool,
409 FT_ULong* pool_size )
410 {
411 FT_Error error = FT_Err_Ok;
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 {
423 error = cff_index_load_offsets( idx );
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
497 FT_LOCAL_DEF( FT_Error )
498 cff_index_access_element( CFF_Index idx,
499 FT_UInt element,
500 FT_Byte** pbytes,
501 FT_ULong* pbyte_len )
502 {
503 FT_Error error = FT_Err_Ok;
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 )
596 cff_index_forget_element( CFF_Index idx,
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 */
610 FT_LOCAL_DEF( FT_String* )
611 cff_index_get_name( CFF_Font font,
612 FT_UInt element )
613 {
614 CFF_Index idx = &font->name_index;
615 FT_Memory memory;
616 FT_Byte* bytes;
617 FT_ULong byte_len;
618 FT_Error error;
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
627 error = cff_index_access_element( idx, element, &bytes, &byte_len );
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 }
637 cff_index_forget_element( idx, &bytes );
638
639 Exit:
640 return name;
641 }
642
643
644 /* get an entry from String INDEX */
645 FT_LOCAL_DEF( FT_String* )
646 cff_index_get_string( CFF_Font font,
647 FT_UInt element )
648 {
649 return ( element < font->num_strings )
650 ? (FT_String*)font->strings[element]
651 : NULL;
652 }
653
654
655 FT_LOCAL_DEF( FT_String* )
656 cff_index_get_sid_string( CFF_Font font,
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
686 CFF_Done_FD_Select( CFF_FDSelect fdselect,
687 FT_Stream stream )
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
699 CFF_Load_FD_Select( CFF_FDSelect fdselect,
700 FT_UInt num_glyphs,
701 FT_Stream stream,
702 FT_ULong offset )
703 {
704 FT_Error error;
705 FT_Byte format;
706 FT_UInt num_ranges;
707
708
709 /* read format */
710 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( 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
749 FT_LOCAL_DEF( FT_Byte )
750 cff_fd_select_get( CFF_FDSelect fdselect,
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;
781 FT_UInt first, limit;
782
783
784 first = FT_NEXT_USHORT( p );
785 do
786 {
787 if ( glyph_index < first )
788 break;
789
790 fd2 = *p++;
791 limit = FT_NEXT_USHORT( 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
827 cff_charset_compute_cids( CFF_Charset charset,
828 FT_UInt num_glyphs,
829 FT_Memory memory )
830 {
831 FT_Error error = FT_Err_Ok;
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-- )
853 charset->cids[charset->sids[j]] = (FT_UShort)j;
854
855 charset->max_cid = max_cid;
856 charset->num_glyphs = num_glyphs;
857
858 Exit:
859 return error;
860 }
861
862
863 FT_LOCAL_DEF( FT_UInt )
864 cff_charset_cid_to_gindex( CFF_Charset charset,
865 FT_UInt cid )
866 {
867 FT_UInt result = 0;
868
869
870 if ( cid <= charset->max_cid )
871 result = charset->cids[cid];
872
873 return result;
874 }
875
876
877 static void
878 cff_charset_free_cids( CFF_Charset charset,
879 FT_Memory memory )
880 {
881 FT_FREE( charset->cids );
882 charset->max_cid = 0;
883 }
884
885
886 static void
887 cff_charset_done( CFF_Charset charset,
888 FT_Stream stream )
889 {
890 FT_Memory memory = stream->memory;
891
892
893 cff_charset_free_cids( charset, memory );
894
895 FT_FREE( charset->sids );
896 charset->format = 0;
897 charset->offset = 0;
898 }
899
900
901 static FT_Error
902 cff_charset_load( CFF_Charset charset,
903 FT_UInt num_glyphs,
904 FT_Stream stream,
905 FT_ULong base_offset,
906 FT_ULong offset,
907 FT_Bool invert )
908 {
909 FT_Memory memory = stream->memory;
910 FT_Error error = FT_Err_Ok;
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 ) ||
925 FT_READ_BYTE( charset->format ) )
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++ )
944 charset->sids[j] = FT_GET_USHORT();
945
946 FT_FRAME_EXIT();
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. */
1026 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
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. */
1044 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
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. */
1062 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
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
1092 cff_vstore_done( CFF_VStoreRec* vstore,
1093 FT_Memory memory )
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
1121 cff_vstore_load( CFF_VStoreRec* vstore,
1122 FT_Stream stream,
1123 FT_ULong base_offset,
1124 FT_ULong 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;
1137 FT_UInt format;
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 )
1262 cff_blend_clear( CFF_SubFont subFont )
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. */
1279 FT_LOCAL_DEF( FT_Error )
1280 cff_blend_doBlend( CFF_SubFont subFont,
1281 CFF_Parser parser,
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,...). */
1386 FT_LOCAL_DEF( FT_Error )
1387 cff_blend_build_vector( CFF_Blend blend,
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. */
1553 FT_LOCAL_DEF( FT_Bool )
1554 cff_blend_check_vector( CFF_Blend blend,
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
1577 FT_LOCAL_DEF( FT_Error )
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
1609 cff_encoding_done( CFF_Encoding encoding )
1610 {
1611 encoding->format = 0;
1612 encoding->offset = 0;
1613 encoding->count = 0;
1614 }
1615
1616
1617 static FT_Error
1618 cff_encoding_load( CFF_Encoding encoding,
1619 CFF_Charset charset,
1620 FT_UInt num_glyphs,
1621 FT_Stream stream,
1622 FT_ULong base_offset,
1623 FT_ULong offset )
1624 {
1625 FT_Error error = FT_Err_Ok;
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. */
1806 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1807 goto Populate;
1808
1809 case 1:
1810 /* First, copy the code to SID mapping. */
1811 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
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 )
1831 gid = cff_charset_cid_to_gindex( charset, 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. */
1864 FT_LOCAL_DEF( FT_Error )
1865 cff_load_private_dict( CFF_Font font,
1866 CFF_SubFont subfont,
1867 FT_UInt lenNDV,
1868 FT_Fixed* NDV )
1869 {
1870 FT_Error error = FT_Err_Ok;
1871 CFF_ParserRec parser;
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,
1905 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
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" ));
1918 error = cff_parser_run( &parser,
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 )
1932 priv->initial_random_seed = -priv->initial_random_seed;
1933 else if ( priv->initial_random_seed == 0 )
1934 priv->initial_random_seed = 987654321;
1935
1936 /* some sanitizing to avoid overflows later on; */
1937 /* the upper limits are ad-hoc values */
1938 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
1939 {
1940 FT_TRACE2(( "cff_load_private_dict:"
1941 " setting unlikely BlueShift value %d to default (7)\n",
1942 priv->blue_shift ));
1943 priv->blue_shift = 7;
1944 }
1945
1946 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
1947 {
1948 FT_TRACE2(( "cff_load_private_dict:"
1949 " setting unlikely BlueFuzz value %d to default (1)\n",
1950 priv->blue_fuzz ));
1951 priv->blue_fuzz = 1;
1952 }
1953
1954 Exit:
1955 /* clean up */
1956 cff_blend_clear( subfont ); /* clear blend stack */
1957 cff_parser_done( &parser ); /* free parser stack */
1958
1959 Exit2:
1960 /* no clean up (parser not initialized) */
1961 return error;
1962 }
1963
1964
1965 /* There are 3 ways to call this function, distinguished by code. */
1966 /* */
1967 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
1968 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */
1969 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */
1970
1971 static FT_Error
1972 cff_subfont_load( CFF_SubFont subfont,
1973 CFF_Index idx,
1974 FT_UInt font_index,
1975 FT_Stream stream,
1976 FT_ULong base_offset,
1977 FT_UInt code,
1978 CFF_Font font,
1979 CFF_Face face )
1980 {
1981 FT_Error error;
1982 CFF_ParserRec parser;
1983 FT_Byte* dict = NULL;
1984 FT_ULong dict_len;
1985 CFF_FontRecDict top = &subfont->font_dict;
1986 CFF_Private priv = &subfont->private_dict;
1987
1988 PSAux_Service psaux = (PSAux_Service)face->psaux;
1989
1990 FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT ||
1991 code == CFF2_CODE_FONTDICT );
1992 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK
1993 : CFF_MAX_STACK_DEPTH;
1994
1995
1996 /* Note: We use default stack size for CFF2 Font DICT because */
1997 /* Top and Font DICTs are not allowed to have blend operators. */
1998 error = cff_parser_init( &parser,
1999 code,
2000 &subfont->font_dict,
2001 font->library,
2002 stackSize,
2003 0,
2004 0 );
2005 if ( error )
2006 goto Exit;
2007
2008 /* set defaults */
2009 FT_ZERO( top );
2010
2011 top->underline_position = -( 100L << 16 );
2012 top->underline_thickness = 50L << 16;
2013 top->charstring_type = 2;
2014 top->font_matrix.xx = 0x10000L;
2015 top->font_matrix.yy = 0x10000L;
2016 top->cid_count = 8720;
2017
2018 /* we use the implementation specific SID value 0xFFFF to indicate */
2019 /* missing entries */
2020 top->version = 0xFFFFU;
2021 top->notice = 0xFFFFU;
2022 top->copyright = 0xFFFFU;
2023 top->full_name = 0xFFFFU;
2024 top->family_name = 0xFFFFU;
2025 top->weight = 0xFFFFU;
2026 top->embedded_postscript = 0xFFFFU;
2027
2028 top->cid_registry = 0xFFFFU;
2029 top->cid_ordering = 0xFFFFU;
2030 top->cid_font_name = 0xFFFFU;
2031
2032 /* set default stack size */
2033 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48;
2034
2035 if ( idx->count ) /* count is nonzero for a real index */
2036 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2037 else
2038 {
2039 /* CFF2 has a fake top dict index; */
2040 /* simulate `cff_index_access_element' */
2041
2042 /* Note: macros implicitly use `stream' and set `error' */
2043 if ( FT_STREAM_SEEK( idx->data_offset ) ||
2044 FT_FRAME_EXTRACT( idx->data_size, dict ) )
2045 goto Exit;
2046
2047 dict_len = idx->data_size;
2048 }
2049
2050 if ( !error )
2051 {
2052 FT_TRACE4(( " top dictionary:\n" ));
2053 error = cff_parser_run( &parser, dict, dict + dict_len );
2054 }
2055
2056 /* clean up regardless of error */
2057 if ( idx->count )
2058 cff_index_forget_element( idx, &dict );
2059 else
2060 FT_FRAME_RELEASE( dict );
2061
2062 if ( error )
2063 goto Exit;
2064
2065 /* if it is a CID font, we stop there */
2066 if ( top->cid_registry != 0xFFFFU )
2067 goto Exit;
2068
2069 /* Parse the private dictionary, if any. */
2070 /* */
2071 /* CFF2 does not have a private dictionary in the Top DICT */
2072 /* but may have one in a Font DICT. We need to parse */
2073 /* the latter here in order to load any local subrs. */
2074 error = cff_load_private_dict( font, subfont, 0, 0 );
2075 if ( error )
2076 goto Exit;
2077
2078 if ( !cff2 )
2079 {
2080 /*
2081 * Initialize the random number generator.
2082 *
2083 * . If we have a face-specific seed, use it.
2084 * If non-zero, update it to a positive value.
2085 *
2086 * . Otherwise, use the seed from the CFF driver.
2087 * If non-zero, update it to a positive value.
2088 *
2089 * . If the random value is zero, use the seed given by the subfont's
2090 * `initialRandomSeed' value.
2091 *
2092 */
2093 if ( face->root.internal->random_seed == -1 )
2094 {
2095 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
2096
2097
2098 subfont->random = (FT_UInt32)driver->random_seed;
2099 if ( driver->random_seed )
2100 {
2101 do
2102 {
2103 driver->random_seed =
2104 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2105
2106 } while ( driver->random_seed < 0 );
2107 }
2108 }
2109 else
2110 {
2111 subfont->random = (FT_UInt32)face->root.internal->random_seed;
2112 if ( face->root.internal->random_seed )
2113 {
2114 do
2115 {
2116 face->root.internal->random_seed =
2117 (FT_Int32)psaux->cff_random(
2118 (FT_UInt32)face->root.internal->random_seed );
2119
2120 } while ( face->root.internal->random_seed < 0 );
2121 }
2122 }
2123
2124 if ( !subfont->random )
2125 subfont->random = (FT_UInt32)priv->initial_random_seed;
2126 }
2127
2128 /* read the local subrs, if any */
2129 if ( priv->local_subrs_offset )
2130 {
2131 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2132 priv->local_subrs_offset ) )
2133 goto Exit;
2134
2135 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2136 if ( error )
2137 goto Exit;
2138
2139 error = cff_index_get_pointers( &subfont->local_subrs_index,
2140 &subfont->local_subrs, NULL, NULL );
2141 if ( error )
2142 goto Exit;
2143 }
2144
2145 Exit:
2146 cff_parser_done( &parser ); /* free parser stack */
2147
2148 return error;
2149 }
2150
2151
2152 static void
2153 cff_subfont_done( FT_Memory memory,
2154 CFF_SubFont subfont )
2155 {
2156 if ( subfont )
2157 {
2158 cff_index_done( &subfont->local_subrs_index );
2159 FT_FREE( subfont->local_subrs );
2160
2161 FT_FREE( subfont->blend.lastNDV );
2162 FT_FREE( subfont->blend.BV );
2163 FT_FREE( subfont->blend_stack );
2164 }
2165 }
2166
2167
2168 FT_LOCAL_DEF( FT_Error )
2169 cff_font_load( FT_Library library,
2170 FT_Stream stream,
2171 FT_Int face_index,
2172 CFF_Font font,
2173 CFF_Face face,
2174 FT_Bool pure_cff,
2175 FT_Bool cff2 )
2176 {
2177 static const FT_Frame_Field cff_header_fields[] =
2178 {
2179#undef FT_STRUCTURE
2180#define FT_STRUCTURE CFF_FontRec
2181
2182 FT_FRAME_START( 3 ),
2183 FT_FRAME_BYTE( version_major ),
2184 FT_FRAME_BYTE( version_minor ),
2185 FT_FRAME_BYTE( header_size ),
2186 FT_FRAME_END
2187 };
2188
2189 FT_Error error;
2190 FT_Memory memory = stream->memory;
2191 FT_ULong base_offset;
2192 CFF_FontRecDict dict;
2193 CFF_IndexRec string_index;
2194 FT_UInt subfont_index;
2195
2196
2197 FT_ZERO( font );
2198 FT_ZERO( &string_index );
2199
2200 dict = &font->top_font.font_dict;
2201 base_offset = FT_STREAM_POS();
2202
2203 font->library = library;
2204 font->stream = stream;
2205 font->memory = memory;
2206 font->cff2 = cff2;
2207 font->base_offset = base_offset;
2208
2209 /* read CFF font header */
2210 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2211 goto Exit;
2212
2213 if ( cff2 )
2214 {
2215 if ( font->version_major != 2 ||
2216 font->header_size < 5 )
2217 {
2218 FT_TRACE2(( " not a CFF2 font header\n" ));
2219 error = FT_THROW( Unknown_File_Format );
2220 goto Exit;
2221 }
2222
2223 if ( FT_READ_USHORT( font->top_dict_length ) )
2224 goto Exit;
2225 }
2226 else
2227 {
2228 FT_Byte absolute_offset;
2229
2230
2231 if ( FT_READ_BYTE( absolute_offset ) )
2232 goto Exit;
2233
2234 if ( font->version_major != 1 ||
2235 font->header_size < 4 ||
2236 absolute_offset > 4 )
2237 {
2238 FT_TRACE2(( " not a CFF font header\n" ));
2239 error = FT_THROW( Unknown_File_Format );
2240 goto Exit;
2241 }
2242 }
2243
2244 /* skip the rest of the header */
2245 if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2246 {
2247 /* For pure CFFs we have read only four bytes so far. Contrary to */
2248 /* other formats like SFNT those bytes doesn't define a signature; */
2249 /* it is thus possible that the font isn't a CFF at all. */
2250 if ( pure_cff )
2251 {
2252 FT_TRACE2(( " not a CFF file\n" ));
2253 error = FT_THROW( Unknown_File_Format );
2254 }
2255 goto Exit;
2256 }
2257
2258 if ( cff2 )
2259 {
2260 /* For CFF2, the top dict data immediately follow the header */
2261 /* and the length is stored in the header `offSize' field; */
2262 /* there is no index for it. */
2263 /* */
2264 /* Use the `font_dict_index' to save the current position */
2265 /* and length of data, but leave count at zero as an indicator. */
2266 FT_ZERO( &font->font_dict_index );
2267
2268 font->font_dict_index.data_offset = FT_STREAM_POS();
2269 font->font_dict_index.data_size = font->top_dict_length;
2270
2271 /* skip the top dict data for now, we will parse it later */
2272 if ( FT_STREAM_SKIP( font->top_dict_length ) )
2273 goto Exit;
2274
2275 /* next, read the global subrs index */
2276 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2277 stream, 1, cff2 ) ) )
2278 goto Exit;
2279 }
2280 else
2281 {
2282 /* for CFF, read the name, top dict, string and global subrs index */
2283 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2284 stream, 0, cff2 ) ) )
2285 {
2286 if ( pure_cff )
2287 {
2288 FT_TRACE2(( " not a CFF file\n" ));
2289 error = FT_THROW( Unknown_File_Format );
2290 }
2291 goto Exit;
2292 }
2293
2294 /* if we have an empty font name, */
2295 /* it must be the only font in the CFF */
2296 if ( font->name_index.count > 1 &&
2297 font->name_index.data_size < font->name_index.count )
2298 {
2299 /* for pure CFFs, we still haven't checked enough bytes */
2300 /* to be sure that it is a CFF at all */
2301 error = pure_cff ? FT_THROW( Unknown_File_Format )
2302 : FT_THROW( Invalid_File_Format );
2303 goto Exit;
2304 }
2305
2306 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2307 stream, 0, cff2 ) ) ||
2308 FT_SET_ERROR( cff_index_init( &string_index,
2309 stream, 1, cff2 ) ) ||
2310 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2311 stream, 1, cff2 ) ) ||
2312 FT_SET_ERROR( cff_index_get_pointers( &string_index,
2313 &font->strings,
2314 &font->string_pool,
2315 &font->string_pool_size ) ) )
2316 goto Exit;
2317
2318 /* there must be a Top DICT index entry for each name index entry */
2319 if ( font->name_index.count > font->font_dict_index.count )
2320 {
2321 FT_ERROR(( "cff_font_load:"
2322 " not enough entries in Top DICT index\n" ));
2323 error = FT_THROW( Invalid_File_Format );
2324 goto Exit;
2325 }
2326 }
2327
2328 font->num_strings = string_index.count;
2329
2330 if ( pure_cff )
2331 {
2332 /* well, we don't really forget the `disabled' fonts... */
2333 subfont_index = (FT_UInt)( face_index & 0xFFFF );
2334
2335 if ( face_index > 0 && subfont_index >= font->name_index.count )
2336 {
2337 FT_ERROR(( "cff_font_load:"
2338 " invalid subfont index for pure CFF font (%d)\n",
2339 subfont_index ));
2340 error = FT_THROW( Invalid_Argument );
2341 goto Exit;
2342 }
2343
2344 font->num_faces = font->name_index.count;
2345 }
2346 else
2347 {
2348 subfont_index = 0;
2349
2350 if ( font->name_index.count > 1 )
2351 {
2352 FT_ERROR(( "cff_font_load:"
2353 " invalid CFF font with multiple subfonts\n"
2354 " "
2355 " in SFNT wrapper\n" ));
2356 error = FT_THROW( Invalid_File_Format );
2357 goto Exit;
2358 }
2359 }
2360
2361 /* in case of a font format check, simply exit now */
2362 if ( face_index < 0 )
2363 goto Exit;
2364
2365 /* now, parse the top-level font dictionary */
2366 FT_TRACE4(( "parsing top-level\n" ));
2367 error = cff_subfont_load( &font->top_font,
2368 &font->font_dict_index,
2369 subfont_index,
2370 stream,
2371 base_offset,
2372 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
2373 font,
2374 face );
2375 if ( error )
2376 goto Exit;
2377
2378 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2379 goto Exit;
2380
2381 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2382 if ( error )
2383 goto Exit;
2384
2385 /* now, check for a CID or CFF2 font */
2386 if ( dict->cid_registry != 0xFFFFU ||
2387 cff2 )
2388 {
2389 CFF_IndexRec fd_index;
2390 CFF_SubFont sub = NULL;
2391 FT_UInt idx;
2392
2393
2394 /* for CFF2, read the Variation Store if available; */
2395 /* this must follow the Top DICT parse and precede any Private DICT */
2396 error = cff_vstore_load( &font->vstore,
2397 stream,
2398 base_offset,
2399 dict->vstore_offset );
2400 if ( error )
2401 goto Exit;
2402
2403 /* this is a CID-keyed font, we must now allocate a table of */
2404 /* sub-fonts, then load each of them separately */
2405 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2406 goto Exit;
2407
2408 error = cff_index_init( &fd_index, stream, 0, cff2 );
2409 if ( error )
2410 goto Exit;
2411
2412 /* Font Dicts are not limited to 256 for CFF2. */
2413 /* TODO: support this for CFF2 */
2414 if ( fd_index.count > CFF_MAX_CID_FONTS )
2415 {
2416 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
2417 goto Fail_CID;
2418 }
2419
2420 /* allocate & read each font dict independently */
2421 font->num_subfonts = fd_index.count;
2422 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2423 goto Fail_CID;
2424
2425 /* set up pointer table */
2426 for ( idx = 0; idx < fd_index.count; idx++ )
2427 font->subfonts[idx] = sub + idx;
2428
2429 /* now load each subfont independently */
2430 for ( idx = 0; idx < fd_index.count; idx++ )
2431 {
2432 sub = font->subfonts[idx];
2433 FT_TRACE4(( "parsing subfont %u\n", idx ));
2434 error = cff_subfont_load( sub,
2435 &fd_index,
2436 idx,
2437 stream,
2438 base_offset,
2439 cff2 ? CFF2_CODE_FONTDICT
2440 : CFF_CODE_TOPDICT,
2441 font,
2442 face );
2443 if ( error )
2444 goto Fail_CID;
2445 }
2446
2447 /* now load the FD Select array; */
2448 /* CFF2 omits FDSelect if there is only one FD */
2449 if ( !cff2 || fd_index.count > 1 )
2450 error = CFF_Load_FD_Select( &font->fd_select,
2451 font->charstrings_index.count,
2452 stream,
2453 base_offset + dict->cid_fd_select_offset );
2454
2455 Fail_CID:
2456 cff_index_done( &fd_index );
2457
2458 if ( error )
2459 goto Exit;
2460 }
2461 else
2462 font->num_subfonts = 0;
2463
2464 /* read the charstrings index now */
2465 if ( dict->charstrings_offset == 0 )
2466 {
2467 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
2468 error = FT_THROW( Invalid_File_Format );
2469 goto Exit;
2470 }
2471
2472 font->num_glyphs = font->charstrings_index.count;
2473
2474 error = cff_index_get_pointers( &font->global_subrs_index,
2475 &font->global_subrs, NULL, NULL );
2476
2477 if ( error )
2478 goto Exit;
2479
2480 /* read the Charset and Encoding tables if available */
2481 if ( !cff2 && font->num_glyphs > 0 )
2482 {
2483 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2484
2485
2486 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2487 base_offset, dict->charset_offset, invert );
2488 if ( error )
2489 goto Exit;
2490
2491 /* CID-keyed CFFs don't have an encoding */
2492 if ( dict->cid_registry == 0xFFFFU )
2493 {
2494 error = cff_encoding_load( &font->encoding,
2495 &font->charset,
2496 font->num_glyphs,
2497 stream,
2498 base_offset,
2499 dict->encoding_offset );
2500 if ( error )
2501 goto Exit;
2502 }
2503 }
2504
2505 /* get the font name (/CIDFontName for CID-keyed fonts, */
2506 /* /FontName otherwise) */
2507 font->font_name = cff_index_get_name( font, subfont_index );
2508
2509 Exit:
2510 cff_index_done( &string_index );
2511
2512 return error;
2513 }
2514
2515
2516 FT_LOCAL_DEF( void )
2517 cff_font_done( CFF_Font font )
2518 {
2519 FT_Memory memory = font->memory;
2520 FT_UInt idx;
2521
2522
2523 cff_index_done( &font->global_subrs_index );
2524 cff_index_done( &font->font_dict_index );
2525 cff_index_done( &font->name_index );
2526 cff_index_done( &font->charstrings_index );
2527
2528 /* release font dictionaries, but only if working with */
2529 /* a CID keyed CFF font or a CFF2 font */
2530 if ( font->num_subfonts > 0 )
2531 {
2532 for ( idx = 0; idx < font->num_subfonts; idx++ )
2533 cff_subfont_done( memory, font->subfonts[idx] );
2534
2535 /* the subfonts array has been allocated as a single block */
2536 FT_FREE( font->subfonts[0] );
2537 }
2538
2539 cff_encoding_done( &font->encoding );
2540 cff_charset_done( &font->charset, font->stream );
2541 cff_vstore_done( &font->vstore, memory );
2542
2543 cff_subfont_done( memory, &font->top_font );
2544
2545 CFF_Done_FD_Select( &font->fd_select, font->stream );
2546
2547 FT_FREE( font->font_info );
2548
2549 FT_FREE( font->font_name );
2550 FT_FREE( font->global_subrs );
2551 FT_FREE( font->strings );
2552 FT_FREE( font->string_pool );
2553
2554 if ( font->cf2_instance.finalizer )
2555 {
2556 font->cf2_instance.finalizer( font->cf2_instance.data );
2557 FT_FREE( font->cf2_instance.data );
2558 }
2559
2560 FT_FREE( font->font_extra );
2561 }
2562
2563
2564/* END */
2565