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