Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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-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 
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,
228  FT_Bool load )
229  {
230  FT_Error error;
231  FT_Memory memory = stream->memory;
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  {
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  {
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 
471  FT_UInt element,
472  FT_Byte** pbytes,
473  FT_ULong* pbyte_len )
474  {
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 )
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 */
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 */
613  FT_UInt element )
614  {
615  return ( element < font->num_strings )
616  ? (FT_String*)font->strings[element]
617  : NULL;
618  }
619 
620 
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 
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;
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  {
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 
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,
860  FT_Bool invert )
861  {
862  FT_Memory memory = stream->memory;
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  {
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,
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 ) ||
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 
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 )
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 */
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
cff_font_done(CFF_Font font)
Definition: cffload.c:1652
FT_ULong charset_offset
Definition: cfftypes.h:126
int FT_Error
Definition: fttypes.h:296
cff_get_standard_encoding(FT_UInt charcode)
Definition: cffload.c:183
GLuint GLuint stream
for(n=1;n< outline->n_points;n++)
Definition: ftbbox.c:593
cff_index_get_name(CFF_Font font, FT_UInt element)
Definition: cffload.c:583
signed long FT_Long
Definition: fttypes.h:238
unsigned long FT_ULong
Definition: fttypes.h:249
unsigned long size
Definition: ftsystem.h:324
CFF_Charset charset
Definition: cffcmap.c:129
GLfloat GLfloat p
FT_ULong cid_fd_select_offset
Definition: cfftypes.h:145
CFF_IndexRec local_subrs_index
Definition: cfftypes.h:210
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
#define NULL
Definition: ftobjs.h:61
FT_Byte cache_fd
Definition: cfftypes.h:198
signed int FT_Int
Definition: fttypes.h:216
FT_ULong private_offset
Definition: cfftypes.h:129
FT_Byte * data
Definition: cfftypes.h:192
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:216
FT_UInt cache_first
Definition: cfftypes.h:196
FT_Fixed blue_scale
Definition: cfftypes.h:163
unsigned char * cursor
Definition: ftsystem.h:333
FT_Pos blue_shift
Definition: cfftypes.h:164
FT_Fixed underline_position
Definition: cfftypes.h:115
cff_parser_init(CFF_Parser parser, FT_UInt code, void *object, FT_Library library)
Definition: cffparse.c:39
return FT_THROW(Missing_Property)
cff_index_get_string(CFF_Font font, FT_UInt element)
Definition: cffload.c:612
FT_UInt sid
Definition: cffcmap.c:130
FT_Int charstring_type
Definition: cfftypes.h:118
FT_UInt embedded_postscript
Definition: cfftypes.h:132
#define FT_READ_BYTE(var)
Definition: ftstream.h:306
FT_ULong private_size
Definition: cfftypes.h:130
#define CFF_CODE_PRIVATE
Definition: cffparse.h:34
FT_Library library
Definition: cffdrivr.c:414
FT_Fixed underline_thickness
Definition: cfftypes.h:116
return FT_Err_Ok
Definition: ftbbox.c:645
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
FT_Fixed expansion_factor
Definition: cfftypes.h:177
FT_UShort sids[256]
Definition: cfftypes.h:84
FT_UShort codes[256]
Definition: cfftypes.h:85
FT_ULong local_subrs_offset
Definition: cfftypes.h:179
png_uint_32 i
Definition: png.h:2640
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
#define FT_PEEK_OFF3(p)
Definition: ftstream.h:184
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
cff_fd_select_get(CFF_FDSelect fdselect, FT_UInt glyph_index)
Definition: cffload.c:709
unsigned char FT_Byte
Definition: fttypes.h:150
cff_index_access_element(CFF_Index idx, FT_UInt element, FT_Byte **pbytes, FT_ULong *pbyte_len)
Definition: cffload.c:470
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
FT_BEGIN_HEADER struct CFF_IndexRec_ CFF_IndexRec
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:506
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:207
#define FT_PEEK_ULONG(p)
Definition: ftstream.h:179
FT_Memory memory
Definition: ftsystem.h:332
#define FT_GET_USHORT()
Definition: ftstream.h:289
#define FT_FREE(ptr)
Definition: ftmemory.h:286
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:492
FT_ULong charstrings_offset
Definition: cfftypes.h:128
GLboolean invert
cff_index_get_sid_string(CFF_Font font, FT_UInt sid)
Definition: cffload.c:622
FT_ULong cid_fd_array_offset
Definition: cfftypes.h:144
FT_ULong offset
Definition: cfftypes.h:81
FT_UInt idx
Definition: cffcmap.c:127
FT_UInt max_cid
Definition: cfftypes.h:99
FT_Error error
Definition: cffdrivr.c:411
#define CFF_CODE_TOPDICT
Definition: cffparse.h:33
char FT_String
Definition: fttypes.h:183
#define FT_ZERO(p)
Definition: ftmemory.h:210
FT_UInt family_name
Definition: cfftypes.h:111
cff_parser_run(CFF_Parser parser, FT_Byte *start, FT_Byte *limit)
Definition: cffparse.c:933
FT_ULong encoding_offset
Definition: cfftypes.h:127
GLdouble n
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
CFF_PrivateRec private_dict
Definition: cfftypes.h:208
const GLint * first
FT_UShort * cids
Definition: cfftypes.h:97
#define CFF_MAX_CID_FONTS
Definition: cfftypes.h:216
GLintptr offset
#define FT_PEEK_USHORT(p)
Definition: ftstream.h:171
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Fixed xx
Definition: fttypes.h:383
#define FT_BOOL(x)
Definition: fttypes.h:574
FT_Byte ** local_subrs
Definition: cfftypes.h:211
#define FT_FRAME_EXIT()
Definition: ftstream.h:514
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
FT_UInt format
Definition: cfftypes.h:80
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
FT_ULong cid_count
Definition: cfftypes.h:142
GLuint const GLchar * name
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:522
FT_Int lenIV
Definition: cfftypes.h:175
FT_ULong offset
Definition: cfftypes.h:94
#define FT_STREAM_POS()
Definition: ftstream.h:486
FT_UInt cid_font_name
Definition: cfftypes.h:146
FT_Byte format
Definition: cfftypes.h:188
GLdouble GLdouble GLdouble GLdouble top
signed long FT_Fixed
Definition: fttypes.h:284
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
FT_UInt cid_ordering
Definition: cfftypes.h:136
GLuint64EXT * result
local void * load(const char *name, size_t *len)
Definition: pufftest.c:60
unsigned int FT_UInt
Definition: fttypes.h:227
FT_UInt cache_count
Definition: cfftypes.h:197
#define FT_FRAME_BYTE(f)
Definition: ftstream.h:126
FT_Matrix font_matrix
Definition: cfftypes.h:119
unsigned char * limit
Definition: ftsystem.h:334
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:517
cff_charset_cid_to_gindex(CFF_Charset charset, FT_UInt cid)
Definition: cffload.c:817
FT_Byte num_blue_values
Definition: cfftypes.h:153
FT_Pos blue_fuzz
Definition: cfftypes.h:165
GLuint GLuint GLsizei count
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:510
FT_Fixed yy
Definition: fttypes.h:384
GLdouble GLdouble t
FT_UInt num_glyphs
Definition: cfftypes.h:100
FT_TRACE0(("cff_property_set: missing property `%s'\, property_name))
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:203
FT_UInt count
Definition: cfftypes.h:83
FT_UShort * sids
Definition: cfftypes.h:96
FT_UInt format
Definition: cfftypes.h:93
unsigned short FT_UShort
Definition: fttypes.h:205
GLenum GLsizei GLenum GLenum const GLvoid * table
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:495
GLsizeiptr size
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
FT_UInt data_size
Definition: cfftypes.h:193
FT_UInt cid_registry
Definition: cfftypes.h:135
#define FT_FRAME_START(size)
Definition: ftstream.h:117
GLint limit
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
cff_index_forget_element(CFF_Index idx, FT_Byte **pbytes)
Definition: cffload.c:568
cff_font_load(FT_Library library, FT_Stream stream, FT_Int face_index, CFF_Font font, FT_Bool pure_cff)
Definition: cffload.c:1419
FT_UInt range_count
Definition: cfftypes.h:189
FT_BEGIN_HEADER struct CFF_IndexRec_ * CFF_Index