zenilib: zenilib/jni/external/freetype2/src/cff/cffload.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
cffload.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* cffload.c */
4 /* */
5 /* OpenType and CFF data/program tables loader (body). */
6 /* */
7 /* Copyright 1996-2011 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
26 #include "cffload.h"
27 #include "cffparse.h"
28
29 #include "cfferrs.h"
30
31
32 #if 1
33
34 static const FT_UShort cff_isoadobe_charset[229] =
35 {
36 0, 1, 2, 3, 4, 5, 6, 7,
37 8, 9, 10, 11, 12, 13, 14, 15,
38 16, 17, 18, 19, 20, 21, 22, 23,
39 24, 25, 26, 27, 28, 29, 30, 31,
40 32, 33, 34, 35, 36, 37, 38, 39,
41 40, 41, 42, 43, 44, 45, 46, 47,
42 48, 49, 50, 51, 52, 53, 54, 55,
43 56, 57, 58, 59, 60, 61, 62, 63,
44 64, 65, 66, 67, 68, 69, 70, 71,
45 72, 73, 74, 75, 76, 77, 78, 79,
46 80, 81, 82, 83, 84, 85, 86, 87,
47 88, 89, 90, 91, 92, 93, 94, 95,
48 96, 97, 98, 99, 100, 101, 102, 103,
49 104, 105, 106, 107, 108, 109, 110, 111,
50 112, 113, 114, 115, 116, 117, 118, 119,
51 120, 121, 122, 123, 124, 125, 126, 127,
52 128, 129, 130, 131, 132, 133, 134, 135,
53 136, 137, 138, 139, 140, 141, 142, 143,
54 144, 145, 146, 147, 148, 149, 150, 151,
55 152, 153, 154, 155, 156, 157, 158, 159,
56 160, 161, 162, 163, 164, 165, 166, 167,
57 168, 169, 170, 171, 172, 173, 174, 175,
58 176, 177, 178, 179, 180, 181, 182, 183,
59 184, 185, 186, 187, 188, 189, 190, 191,
60 192, 193, 194, 195, 196, 197, 198, 199,
61 200, 201, 202, 203, 204, 205, 206, 207,
62 208, 209, 210, 211, 212, 213, 214, 215,
63 216, 217, 218, 219, 220, 221, 222, 223,
64 224, 225, 226, 227, 228
65 };
66
67 static const FT_UShort cff_expert_charset[166] =
68 {
69 0, 1, 229, 230, 231, 232, 233, 234,
70 235, 236, 237, 238, 13, 14, 15, 99,
71 239, 240, 241, 242, 243, 244, 245, 246,
72 247, 248, 27, 28, 249, 250, 251, 252,
73 253, 254, 255, 256, 257, 258, 259, 260,
74 261, 262, 263, 264, 265, 266, 109, 110,
75 267, 268, 269, 270, 271, 272, 273, 274,
76 275, 276, 277, 278, 279, 280, 281, 282,
77 283, 284, 285, 286, 287, 288, 289, 290,
78 291, 292, 293, 294, 295, 296, 297, 298,
79 299, 300, 301, 302, 303, 304, 305, 306,
80 307, 308, 309, 310, 311, 312, 313, 314,
81 315, 316, 317, 318, 158, 155, 163, 319,
82 320, 321, 322, 323, 324, 325, 326, 150,
83 164, 169, 327, 328, 329, 330, 331, 332,
84 333, 334, 335, 336, 337, 338, 339, 340,
85 341, 342, 343, 344, 345, 346, 347, 348,
86 349, 350, 351, 352, 353, 354, 355, 356,
87 357, 358, 359, 360, 361, 362, 363, 364,
88 365, 366, 367, 368, 369, 370, 371, 372,
89 373, 374, 375, 376, 377, 378
90 };
91
92 static const FT_UShort cff_expertsubset_charset[87] =
93 {
94 0, 1, 231, 232, 235, 236, 237, 238,
95 13, 14, 15, 99, 239, 240, 241, 242,
96 243, 244, 245, 246, 247, 248, 27, 28,
97 249, 250, 251, 253, 254, 255, 256, 257,
98 258, 259, 260, 261, 262, 263, 264, 265,
99 266, 109, 110, 267, 268, 269, 270, 272,
100 300, 301, 302, 305, 314, 315, 158, 155,
101 163, 320, 321, 322, 323, 324, 325, 326,
102 150, 164, 169, 327, 328, 329, 330, 331,
103 332, 333, 334, 335, 336, 337, 338, 339,
104 340, 341, 342, 343, 344, 345, 346
105 };
106
107 static const FT_UShort cff_standard_encoding[256] =
108 {
109 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0,
113 1, 2, 3, 4, 5, 6, 7, 8,
114 9, 10, 11, 12, 13, 14, 15, 16,
115 17, 18, 19, 20, 21, 22, 23, 24,
116 25, 26, 27, 28, 29, 30, 31, 32,
117 33, 34, 35, 36, 37, 38, 39, 40,
118 41, 42, 43, 44, 45, 46, 47, 48,
119 49, 50, 51, 52, 53, 54, 55, 56,
120 57, 58, 59, 60, 61, 62, 63, 64,
121 65, 66, 67, 68, 69, 70, 71, 72,
122 73, 74, 75, 76, 77, 78, 79, 80,
123 81, 82, 83, 84, 85, 86, 87, 88,
124 89, 90, 91, 92, 93, 94, 95, 0,
125 0, 0, 0, 0, 0, 0, 0, 0,
126 0, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 96, 97, 98, 99, 100, 101, 102,
130 103, 104, 105, 106, 107, 108, 109, 110,
131 0, 111, 112, 113, 114, 0, 115, 116,
132 117, 118, 119, 120, 121, 122, 0, 123,
133 0, 124, 125, 126, 127, 128, 129, 130,
134 131, 0, 132, 133, 0, 134, 135, 136,
135 137, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 138, 0, 139, 0, 0, 0, 0,
138 140, 141, 142, 143, 0, 0, 0, 0,
139 0, 144, 0, 0, 0, 145, 0, 0,
140 146, 147, 148, 149, 0, 0, 0, 0
141 };
142
143 static const FT_UShort cff_expert_encoding[256] =
144 {
145 0, 0, 0, 0, 0, 0, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0,
147 0, 0, 0, 0, 0, 0, 0, 0,
148 0, 0, 0, 0, 0, 0, 0, 0,
149 1, 229, 230, 0, 231, 232, 233, 234,
150 235, 236, 237, 238, 13, 14, 15, 99,
151 239, 240, 241, 242, 243, 244, 245, 246,
152 247, 248, 27, 28, 249, 250, 251, 252,
153 0, 253, 254, 255, 256, 257, 0, 0,
154 0, 258, 0, 0, 259, 260, 261, 262,
155 0, 0, 263, 264, 265, 0, 266, 109,
156 110, 267, 268, 269, 0, 270, 271, 272,
157 273, 274, 275, 276, 277, 278, 279, 280,
158 281, 282, 283, 284, 285, 286, 287, 288,
159 289, 290, 291, 292, 293, 294, 295, 296,
160 297, 298, 299, 300, 301, 302, 303, 0,
161 0, 0, 0, 0, 0, 0, 0, 0,
162 0, 0, 0, 0, 0, 0, 0, 0,
163 0, 0, 0, 0, 0, 0, 0, 0,
164 0, 0, 0, 0, 0, 0, 0, 0,
165 0, 304, 305, 306, 0, 0, 307, 308,
166 309, 310, 311, 0, 312, 0, 0, 312,
167 0, 0, 314, 315, 0, 0, 316, 317,
168 318, 0, 0, 0, 158, 155, 163, 319,
169 320, 321, 322, 323, 324, 325, 0, 0,
170 326, 150, 164, 169, 327, 328, 329, 330,
171 331, 332, 333, 334, 335, 336, 337, 338,
172 339, 340, 341, 342, 343, 344, 345, 346,
173 347, 348, 349, 350, 351, 352, 353, 354,
174 355, 356, 357, 358, 359, 360, 361, 362,
175 363, 364, 365, 366, 367, 368, 369, 370,
176 371, 372, 373, 374, 375, 376, 377, 378
177 };
178
179 #endif /* 1 */
180
181
182 FT_LOCAL_DEF( FT_UShort )
183 cff_get_standard_encoding( FT_UInt charcode )
184 {
185 return (FT_UShort)( charcode < 256 ? cff_standard_encoding[charcode]
186 : 0 );
187 }
188
189
190 /*************************************************************************/
191 /* */
192 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
193 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
194 /* messages during execution. */
195 /* */
196 #undef FT_COMPONENT
197 #define FT_COMPONENT trace_cffload
198
199
200 /* read an offset from the index's stream current position */
201 static FT_ULong
202 cff_index_read_offset( CFF_Index idx,
203 FT_Error *errorp )
204 {
205 FT_Error error;
206 FT_Stream stream = idx->stream;
207 FT_Byte tmp[4];
208 FT_ULong result = 0;
209
210
211 if ( !FT_STREAM_READ( tmp, idx->off_size ) )
212 {
213 FT_Int nn;
214
215
216 for ( nn = 0; nn < idx->off_size; nn++ )
217 result = ( result << 8 ) | tmp[nn];
218 }
219
220 *errorp = error;
221 return result;
222 }
223
224
225 static FT_Error
226 cff_index_init( CFF_Index idx,
227 FT_Stream stream,
228 FT_Bool load )
229 {
230 FT_Error error;
231 FT_Memory memory = stream->memory;
232 FT_UShort count;
233
234
235 FT_MEM_ZERO( idx, sizeof ( *idx ) );
236
237 idx->stream = stream;
238 idx->start = FT_STREAM_POS();
239 if ( !FT_READ_USHORT( count ) &&
240 count > 0 )
241 {
242 FT_Byte offsize;
243 FT_ULong size;
244
245
246 /* there is at least one element; read the offset size, */
247 /* then access the offset table to compute the index's total size */
248 if ( FT_READ_BYTE( offsize ) )
249 goto Exit;
250
251 if ( offsize < 1 || offsize > 4 )
252 {
253 error = CFF_Err_Invalid_Table;
254 goto Exit;
255 }
256
257 idx->count = count;
258 idx->off_size = offsize;
259 size = (FT_ULong)( count + 1 ) * offsize;
260
261 idx->data_offset = idx->start + 3 + size;
262
263 if ( FT_STREAM_SKIP( size - offsize ) )
264 goto Exit;
265
266 size = cff_index_read_offset( idx, &error );
267 if ( error )
268 goto Exit;
269
270 if ( size == 0 )
271 {
272 error = CFF_Err_Invalid_Table;
273 goto Exit;
274 }
275
276 idx->data_size = --size;
277
278 if ( load )
279 {
280 /* load the data */
281 if ( FT_FRAME_EXTRACT( size, idx->bytes ) )
282 goto Exit;
283 }
284 else
285 {
286 /* skip the data */
287 if ( FT_STREAM_SKIP( size ) )
288 goto Exit;
289 }
290 }
291
292 Exit:
293 if ( error )
294 FT_FREE( idx->offsets );
295
296 return error;
297 }
298
299
300 static void
301 cff_index_done( CFF_Index idx )
302 {
303 if ( idx->stream )
304 {
305 FT_Stream stream = idx->stream;
306 FT_Memory memory = stream->memory;
307
308
309 if ( idx->bytes )
310 FT_FRAME_RELEASE( idx->bytes );
311
312 FT_FREE( idx->offsets );
313 FT_MEM_ZERO( idx, sizeof ( *idx ) );
314 }
315 }
316
317
318 static FT_Error
319 cff_index_load_offsets( CFF_Index idx )
320 {
321 FT_Error error = CFF_Err_Ok;
322 FT_Stream stream = idx->stream;
323 FT_Memory memory = stream->memory;
324
325
326 if ( idx->count > 0 && idx->offsets == NULL )
327 {
328 FT_Byte offsize = idx->off_size;
329 FT_ULong data_size;
330 FT_Byte* p;
331 FT_Byte* p_end;
332 FT_ULong* poff;
333
334
335 data_size = (FT_ULong)( idx->count + 1 ) * offsize;
336
337 if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
338 FT_STREAM_SEEK( idx->start + 3 ) ||
339 FT_FRAME_ENTER( data_size ) )
340 goto Exit;
341
342 poff = idx->offsets;
343 p = (FT_Byte*)stream->cursor;
344 p_end = p + data_size;
345
346 switch ( offsize )
347 {
348 case 1:
349 for ( ; p < p_end; p++, poff++ )
350 poff[0] = p[0];
351 break;
352
353 case 2:
354 for ( ; p < p_end; p += 2, poff++ )
355 poff[0] = FT_PEEK_USHORT( p );
356 break;
357
358 case 3:
359 for ( ; p < p_end; p += 3, poff++ )
360 poff[0] = FT_PEEK_OFF3( p );
361 break;
362
363 default:
364 for ( ; p < p_end; p += 4, poff++ )
365 poff[0] = FT_PEEK_ULONG( p );
366 }
367
368 FT_FRAME_EXIT();
369 }
370
371 Exit:
372 if ( error )
373 FT_FREE( idx->offsets );
374
375 return error;
376 }
377
378
379 /* Allocate a table containing pointers to an index's elements. */
380 /* The `pool' argument makes this function convert the index */
381 /* entries to C-style strings (this is, NULL-terminated). */
382 static FT_Error
383 cff_index_get_pointers( CFF_Index idx,
384 FT_Byte*** table,
385 FT_Byte** pool )
386 {
387 FT_Error error = CFF_Err_Ok;
388 FT_Memory memory = idx->stream->memory;
389 FT_Byte** t = NULL;
390 FT_Byte* new_bytes = NULL;
391
392
393 *table = NULL;
394
395 if ( idx->offsets == NULL )
396 {
397 error = cff_index_load_offsets( idx );
398 if ( error )
399 goto Exit;
400 }
401
402 if ( idx->count > 0 &&
403 !FT_NEW_ARRAY( t, idx->count + 1 ) &&
404 ( !pool || !FT_ALLOC( new_bytes,
405 idx->data_size + idx->count ) ) )
406 {
407 FT_ULong n, cur_offset;
408 FT_ULong extra = 0;
409 FT_Byte* org_bytes = idx->bytes;
410
411
412 /* at this point, `idx->offsets' can't be NULL */
413 cur_offset = idx->offsets[0] - 1;
414
415 /* sanity check */
416 if ( cur_offset >= idx->data_size )
417 {
418 FT_TRACE0(( "cff_index_get_pointers:"
419 " invalid first offset value %d set to zero\n",
420 cur_offset ));
421 cur_offset = 0;
422 }
423
424 if ( !pool )
425 t[0] = org_bytes + cur_offset;
426 else
427 t[0] = new_bytes + cur_offset;
428
429 for ( n = 1; n <= idx->count; n++ )
430 {
431 FT_ULong next_offset = idx->offsets[n] - 1;
432
433
434 /* empty slot + two sanity checks for invalid offset tables */
435 if ( next_offset == 0 ||
436 next_offset < cur_offset ||
437 ( next_offset >= idx->data_size && n < idx-> count ) )
438 next_offset = cur_offset;
439
440 if ( !pool )
441 t[n] = org_bytes + next_offset;
442 else
443 {
444 t[n] = new_bytes + next_offset + extra;
445
446 if ( next_offset != cur_offset )
447 {
448 FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
449 t[n][0] = '\0';
450 t[n] += 1;
451 extra++;
452 }
453 }
454
455 cur_offset = next_offset;
456 }
457 *table = t;
458
459 if ( pool )
460 *pool = new_bytes;
461 }
462
463 Exit:
464 return error;
465 }
466
467
468 FT_LOCAL_DEF( FT_Error )
469 cff_index_access_element( CFF_Index idx,
470 FT_UInt element,
471 FT_Byte** pbytes,
472 FT_ULong* pbyte_len )
473 {
474 FT_Error error = CFF_Err_Ok;
475
476
477 if ( idx && idx->count > element )
478 {
479 /* compute start and end offsets */
480 FT_Stream stream = idx->stream;
481 FT_ULong off1, off2 = 0;
482
483
484 /* load offsets from file or the offset table */
485 if ( !idx->offsets )
486 {
487 FT_ULong pos = element * idx->off_size;
488
489
490 if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
491 goto Exit;
492
493 off1 = cff_index_read_offset( idx, &error );
494 if ( error )
495 goto Exit;
496
497 if ( off1 != 0 )
498 {
499 do
500 {
501 element++;
502 off2 = cff_index_read_offset( idx, &error );
503 }
504 while ( off2 == 0 && element < idx->count );
505 }
506 }
507 else /* use offsets table */
508 {
509 off1 = idx->offsets[element];
510 if ( off1 )
511 {
512 do
513 {
514 element++;
515 off2 = idx->offsets[element];
516
517 } while ( off2 == 0 && element < idx->count );
518 }
519 }
520
521 /* XXX: should check off2 does not exceed the end of this entry; */
522 /* at present, only truncate off2 at the end of this stream */
523 if ( off2 > stream->size + 1 ||
524 idx->data_offset > stream->size - off2 + 1 )
525 {
526 FT_ERROR(( "cff_index_access_element:"
527 " offset to next entry (%d)"
528 " exceeds the end of stream (%d)\n",
529 off2, stream->size - idx->data_offset + 1 ));
530 off2 = stream->size - idx->data_offset + 1;
531 }
532
533 /* access element */
534 if ( off1 && off2 > off1 )
535 {
536 *pbyte_len = off2 - off1;
537
538 if ( idx->bytes )
539 {
540 /* this index was completely loaded in memory, that's easy */
541 *pbytes = idx->bytes + off1 - 1;
542 }
543 else
544 {
545 /* this index is still on disk/file, access it through a frame */
546 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
547 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
548 goto Exit;
549 }
550 }
551 else
552 {
553 /* empty index element */
554 *pbytes = 0;
555 *pbyte_len = 0;
556 }
557 }
558 else
559 error = CFF_Err_Invalid_Argument;
560
561 Exit:
562 return error;
563 }
564
565
566 FT_LOCAL_DEF( void )
567 cff_index_forget_element( CFF_Index idx,
568 FT_Byte** pbytes )
569 {
570 if ( idx->bytes == 0 )
571 {
572 FT_Stream stream = idx->stream;
573
574
575 FT_FRAME_RELEASE( *pbytes );
576 }
577 }
578
579
580 /* get an entry from Name INDEX */
581 FT_LOCAL_DEF( FT_String* )
582 cff_index_get_name( CFF_Font font,
583 FT_UInt element )
584 {
585 CFF_Index idx = &font->name_index;
586 FT_Memory memory = idx->stream->memory;
587 FT_Byte* bytes;
588 FT_ULong byte_len;
589 FT_Error error;
590 FT_String* name = 0;
591
592
593 error = cff_index_access_element( idx, element, &bytes, &byte_len );
594 if ( error )
595 goto Exit;
596
597 if ( !FT_ALLOC( name, byte_len + 1 ) )
598 {
599 FT_MEM_COPY( name, bytes, byte_len );
600 name[byte_len] = 0;
601 }
602 cff_index_forget_element( idx, &bytes );
603
604 Exit:
605 return name;
606 }
607
608
609 /* get an entry from String INDEX */
610 FT_LOCAL_DEF( FT_String* )
611 cff_index_get_string( CFF_Font font,
612 FT_UInt element )
613 {
614 return ( element < font->num_strings )
615 ? (FT_String*)font->strings[element]
616 : NULL;
617 }
618
619
620 FT_LOCAL_DEF( FT_String* )
621 cff_index_get_sid_string( CFF_Font font,
622 FT_UInt sid )
623 {
624 /* value 0xFFFFU indicates a missing dictionary entry */
625 if ( sid == 0xFFFFU )
626 return NULL;
627
628 /* if it is not a standard string, return it */
629 if ( sid > 390 )
630 return cff_index_get_string( font, sid - 391 );
631
632 /* CID-keyed CFF fonts don't have glyph names */
633 if ( !font->psnames )
634 return NULL;
635
636 /* this is a standard string */
637 return (FT_String *)font->psnames->adobe_std_strings( sid );
638 }
639
640
641 /*************************************************************************/
642 /*************************************************************************/
643 /*** ***/
644 /*** FD Select table support ***/
645 /*** ***/
646 /*************************************************************************/
647 /*************************************************************************/
648
649
650 static void
651 CFF_Done_FD_Select( CFF_FDSelect fdselect,
652 FT_Stream stream )
653 {
654 if ( fdselect->data )
655 FT_FRAME_RELEASE( fdselect->data );
656
657 fdselect->data_size = 0;
658 fdselect->format = 0;
659 fdselect->range_count = 0;
660 }
661
662
663 static FT_Error
664 CFF_Load_FD_Select( CFF_FDSelect fdselect,
665 FT_UInt num_glyphs,
666 FT_Stream stream,
667 FT_ULong offset )
668 {
669 FT_Error error;
670 FT_Byte format;
671 FT_UInt num_ranges;
672
673
674 /* read format */
675 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
676 goto Exit;
677
678 fdselect->format = format;
679 fdselect->cache_count = 0; /* clear cache */
680
681 switch ( format )
682 {
683 case 0: /* format 0, that's simple */
684 fdselect->data_size = num_glyphs;
685 goto Load_Data;
686
687 case 3: /* format 3, a tad more complex */
688 if ( FT_READ_USHORT( num_ranges ) )
689 goto Exit;
690
691 fdselect->data_size = num_ranges * 3 + 2;
692
693 Load_Data:
694 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
695 goto Exit;
696 break;
697
698 default: /* hmm... that's wrong */
699 error = CFF_Err_Invalid_File_Format;
700 }
701
702 Exit:
703 return error;
704 }
705
706
707 FT_LOCAL_DEF( FT_Byte )
708 cff_fd_select_get( CFF_FDSelect fdselect,
709 FT_UInt glyph_index )
710 {
711 FT_Byte fd = 0;
712
713
714 switch ( fdselect->format )
715 {
716 case 0:
717 fd = fdselect->data[glyph_index];
718 break;
719
720 case 3:
721 /* first, compare to cache */
722 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
723 fdselect->cache_count )
724 {
725 fd = fdselect->cache_fd;
726 break;
727 }
728
729 /* then, lookup the ranges array */
730 {
731 FT_Byte* p = fdselect->data;
732 FT_Byte* p_limit = p + fdselect->data_size;
733 FT_Byte fd2;
734 FT_UInt first, limit;
735
736
737 first = FT_NEXT_USHORT( p );
738 do
739 {
740 if ( glyph_index < first )
741 break;
742
743 fd2 = *p++;
744 limit = FT_NEXT_USHORT( p );
745
746 if ( glyph_index < limit )
747 {
748 fd = fd2;
749
750 /* update cache */
751 fdselect->cache_first = first;
752 fdselect->cache_count = limit-first;
753 fdselect->cache_fd = fd2;
754 break;
755 }
756 first = limit;
757
758 } while ( p < p_limit );
759 }
760 break;
761
762 default:
763 ;
764 }
765
766 return fd;
767 }
768
769
770 /*************************************************************************/
771 /*************************************************************************/
772 /*** ***/
773 /*** CFF font support ***/
774 /*** ***/
775 /*************************************************************************/
776 /*************************************************************************/
777
778 static FT_Error
779 cff_charset_compute_cids( CFF_Charset charset,
780 FT_UInt num_glyphs,
781 FT_Memory memory )
782 {
783 FT_Error error = CFF_Err_Ok;
784 FT_UInt i;
785 FT_Long j;
786 FT_UShort max_cid = 0;
787
788
789 if ( charset->max_cid > 0 )
790 goto Exit;
791
792 for ( i = 0; i < num_glyphs; i++ )
793 {
794 if ( charset->sids[i] > max_cid )
795 max_cid = charset->sids[i];
796 }
797
798 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
799 goto Exit;
800
801 /* When multiple GIDs map to the same CID, we choose the lowest */
802 /* GID. This is not described in any spec, but it matches the */
803 /* behaviour of recent Acroread versions. */
804 for ( j = num_glyphs - 1; j >= 0 ; j-- )
805 charset->cids[charset->sids[j]] = (FT_UShort)j;
806
807 charset->max_cid = max_cid;
808 charset->num_glyphs = num_glyphs;
809
810 Exit:
811 return error;
812 }
813
814
815 FT_LOCAL_DEF( FT_UInt )
816 cff_charset_cid_to_gindex( CFF_Charset charset,
817 FT_UInt cid )
818 {
819 FT_UInt result = 0;
820
821
822 if ( cid <= charset->max_cid )
823 result = charset->cids[cid];
824
825 return result;
826 }
827
828
829 static void
830 cff_charset_free_cids( CFF_Charset charset,
831 FT_Memory memory )
832 {
833 FT_FREE( charset->cids );
834 charset->max_cid = 0;
835 }
836
837
838 static void
839 cff_charset_done( CFF_Charset charset,
840 FT_Stream stream )
841 {
842 FT_Memory memory = stream->memory;
843
844
845 cff_charset_free_cids( charset, memory );
846
847 FT_FREE( charset->sids );
848 charset->format = 0;
849 charset->offset = 0;
850 }
851
852
853 static FT_Error
854 cff_charset_load( CFF_Charset charset,
855 FT_UInt num_glyphs,
856 FT_Stream stream,
857 FT_ULong base_offset,
858 FT_ULong offset,
859 FT_Bool invert )
860 {
861 FT_Memory memory = stream->memory;
862 FT_Error error = CFF_Err_Ok;
863 FT_UShort glyph_sid;
864
865
866 /* If the the offset is greater than 2, we have to parse the */
867 /* charset table. */
868 if ( offset > 2 )
869 {
870 FT_UInt j;
871
872
873 charset->offset = base_offset + offset;
874
875 /* Get the format of the table. */
876 if ( FT_STREAM_SEEK( charset->offset ) ||
877 FT_READ_BYTE( charset->format ) )
878 goto Exit;
879
880 /* Allocate memory for sids. */
881 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
882 goto Exit;
883
884 /* assign the .notdef glyph */
885 charset->sids[0] = 0;
886
887 switch ( charset->format )
888 {
889 case 0:
890 if ( num_glyphs > 0 )
891 {
892 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
893 goto Exit;
894
895 for ( j = 1; j < num_glyphs; j++ )
896 charset->sids[j] = FT_GET_USHORT();
897
898 FT_FRAME_EXIT();
899 }
900 break;
901
902 case 1:
903 case 2:
904 {
905 FT_UInt nleft;
906 FT_UInt i;
907
908
909 j = 1;
910
911 while ( j < num_glyphs )
912 {
913 /* Read the first glyph sid of the range. */
914 if ( FT_READ_USHORT( glyph_sid ) )
915 goto Exit;
916
917 /* Read the number of glyphs in the range. */
918 if ( charset->format == 2 )
919 {
920 if ( FT_READ_USHORT( nleft ) )
921 goto Exit;
922 }
923 else
924 {
925 if ( FT_READ_BYTE( nleft ) )
926 goto Exit;
927 }
928
929 /* try to rescue some of the SIDs if `nleft' is too large */
930 if ( glyph_sid > 0xFFFFL - nleft )
931 {
932 FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
933 " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
934 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
935 }
936
937 /* Fill in the range of sids -- `nleft + 1' glyphs. */
938 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
939 charset->sids[j] = glyph_sid;
940 }
941 }
942 break;
943
944 default:
945 FT_ERROR(( "cff_charset_load: invalid table format\n" ));
946 error = CFF_Err_Invalid_File_Format;
947 goto Exit;
948 }
949 }
950 else
951 {
952 /* Parse default tables corresponding to offset == 0, 1, or 2. */
953 /* CFF specification intimates the following: */
954 /* */
955 /* In order to use a predefined charset, the following must be */
956 /* true: The charset constructed for the glyphs in the font's */
957 /* charstrings dictionary must match the predefined charset in */
958 /* the first num_glyphs. */
959
960 charset->offset = offset; /* record charset type */
961
962 switch ( (FT_UInt)offset )
963 {
964 case 0:
965 if ( num_glyphs > 229 )
966 {
967 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
968 "predefined charset (Adobe ISO-Latin)\n" ));
969 error = CFF_Err_Invalid_File_Format;
970 goto Exit;
971 }
972
973 /* Allocate memory for sids. */
974 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
975 goto Exit;
976
977 /* Copy the predefined charset into the allocated memory. */
978 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
979
980 break;
981
982 case 1:
983 if ( num_glyphs > 166 )
984 {
985 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
986 "predefined charset (Adobe Expert)\n" ));
987 error = CFF_Err_Invalid_File_Format;
988 goto Exit;
989 }
990
991 /* Allocate memory for sids. */
992 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
993 goto Exit;
994
995 /* Copy the predefined charset into the allocated memory. */
996 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
997
998 break;
999
1000 case 2:
1001 if ( num_glyphs > 87 )
1002 {
1003 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1004 "predefined charset (Adobe Expert Subset)\n" ));
1005 error = CFF_Err_Invalid_File_Format;
1006 goto Exit;
1007 }
1008
1009 /* Allocate memory for sids. */
1010 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1011 goto Exit;
1012
1013 /* Copy the predefined charset into the allocated memory. */
1014 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1015
1016 break;
1017
1018 default:
1019 error = CFF_Err_Invalid_File_Format;
1020 goto Exit;
1021 }
1022 }
1023
1024 /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1025 if ( invert )
1026 error = cff_charset_compute_cids( charset, num_glyphs, memory );
1027
1028 Exit:
1029 /* Clean up if there was an error. */
1030 if ( error )
1031 {
1032 FT_FREE( charset->sids );
1033 FT_FREE( charset->cids );
1034 charset->format = 0;
1035 charset->offset = 0;
1036 charset->sids = 0;
1037 }
1038
1039 return error;
1040 }
1041
1042
1043 static void
1044 cff_encoding_done( CFF_Encoding encoding )
1045 {
1046 encoding->format = 0;
1047 encoding->offset = 0;
1048 encoding->count = 0;
1049 }
1050
1051
1052 static FT_Error
1053 cff_encoding_load( CFF_Encoding encoding,
1054 CFF_Charset charset,
1055 FT_UInt num_glyphs,
1056 FT_Stream stream,
1057 FT_ULong base_offset,
1058 FT_ULong offset )
1059 {
1060 FT_Error error = CFF_Err_Ok;
1061 FT_UInt count;
1062 FT_UInt j;
1063 FT_UShort glyph_sid;
1064 FT_UInt glyph_code;
1065
1066
1067 /* Check for charset->sids. If we do not have this, we fail. */
1068 if ( !charset->sids )
1069 {
1070 error = CFF_Err_Invalid_File_Format;
1071 goto Exit;
1072 }
1073
1074 /* Zero out the code to gid/sid mappings. */
1075 for ( j = 0; j < 256; j++ )
1076 {
1077 encoding->sids [j] = 0;
1078 encoding->codes[j] = 0;
1079 }
1080
1081 /* Note: The encoding table in a CFF font is indexed by glyph index; */
1082 /* the first encoded glyph index is 1. Hence, we read the character */
1083 /* code (`glyph_code') at index j and make the assignment: */
1084 /* */
1085 /* encoding->codes[glyph_code] = j + 1 */
1086 /* */
1087 /* We also make the assignment: */
1088 /* */
1089 /* encoding->sids[glyph_code] = charset->sids[j + 1] */
1090 /* */
1091 /* This gives us both a code to GID and a code to SID mapping. */
1092
1093 if ( offset > 1 )
1094 {
1095 encoding->offset = base_offset + offset;
1096
1097 /* we need to parse the table to determine its size */
1098 if ( FT_STREAM_SEEK( encoding->offset ) ||
1099 FT_READ_BYTE( encoding->format ) ||
1100 FT_READ_BYTE( count ) )
1101 goto Exit;
1102
1103 switch ( encoding->format & 0x7F )
1104 {
1105 case 0:
1106 {
1107 FT_Byte* p;
1108
1109
1110 /* By convention, GID 0 is always ".notdef" and is never */
1111 /* coded in the font. Hence, the number of codes found */
1112 /* in the table is `count+1'. */
1113 /* */
1114 encoding->count = count + 1;
1115
1116 if ( FT_FRAME_ENTER( count ) )
1117 goto Exit;
1118
1119 p = (FT_Byte*)stream->cursor;
1120
1121 for ( j = 1; j <= count; j++ )
1122 {
1123 glyph_code = *p++;
1124
1125 /* Make sure j is not too big. */
1126 if ( j < num_glyphs )
1127 {
1128 /* Assign code to GID mapping. */
1129 encoding->codes[glyph_code] = (FT_UShort)j;
1130
1131 /* Assign code to SID mapping. */
1132 encoding->sids[glyph_code] = charset->sids[j];
1133 }
1134 }
1135
1136 FT_FRAME_EXIT();
1137 }
1138 break;
1139
1140 case 1:
1141 {
1142 FT_UInt nleft;
1143 FT_UInt i = 1;
1144 FT_UInt k;
1145
1146
1147 encoding->count = 0;
1148
1149 /* Parse the Format1 ranges. */
1150 for ( j = 0; j < count; j++, i += nleft )
1151 {
1152 /* Read the first glyph code of the range. */
1153 if ( FT_READ_BYTE( glyph_code ) )
1154 goto Exit;
1155
1156 /* Read the number of codes in the range. */
1157 if ( FT_READ_BYTE( nleft ) )
1158 goto Exit;
1159
1160 /* Increment nleft, so we read `nleft + 1' codes/sids. */
1161 nleft++;
1162
1163 /* compute max number of character codes */
1164 if ( (FT_UInt)nleft > encoding->count )
1165 encoding->count = nleft;
1166
1167 /* Fill in the range of codes/sids. */
1168 for ( k = i; k < nleft + i; k++, glyph_code++ )
1169 {
1170 /* Make sure k is not too big. */
1171 if ( k < num_glyphs && glyph_code < 256 )
1172 {
1173 /* Assign code to GID mapping. */
1174 encoding->codes[glyph_code] = (FT_UShort)k;
1175
1176 /* Assign code to SID mapping. */
1177 encoding->sids[glyph_code] = charset->sids[k];
1178 }
1179 }
1180 }
1181
1182 /* simple check; one never knows what can be found in a font */
1183 if ( encoding->count > 256 )
1184 encoding->count = 256;
1185 }
1186 break;
1187
1188 default:
1189 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1190 error = CFF_Err_Invalid_File_Format;
1191 goto Exit;
1192 }
1193
1194 /* Parse supplemental encodings, if any. */
1195 if ( encoding->format & 0x80 )
1196 {
1197 FT_UInt gindex;
1198
1199
1200 /* count supplements */
1201 if ( FT_READ_BYTE( count ) )
1202 goto Exit;
1203
1204 for ( j = 0; j < count; j++ )
1205 {
1206 /* Read supplemental glyph code. */
1207 if ( FT_READ_BYTE( glyph_code ) )
1208 goto Exit;
1209
1210 /* Read the SID associated with this glyph code. */
1211 if ( FT_READ_USHORT( glyph_sid ) )
1212 goto Exit;
1213
1214 /* Assign code to SID mapping. */
1215 encoding->sids[glyph_code] = glyph_sid;
1216
1217 /* First, look up GID which has been assigned to */
1218 /* SID glyph_sid. */
1219 for ( gindex = 0; gindex < num_glyphs; gindex++ )
1220 {
1221 if ( charset->sids[gindex] == glyph_sid )
1222 {
1223 encoding->codes[glyph_code] = (FT_UShort)gindex;
1224 break;
1225 }
1226 }
1227 }
1228 }
1229 }
1230 else
1231 {
1232 /* We take into account the fact a CFF font can use a predefined */
1233 /* encoding without containing all of the glyphs encoded by this */
1234 /* encoding (see the note at the end of section 12 in the CFF */
1235 /* specification). */
1236
1237 switch ( (FT_UInt)offset )
1238 {
1239 case 0:
1240 /* First, copy the code to SID mapping. */
1241 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1242 goto Populate;
1243
1244 case 1:
1245 /* First, copy the code to SID mapping. */
1246 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1247
1248 Populate:
1249 /* Construct code to GID mapping from code to SID mapping */
1250 /* and charset. */
1251
1252 encoding->count = 0;
1253
1254 error = cff_charset_compute_cids( charset, num_glyphs,
1255 stream->memory );
1256 if ( error )
1257 goto Exit;
1258
1259 for ( j = 0; j < 256; j++ )
1260 {
1261 FT_UInt sid = encoding->sids[j];
1262 FT_UInt gid = 0;
1263
1264
1265 if ( sid )
1266 gid = cff_charset_cid_to_gindex( charset, sid );
1267
1268 if ( gid != 0 )
1269 {
1270 encoding->codes[j] = (FT_UShort)gid;
1271 encoding->count = j + 1;
1272 }
1273 else
1274 {
1275 encoding->codes[j] = 0;
1276 encoding->sids [j] = 0;
1277 }
1278 }
1279 break;
1280
1281 default:
1282 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1283 error = CFF_Err_Invalid_File_Format;
1284 goto Exit;
1285 }
1286 }
1287
1288 Exit:
1289
1290 /* Clean up if there was an error. */
1291 return error;
1292 }
1293
1294
1295 static FT_Error
1296 cff_subfont_load( CFF_SubFont font,
1297 CFF_Index idx,
1298 FT_UInt font_index,
1299 FT_Stream stream,
1300 FT_ULong base_offset,
1301 FT_Library library )
1302 {
1303 FT_Error error;
1304 CFF_ParserRec parser;
1305 FT_Byte* dict = NULL;
1306 FT_ULong dict_len;
1307 CFF_FontRecDict top = &font->font_dict;
1308 CFF_Private priv = &font->private_dict;
1309
1310
1311 cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
1312
1313 /* set defaults */
1314 FT_MEM_ZERO( top, sizeof ( *top ) );
1315
1316 top->underline_position = -100L << 16;
1317 top->underline_thickness = 50L << 16;
1318 top->charstring_type = 2;
1319 top->font_matrix.xx = 0x10000L;
1320 top->font_matrix.yy = 0x10000L;
1321 top->cid_count = 8720;
1322
1323 /* we use the implementation specific SID value 0xFFFF to indicate */
1324 /* missing entries */
1325 top->version = 0xFFFFU;
1326 top->notice = 0xFFFFU;
1327 top->copyright = 0xFFFFU;
1328 top->full_name = 0xFFFFU;
1329 top->family_name = 0xFFFFU;
1330 top->weight = 0xFFFFU;
1331 top->embedded_postscript = 0xFFFFU;
1332
1333 top->cid_registry = 0xFFFFU;
1334 top->cid_ordering = 0xFFFFU;
1335 top->cid_font_name = 0xFFFFU;
1336
1337 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1338 if ( !error )
1339 {
1340 FT_TRACE4(( " top dictionary:\n" ));
1341 error = cff_parser_run( &parser, dict, dict + dict_len );
1342 }
1343
1344 cff_index_forget_element( idx, &dict );
1345
1346 if ( error )
1347 goto Exit;
1348
1349 /* if it is a CID font, we stop there */
1350 if ( top->cid_registry != 0xFFFFU )
1351 goto Exit;
1352
1353 /* parse the private dictionary, if any */
1354 if ( top->private_offset && top->private_size )
1355 {
1356 /* set defaults */
1357 FT_MEM_ZERO( priv, sizeof ( *priv ) );
1358
1359 priv->blue_shift = 7;
1360 priv->blue_fuzz = 1;
1361 priv->lenIV = -1;
1362 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1363 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1364
1365 cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
1366
1367 if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1368 FT_FRAME_ENTER( font->font_dict.private_size ) )
1369 goto Exit;
1370
1371 FT_TRACE4(( " private dictionary:\n" ));
1372 error = cff_parser_run( &parser,
1373 (FT_Byte*)stream->cursor,
1374 (FT_Byte*)stream->limit );
1375 FT_FRAME_EXIT();
1376 if ( error )
1377 goto Exit;
1378
1379 /* ensure that `num_blue_values' is even */
1380 priv->num_blue_values &= ~1;
1381 }
1382
1383 /* read the local subrs, if any */
1384 if ( priv->local_subrs_offset )
1385 {
1386 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1387 priv->local_subrs_offset ) )
1388 goto Exit;
1389
1390 error = cff_index_init( &font->local_subrs_index, stream, 1 );
1391 if ( error )
1392 goto Exit;
1393
1394 error = cff_index_get_pointers( &font->local_subrs_index,
1395 &font->local_subrs, NULL );
1396 if ( error )
1397 goto Exit;
1398 }
1399
1400 Exit:
1401 return error;
1402 }
1403
1404
1405 static void
1406 cff_subfont_done( FT_Memory memory,
1407 CFF_SubFont subfont )
1408 {
1409 if ( subfont )
1410 {
1411 cff_index_done( &subfont->local_subrs_index );
1412 FT_FREE( subfont->local_subrs );
1413 }
1414 }
1415
1416
1417 FT_LOCAL_DEF( FT_Error )
1418 cff_font_load( FT_Library library,
1419 FT_Stream stream,
1420 FT_Int face_index,
1421 CFF_Font font,
1422 FT_Bool pure_cff )
1423 {
1424 static const FT_Frame_Field cff_header_fields[] =
1425 {
1426 #undef FT_STRUCTURE
1427 #define FT_STRUCTURE CFF_FontRec
1428
1429 FT_FRAME_START( 4 ),
1430 FT_FRAME_BYTE( version_major ),
1431 FT_FRAME_BYTE( version_minor ),
1432 FT_FRAME_BYTE( header_size ),
1433 FT_FRAME_BYTE( absolute_offsize ),
1434 FT_FRAME_END
1435 };
1436
1437 FT_Error error;
1438 FT_Memory memory = stream->memory;
1439 FT_ULong base_offset;
1440 CFF_FontRecDict dict;
1441 CFF_IndexRec string_index;
1442
1443
1444 FT_ZERO( font );
1445 FT_ZERO( &string_index );
1446
1447 font->stream = stream;
1448 font->memory = memory;
1449 dict = &font->top_font.font_dict;
1450 base_offset = FT_STREAM_POS();
1451
1452 /* read CFF font header */
1453 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1454 goto Exit;
1455
1456 /* check format */
1457 if ( font->version_major != 1 ||
1458 font->header_size < 4 ||
1459 font->absolute_offsize > 4 )
1460 {
1461 FT_TRACE2(( " not a CFF font header\n" ));
1462 error = CFF_Err_Unknown_File_Format;
1463 goto Exit;
1464 }
1465
1466 /* skip the rest of the header */
1467 if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1468 goto Exit;
1469
1470 /* read the name, top dict, string and global subrs index */
1471 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1472 stream, 0 ) ) ||
1473 FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1474 stream, 0 ) ) ||
1475 FT_SET_ERROR( cff_index_init( &string_index,
1476 stream, 1 ) ) ||
1477 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1478 stream, 1 ) ) ||
1479 FT_SET_ERROR( cff_index_get_pointers( &string_index,
1480 &font->strings,
1481 &font->string_pool ) ) )
1482 goto Exit;
1483
1484 font->num_strings = string_index.count;
1485
1486 /* well, we don't really forget the `disabled' fonts... */
1487 font->num_faces = font->name_index.count;
1488 if ( face_index >= (FT_Int)font->num_faces )
1489 {
1490 FT_ERROR(( "cff_font_load: incorrect face index = %d\n",
1491 face_index ));
1492 error = CFF_Err_Invalid_Argument;
1493 }
1494
1495 /* in case of a font format check, simply exit now */
1496 if ( face_index < 0 )
1497 goto Exit;
1498
1499 /* now, parse the top-level font dictionary */
1500 FT_TRACE4(( "parsing top-level\n" ));
1501 error = cff_subfont_load( &font->top_font,
1502 &font->font_dict_index,
1503 face_index,
1504 stream,
1505 base_offset,
1506 library );
1507 if ( error )
1508 goto Exit;
1509
1510 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1511 goto Exit;
1512
1513 error = cff_index_init( &font->charstrings_index, stream, 0 );
1514 if ( error )
1515 goto Exit;
1516
1517 /* now, check for a CID font */
1518 if ( dict->cid_registry != 0xFFFFU )
1519 {
1520 CFF_IndexRec fd_index;
1521 CFF_SubFont sub = NULL;
1522 FT_UInt idx;
1523
1524
1525 /* this is a CID-keyed font, we must now allocate a table of */
1526 /* sub-fonts, then load each of them separately */
1527 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1528 goto Exit;
1529
1530 error = cff_index_init( &fd_index, stream, 0 );
1531 if ( error )
1532 goto Exit;
1533
1534 if ( fd_index.count > CFF_MAX_CID_FONTS )
1535 {
1536 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
1537 goto Fail_CID;
1538 }
1539
1540 /* allocate & read each font dict independently */
1541 font->num_subfonts = fd_index.count;
1542 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1543 goto Fail_CID;
1544
1545 /* set up pointer table */
1546 for ( idx = 0; idx < fd_index.count; idx++ )
1547 font->subfonts[idx] = sub + idx;
1548
1549 /* now load each subfont independently */
1550 for ( idx = 0; idx < fd_index.count; idx++ )
1551 {
1552 sub = font->subfonts[idx];
1553 FT_TRACE4(( "parsing subfont %u\n", idx ));
1554 error = cff_subfont_load( sub, &fd_index, idx,
1555 stream, base_offset, library );
1556 if ( error )
1557 goto Fail_CID;
1558 }
1559
1560 /* now load the FD Select array */
1561 error = CFF_Load_FD_Select( &font->fd_select,
1562 font->charstrings_index.count,
1563 stream,
1564 base_offset + dict->cid_fd_select_offset );
1565
1566 Fail_CID:
1567 cff_index_done( &fd_index );
1568
1569 if ( error )
1570 goto Exit;
1571 }
1572 else
1573 font->num_subfonts = 0;
1574
1575 /* read the charstrings index now */
1576 if ( dict->charstrings_offset == 0 )
1577 {
1578 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
1579 error = CFF_Err_Invalid_File_Format;
1580 goto Exit;
1581 }
1582
1583 font->num_glyphs = font->charstrings_index.count;
1584
1585 error = cff_index_get_pointers( &font->global_subrs_index,
1586 &font->global_subrs, NULL );
1587
1588 if ( error )
1589 goto Exit;
1590
1591 /* read the Charset and Encoding tables if available */
1592 if ( font->num_glyphs > 0 )
1593 {
1594 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1595
1596
1597 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1598 base_offset, dict->charset_offset, invert );
1599 if ( error )
1600 goto Exit;
1601
1602 /* CID-keyed CFFs don't have an encoding */
1603 if ( dict->cid_registry == 0xFFFFU )
1604 {
1605 error = cff_encoding_load( &font->encoding,
1606 &font->charset,
1607 font->num_glyphs,
1608 stream,
1609 base_offset,
1610 dict->encoding_offset );
1611 if ( error )
1612 goto Exit;
1613 }
1614 }
1615
1616 /* get the font name (/CIDFontName for CID-keyed fonts, */
1617 /* /FontName otherwise) */
1618 font->font_name = cff_index_get_name( font, face_index );
1619
1620 Exit:
1621 cff_index_done( &string_index );
1622
1623 return error;
1624 }
1625
1626
1627 FT_LOCAL_DEF( void )
1628 cff_font_done( CFF_Font font )
1629 {
1630 FT_Memory memory = font->memory;
1631 FT_UInt idx;
1632
1633
1634 cff_index_done( &font->global_subrs_index );
1635 cff_index_done( &font->font_dict_index );
1636 cff_index_done( &font->name_index );
1637 cff_index_done( &font->charstrings_index );
1638
1639 /* release font dictionaries, but only if working with */
1640 /* a CID keyed CFF font */
1641 if ( font->num_subfonts > 0 )
1642 {
1643 for ( idx = 0; idx < font->num_subfonts; idx++ )
1644 cff_subfont_done( memory, font->subfonts[idx] );
1645
1646 /* the subfonts array has been allocated as a single block */
1647 FT_FREE( font->subfonts[0] );
1648 }
1649
1650 cff_encoding_done( &font->encoding );
1651 cff_charset_done( &font->charset, font->stream );
1652
1653 cff_subfont_done( memory, &font->top_font );
1654
1655 CFF_Done_FD_Select( &font->fd_select, font->stream );
1656
1657 FT_FREE( font->font_info );
1658
1659 FT_FREE( font->font_name );
1660 FT_FREE( font->global_subrs );
1661 FT_FREE( font->strings );
1662 FT_FREE( font->string_pool );
1663 }
1664
1665
1666 /* END */
FT_ALLOC
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
table
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glew.h:4422
cff_font_done
cff_font_done(CFF_Font font)
Definition: cffload.c:1628
CFF_FontRecDictRec_::charset_offset
FT_ULong charset_offset
Definition: cfftypes.h:126
FT_Error
int FT_Error
Definition: fttypes.h:296
cff_get_standard_encoding
cff_get_standard_encoding(FT_UInt charcode)
Definition: cffload.c:183
cff_index_get_name
cff_index_get_name(CFF_Font font, FT_UInt element)
Definition: cffload.c:582
FT_Long
signed long FT_Long
Definition: fttypes.h:238
cff_index_load_offsets
static FT_Error cff_index_load_offsets(CFF_Index idx)
Definition: cffload.c:319
FT_ULong
unsigned long FT_ULong
Definition: fttypes.h:249
FT_StreamRec_::size
unsigned long size
Definition: ftsystem.h:324
cff_subfont_done
static void cff_subfont_done(FT_Memory memory, CFF_SubFont subfont)
Definition: cffload.c:1406
charset
CFF_Charset charset
Definition: cffcmap.c:127
CFF_FontRecDictRec_::cid_fd_select_offset
FT_ULong cid_fd_select_offset
Definition: cfftypes.h:145
CFF_SubFontRec_::local_subrs_index
CFF_IndexRec local_subrs_index
Definition: cfftypes.h:210
cff_charset_compute_cids
static FT_Error cff_charset_compute_cids(CFF_Charset charset, FT_UInt num_glyphs, FT_Memory memory)
Definition: cffload.c:779
cffparse.h
FT_MEM_ZERO
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
NULL
#define NULL
Definition: ftobjs.h:61
FT_Int
signed int FT_Int
Definition: fttypes.h:216
CFF_FontRecDictRec_::private_offset
FT_ULong private_offset
Definition: cfftypes.h:129
CFF_FDSelectRec_::data
FT_Byte * data
Definition: cfftypes.h:192
FT_ARRAY_COPY
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:216
FT_Frame_Field_
Definition: ftstream.h:86
CFF_PrivateRec_::blue_scale
FT_Fixed blue_scale
Definition: cfftypes.h:163
invert
GLboolean invert
Definition: glew.h:1408
k
int32_t k
Definition: e_log.c:102
FT_StreamRec_::cursor
unsigned char * cursor
Definition: ftsystem.h:333
CFF_PrivateRec_::blue_shift
FT_Pos blue_shift
Definition: cfftypes.h:164
cff_index_read_offset
static FT_ULong cff_index_read_offset(CFF_Index idx, FT_Error *errorp)
Definition: cffload.c:202
CFF_FontRecDictRec_::underline_position
FT_Fixed underline_position
Definition: cfftypes.h:115
stream
GLuint GLuint stream
Definition: glew.h:6573
n
GLclampd n
Definition: glew.h:7287
cff_parser_init
cff_parser_init(CFF_Parser parser, FT_UInt code, void *object, FT_Library library)
Definition: cffparse.c:39
cff_index_get_string
cff_index_get_string(CFF_Font font, FT_UInt element)
Definition: cffload.c:611
sid
FT_UInt sid
Definition: cffcmap.c:128
CFF_FontRecDictRec_::charstring_type
FT_Int charstring_type
Definition: cfftypes.h:118
t
GLdouble GLdouble t
Definition: glew.h:1384
CFF_FontRecDictRec_::embedded_postscript
FT_UInt embedded_postscript
Definition: cfftypes.h:132
j
int32_t j
Definition: e_log.c:102
FT_READ_BYTE
#define FT_READ_BYTE(var)
Definition: ftstream.h:313
CFF_FontRecDictRec_::private_size
FT_ULong private_size
Definition: cfftypes.h:130
cff_standard_encoding
static const FT_UShort cff_standard_encoding[256]
Definition: cffload.c:107
CFF_CODE_PRIVATE
#define CFF_CODE_PRIVATE
Definition: cffparse.h:34
library
FT_Library library
Definition: cffdrivr.c:409
CFF_FontRecDictRec_::underline_thickness
FT_Fixed underline_thickness
Definition: cfftypes.h:116
name
EGLImageKHR EGLint * name
Definition: eglext.h:284
FT_READ_USHORT
#define FT_READ_USHORT(var)
Definition: ftstream.h:316
cff_expert_charset
static const FT_UShort cff_expert_charset[166]
Definition: cffload.c:67
CFF_PrivateRec_::expansion_factor
FT_Fixed expansion_factor
Definition: cfftypes.h:177
CFF_EncodingRec_::sids
FT_UShort sids[256]
Definition: cfftypes.h:84
CFF_EncodingRec_::codes
FT_UShort codes[256]
Definition: cfftypes.h:85
switch
switch(yytype)
Definition: glslang_tab.cpp:1918
CFF_PrivateRec_::local_subrs_offset
FT_ULong local_subrs_offset
Definition: cfftypes.h:179
cff_index_get_sid_string
return cff_index_get_sid_string(cff, sid)
cff_charset_done
static void cff_charset_done(CFF_Charset charset, FT_Stream stream)
Definition: cffload.c:839
FT_Bool
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
FT_PEEK_OFF3
#define FT_PEEK_OFF3(p)
Definition: ftstream.h:191
CFF_Load_FD_Select
static FT_Error CFF_Load_FD_Select(CFF_FDSelect fdselect, FT_UInt num_glyphs, FT_Stream stream, FT_ULong offset)
Definition: cffload.c:664
cff_expertsubset_charset
static const FT_UShort cff_expertsubset_charset[87]
Definition: cffload.c:92
CFF_FontRec_
Definition: cfftypes.h:219
FT_ERROR
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
CFF_FontRecDictRec_::weight
FT_UInt weight
Definition: cfftypes.h:112
cff_encoding_done
static void cff_encoding_done(CFF_Encoding encoding)
Definition: cffload.c:1044
cff_fd_select_get
cff_fd_select_get(CFF_FDSelect fdselect, FT_UInt glyph_index)
Definition: cffload.c:708
FT_Byte
unsigned char FT_Byte
Definition: fttypes.h:150
cff_index_access_element
cff_index_access_element(CFF_Index idx, FT_UInt element, FT_Byte **pbytes, FT_ULong *pbyte_len)
Definition: cffload.c:469
FT_TRACE4
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
CFF_IndexRec
FT_BEGIN_HEADER struct CFF_IndexRec_ CFF_IndexRec
FT_STREAM_READ_FIELDS
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:513
CFF_SubFontRec_::font_dict
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:207
cff_index_init
static FT_Error cff_index_init(CFF_Index idx, FT_Stream stream, FT_Bool load)
Definition: cffload.c:226
cff_index_done
static void cff_index_done(CFF_Index idx)
Definition: cffload.c:301
CFF_FontRecDictRec_::copyright
FT_UInt copyright
Definition: cfftypes.h:109
FT_PEEK_ULONG
#define FT_PEEK_ULONG(p)
Definition: ftstream.h:186
CFF_FontRecDictRec_::version
FT_UInt version
Definition: cfftypes.h:107
FT_StreamRec_::memory
FT_Memory memory
Definition: ftsystem.h:332
FT_GET_USHORT
#define FT_GET_USHORT()
Definition: ftstream.h:296
FT_FREE
#define FT_FREE(ptr)
Definition: ftmemory.h:286
FT_FRAME_END
#define FT_FRAME_END
Definition: ftstream.h:118
FT_STREAM_SKIP
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:499
first
GLint first
Definition: gl2ext.h:1011
CFF_FontRecDictRec_::charstrings_offset
FT_ULong charstrings_offset
Definition: cfftypes.h:128
result
GLuint64EXT * result
Definition: glew.h:12708
FT_LOCAL_DEF
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:467
cff_expert_encoding
static const FT_UShort cff_expert_encoding[256]
Definition: cffload.c:143
CFF_FontRecDictRec_::cid_fd_array_offset
FT_ULong cid_fd_array_offset
Definition: cfftypes.h:144
cffload.h
CFF_EncodingRec_::offset
FT_ULong offset
Definition: cfftypes.h:81
idx
FT_UInt idx
Definition: cffcmap.c:125
for
for(;;)
Definition: glslang_tab.cpp:4773
CFF_Done_FD_Select
static void CFF_Done_FD_Select(CFF_FDSelect fdselect, FT_Stream stream)
Definition: cffload.c:651
CFF_CharsetRec_::max_cid
FT_UInt max_cid
Definition: cfftypes.h:99
error
FT_Error error
Definition: cffdrivr.c:407
CFF_PrivateRec_
Definition: cfftypes.h:151
FT_TRACE0
#define FT_TRACE0(varformat)
Definition: ftdebug.h:157
CFF_EncodingRec_
Definition: cfftypes.h:78
CFF_CODE_TOPDICT
#define CFF_CODE_TOPDICT
Definition: cffparse.h:33
cfferrs.h
FT_String
char FT_String
Definition: fttypes.h:183
FT_ZERO
#define FT_ZERO(p)
Definition: ftmemory.h:210
CFF_FontRecDictRec_::family_name
FT_UInt family_name
Definition: cfftypes.h:111
count
GLint GLsizei count
Definition: gl2ext.h:1011
cff_parser_run
cff_parser_run(CFF_Parser parser, FT_Byte *start, FT_Byte *limit)
Definition: cffparse.c:868
p
GLfloat GLfloat p
Definition: glew.h:14938
cff_encoding_load
static FT_Error cff_encoding_load(CFF_Encoding encoding, CFF_Charset charset, FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, FT_ULong offset)
Definition: cffload.c:1053
CFF_FontRecDictRec_::encoding_offset
FT_ULong encoding_offset
Definition: cfftypes.h:127
FT_TRACE2
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
CFF_SubFontRec_::private_dict
CFF_PrivateRec private_dict
Definition: cfftypes.h:208
format
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
limit
GLint limit
Definition: glew.h:11829
CFF_CharsetRec_::cids
FT_UShort * cids
Definition: cfftypes.h:97
CFF_MAX_CID_FONTS
#define CFF_MAX_CID_FONTS
Definition: cfftypes.h:216
top
GLfloat GLfloat GLfloat top
Definition: glew.h:13816
FT_PEEK_USHORT
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:178
FT_LibraryRec_
Definition: ftobjs.h:824
CFF_FontRecDictRec_::notice
FT_UInt notice
Definition: cfftypes.h:108
FT_Memory
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Matrix_::xx
FT_Fixed xx
Definition: fttypes.h:383
FT_BOOL
#define FT_BOOL(x)
Definition: fttypes.h:581
CFF_SubFontRec_::local_subrs
FT_Byte ** local_subrs
Definition: cfftypes.h:211
FT_FRAME_EXIT
#define FT_FRAME_EXIT()
Definition: ftstream.h:521
FT_NEW_ARRAY
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
cff_index_get_pointers
static FT_Error cff_index_get_pointers(CFF_Index idx, FT_Byte ***table, FT_Byte **pool)
Definition: cffload.c:383
CFF_EncodingRec_::format
FT_UInt format
Definition: cfftypes.h:80
CFF_ParserRec_
Definition: cffparse.h:37
FT_STREAM_SEEK
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:496
cff_subfont_load
static FT_Error cff_subfont_load(CFF_SubFont font, CFF_Index idx, FT_UInt font_index, FT_Stream stream, FT_ULong base_offset, FT_Library library)
Definition: cffload.c:1296
CFF_FontRecDictRec_::cid_count
FT_ULong cid_count
Definition: cfftypes.h:142
FT_NEXT_USHORT
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:233
FT_FRAME_RELEASE
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:529
CFF_PrivateRec_::lenIV
FT_Int lenIV
Definition: cfftypes.h:175
CFF_CharsetRec_::offset
FT_ULong offset
Definition: cfftypes.h:94
FT_STREAM_POS
#define FT_STREAM_POS()
Definition: ftstream.h:493
CFF_FontRecDictRec_::cid_font_name
FT_UInt cid_font_name
Definition: cfftypes.h:146
CFF_FDSelectRec_::format
FT_Byte format
Definition: cfftypes.h:188
ft2build.h
offset
GLintptr offset
Definition: glew.h:1668
FT_Fixed
signed long FT_Fixed
Definition: fttypes.h:284
FT_SET_ERROR
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
CFF_FontRecDictRec_::cid_ordering
FT_UInt cid_ordering
Definition: cfftypes.h:136
FT_UInt
unsigned int FT_UInt
Definition: fttypes.h:227
CFF_FDSelectRec_::cache_count
FT_UInt cache_count
Definition: cfftypes.h:197
FT_FRAME_BYTE
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
CFF_FontRecDictRec_::font_matrix
FT_Matrix font_matrix
Definition: cfftypes.h:119
cff_isoadobe_charset
static const FT_UShort cff_isoadobe_charset[229]
Definition: cffload.c:34
cff_charset_load
static FT_Error cff_charset_load(CFF_Charset charset, FT_UInt num_glyphs, FT_Stream stream, FT_ULong base_offset, FT_ULong offset, FT_Bool invert)
Definition: cffload.c:854
FT_StreamRec_::limit
unsigned char * limit
Definition: ftsystem.h:334
CFF_SubFontRec_
Definition: cfftypes.h:205
FT_FRAME_EXTRACT
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:524
CFF_FontRecDictRec_::full_name
FT_UInt full_name
Definition: cfftypes.h:110
cff_charset_cid_to_gindex
cff_charset_cid_to_gindex(CFF_Charset charset, FT_UInt cid)
Definition: cffload.c:816
CFF_PrivateRec_::num_blue_values
FT_Byte num_blue_values
Definition: cfftypes.h:153
CFF_PrivateRec_::blue_fuzz
FT_Pos blue_fuzz
Definition: cfftypes.h:165
FT_FRAME_ENTER
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:517
FT_Matrix_::yy
FT_Fixed yy
Definition: fttypes.h:384
cff_charset_free_cids
static void cff_charset_free_cids(CFF_Charset charset, FT_Memory memory)
Definition: cffload.c:830
CFF_FontRecDictRec_
Definition: cfftypes.h:105
i
int i
Definition: pngrutil.c:1377
CFF_CharsetRec_::num_glyphs
FT_UInt num_glyphs
Definition: cfftypes.h:100
FT_MEM_COPY
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:203
CFF_EncodingRec_::count
FT_UInt count
Definition: cfftypes.h:83
CFF_CharsetRec_::sids
FT_UShort * sids
Definition: cfftypes.h:96
CFF_FDSelectRec_
Definition: cfftypes.h:186
CFF_CharsetRec_::format
FT_UInt format
Definition: cfftypes.h:93
CFF_CharsetRec_
Definition: cfftypes.h:90
FT_UShort
unsigned short FT_UShort
Definition: fttypes.h:205
FT_StreamRec_
Definition: ftsystem.h:321
FT_STREAM_READ
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:502
CFF_FDSelectRec_::data_size
FT_UInt data_size
Definition: cfftypes.h:193
CFF_FontRecDictRec_::cid_registry
FT_UInt cid_registry
Definition: cfftypes.h:135
FT_FRAME_START
#define FT_FRAME_START(size)
Definition: ftstream.h:117
cff_index_forget_element
cff_index_forget_element(CFF_Index idx, FT_Byte **pbytes)
Definition: cffload.c:567
cff_font_load
cff_font_load(FT_Library library, FT_Stream stream, FT_Int face_index, CFF_Font font, FT_Bool pure_cff)
Definition: cffload.c:1418
CFF_FDSelectRec_::range_count
FT_UInt range_count
Definition: cfftypes.h:189
CFF_Index
FT_BEGIN_HEADER struct CFF_IndexRec_ * CFF_Index
size
GLsizei size
Definition: gl2ext.h:1467