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