[FREETYPE]
[reactos.git] / reactos / lib / 3rdparty / freetype / src / cff / cffload.c
1 /***************************************************************************/
2 /* */
3 /* cffload.c */
4 /* */
5 /* OpenType and CFF data/program tables loader (body). */
6 /* */
7 /* Copyright 1996-2013 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 = FT_THROW( 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 = FT_THROW( 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 = FT_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 = FT_Err_Ok;
388 FT_Memory memory = idx->stream->memory;
389
390 FT_Byte** t = NULL;
391 FT_Byte* new_bytes = NULL;
392
393
394 *table = NULL;
395
396 if ( idx->offsets == NULL )
397 {
398 error = cff_index_load_offsets( idx );
399 if ( error )
400 goto Exit;
401 }
402
403 if ( idx->count > 0 &&
404 !FT_NEW_ARRAY( t, idx->count + 1 ) &&
405 ( !pool || !FT_ALLOC( new_bytes,
406 idx->data_size + idx->count ) ) )
407 {
408 FT_ULong n, cur_offset;
409 FT_ULong extra = 0;
410 FT_Byte* org_bytes = idx->bytes;
411
412
413 /* at this point, `idx->offsets' can't be NULL */
414 cur_offset = idx->offsets[0] - 1;
415
416 /* sanity check */
417 if ( cur_offset >= idx->data_size )
418 {
419 FT_TRACE0(( "cff_index_get_pointers:"
420 " invalid first offset value %d set to zero\n",
421 cur_offset ));
422 cur_offset = 0;
423 }
424
425 if ( !pool )
426 t[0] = org_bytes + cur_offset;
427 else
428 t[0] = new_bytes + cur_offset;
429
430 for ( n = 1; n <= idx->count; n++ )
431 {
432 FT_ULong next_offset = idx->offsets[n] - 1;
433
434
435 /* empty slot + two sanity checks for invalid offset tables */
436 if ( next_offset == 0 ||
437 next_offset < cur_offset ||
438 ( next_offset >= idx->data_size && n < idx->count ) )
439 next_offset = cur_offset;
440
441 if ( !pool )
442 t[n] = org_bytes + next_offset;
443 else
444 {
445 t[n] = new_bytes + next_offset + extra;
446
447 if ( next_offset != cur_offset )
448 {
449 FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] );
450 t[n][0] = '\0';
451 t[n] += 1;
452 extra++;
453 }
454 }
455
456 cur_offset = next_offset;
457 }
458 *table = t;
459
460 if ( pool )
461 *pool = new_bytes;
462 }
463
464 Exit:
465 return error;
466 }
467
468
469 FT_LOCAL_DEF( FT_Error )
470 cff_index_access_element( CFF_Index idx,
471 FT_UInt element,
472 FT_Byte** pbytes,
473 FT_ULong* pbyte_len )
474 {
475 FT_Error error = FT_Err_Ok;
476
477
478 if ( idx && idx->count > element )
479 {
480 /* compute start and end offsets */
481 FT_Stream stream = idx->stream;
482 FT_ULong off1, off2 = 0;
483
484
485 /* load offsets from file or the offset table */
486 if ( !idx->offsets )
487 {
488 FT_ULong pos = element * idx->off_size;
489
490
491 if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
492 goto Exit;
493
494 off1 = cff_index_read_offset( idx, &error );
495 if ( error )
496 goto Exit;
497
498 if ( off1 != 0 )
499 {
500 do
501 {
502 element++;
503 off2 = cff_index_read_offset( idx, &error );
504 }
505 while ( off2 == 0 && element < idx->count );
506 }
507 }
508 else /* use offsets table */
509 {
510 off1 = idx->offsets[element];
511 if ( off1 )
512 {
513 do
514 {
515 element++;
516 off2 = idx->offsets[element];
517
518 } while ( off2 == 0 && element < idx->count );
519 }
520 }
521
522 /* XXX: should check off2 does not exceed the end of this entry; */
523 /* at present, only truncate off2 at the end of this stream */
524 if ( off2 > stream->size + 1 ||
525 idx->data_offset > stream->size - off2 + 1 )
526 {
527 FT_ERROR(( "cff_index_access_element:"
528 " offset to next entry (%d)"
529 " exceeds the end of stream (%d)\n",
530 off2, stream->size - idx->data_offset + 1 ));
531 off2 = stream->size - idx->data_offset + 1;
532 }
533
534 /* access element */
535 if ( off1 && off2 > off1 )
536 {
537 *pbyte_len = off2 - off1;
538
539 if ( idx->bytes )
540 {
541 /* this index was completely loaded in memory, that's easy */
542 *pbytes = idx->bytes + off1 - 1;
543 }
544 else
545 {
546 /* this index is still on disk/file, access it through a frame */
547 if ( FT_STREAM_SEEK( idx->data_offset + off1 - 1 ) ||
548 FT_FRAME_EXTRACT( off2 - off1, *pbytes ) )
549 goto Exit;
550 }
551 }
552 else
553 {
554 /* empty index element */
555 *pbytes = 0;
556 *pbyte_len = 0;
557 }
558 }
559 else
560 error = FT_THROW( Invalid_Argument );
561
562 Exit:
563 return error;
564 }
565
566
567 FT_LOCAL_DEF( void )
568 cff_index_forget_element( CFF_Index idx,
569 FT_Byte** pbytes )
570 {
571 if ( idx->bytes == 0 )
572 {
573 FT_Stream stream = idx->stream;
574
575
576 FT_FRAME_RELEASE( *pbytes );
577 }
578 }
579
580
581 /* get an entry from Name INDEX */
582 FT_LOCAL_DEF( FT_String* )
583 cff_index_get_name( CFF_Font font,
584 FT_UInt element )
585 {
586 CFF_Index idx = &font->name_index;
587 FT_Memory memory = idx->stream->memory;
588 FT_Byte* bytes;
589 FT_ULong byte_len;
590 FT_Error error;
591 FT_String* name = 0;
592
593
594 error = cff_index_access_element( idx, element, &bytes, &byte_len );
595 if ( error )
596 goto Exit;
597
598 if ( !FT_ALLOC( name, byte_len + 1 ) )
599 {
600 FT_MEM_COPY( name, bytes, byte_len );
601 name[byte_len] = 0;
602 }
603 cff_index_forget_element( idx, &bytes );
604
605 Exit:
606 return name;
607 }
608
609
610 /* get an entry from String INDEX */
611 FT_LOCAL_DEF( FT_String* )
612 cff_index_get_string( CFF_Font font,
613 FT_UInt element )
614 {
615 return ( element < font->num_strings )
616 ? (FT_String*)font->strings[element]
617 : NULL;
618 }
619
620
621 FT_LOCAL_DEF( FT_String* )
622 cff_index_get_sid_string( CFF_Font font,
623 FT_UInt sid )
624 {
625 /* value 0xFFFFU indicates a missing dictionary entry */
626 if ( sid == 0xFFFFU )
627 return NULL;
628
629 /* if it is not a standard string, return it */
630 if ( sid > 390 )
631 return cff_index_get_string( font, sid - 391 );
632
633 /* CID-keyed CFF fonts don't have glyph names */
634 if ( !font->psnames )
635 return NULL;
636
637 /* this is a standard string */
638 return (FT_String *)font->psnames->adobe_std_strings( sid );
639 }
640
641
642 /*************************************************************************/
643 /*************************************************************************/
644 /*** ***/
645 /*** FD Select table support ***/
646 /*** ***/
647 /*************************************************************************/
648 /*************************************************************************/
649
650
651 static void
652 CFF_Done_FD_Select( CFF_FDSelect fdselect,
653 FT_Stream stream )
654 {
655 if ( fdselect->data )
656 FT_FRAME_RELEASE( fdselect->data );
657
658 fdselect->data_size = 0;
659 fdselect->format = 0;
660 fdselect->range_count = 0;
661 }
662
663
664 static FT_Error
665 CFF_Load_FD_Select( CFF_FDSelect fdselect,
666 FT_UInt num_glyphs,
667 FT_Stream stream,
668 FT_ULong offset )
669 {
670 FT_Error error;
671 FT_Byte format;
672 FT_UInt num_ranges;
673
674
675 /* read format */
676 if ( FT_STREAM_SEEK( offset ) || FT_READ_BYTE( format ) )
677 goto Exit;
678
679 fdselect->format = format;
680 fdselect->cache_count = 0; /* clear cache */
681
682 switch ( format )
683 {
684 case 0: /* format 0, that's simple */
685 fdselect->data_size = num_glyphs;
686 goto Load_Data;
687
688 case 3: /* format 3, a tad more complex */
689 if ( FT_READ_USHORT( num_ranges ) )
690 goto Exit;
691
692 fdselect->data_size = num_ranges * 3 + 2;
693
694 Load_Data:
695 if ( FT_FRAME_EXTRACT( fdselect->data_size, fdselect->data ) )
696 goto Exit;
697 break;
698
699 default: /* hmm... that's wrong */
700 error = FT_THROW( Invalid_File_Format );
701 }
702
703 Exit:
704 return error;
705 }
706
707
708 FT_LOCAL_DEF( FT_Byte )
709 cff_fd_select_get( CFF_FDSelect fdselect,
710 FT_UInt glyph_index )
711 {
712 FT_Byte fd = 0;
713
714
715 switch ( fdselect->format )
716 {
717 case 0:
718 fd = fdselect->data[glyph_index];
719 break;
720
721 case 3:
722 /* first, compare to cache */
723 if ( (FT_UInt)( glyph_index - fdselect->cache_first ) <
724 fdselect->cache_count )
725 {
726 fd = fdselect->cache_fd;
727 break;
728 }
729
730 /* then, lookup the ranges array */
731 {
732 FT_Byte* p = fdselect->data;
733 FT_Byte* p_limit = p + fdselect->data_size;
734 FT_Byte fd2;
735 FT_UInt first, limit;
736
737
738 first = FT_NEXT_USHORT( p );
739 do
740 {
741 if ( glyph_index < first )
742 break;
743
744 fd2 = *p++;
745 limit = FT_NEXT_USHORT( p );
746
747 if ( glyph_index < limit )
748 {
749 fd = fd2;
750
751 /* update cache */
752 fdselect->cache_first = first;
753 fdselect->cache_count = limit-first;
754 fdselect->cache_fd = fd2;
755 break;
756 }
757 first = limit;
758
759 } while ( p < p_limit );
760 }
761 break;
762
763 default:
764 ;
765 }
766
767 return fd;
768 }
769
770
771 /*************************************************************************/
772 /*************************************************************************/
773 /*** ***/
774 /*** CFF font support ***/
775 /*** ***/
776 /*************************************************************************/
777 /*************************************************************************/
778
779 static FT_Error
780 cff_charset_compute_cids( CFF_Charset charset,
781 FT_UInt num_glyphs,
782 FT_Memory memory )
783 {
784 FT_Error error = FT_Err_Ok;
785 FT_UInt i;
786 FT_Long j;
787 FT_UShort max_cid = 0;
788
789
790 if ( charset->max_cid > 0 )
791 goto Exit;
792
793 for ( i = 0; i < num_glyphs; i++ )
794 {
795 if ( charset->sids[i] > max_cid )
796 max_cid = charset->sids[i];
797 }
798
799 if ( FT_NEW_ARRAY( charset->cids, (FT_ULong)max_cid + 1 ) )
800 goto Exit;
801
802 /* When multiple GIDs map to the same CID, we choose the lowest */
803 /* GID. This is not described in any spec, but it matches the */
804 /* behaviour of recent Acroread versions. */
805 for ( j = num_glyphs - 1; j >= 0 ; j-- )
806 charset->cids[charset->sids[j]] = (FT_UShort)j;
807
808 charset->max_cid = max_cid;
809 charset->num_glyphs = num_glyphs;
810
811 Exit:
812 return error;
813 }
814
815
816 FT_LOCAL_DEF( FT_UInt )
817 cff_charset_cid_to_gindex( CFF_Charset charset,
818 FT_UInt cid )
819 {
820 FT_UInt result = 0;
821
822
823 if ( cid <= charset->max_cid )
824 result = charset->cids[cid];
825
826 return result;
827 }
828
829
830 static void
831 cff_charset_free_cids( CFF_Charset charset,
832 FT_Memory memory )
833 {
834 FT_FREE( charset->cids );
835 charset->max_cid = 0;
836 }
837
838
839 static void
840 cff_charset_done( CFF_Charset charset,
841 FT_Stream stream )
842 {
843 FT_Memory memory = stream->memory;
844
845
846 cff_charset_free_cids( charset, memory );
847
848 FT_FREE( charset->sids );
849 charset->format = 0;
850 charset->offset = 0;
851 }
852
853
854 static FT_Error
855 cff_charset_load( CFF_Charset charset,
856 FT_UInt num_glyphs,
857 FT_Stream stream,
858 FT_ULong base_offset,
859 FT_ULong offset,
860 FT_Bool invert )
861 {
862 FT_Memory memory = stream->memory;
863 FT_Error error = FT_Err_Ok;
864 FT_UShort glyph_sid;
865
866
867 /* If the the offset is greater than 2, we have to parse the */
868 /* charset table. */
869 if ( offset > 2 )
870 {
871 FT_UInt j;
872
873
874 charset->offset = base_offset + offset;
875
876 /* Get the format of the table. */
877 if ( FT_STREAM_SEEK( charset->offset ) ||
878 FT_READ_BYTE( charset->format ) )
879 goto Exit;
880
881 /* Allocate memory for sids. */
882 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
883 goto Exit;
884
885 /* assign the .notdef glyph */
886 charset->sids[0] = 0;
887
888 switch ( charset->format )
889 {
890 case 0:
891 if ( num_glyphs > 0 )
892 {
893 if ( FT_FRAME_ENTER( ( num_glyphs - 1 ) * 2 ) )
894 goto Exit;
895
896 for ( j = 1; j < num_glyphs; j++ )
897 charset->sids[j] = FT_GET_USHORT();
898
899 FT_FRAME_EXIT();
900 }
901 break;
902
903 case 1:
904 case 2:
905 {
906 FT_UInt nleft;
907 FT_UInt i;
908
909
910 j = 1;
911
912 while ( j < num_glyphs )
913 {
914 /* Read the first glyph sid of the range. */
915 if ( FT_READ_USHORT( glyph_sid ) )
916 goto Exit;
917
918 /* Read the number of glyphs in the range. */
919 if ( charset->format == 2 )
920 {
921 if ( FT_READ_USHORT( nleft ) )
922 goto Exit;
923 }
924 else
925 {
926 if ( FT_READ_BYTE( nleft ) )
927 goto Exit;
928 }
929
930 /* try to rescue some of the SIDs if `nleft' is too large */
931 if ( glyph_sid > 0xFFFFL - nleft )
932 {
933 FT_ERROR(( "cff_charset_load: invalid SID range trimmed"
934 " nleft=%d -> %d\n", nleft, 0xFFFFL - glyph_sid ));
935 nleft = ( FT_UInt )( 0xFFFFL - glyph_sid );
936 }
937
938 /* Fill in the range of sids -- `nleft + 1' glyphs. */
939 for ( i = 0; j < num_glyphs && i <= nleft; i++, j++, glyph_sid++ )
940 charset->sids[j] = glyph_sid;
941 }
942 }
943 break;
944
945 default:
946 FT_ERROR(( "cff_charset_load: invalid table format\n" ));
947 error = FT_THROW( Invalid_File_Format );
948 goto Exit;
949 }
950 }
951 else
952 {
953 /* Parse default tables corresponding to offset == 0, 1, or 2. */
954 /* CFF specification intimates the following: */
955 /* */
956 /* In order to use a predefined charset, the following must be */
957 /* true: The charset constructed for the glyphs in the font's */
958 /* charstrings dictionary must match the predefined charset in */
959 /* the first num_glyphs. */
960
961 charset->offset = offset; /* record charset type */
962
963 switch ( (FT_UInt)offset )
964 {
965 case 0:
966 if ( num_glyphs > 229 )
967 {
968 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
969 "predefined charset (Adobe ISO-Latin)\n" ));
970 error = FT_THROW( Invalid_File_Format );
971 goto Exit;
972 }
973
974 /* Allocate memory for sids. */
975 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
976 goto Exit;
977
978 /* Copy the predefined charset into the allocated memory. */
979 FT_ARRAY_COPY( charset->sids, cff_isoadobe_charset, num_glyphs );
980
981 break;
982
983 case 1:
984 if ( num_glyphs > 166 )
985 {
986 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
987 "predefined charset (Adobe Expert)\n" ));
988 error = FT_THROW( Invalid_File_Format );
989 goto Exit;
990 }
991
992 /* Allocate memory for sids. */
993 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
994 goto Exit;
995
996 /* Copy the predefined charset into the allocated memory. */
997 FT_ARRAY_COPY( charset->sids, cff_expert_charset, num_glyphs );
998
999 break;
1000
1001 case 2:
1002 if ( num_glyphs > 87 )
1003 {
1004 FT_ERROR(( "cff_charset_load: implicit charset larger than\n"
1005 "predefined charset (Adobe Expert Subset)\n" ));
1006 error = FT_THROW( Invalid_File_Format );
1007 goto Exit;
1008 }
1009
1010 /* Allocate memory for sids. */
1011 if ( FT_NEW_ARRAY( charset->sids, num_glyphs ) )
1012 goto Exit;
1013
1014 /* Copy the predefined charset into the allocated memory. */
1015 FT_ARRAY_COPY( charset->sids, cff_expertsubset_charset, num_glyphs );
1016
1017 break;
1018
1019 default:
1020 error = FT_THROW( Invalid_File_Format );
1021 goto Exit;
1022 }
1023 }
1024
1025 /* we have to invert the `sids' array for subsetted CID-keyed fonts */
1026 if ( invert )
1027 error = cff_charset_compute_cids( charset, num_glyphs, memory );
1028
1029 Exit:
1030 /* Clean up if there was an error. */
1031 if ( error )
1032 {
1033 FT_FREE( charset->sids );
1034 FT_FREE( charset->cids );
1035 charset->format = 0;
1036 charset->offset = 0;
1037 charset->sids = 0;
1038 }
1039
1040 return error;
1041 }
1042
1043
1044 static void
1045 cff_encoding_done( CFF_Encoding encoding )
1046 {
1047 encoding->format = 0;
1048 encoding->offset = 0;
1049 encoding->count = 0;
1050 }
1051
1052
1053 static FT_Error
1054 cff_encoding_load( CFF_Encoding encoding,
1055 CFF_Charset charset,
1056 FT_UInt num_glyphs,
1057 FT_Stream stream,
1058 FT_ULong base_offset,
1059 FT_ULong offset )
1060 {
1061 FT_Error error = FT_Err_Ok;
1062 FT_UInt count;
1063 FT_UInt j;
1064 FT_UShort glyph_sid;
1065 FT_UInt glyph_code;
1066
1067
1068 /* Check for charset->sids. If we do not have this, we fail. */
1069 if ( !charset->sids )
1070 {
1071 error = FT_THROW( Invalid_File_Format );
1072 goto Exit;
1073 }
1074
1075 /* Zero out the code to gid/sid mappings. */
1076 for ( j = 0; j < 256; j++ )
1077 {
1078 encoding->sids [j] = 0;
1079 encoding->codes[j] = 0;
1080 }
1081
1082 /* Note: The encoding table in a CFF font is indexed by glyph index; */
1083 /* the first encoded glyph index is 1. Hence, we read the character */
1084 /* code (`glyph_code') at index j and make the assignment: */
1085 /* */
1086 /* encoding->codes[glyph_code] = j + 1 */
1087 /* */
1088 /* We also make the assignment: */
1089 /* */
1090 /* encoding->sids[glyph_code] = charset->sids[j + 1] */
1091 /* */
1092 /* This gives us both a code to GID and a code to SID mapping. */
1093
1094 if ( offset > 1 )
1095 {
1096 encoding->offset = base_offset + offset;
1097
1098 /* we need to parse the table to determine its size */
1099 if ( FT_STREAM_SEEK( encoding->offset ) ||
1100 FT_READ_BYTE( encoding->format ) ||
1101 FT_READ_BYTE( count ) )
1102 goto Exit;
1103
1104 switch ( encoding->format & 0x7F )
1105 {
1106 case 0:
1107 {
1108 FT_Byte* p;
1109
1110
1111 /* By convention, GID 0 is always ".notdef" and is never */
1112 /* coded in the font. Hence, the number of codes found */
1113 /* in the table is `count+1'. */
1114 /* */
1115 encoding->count = count + 1;
1116
1117 if ( FT_FRAME_ENTER( count ) )
1118 goto Exit;
1119
1120 p = (FT_Byte*)stream->cursor;
1121
1122 for ( j = 1; j <= count; j++ )
1123 {
1124 glyph_code = *p++;
1125
1126 /* Make sure j is not too big. */
1127 if ( j < num_glyphs )
1128 {
1129 /* Assign code to GID mapping. */
1130 encoding->codes[glyph_code] = (FT_UShort)j;
1131
1132 /* Assign code to SID mapping. */
1133 encoding->sids[glyph_code] = charset->sids[j];
1134 }
1135 }
1136
1137 FT_FRAME_EXIT();
1138 }
1139 break;
1140
1141 case 1:
1142 {
1143 FT_UInt nleft;
1144 FT_UInt i = 1;
1145 FT_UInt k;
1146
1147
1148 encoding->count = 0;
1149
1150 /* Parse the Format1 ranges. */
1151 for ( j = 0; j < count; j++, i += nleft )
1152 {
1153 /* Read the first glyph code of the range. */
1154 if ( FT_READ_BYTE( glyph_code ) )
1155 goto Exit;
1156
1157 /* Read the number of codes in the range. */
1158 if ( FT_READ_BYTE( nleft ) )
1159 goto Exit;
1160
1161 /* Increment nleft, so we read `nleft + 1' codes/sids. */
1162 nleft++;
1163
1164 /* compute max number of character codes */
1165 if ( (FT_UInt)nleft > encoding->count )
1166 encoding->count = nleft;
1167
1168 /* Fill in the range of codes/sids. */
1169 for ( k = i; k < nleft + i; k++, glyph_code++ )
1170 {
1171 /* Make sure k is not too big. */
1172 if ( k < num_glyphs && glyph_code < 256 )
1173 {
1174 /* Assign code to GID mapping. */
1175 encoding->codes[glyph_code] = (FT_UShort)k;
1176
1177 /* Assign code to SID mapping. */
1178 encoding->sids[glyph_code] = charset->sids[k];
1179 }
1180 }
1181 }
1182
1183 /* simple check; one never knows what can be found in a font */
1184 if ( encoding->count > 256 )
1185 encoding->count = 256;
1186 }
1187 break;
1188
1189 default:
1190 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1191 error = FT_THROW( Invalid_File_Format );
1192 goto Exit;
1193 }
1194
1195 /* Parse supplemental encodings, if any. */
1196 if ( encoding->format & 0x80 )
1197 {
1198 FT_UInt gindex;
1199
1200
1201 /* count supplements */
1202 if ( FT_READ_BYTE( count ) )
1203 goto Exit;
1204
1205 for ( j = 0; j < count; j++ )
1206 {
1207 /* Read supplemental glyph code. */
1208 if ( FT_READ_BYTE( glyph_code ) )
1209 goto Exit;
1210
1211 /* Read the SID associated with this glyph code. */
1212 if ( FT_READ_USHORT( glyph_sid ) )
1213 goto Exit;
1214
1215 /* Assign code to SID mapping. */
1216 encoding->sids[glyph_code] = glyph_sid;
1217
1218 /* First, look up GID which has been assigned to */
1219 /* SID glyph_sid. */
1220 for ( gindex = 0; gindex < num_glyphs; gindex++ )
1221 {
1222 if ( charset->sids[gindex] == glyph_sid )
1223 {
1224 encoding->codes[glyph_code] = (FT_UShort)gindex;
1225 break;
1226 }
1227 }
1228 }
1229 }
1230 }
1231 else
1232 {
1233 /* We take into account the fact a CFF font can use a predefined */
1234 /* encoding without containing all of the glyphs encoded by this */
1235 /* encoding (see the note at the end of section 12 in the CFF */
1236 /* specification). */
1237
1238 switch ( (FT_UInt)offset )
1239 {
1240 case 0:
1241 /* First, copy the code to SID mapping. */
1242 FT_ARRAY_COPY( encoding->sids, cff_standard_encoding, 256 );
1243 goto Populate;
1244
1245 case 1:
1246 /* First, copy the code to SID mapping. */
1247 FT_ARRAY_COPY( encoding->sids, cff_expert_encoding, 256 );
1248
1249 Populate:
1250 /* Construct code to GID mapping from code to SID mapping */
1251 /* and charset. */
1252
1253 encoding->count = 0;
1254
1255 error = cff_charset_compute_cids( charset, num_glyphs,
1256 stream->memory );
1257 if ( error )
1258 goto Exit;
1259
1260 for ( j = 0; j < 256; j++ )
1261 {
1262 FT_UInt sid = encoding->sids[j];
1263 FT_UInt gid = 0;
1264
1265
1266 if ( sid )
1267 gid = cff_charset_cid_to_gindex( charset, sid );
1268
1269 if ( gid != 0 )
1270 {
1271 encoding->codes[j] = (FT_UShort)gid;
1272 encoding->count = j + 1;
1273 }
1274 else
1275 {
1276 encoding->codes[j] = 0;
1277 encoding->sids [j] = 0;
1278 }
1279 }
1280 break;
1281
1282 default:
1283 FT_ERROR(( "cff_encoding_load: invalid table format\n" ));
1284 error = FT_THROW( Invalid_File_Format );
1285 goto Exit;
1286 }
1287 }
1288
1289 Exit:
1290
1291 /* Clean up if there was an error. */
1292 return error;
1293 }
1294
1295
1296 static FT_Error
1297 cff_subfont_load( CFF_SubFont font,
1298 CFF_Index idx,
1299 FT_UInt font_index,
1300 FT_Stream stream,
1301 FT_ULong base_offset,
1302 FT_Library library )
1303 {
1304 FT_Error error;
1305 CFF_ParserRec parser;
1306 FT_Byte* dict = NULL;
1307 FT_ULong dict_len;
1308 CFF_FontRecDict top = &font->font_dict;
1309 CFF_Private priv = &font->private_dict;
1310
1311
1312 cff_parser_init( &parser, CFF_CODE_TOPDICT, &font->font_dict, library );
1313
1314 /* set defaults */
1315 FT_MEM_ZERO( top, sizeof ( *top ) );
1316
1317 top->underline_position = -( 100L << 16 );
1318 top->underline_thickness = 50L << 16;
1319 top->charstring_type = 2;
1320 top->font_matrix.xx = 0x10000L;
1321 top->font_matrix.yy = 0x10000L;
1322 top->cid_count = 8720;
1323
1324 /* we use the implementation specific SID value 0xFFFF to indicate */
1325 /* missing entries */
1326 top->version = 0xFFFFU;
1327 top->notice = 0xFFFFU;
1328 top->copyright = 0xFFFFU;
1329 top->full_name = 0xFFFFU;
1330 top->family_name = 0xFFFFU;
1331 top->weight = 0xFFFFU;
1332 top->embedded_postscript = 0xFFFFU;
1333
1334 top->cid_registry = 0xFFFFU;
1335 top->cid_ordering = 0xFFFFU;
1336 top->cid_font_name = 0xFFFFU;
1337
1338 error = cff_index_access_element( idx, font_index, &dict, &dict_len );
1339 if ( !error )
1340 {
1341 FT_TRACE4(( " top dictionary:\n" ));
1342 error = cff_parser_run( &parser, dict, dict + dict_len );
1343 }
1344
1345 cff_index_forget_element( idx, &dict );
1346
1347 if ( error )
1348 goto Exit;
1349
1350 /* if it is a CID font, we stop there */
1351 if ( top->cid_registry != 0xFFFFU )
1352 goto Exit;
1353
1354 /* parse the private dictionary, if any */
1355 if ( top->private_offset && top->private_size )
1356 {
1357 /* set defaults */
1358 FT_MEM_ZERO( priv, sizeof ( *priv ) );
1359
1360 priv->blue_shift = 7;
1361 priv->blue_fuzz = 1;
1362 priv->lenIV = -1;
1363 priv->expansion_factor = (FT_Fixed)( 0.06 * 0x10000L );
1364 priv->blue_scale = (FT_Fixed)( 0.039625 * 0x10000L * 1000 );
1365
1366 cff_parser_init( &parser, CFF_CODE_PRIVATE, priv, library );
1367
1368 if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
1369 FT_FRAME_ENTER( font->font_dict.private_size ) )
1370 goto Exit;
1371
1372 FT_TRACE4(( " private dictionary:\n" ));
1373 error = cff_parser_run( &parser,
1374 (FT_Byte*)stream->cursor,
1375 (FT_Byte*)stream->limit );
1376 FT_FRAME_EXIT();
1377 if ( error )
1378 goto Exit;
1379
1380 /* ensure that `num_blue_values' is even */
1381 priv->num_blue_values &= ~1;
1382 }
1383
1384 /* read the local subrs, if any */
1385 if ( priv->local_subrs_offset )
1386 {
1387 if ( FT_STREAM_SEEK( base_offset + top->private_offset +
1388 priv->local_subrs_offset ) )
1389 goto Exit;
1390
1391 error = cff_index_init( &font->local_subrs_index, stream, 1 );
1392 if ( error )
1393 goto Exit;
1394
1395 error = cff_index_get_pointers( &font->local_subrs_index,
1396 &font->local_subrs, NULL );
1397 if ( error )
1398 goto Exit;
1399 }
1400
1401 Exit:
1402 return error;
1403 }
1404
1405
1406 static void
1407 cff_subfont_done( FT_Memory memory,
1408 CFF_SubFont subfont )
1409 {
1410 if ( subfont )
1411 {
1412 cff_index_done( &subfont->local_subrs_index );
1413 FT_FREE( subfont->local_subrs );
1414 }
1415 }
1416
1417
1418 FT_LOCAL_DEF( FT_Error )
1419 cff_font_load( FT_Library library,
1420 FT_Stream stream,
1421 FT_Int face_index,
1422 CFF_Font font,
1423 FT_Bool pure_cff )
1424 {
1425 static const FT_Frame_Field cff_header_fields[] =
1426 {
1427 #undef FT_STRUCTURE
1428 #define FT_STRUCTURE CFF_FontRec
1429
1430 FT_FRAME_START( 4 ),
1431 FT_FRAME_BYTE( version_major ),
1432 FT_FRAME_BYTE( version_minor ),
1433 FT_FRAME_BYTE( header_size ),
1434 FT_FRAME_BYTE( absolute_offsize ),
1435 FT_FRAME_END
1436 };
1437
1438 FT_Error error;
1439 FT_Memory memory = stream->memory;
1440 FT_ULong base_offset;
1441 CFF_FontRecDict dict;
1442 CFF_IndexRec string_index;
1443 FT_Int subfont_index;
1444
1445
1446 FT_ZERO( font );
1447 FT_ZERO( &string_index );
1448
1449 font->stream = stream;
1450 font->memory = memory;
1451 dict = &font->top_font.font_dict;
1452 base_offset = FT_STREAM_POS();
1453
1454 /* read CFF font header */
1455 if ( FT_STREAM_READ_FIELDS( cff_header_fields, font ) )
1456 goto Exit;
1457
1458 /* check format */
1459 if ( font->version_major != 1 ||
1460 font->header_size < 4 ||
1461 font->absolute_offsize > 4 )
1462 {
1463 FT_TRACE2(( " not a CFF font header\n" ));
1464 error = FT_THROW( Unknown_File_Format );
1465 goto Exit;
1466 }
1467
1468 /* skip the rest of the header */
1469 if ( FT_STREAM_SKIP( font->header_size - 4 ) )
1470 goto Exit;
1471
1472 /* read the name, top dict, string and global subrs index */
1473 if ( FT_SET_ERROR( cff_index_init( &font->name_index,
1474 stream, 0 ) ) ||
1475 FT_SET_ERROR( cff_index_init( &font->font_dict_index,
1476 stream, 0 ) ) ||
1477 FT_SET_ERROR( cff_index_init( &string_index,
1478 stream, 1 ) ) ||
1479 FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
1480 stream, 1 ) ) ||
1481 FT_SET_ERROR( cff_index_get_pointers( &string_index,
1482 &font->strings,
1483 &font->string_pool ) ) )
1484 goto Exit;
1485
1486 font->num_strings = string_index.count;
1487
1488 if ( pure_cff )
1489 {
1490 /* well, we don't really forget the `disabled' fonts... */
1491 subfont_index = face_index;
1492
1493 if ( subfont_index >= (FT_Int)font->name_index.count )
1494 {
1495 FT_ERROR(( "cff_font_load:"
1496 " invalid subfont index for pure CFF font (%d)\n",
1497 subfont_index ));
1498 error = FT_THROW( Invalid_Argument );
1499 goto Exit;
1500 }
1501
1502 font->num_faces = font->name_index.count;
1503 }
1504 else
1505 {
1506 subfont_index = 0;
1507
1508 if ( font->name_index.count > 1 )
1509 {
1510 FT_ERROR(( "cff_font_load:"
1511 " invalid CFF font with multiple subfonts\n"
1512 " "
1513 " in SFNT wrapper\n" ));
1514 error = FT_THROW( Invalid_File_Format );
1515 goto Exit;
1516 }
1517 }
1518
1519 /* in case of a font format check, simply exit now */
1520 if ( face_index < 0 )
1521 goto Exit;
1522
1523 /* now, parse the top-level font dictionary */
1524 FT_TRACE4(( "parsing top-level\n" ));
1525 error = cff_subfont_load( &font->top_font,
1526 &font->font_dict_index,
1527 subfont_index,
1528 stream,
1529 base_offset,
1530 library );
1531 if ( error )
1532 goto Exit;
1533
1534 if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
1535 goto Exit;
1536
1537 error = cff_index_init( &font->charstrings_index, stream, 0 );
1538 if ( error )
1539 goto Exit;
1540
1541 /* now, check for a CID font */
1542 if ( dict->cid_registry != 0xFFFFU )
1543 {
1544 CFF_IndexRec fd_index;
1545 CFF_SubFont sub = NULL;
1546 FT_UInt idx;
1547
1548
1549 /* this is a CID-keyed font, we must now allocate a table of */
1550 /* sub-fonts, then load each of them separately */
1551 if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
1552 goto Exit;
1553
1554 error = cff_index_init( &fd_index, stream, 0 );
1555 if ( error )
1556 goto Exit;
1557
1558 if ( fd_index.count > CFF_MAX_CID_FONTS )
1559 {
1560 FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
1561 goto Fail_CID;
1562 }
1563
1564 /* allocate & read each font dict independently */
1565 font->num_subfonts = fd_index.count;
1566 if ( FT_NEW_ARRAY( sub, fd_index.count ) )
1567 goto Fail_CID;
1568
1569 /* set up pointer table */
1570 for ( idx = 0; idx < fd_index.count; idx++ )
1571 font->subfonts[idx] = sub + idx;
1572
1573 /* now load each subfont independently */
1574 for ( idx = 0; idx < fd_index.count; idx++ )
1575 {
1576 sub = font->subfonts[idx];
1577 FT_TRACE4(( "parsing subfont %u\n", idx ));
1578 error = cff_subfont_load( sub, &fd_index, idx,
1579 stream, base_offset, library );
1580 if ( error )
1581 goto Fail_CID;
1582 }
1583
1584 /* now load the FD Select array */
1585 error = CFF_Load_FD_Select( &font->fd_select,
1586 font->charstrings_index.count,
1587 stream,
1588 base_offset + dict->cid_fd_select_offset );
1589
1590 Fail_CID:
1591 cff_index_done( &fd_index );
1592
1593 if ( error )
1594 goto Exit;
1595 }
1596 else
1597 font->num_subfonts = 0;
1598
1599 /* read the charstrings index now */
1600 if ( dict->charstrings_offset == 0 )
1601 {
1602 FT_ERROR(( "cff_font_load: no charstrings offset\n" ));
1603 error = FT_THROW( Invalid_File_Format );
1604 goto Exit;
1605 }
1606
1607 font->num_glyphs = font->charstrings_index.count;
1608
1609 error = cff_index_get_pointers( &font->global_subrs_index,
1610 &font->global_subrs, NULL );
1611
1612 if ( error )
1613 goto Exit;
1614
1615 /* read the Charset and Encoding tables if available */
1616 if ( font->num_glyphs > 0 )
1617 {
1618 FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
1619
1620
1621 error = cff_charset_load( &font->charset, font->num_glyphs, stream,
1622 base_offset, dict->charset_offset, invert );
1623 if ( error )
1624 goto Exit;
1625
1626 /* CID-keyed CFFs don't have an encoding */
1627 if ( dict->cid_registry == 0xFFFFU )
1628 {
1629 error = cff_encoding_load( &font->encoding,
1630 &font->charset,
1631 font->num_glyphs,
1632 stream,
1633 base_offset,
1634 dict->encoding_offset );
1635 if ( error )
1636 goto Exit;
1637 }
1638 }
1639
1640 /* get the font name (/CIDFontName for CID-keyed fonts, */
1641 /* /FontName otherwise) */
1642 font->font_name = cff_index_get_name( font, subfont_index );
1643
1644 Exit:
1645 cff_index_done( &string_index );
1646
1647 return error;
1648 }
1649
1650
1651 FT_LOCAL_DEF( void )
1652 cff_font_done( CFF_Font font )
1653 {
1654 FT_Memory memory = font->memory;
1655 FT_UInt idx;
1656
1657
1658 cff_index_done( &font->global_subrs_index );
1659 cff_index_done( &font->font_dict_index );
1660 cff_index_done( &font->name_index );
1661 cff_index_done( &font->charstrings_index );
1662
1663 /* release font dictionaries, but only if working with */
1664 /* a CID keyed CFF font */
1665 if ( font->num_subfonts > 0 )
1666 {
1667 for ( idx = 0; idx < font->num_subfonts; idx++ )
1668 cff_subfont_done( memory, font->subfonts[idx] );
1669
1670 /* the subfonts array has been allocated as a single block */
1671 FT_FREE( font->subfonts[0] );
1672 }
1673
1674 cff_encoding_done( &font->encoding );
1675 cff_charset_done( &font->charset, font->stream );
1676
1677 cff_subfont_done( memory, &font->top_font );
1678
1679 CFF_Done_FD_Select( &font->fd_select, font->stream );
1680
1681 FT_FREE( font->font_info );
1682
1683 FT_FREE( font->font_name );
1684 FT_FREE( font->global_subrs );
1685 FT_FREE( font->strings );
1686 FT_FREE( font->string_pool );
1687
1688 if ( font->cf2_instance.finalizer )
1689 {
1690 font->cf2_instance.finalizer( font->cf2_instance.data );
1691 FT_FREE( font->cf2_instance.data );
1692 }
1693 }
1694
1695
1696 /* END */