1/****************************************************************************
2 *
3 * cffload.c
4 *
5 * OpenType and CFF data/program tables loader (body).
6 *
7 * Copyright (C) 1996-2019 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 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 /* protect against malformed fonts */
1402 if ( !( lenNDV == 0 || NDV ) )
1403 {
1404 FT_TRACE4(( " cff_blend_build_vector:"
1405 " Malformed Normalize Design Vector data\n" ));
1406 error = FT_THROW( Invalid_File_Format );
1407 goto Exit;
1408 }
1409
1410 blend->builtBV = FALSE;
1411
1412 vs = &blend->font->vstore;
1413
1414 /* VStore and fvar must be consistent */
1415 if ( lenNDV != 0 && lenNDV != vs->axisCount )
1416 {
1417 FT_TRACE4(( " cff_blend_build_vector: Axis count mismatch\n" ));
1418 error = FT_THROW( Invalid_File_Format );
1419 goto Exit;
1420 }
1421
1422 if ( vsindex >= vs->dataCount )
1423 {
1424 FT_TRACE4(( " cff_blend_build_vector: vsindex out of range\n" ));
1425 error = FT_THROW( Invalid_File_Format );
1426 goto Exit;
1427 }
1428
1429 /* select the item variation data structure */
1430 varData = &vs->varData[vsindex];
1431
1432 /* prepare buffer for the blend vector */
1433 len = varData->regionIdxCount + 1; /* add 1 for default component */
1434 if ( FT_REALLOC( blend->BV,
1435 blend->lenBV * sizeof( *blend->BV ),
1436 len * sizeof( *blend->BV ) ) )
1437 goto Exit;
1438
1439 blend->lenBV = len;
1440
1441 /* outer loop steps through master designs to be blended */
1442 for ( master = 0; master < len; master++ )
1443 {
1444 FT_UInt j;
1445 FT_UInt idx;
1446 CFF_VarRegion* varRegion;
1447
1448
1449 /* default factor is always one */
1450 if ( master == 0 )
1451 {
1452 blend->BV[master] = FT_FIXED_ONE;
1453 FT_TRACE4(( " build blend vector len %d\n"
1454 " [ %f ",
1455 len,
1456 blend->BV[master] / 65536.0 ));
1457 continue;
1458 }
1459
1460 /* VStore array does not include default master, so subtract one */
1461 idx = varData->regionIndices[master - 1];
1462 varRegion = &vs->varRegionList[idx];
1463
1464 if ( idx >= vs->regionCount )
1465 {
1466 FT_TRACE4(( " cff_blend_build_vector:"
1467 " region index out of range\n" ));
1468 error = FT_THROW( Invalid_File_Format );
1469 goto Exit;
1470 }
1471
1472 /* Note: `lenNDV' could be zero. */
1473 /* In that case, build default blend vector (1,0,0...). */
1474 if ( !lenNDV )
1475 {
1476 blend->BV[master] = 0;
1477 continue;
1478 }
1479
1480 /* In the normal case, initialize each component to 1 */
1481 /* before inner loop. */
1482 blend->BV[master] = FT_FIXED_ONE; /* default */
1483
1484 /* inner loop steps through axes in this region */
1485 for ( j = 0; j < lenNDV; j++ )
1486 {
1487 CFF_AxisCoords* axis = &varRegion->axisList[j];
1488 FT_Fixed axisScalar;
1489
1490
1491 /* compute the scalar contribution of this axis; */
1492 /* ignore invalid ranges */
1493 if ( axis->startCoord > axis->peakCoord ||
1494 axis->peakCoord > axis->endCoord )
1495 axisScalar = FT_FIXED_ONE;
1496
1497 else if ( axis->startCoord < 0 &&
1498 axis->endCoord > 0 &&
1499 axis->peakCoord != 0 )
1500 axisScalar = FT_FIXED_ONE;
1501
1502 /* peak of 0 means ignore this axis */
1503 else if ( axis->peakCoord == 0 )
1504 axisScalar = FT_FIXED_ONE;
1505
1506 /* ignore this region if coords are out of range */
1507 else if ( NDV[j] < axis->startCoord ||
1508 NDV[j] > axis->endCoord )
1509 axisScalar = 0;
1510
1511 /* calculate a proportional factor */
1512 else
1513 {
1514 if ( NDV[j] == axis->peakCoord )
1515 axisScalar = FT_FIXED_ONE;
1516 else if ( NDV[j] < axis->peakCoord )
1517 axisScalar = FT_DivFix( NDV[j] - axis->startCoord,
1518 axis->peakCoord - axis->startCoord );
1519 else
1520 axisScalar = FT_DivFix( axis->endCoord - NDV[j],
1521 axis->endCoord - axis->peakCoord );
1522 }
1523
1524 /* take product of all the axis scalars */
1525 blend->BV[master] = FT_MulFix( blend->BV[master], axisScalar );
1526 }
1527
1528 FT_TRACE4(( ", %f ",
1529 blend->BV[master] / 65536.0 ));
1530 }
1531
1532 FT_TRACE4(( "]\n" ));
1533
1534 /* record the parameters used to build the blend vector */
1535 blend->lastVsindex = vsindex;
1536
1537 if ( lenNDV != 0 )
1538 {
1539 /* user has set a normalized vector */
1540 if ( FT_REALLOC( blend->lastNDV,
1541 blend->lenNDV * sizeof ( *NDV ),
1542 lenNDV * sizeof ( *NDV ) ) )
1543 goto Exit;
1544
1545 FT_MEM_COPY( blend->lastNDV,
1546 NDV,
1547 lenNDV * sizeof ( *NDV ) );
1548 }
1549
1550 blend->lenNDV = lenNDV;
1551 blend->builtBV = TRUE;
1552
1553 Exit:
1554 return error;
1555 }
1556
1557
1558 /* `lenNDV' is zero for default vector; */
1559 /* return TRUE if blend vector needs to be built. */
1560 FT_LOCAL_DEF( FT_Bool )
1561 cff_blend_check_vector( CFF_Blend blend,
1562 FT_UInt vsindex,
1563 FT_UInt lenNDV,
1564 FT_Fixed* NDV )
1565 {
1566 if ( !blend->builtBV ||
1567 blend->lastVsindex != vsindex ||
1568 blend->lenNDV != lenNDV ||
1569 ( lenNDV &&
1570 ft_memcmp( NDV,
1571 blend->lastNDV,
1572 lenNDV * sizeof ( *NDV ) ) != 0 ) )
1573 {
1574 /* need to build blend vector */
1575 return TRUE;
1576 }
1577
1578 return FALSE;
1579 }
1580
1581
1582#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1583
1584 FT_LOCAL_DEF( FT_Error )
1585 cff_get_var_blend( CFF_Face face,
1586 FT_UInt *num_coords,
1587 FT_Fixed* *coords,
1588 FT_Fixed* *normalizedcoords,
1589 FT_MM_Var* *mm_var )
1590 {
1591 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
1592
1593
1594 return mm->get_var_blend( FT_FACE( face ),
1595 num_coords,
1596 coords,
1597 normalizedcoords,
1598 mm_var );
1599 }
1600
1601
1602 FT_LOCAL_DEF( void )
1603 cff_done_blend( CFF_Face face )
1604 {
1605 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
1606
1607
1608 if (mm)
1609 mm->done_blend( FT_FACE( face ) );
1610 }
1611
1612#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1613
1614
1615 static void
1616 cff_encoding_done( CFF_Encoding encoding )
1617 {
1618 encoding->format = 0;
1619 encoding->offset = 0;
1620 encoding->count = 0;
1621 }
1622
1623
1624 static FT_Error
1625 cff_encoding_load( CFF_Encoding encoding,
1626 CFF_Charset charset,
1627 FT_UInt num_glyphs,
1628 FT_Stream stream,
1629 FT_ULong base_offset,
1630 FT_ULong offset )
1631 {
1632 FT_Error error = FT_Err_Ok;
1633 FT_UInt count;
1634 FT_UInt j;
1635 FT_UShort glyph_sid;
1636 FT_UInt glyph_code;
1637
1638
1639 /* Check for charset->sids. If we do not have this, we fail. */
1640 if ( !charset->sids )
1641 {
1642 error = FT_THROW( Invalid_File_Format );
1643 goto Exit;
1644 }
1645
1646 /* Zero out the code to gid/sid mappings. */
1647 for ( j = 0; j < 256; j++ )
1648 {
1649 encoding->sids [j] = 0;
1650 encoding->codes[j] = 0;
1651 }
1652
1653 /* Note: The encoding table in a CFF font is indexed by glyph index; */
1654 /* the first encoded glyph index is 1. Hence, we read the character */
1655 /* code (`glyph_code') at index j and make the assignment: */
1656 /* */
1657 /* encoding->codes[glyph_code] = j + 1 */
1658 /* */
1659 /* We also make the assignment: */
1660 /* */
1661 /* encoding->sids[glyph_code] = charset->sids[j + 1] */
1662 /* */
1663 /* This gives us both a code to GID and a code to SID mapping. */
1664
1665 if ( offset > 1 )
1666 {
1667 encoding->offset = base_offset + offset;
1668
1669 /* we need to parse the table to determine its size */
1670 if ( FT_STREAM_SEEK( encoding->offset ) ||
1671 FT_READ_BYTE( encoding->format ) ||
1672 FT_READ_BYTE( count ) )
1673 goto Exit;
1674
1675 switch ( encoding->format & 0x7F )
1676 {
1677 case 0:
1678 {
1679 FT_Byte* p;
1680
1681
1682 /* By convention, GID 0 is always ".notdef" and is never */
1683 /* coded in the font. Hence, the number of codes found */
1684 /* in the table is `count+1'. */
1685 /* */
1686 encoding->count = count + 1;
1687
1688 if ( FT_FRAME_ENTER( count ) )
1689 goto Exit;
1690
1691 p = (FT_Byte*)stream->cursor;
1692
1693 for ( j = 1; j <= count; j++ )
1694 {
1695 glyph_code = *p++;
1696
1697 /* Make sure j is not too big. */
1698 if ( j < num_glyphs )
1699 {
1700 /* Assign code to GID mapping. */
1701 encoding->codes[glyph_code] = (FT_UShort)j;
1702
1703 /* Assign code to SID mapping. */
1704 encoding->sids[glyph_code] = charset->sids[j];
1705 }
1706 }
1707
1708 FT_FRAME_EXIT();
1709 }
1710 break;
1711
1712 case 1:
1713 {
1714 FT_UInt nleft;
1715 FT_UInt i = 1;
1716 FT_UInt k;
1717
1718
1719 encoding->count = 0;
1720
1721 /* Parse the Format1 ranges. */
1722 for ( j = 0; j < count; j++, i += nleft )
1723 {
1724 /* Read the first glyph code of the range. */
1725 if ( FT_READ_BYTE( glyph_code ) )
1726 goto Exit;
1727
1728 /* Read the number of codes in the range. */
1729 if ( FT_READ_BYTE( nleft ) )
1730 goto Exit;
1731
1732 /* Increment nleft, so we read `nleft + 1' codes/sids. */
1733 nleft++;
1734
1735 /* compute max number of character codes */
1736 if ( (FT_UInt)nleft > encoding->count )
1737 encoding->count = nleft;
1738
1739 /* Fill in the range of codes/sids. */
1740 for ( k = i; k < nleft + i; k++, glyph_code++ )
1741 {
1742 /* Make sure k is not too big. */
1743 if ( k < num_glyphs && glyph_code < 256 )
1744 {
1745 /* Assign code to GID mapping. */
1746 encoding->codes[glyph_code] = (FT_UShort)k;
1747
1748 /* Assign code to SID mapping. */
1749 encoding->sids[glyph_code] = charset->sids[k];
1750 }
1751 }
1752 }
1753
1754 /* simple check; one never knows what can be found in a font */
1755 if ( encoding->count > 256 )
1756 encoding->count = 256;
1757 }
1758 break;
1759
1760 default:
1761 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1762 error = FT_THROW( Invalid_File_Format );
1763 goto Exit;
1764 }
1765
1766 /* Parse supplemental encodings, if any. */
1767 if ( encoding->format & 0x80 )
1768 {
1769 FT_UInt gindex;
1770
1771
1772 /* count supplements */
1773 if ( FT_READ_BYTE( count ) )
1774 goto Exit;
1775
1776 for ( j = 0; j < count; j++ )
1777 {
1778 /* Read supplemental glyph code. */
1779 if ( FT_READ_BYTE( glyph_code ) )
1780 goto Exit;
1781
1782 /* Read the SID associated with this glyph code. */
1783 if ( FT_READ_USHORT( glyph_sid ) )
1784 goto Exit;
1785
1786 /* Assign code to SID mapping. */
1787 encoding->sids[glyph_code] = glyph_sid;
1788
1789 /* First, look up GID which has been assigned to */
1790 /* SID glyph_sid. */
1791 for ( gindex = 0; gindex < num_glyphs; gindex++ )
1792 {
1793 if ( charset->sids[gindex] == glyph_sid )
1794 {
1795 encoding->codes[glyph_code] = (FT_UShort)gindex;
1796 break;
1797 }
1798 }
1799 }
1800 }
1801 }
1802 else
1803 {
1804 /* We take into account the fact a CFF font can use a predefined */
1805 /* encoding without containing all of the glyphs encoded by this */
1806 /* encoding (see the note at the end of section 12 in the CFF */
1807 /* specification). */
1808
1809 switch ( (FT_UInt)offset )
1810 {
1811 case 0:
1812 /* First, copy the code to SID mapping. */
1813 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1814 goto Populate;
1815
1816 case 1:
1817 /* First, copy the code to SID mapping. */
1818 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1819
1820 Populate:
1821 /* Construct code to GID mapping from code to SID mapping */
1822 /* and charset. */
1823
1824 encoding->count = 0;
1825
1826 error = cff_charset_compute_cids( charset, num_glyphs,
1827 stream->memory );
1828 if ( error )
1829 goto Exit;
1830
1831 for ( j = 0; j < 256; j++ )
1832 {
1833 FT_UInt sid = encoding->sids[j];
1834 FT_UInt gid = 0;
1835
1836
1837 if ( sid )
1838 gid = cff_charset_cid_to_gindex( charset, sid );
1839
1840 if ( gid != 0 )
1841 {
1842 encoding->codes[j] = (FT_UShort)gid;
1843 encoding->count = j + 1;
1844 }
1845 else
1846 {
1847 encoding->codes[j] = 0;
1848 encoding->sids [j] = 0;
1849 }
1850 }
1851 break;
1852
1853 default:
1854 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1855 error = FT_THROW( Invalid_File_Format );
1856 goto Exit;
1857 }
1858 }
1859
1860 Exit:
1861
1862 /* Clean up if there was an error. */
1863 return error;
1864 }
1865
1866
1867 /* Parse private dictionary; first call is always from `cff_face_init', */
1868 /* so NDV has not been set for CFF2 variation. */
1869 /* */
1870 /* `cff_slot_load' must call this function each time NDV changes. */
1871 FT_LOCAL_DEF( FT_Error )
1872 cff_load_private_dict( CFF_Font font,
1873 CFF_SubFont subfont,
1874 FT_UInt lenNDV,
1875 FT_Fixed* NDV )
1876 {
1877 FT_Error error = FT_Err_Ok;
1878 CFF_ParserRec parser;
1879 CFF_FontRecDict top = &subfont->font_dict;
1880 CFF_Private priv = &subfont->private_dict;
1881 FT_Stream stream = font->stream;
1882 FT_UInt stackSize;
1883
1884
1885 /* store handle needed to access memory, vstore for blend; */
1886 /* we need this for clean-up even if there is no private DICT */
1887 subfont->blend.font = font;
1888 subfont->blend.usedBV = FALSE; /* clear state */
1889
1890 if ( !top->private_offset || !top->private_size )
1891 goto Exit2; /* no private DICT, do nothing */
1892
1893 /* set defaults */
1894 FT_ZERO( priv );
1895
1896 priv->blue_shift = 7;
1897 priv->blue_fuzz = 1;
1898 priv->lenIV = -1;
1899 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1900 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1901
1902 /* provide inputs for blend calculations */
1903 priv->subfont = subfont;
1904 subfont->lenNDV = lenNDV;
1905 subfont->NDV = NDV;
1906
1907 /* add 1 for the operator */
1908 stackSize = font->cff2 ? font->top_font.font_dict.maxstack + 1
1909 : CFF_MAX_STACK_DEPTH + 1;
1910
1911 if ( cff_parser_init( &parser,
1912 font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
1913 priv,
1914 font->library,
1915 stackSize,
1916 top->num_designs,
1917 top->num_axes ) )
1918 goto Exit;
1919
1920 if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
1921 FT_FRAME_ENTER( top->private_size ) )
1922 goto Exit;
1923
1924 FT_TRACE4(( " private dictionary:\n" ));
1925 error = cff_parser_run( &parser,
1926 (FT_Byte*)stream->cursor,
1927 (FT_Byte*)stream->limit );
1928 FT_FRAME_EXIT();
1929
1930 if ( error )
1931 goto Exit;
1932
1933 /* ensure that `num_blue_values' is even */
1934 priv->num_blue_values &= ~1;
1935
1936 /* sanitize `initialRandomSeed' to be a positive value, if necessary; */
1937 /* this is not mandated by the specification but by our implementation */
1938 if ( priv->initial_random_seed < 0 )
1939 priv->initial_random_seed = -priv->initial_random_seed;
1940 else if ( priv->initial_random_seed == 0 )
1941 priv->initial_random_seed = 987654321;
1942
1943 /* some sanitizing to avoid overflows later on; */
1944 /* the upper limits are ad-hoc values */
1945 if ( priv->blue_shift > 1000 || priv->blue_shift < 0 )
1946 {
1947 FT_TRACE2(( "cff_load_private_dict:"
1948 " setting unlikely BlueShift value %d to default (7)\n",
1949 priv->blue_shift ));
1950 priv->blue_shift = 7;
1951 }
1952
1953 if ( priv->blue_fuzz > 1000 || priv->blue_fuzz < 0 )
1954 {
1955 FT_TRACE2(( "cff_load_private_dict:"
1956 " setting unlikely BlueFuzz value %d to default (1)\n",
1957 priv->blue_fuzz ));
1958 priv->blue_fuzz = 1;
1959 }
1960
1961 Exit:
1962 /* clean up */
1963 cff_blend_clear( subfont ); /* clear blend stack */
1964 cff_parser_done( &parser ); /* free parser stack */
1965
1966 Exit2:
1967 /* no clean up (parser not initialized) */
1968 return error;
1969 }
1970
1971
1972 /* There are 3 ways to call this function, distinguished by code. */
1973 /* */
1974 /* . CFF_CODE_TOPDICT for either a CFF Top DICT or a CFF Font DICT */
1975 /* . CFF2_CODE_TOPDICT for CFF2 Top DICT */
1976 /* . CFF2_CODE_FONTDICT for CFF2 Font DICT */
1977
1978 static FT_Error
1979 cff_subfont_load( CFF_SubFont subfont,
1980 CFF_Index idx,
1981 FT_UInt font_index,
1982 FT_Stream stream,
1983 FT_ULong base_offset,
1984 FT_UInt code,
1985 CFF_Font font,
1986 CFF_Face face )
1987 {
1988 FT_Error error;
1989 CFF_ParserRec parser;
1990 FT_Byte* dict = NULL;
1991 FT_ULong dict_len;
1992 CFF_FontRecDict top = &subfont->font_dict;
1993 CFF_Private priv = &subfont->private_dict;
1994
1995 PSAux_Service psaux = (PSAux_Service)face->psaux;
1996
1997 FT_Bool cff2 = FT_BOOL( code == CFF2_CODE_TOPDICT ||
1998 code == CFF2_CODE_FONTDICT );
1999 FT_UInt stackSize = cff2 ? CFF2_DEFAULT_STACK
2000 : CFF_MAX_STACK_DEPTH;
2001
2002
2003 /* Note: We use default stack size for CFF2 Font DICT because */
2004 /* Top and Font DICTs are not allowed to have blend operators. */
2005 error = cff_parser_init( &parser,
2006 code,
2007 &subfont->font_dict,
2008 font->library,
2009 stackSize,
2010 0,
2011 0 );
2012 if ( error )
2013 goto Exit;
2014
2015 /* set defaults */
2016 FT_ZERO( top );
2017
2018 top->underline_position = -( 100L << 16 );
2019 top->underline_thickness = 50L << 16;
2020 top->charstring_type = 2;
2021 top->font_matrix.xx = 0x10000L;
2022 top->font_matrix.yy = 0x10000L;
2023 top->cid_count = 8720;
2024
2025 /* we use the implementation specific SID value 0xFFFF to indicate */
2026 /* missing entries */
2027 top->version = 0xFFFFU;
2028 top->notice = 0xFFFFU;
2029 top->copyright = 0xFFFFU;
2030 top->full_name = 0xFFFFU;
2031 top->family_name = 0xFFFFU;
2032 top->weight = 0xFFFFU;
2033 top->embedded_postscript = 0xFFFFU;
2034
2035 top->cid_registry = 0xFFFFU;
2036 top->cid_ordering = 0xFFFFU;
2037 top->cid_font_name = 0xFFFFU;
2038
2039 /* set default stack size */
2040 top->maxstack = cff2 ? CFF2_DEFAULT_STACK : 48;
2041
2042 if ( idx->count ) /* count is nonzero for a real index */
2043 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
2044 else
2045 {
2046 /* CFF2 has a fake top dict index; */
2047 /* simulate `cff_index_access_element' */
2048
2049 /* Note: macros implicitly use `stream' and set `error' */
2050 if ( FT_STREAM_SEEK( idx->data_offset ) ||
2051 FT_FRAME_EXTRACT( idx->data_size, dict ) )
2052 goto Exit;
2053
2054 dict_len = idx->data_size;
2055 }
2056
2057 if ( !error )
2058 {
2059 FT_TRACE4(( " top dictionary:\n" ));
2060 error = cff_parser_run( &parser, dict, dict + dict_len );
2061 }
2062
2063 /* clean up regardless of error */
2064 if ( idx->count )
2065 cff_index_forget_element( idx, &dict );
2066 else
2067 FT_FRAME_RELEASE( dict );
2068
2069 if ( error )
2070 goto Exit;
2071
2072 /* if it is a CID font, we stop there */
2073 if ( top->cid_registry != 0xFFFFU )
2074 goto Exit;
2075
2076 /* Parse the private dictionary, if any. */
2077 /* */
2078 /* CFF2 does not have a private dictionary in the Top DICT */
2079 /* but may have one in a Font DICT. We need to parse */
2080 /* the latter here in order to load any local subrs. */
2081 error = cff_load_private_dict( font, subfont, 0, 0 );
2082 if ( error )
2083 goto Exit;
2084
2085 if ( !cff2 )
2086 {
2087 /*
2088 * Initialize the random number generator.
2089 *
2090 * - If we have a face-specific seed, use it.
2091 * If non-zero, update it to a positive value.
2092 *
2093 * - Otherwise, use the seed from the CFF driver.
2094 * If non-zero, update it to a positive value.
2095 *
2096 * - If the random value is zero, use the seed given by the subfont's
2097 * `initialRandomSeed' value.
2098 *
2099 */
2100 if ( face->root.internal->random_seed == -1 )
2101 {
2102 PS_Driver driver = (PS_Driver)FT_FACE_DRIVER( face );
2103
2104
2105 subfont->random = (FT_UInt32)driver->random_seed;
2106 if ( driver->random_seed )
2107 {
2108 do
2109 {
2110 driver->random_seed =
2111 (FT_Int32)psaux->cff_random( (FT_UInt32)driver->random_seed );
2112
2113 } while ( driver->random_seed < 0 );
2114 }
2115 }
2116 else
2117 {
2118 subfont->random = (FT_UInt32)face->root.internal->random_seed;
2119 if ( face->root.internal->random_seed )
2120 {
2121 do
2122 {
2123 face->root.internal->random_seed =
2124 (FT_Int32)psaux->cff_random(
2125 (FT_UInt32)face->root.internal->random_seed );
2126
2127 } while ( face->root.internal->random_seed < 0 );
2128 }
2129 }
2130
2131 if ( !subfont->random )
2132 subfont->random = (FT_UInt32)priv->initial_random_seed;
2133 }
2134
2135 /* read the local subrs, if any */
2136 if ( priv->local_subrs_offset )
2137 {
2138 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
2139 priv->local_subrs_offset ) )
2140 goto Exit;
2141
2142 error = cff_index_init( &subfont->local_subrs_index, stream, 1, cff2 );
2143 if ( error )
2144 goto Exit;
2145
2146 error = cff_index_get_pointers( &subfont->local_subrs_index,
2147 &subfont->local_subrs, NULL, NULL );
2148 if ( error )
2149 goto Exit;
2150 }
2151
2152 Exit:
2153 cff_parser_done( &parser ); /* free parser stack */
2154
2155 return error;
2156 }
2157
2158
2159 static void
2160 cff_subfont_done( FT_Memory memory,
2161 CFF_SubFont subfont )
2162 {
2163 if ( subfont )
2164 {
2165 cff_index_done( &subfont->local_subrs_index );
2166 FT_FREE( subfont->local_subrs );
2167
2168 FT_FREE( subfont->blend.lastNDV );
2169 FT_FREE( subfont->blend.BV );
2170 FT_FREE( subfont->blend_stack );
2171 }
2172 }
2173
2174
2175 FT_LOCAL_DEF( FT_Error )
2176 cff_font_load( FT_Library library,
2177 FT_Stream stream,
2178 FT_Int face_index,
2179 CFF_Font font,
2180 CFF_Face face,
2181 FT_Bool pure_cff,
2182 FT_Bool cff2 )
2183 {
2184 static const FT_Frame_Field cff_header_fields[] =
2185 {
2186#undef FT_STRUCTURE
2187#define FT_STRUCTURE CFF_FontRec
2188
2189 FT_FRAME_START( 3 ),
2190 FT_FRAME_BYTE( version_major ),
2191 FT_FRAME_BYTE( version_minor ),
2192 FT_FRAME_BYTE( header_size ),
2193 FT_FRAME_END
2194 };
2195
2196 FT_Error error;
2197 FT_Memory memory = stream->memory;
2198 FT_ULong base_offset;
2199 CFF_FontRecDict dict;
2200 CFF_IndexRec string_index;
2201 FT_UInt subfont_index;
2202
2203
2204 FT_ZERO( font );
2205 FT_ZERO( &string_index );
2206
2207 dict = &font->top_font.font_dict;
2208 base_offset = FT_STREAM_POS();
2209
2210 font->library = library;
2211 font->stream = stream;
2212 font->memory = memory;
2213 font->cff2 = cff2;
2214 font->base_offset = base_offset;
2215
2216 /* read CFF font header */
2217 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
2218 goto Exit;
2219
2220 if ( cff2 )
2221 {
2222 if ( font->version_major != 2 ||
2223 font->header_size < 5 )
2224 {
2225 FT_TRACE2(( " not a CFF2 font header\n" ));
2226 error = FT_THROW( Unknown_File_Format );
2227 goto Exit;
2228 }
2229
2230 if ( FT_READ_USHORT( font->top_dict_length ) )
2231 goto Exit;
2232 }
2233 else
2234 {
2235 FT_Byte absolute_offset;
2236
2237
2238 if ( FT_READ_BYTE( absolute_offset ) )
2239 goto Exit;
2240
2241 if ( font->version_major != 1 ||
2242 font->header_size < 4 ||
2243 absolute_offset > 4 )
2244 {
2245 FT_TRACE2(( " not a CFF font header\n" ));
2246 error = FT_THROW( Unknown_File_Format );
2247 goto Exit;
2248 }
2249 }
2250
2251 /* skip the rest of the header */
2252 if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
2253 {
2254 /* For pure CFFs we have read only four bytes so far. Contrary to */
2255 /* other formats like SFNT those bytes doesn't define a signature; */
2256 /* it is thus possible that the font isn't a CFF at all. */
2257 if ( pure_cff )
2258 {
2259 FT_TRACE2(( " not a CFF file\n" ));
2260 error = FT_THROW( Unknown_File_Format );
2261 }
2262 goto Exit;
2263 }
2264
2265 if ( cff2 )
2266 {
2267 /* For CFF2, the top dict data immediately follow the header */
2268 /* and the length is stored in the header `offSize' field; */
2269 /* there is no index for it. */
2270 /* */
2271 /* Use the `font_dict_index' to save the current position */
2272 /* and length of data, but leave count at zero as an indicator. */
2273 FT_ZERO( &font->font_dict_index );
2274
2275 font->font_dict_index.data_offset = FT_STREAM_POS();
2276 font->font_dict_index.data_size = font->top_dict_length;
2277
2278 /* skip the top dict data for now, we will parse it later */
2279 if ( FT_STREAM_SKIP( font->top_dict_length ) )
2280 goto Exit;
2281
2282 /* next, read the global subrs index */
2283 if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2284 stream, 1, cff2 ) ) )
2285 goto Exit;
2286 }
2287 else
2288 {
2289 /* for CFF, read the name, top dict, string and global subrs index */
2290 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
2291 stream, 0, cff2 ) ) )
2292 {
2293 if ( pure_cff )
2294 {
2295 FT_TRACE2(( " not a CFF file\n" ));
2296 error = FT_THROW( Unknown_File_Format );
2297 }
2298 goto Exit;
2299 }
2300
2301 /* if we have an empty font name, */
2302 /* it must be the only font in the CFF */
2303 if ( font->name_index.count > 1 &&
2304 font->name_index.data_size < font->name_index.count )
2305 {
2306 /* for pure CFFs, we still haven't checked enough bytes */
2307 /* to be sure that it is a CFF at all */
2308 error = pure_cff ? FT_THROW( Unknown_File_Format )
2309 : FT_THROW( Invalid_File_Format );
2310 goto Exit;
2311 }
2312
2313 if ( FT_SET_ERROR( cff_index_init( &font->font_dict_index,
2314 stream, 0, cff2 ) ) ||
2315 FT_SET_ERROR( cff_index_init( &string_index,
2316 stream, 1, cff2 ) ) ||
2317 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
2318 stream, 1, cff2 ) ) ||
2319 FT_SET_ERROR( cff_index_get_pointers( &string_index,
2320 &font->strings,
2321 &font->string_pool,
2322 &font->string_pool_size ) ) )
2323 goto Exit;
2324
2325 /* there must be a Top DICT index entry for each name index entry */
2326 if ( font->name_index.count > font->font_dict_index.count )
2327 {
2328 FT_ERROR(( "cff_font_load:"
2329 " not enough entries in Top DICT index\n" ));
2330 error = FT_THROW( Invalid_File_Format );
2331 goto Exit;
2332 }
2333 }
2334
2335 font->num_strings = string_index.count;
2336
2337 if ( pure_cff )
2338 {
2339 /* well, we don't really forget the `disabled' fonts... */
2340 subfont_index = (FT_UInt)( face_index & 0xFFFF );
2341
2342 if ( face_index > 0 && subfont_index >= font->name_index.count )
2343 {
2344 FT_ERROR(( "cff_font_load:"
2345 " invalid subfont index for pure CFF font (%d)\n",
2346 subfont_index ));
2347 error = FT_THROW( Invalid_Argument );
2348 goto Exit;
2349 }
2350
2351 font->num_faces = font->name_index.count;
2352 }
2353 else
2354 {
2355 subfont_index = 0;
2356
2357 if ( font->name_index.count > 1 )
2358 {
2359 FT_ERROR(( "cff_font_load:"
2360 " invalid CFF font with multiple subfonts\n"
2361 " "
2362 " in SFNT wrapper\n" ));
2363 error = FT_THROW( Invalid_File_Format );
2364 goto Exit;
2365 }
2366 }
2367
2368 /* in case of a font format check, simply exit now */
2369 if ( face_index < 0 )
2370 goto Exit;
2371
2372 /* now, parse the top-level font dictionary */
2373 FT_TRACE4(( "parsing top-level\n" ));
2374 error = cff_subfont_load( &font->top_font,
2375 &font->font_dict_index,
2376 subfont_index,
2377 stream,
2378 base_offset,
2379 cff2 ? CFF2_CODE_TOPDICT : CFF_CODE_TOPDICT,
2380 font,
2381 face );
2382 if ( error )
2383 goto Exit;
2384
2385 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
2386 goto Exit;
2387
2388 error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
2389 if ( error )
2390 goto Exit;
2391
2392 /* now, check for a CID or CFF2 font */
2393 if ( dict->cid_registry != 0xFFFFU ||
2394 cff2 )
2395 {
2396 CFF_IndexRec fd_index;
2397 CFF_SubFont sub = NULL;
2398 FT_UInt idx;
2399
2400
2401 /* for CFF2, read the Variation Store if available; */
2402 /* this must follow the Top DICT parse and precede any Private DICT */
2403 error = cff_vstore_load( &font->vstore,
2404 stream,
2405 base_offset,
2406 dict->vstore_offset );
2407 if ( error )
2408 goto Exit;
2409
2410 /* this is a CID-keyed font, we must now allocate a table of */
2411 /* sub-fonts, then load each of them separately */
2412 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
2413 goto Exit;
2414
2415 error = cff_index_init( &fd_index, stream, 0, cff2 );
2416 if ( error )
2417 goto Exit;
2418
2419 /* Font Dicts are not limited to 256 for CFF2. */
2420 /* TODO: support this for CFF2 */
2421 if ( fd_index.count > CFF_MAX_CID_FONTS )
2422 {
2423 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
2424 goto Fail_CID;
2425 }
2426
2427 /* allocate & read each font dict independently */
2428 font->num_subfonts = fd_index.count;
2429 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
2430 goto Fail_CID;
2431
2432 /* set up pointer table */
2433 for ( idx = 0; idx < fd_index.count; idx++ )
2434 font->subfonts[idx] = sub + idx;
2435
2436 /* now load each subfont independently */
2437 for ( idx = 0; idx < fd_index.count; idx++ )
2438 {
2439 sub = font->subfonts[idx];
2440 FT_TRACE4(( "parsing subfont %u\n", idx ));
2441 error = cff_subfont_load( sub,
2442 &fd_index,
2443 idx,
2444 stream,
2445 base_offset,
2446 cff2 ? CFF2_CODE_FONTDICT
2447 : CFF_CODE_TOPDICT,
2448 font,
2449 face );
2450 if ( error )
2451 goto Fail_CID;
2452 }
2453
2454 /* now load the FD Select array; */
2455 /* CFF2 omits FDSelect if there is only one FD */
2456 if ( !cff2 || fd_index.count > 1 )
2457 error = CFF_Load_FD_Select( &font->fd_select,
2458 font->charstrings_index.count,
2459 stream,
2460 base_offset + dict->cid_fd_select_offset );
2461
2462 Fail_CID:
2463 cff_index_done( &fd_index );
2464
2465 if ( error )
2466 goto Exit;
2467 }
2468 else
2469 font->num_subfonts = 0;
2470
2471 /* read the charstrings index now */
2472 if ( dict->charstrings_offset == 0 )
2473 {
2474 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
2475 error = FT_THROW( Invalid_File_Format );
2476 goto Exit;
2477 }
2478
2479 font->num_glyphs = font->charstrings_index.count;
2480
2481 error = cff_index_get_pointers( &font->global_subrs_index,
2482 &font->global_subrs, NULL, NULL );
2483
2484 if ( error )
2485 goto Exit;
2486
2487 /* read the Charset and Encoding tables if available */
2488 if ( !cff2 && font->num_glyphs > 0 )
2489 {
2490 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
2491
2492
2493 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
2494 base_offset, dict->charset_offset, invert );
2495 if ( error )
2496 goto Exit;
2497
2498 /* CID-keyed CFFs don't have an encoding */
2499 if ( dict->cid_registry == 0xFFFFU )
2500 {
2501 error = cff_encoding_load( &font->encoding,
2502 &font->charset,
2503 font->num_glyphs,
2504 stream,
2505 base_offset,
2506 dict->encoding_offset );
2507 if ( error )
2508 goto Exit;
2509 }
2510 }
2511
2512 /* get the font name (/CIDFontName for CID-keyed fonts, */
2513 /* /FontName otherwise) */
2514 font->font_name = cff_index_get_name( font, subfont_index );
2515
2516 Exit:
2517 cff_index_done( &string_index );
2518
2519 return error;
2520 }
2521
2522
2523 FT_LOCAL_DEF( void )
2524 cff_font_done( CFF_Font font )
2525 {
2526 FT_Memory memory = font->memory;
2527 FT_UInt idx;
2528
2529
2530 cff_index_done( &font->global_subrs_index );
2531 cff_index_done( &font->font_dict_index );
2532 cff_index_done( &font->name_index );
2533 cff_index_done( &font->charstrings_index );
2534
2535 /* release font dictionaries, but only if working with */
2536 /* a CID keyed CFF font or a CFF2 font */
2537 if ( font->num_subfonts > 0 )
2538 {
2539 for ( idx = 0; idx < font->num_subfonts; idx++ )
2540 cff_subfont_done( memory, font->subfonts[idx] );
2541
2542 /* the subfonts array has been allocated as a single block */
2543 FT_FREE( font->subfonts[0] );
2544 }
2545
2546 cff_encoding_done( &font->encoding );
2547 cff_charset_done( &font->charset, font->stream );
2548 cff_vstore_done( &font->vstore, memory );
2549
2550 cff_subfont_done( memory, &font->top_font );
2551
2552 CFF_Done_FD_Select( &font->fd_select, font->stream );
2553
2554 FT_FREE( font->font_info );
2555
2556 FT_FREE( font->font_name );
2557 FT_FREE( font->global_subrs );
2558 FT_FREE( font->strings );
2559 FT_FREE( font->string_pool );
2560
2561 if ( font->cf2_instance.finalizer )
2562 {
2563 font->cf2_instance.finalizer( font->cf2_instance.data );
2564 FT_FREE( font->cf2_instance.data );
2565 }
2566
2567 FT_FREE( font->font_extra );
2568 }
2569
2570
2571/* END */
2572