ReactOS  0.4.13-dev-544-gede3fdd
sfobjs.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* sfobjs.c */
4 /* */
5 /* SFNT object management (base). */
6 /* */
7 /* Copyright 1996-2018 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 "sfobjs.h"
21 #include "ttload.h"
22 #include "ttcmap.h"
23 #include "ttkern.h"
24 #include FT_INTERNAL_SFNT_H
25 #include FT_INTERNAL_DEBUG_H
26 #include FT_TRUETYPE_IDS_H
27 #include FT_TRUETYPE_TAGS_H
28 #include FT_SERVICE_POSTSCRIPT_CMAPS_H
29 #include FT_SFNT_NAMES_H
30 #include FT_GZIP_H
31 
32 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
33 #include FT_SERVICE_MULTIPLE_MASTERS_H
34 #include FT_SERVICE_METRICS_VARIATIONS_H
35 #endif
36 
37 #include "sferrors.h"
38 
39 #ifdef TT_CONFIG_OPTION_BDF
40 #include "ttbdf.h"
41 #endif
42 
43 
44  /*************************************************************************/
45  /* */
46  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
47  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
48  /* messages during execution. */
49  /* */
50 #undef FT_COMPONENT
51 #define FT_COMPONENT trace_sfobjs
52 
53 
54 
55  /* convert a UTF-16 name entry to ASCII */
56  static FT_String*
59  {
60  FT_String* string = NULL;
61  FT_UInt len, code, n;
62  FT_Byte* read = (FT_Byte*)entry->string;
64 
65 
66  len = (FT_UInt)entry->stringLength / 2;
67 
68  if ( FT_NEW_ARRAY( string, len + 1 ) )
69  return NULL;
70 
71  for ( n = 0; n < len; n++ )
72  {
74 
75  if ( code == 0 )
76  break;
77 
78  if ( code < 32 || code > 127 )
79  code = '?';
80 
81  string[n] = (char)code;
82  }
83 
84  string[n] = 0;
85 
86  return string;
87  }
88 
89 
90  /* convert an Apple Roman or symbol name entry to ASCII */
91  static FT_String*
94  {
95  FT_String* string = NULL;
96  FT_UInt len, code, n;
97  FT_Byte* read = (FT_Byte*)entry->string;
99 
100 
101  len = (FT_UInt)entry->stringLength;
102 
103  if ( FT_NEW_ARRAY( string, len + 1 ) )
104  return NULL;
105 
106  for ( n = 0; n < len; n++ )
107  {
108  code = *read++;
109 
110  if ( code == 0 )
111  break;
112 
113  if ( code < 32 || code > 127 )
114  code = '?';
115 
116  string[n] = (char)code;
117  }
118 
119  string[n] = 0;
120 
121  return string;
122  }
123 
124 
125  typedef FT_String* (*TT_Name_ConvertFunc)( TT_Name entry,
126  FT_Memory memory );
127 
128 
129  /* documentation is in sfnt.h */
130 
133  FT_UShort nameid,
134  FT_String** name )
135  {
136  FT_Memory memory = face->root.memory;
138  FT_String* result = NULL;
139  FT_UShort n;
140  TT_Name rec;
141 
142  FT_Int found_apple = -1;
143  FT_Int found_apple_roman = -1;
144  FT_Int found_apple_english = -1;
145  FT_Int found_win = -1;
146  FT_Int found_unicode = -1;
147 
148  FT_Bool is_english = 0;
149 
151 
152 
153  FT_ASSERT( name );
154 
155  rec = face->name_table.names;
156  for ( n = 0; n < face->num_names; n++, rec++ )
157  {
158  /* According to the OpenType 1.3 specification, only Microsoft or */
159  /* Apple platform IDs might be used in the `name' table. The */
160  /* `Unicode' platform is reserved for the `cmap' table, and the */
161  /* `ISO' one is deprecated. */
162  /* */
163  /* However, the Apple TrueType specification doesn't say the same */
164  /* thing and goes to suggest that all Unicode `name' table entries */
165  /* should be coded in UTF-16 (in big-endian format I suppose). */
166  /* */
167  if ( rec->nameID == nameid && rec->stringLength > 0 )
168  {
169  switch ( rec->platformID )
170  {
172  case TT_PLATFORM_ISO:
173  /* there is `languageID' to check there. We should use this */
174  /* field only as a last solution when nothing else is */
175  /* available. */
176  /* */
177  found_unicode = n;
178  break;
179 
181  /* This is a bit special because some fonts will use either */
182  /* an English language id, or a Roman encoding id, to indicate */
183  /* the English version of its font name. */
184  /* */
185  if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
186  found_apple_english = n;
187  else if ( rec->encodingID == TT_MAC_ID_ROMAN )
188  found_apple_roman = n;
189  break;
190 
192  /* we only take a non-English name when there is nothing */
193  /* else available in the font */
194  /* */
195  if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )
196  {
197  switch ( rec->encodingID )
198  {
199  case TT_MS_ID_SYMBOL_CS:
200  case TT_MS_ID_UNICODE_CS:
201  case TT_MS_ID_UCS_4:
202  is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
203  found_win = n;
204  break;
205 
206  default:
207  ;
208  }
209  }
210  break;
211 
212  default:
213  ;
214  }
215  }
216  }
217 
218  found_apple = found_apple_roman;
219  if ( found_apple_english >= 0 )
220  found_apple = found_apple_english;
221 
222  /* some fonts contain invalid Unicode or Macintosh formatted entries; */
223  /* we will thus favor names encoded in Windows formats if available */
224  /* (provided it is an English name) */
225  /* */
226  convert = NULL;
227  if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )
228  {
229  rec = face->name_table.names + found_win;
230  switch ( rec->encodingID )
231  {
232  /* all Unicode strings are encoded using UTF-16BE */
233  case TT_MS_ID_UNICODE_CS:
234  case TT_MS_ID_SYMBOL_CS:
236  break;
237 
238  case TT_MS_ID_UCS_4:
239  /* Apparently, if this value is found in a name table entry, it is */
240  /* documented as `full Unicode repertoire'. Experience with the */
241  /* MsGothic font shipped with Windows Vista shows that this really */
242  /* means UTF-16 encoded names (UCS-4 values are only used within */
243  /* charmaps). */
245  break;
246 
247  default:
248  ;
249  }
250  }
251  else if ( found_apple >= 0 )
252  {
253  rec = face->name_table.names + found_apple;
255  }
256  else if ( found_unicode >= 0 )
257  {
258  rec = face->name_table.names + found_unicode;
260  }
261 
262  if ( rec && convert )
263  {
264  if ( !rec->string )
265  {
266  FT_Stream stream = face->name_table.stream;
267 
268 
269  if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
270  FT_STREAM_SEEK( rec->stringOffset ) ||
271  FT_STREAM_READ( rec->string, rec->stringLength ) )
272  {
273  FT_FREE( rec->string );
274  rec->stringLength = 0;
275  result = NULL;
276  goto Exit;
277  }
278  }
279 
280  result = convert( rec, memory );
281  }
282 
283  Exit:
284  *name = result;
285  return error;
286  }
287 
288 
289  static FT_Encoding
290  sfnt_find_encoding( int platform_id,
291  int encoding_id )
292  {
293  typedef struct TEncoding_
294  {
295  int platform_id;
296  int encoding_id;
298 
299  } TEncoding;
300 
301  static
302  const TEncoding tt_encodings[] =
303  {
304  { TT_PLATFORM_ISO, -1, FT_ENCODING_UNICODE },
305 
306  { TT_PLATFORM_APPLE_UNICODE, -1, FT_ENCODING_UNICODE },
307 
308  { TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, FT_ENCODING_APPLE_ROMAN },
309 
310  { TT_PLATFORM_MICROSOFT, TT_MS_ID_SYMBOL_CS, FT_ENCODING_MS_SYMBOL },
311  { TT_PLATFORM_MICROSOFT, TT_MS_ID_UCS_4, FT_ENCODING_UNICODE },
312  { TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
313  { TT_PLATFORM_MICROSOFT, TT_MS_ID_SJIS, FT_ENCODING_SJIS },
314  { TT_PLATFORM_MICROSOFT, TT_MS_ID_PRC, FT_ENCODING_PRC },
315  { TT_PLATFORM_MICROSOFT, TT_MS_ID_BIG_5, FT_ENCODING_BIG5 },
316  { TT_PLATFORM_MICROSOFT, TT_MS_ID_WANSUNG, FT_ENCODING_WANSUNG },
317  { TT_PLATFORM_MICROSOFT, TT_MS_ID_JOHAB, FT_ENCODING_JOHAB }
318  };
319 
320  const TEncoding *cur, *limit;
321 
322 
323  cur = tt_encodings;
324  limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
325 
326  for ( ; cur < limit; cur++ )
327  {
328  if ( cur->platform_id == platform_id )
329  {
330  if ( cur->encoding_id == encoding_id ||
331  cur->encoding_id == -1 )
332  return cur->encoding;
333  }
334  }
335 
336  return FT_ENCODING_NONE;
337  }
338 
339 
340 #define WRITE_USHORT( p, v ) \
341  do \
342  { \
343  *(p)++ = (FT_Byte)( (v) >> 8 ); \
344  *(p)++ = (FT_Byte)( (v) >> 0 ); \
345  \
346  } while ( 0 )
347 
348 #define WRITE_ULONG( p, v ) \
349  do \
350  { \
351  *(p)++ = (FT_Byte)( (v) >> 24 ); \
352  *(p)++ = (FT_Byte)( (v) >> 16 ); \
353  *(p)++ = (FT_Byte)( (v) >> 8 ); \
354  *(p)++ = (FT_Byte)( (v) >> 0 ); \
355  \
356  } while ( 0 )
357 
358 
359  static void
361  {
362  FT_Memory memory = stream->memory;
363 
364 
365  FT_FREE( stream->base );
366 
367  stream->size = 0;
368  stream->base = NULL;
369  stream->close = NULL;
370  }
371 
372 
373  FT_CALLBACK_DEF( int )
375  const void* b )
376  {
377  WOFF_Table table1 = *(WOFF_Table*)a;
378  WOFF_Table table2 = *(WOFF_Table*)b;
379 
380  FT_ULong offset1 = table1->Offset;
381  FT_ULong offset2 = table2->Offset;
382 
383 
384  if ( offset1 > offset2 )
385  return 1;
386  else if ( offset1 < offset2 )
387  return -1;
388  else
389  return 0;
390  }
391 
392 
393  /* Replace `face->root.stream' with a stream containing the extracted */
394  /* SFNT of a WOFF font. */
395 
396  static FT_Error
398  TT_Face face )
399  {
400  FT_Memory memory = stream->memory;
402 
403  WOFF_HeaderRec woff;
406 
407  FT_ULong woff_offset;
408 
409  FT_Byte* sfnt = NULL;
410  FT_Stream sfnt_stream = NULL;
411 
412  FT_Byte* sfnt_header;
413  FT_ULong sfnt_offset;
414 
415  FT_Int nn;
416  FT_ULong old_tag = 0;
417 
418  static const FT_Frame_Field woff_header_fields[] =
419  {
420 #undef FT_STRUCTURE
421 #define FT_STRUCTURE WOFF_HeaderRec
422 
423  FT_FRAME_START( 44 ),
424  FT_FRAME_ULONG ( signature ),
425  FT_FRAME_ULONG ( flavor ),
427  FT_FRAME_USHORT( num_tables ),
429  FT_FRAME_ULONG ( totalSfntSize ),
430  FT_FRAME_USHORT( majorVersion ),
431  FT_FRAME_USHORT( minorVersion ),
432  FT_FRAME_ULONG ( metaOffset ),
433  FT_FRAME_ULONG ( metaLength ),
434  FT_FRAME_ULONG ( metaOrigLength ),
435  FT_FRAME_ULONG ( privOffset ),
436  FT_FRAME_ULONG ( privLength ),
438  };
439 
440 
441  FT_ASSERT( stream == face->root.stream );
442  FT_ASSERT( FT_STREAM_POS() == 0 );
443 
444  if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) )
445  return error;
446 
447  /* Make sure we don't recurse back here or hit TTC code. */
448  if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf )
449  return FT_THROW( Invalid_Table );
450 
451  /* Miscellaneous checks. */
452  if ( woff.length != stream->size ||
453  woff.num_tables == 0 ||
454  44 + woff.num_tables * 20UL >= woff.length ||
455  12 + woff.num_tables * 16UL >= woff.totalSfntSize ||
456  ( woff.totalSfntSize & 3 ) != 0 ||
457  ( woff.metaOffset == 0 && ( woff.metaLength != 0 ||
458  woff.metaOrigLength != 0 ) ) ||
459  ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) ||
460  ( woff.privOffset == 0 && woff.privLength != 0 ) )
461  {
462  FT_ERROR(( "woff_font_open: invalid WOFF header\n" ));
463  return FT_THROW( Invalid_Table );
464  }
465 
466  /* Don't trust `totalSfntSize' before thorough checks. */
467  if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) ||
468  FT_NEW( sfnt_stream ) )
469  goto Exit;
470 
471  sfnt_header = sfnt;
472 
473  /* Write sfnt header. */
474  {
475  FT_UInt searchRange, entrySelector, rangeShift, x;
476 
477 
478  x = woff.num_tables;
479  entrySelector = 0;
480  while ( x )
481  {
482  x >>= 1;
483  entrySelector += 1;
484  }
485  entrySelector--;
486 
487  searchRange = ( 1 << entrySelector ) * 16;
488  rangeShift = woff.num_tables * 16 - searchRange;
489 
490  WRITE_ULONG ( sfnt_header, woff.flavor );
491  WRITE_USHORT( sfnt_header, woff.num_tables );
492  WRITE_USHORT( sfnt_header, searchRange );
493  WRITE_USHORT( sfnt_header, entrySelector );
494  WRITE_USHORT( sfnt_header, rangeShift );
495  }
496 
497  /* While the entries in the sfnt header must be sorted by the */
498  /* tag value, the tables themselves are not. We thus have to */
499  /* sort them by offset and check that they don't overlap. */
500 
501  if ( FT_NEW_ARRAY( tables, woff.num_tables ) ||
502  FT_NEW_ARRAY( indices, woff.num_tables ) )
503  goto Exit;
504 
505  FT_TRACE2(( "\n"
506  " tag offset compLen origLen checksum\n"
507  " -------------------------------------------\n" ));
508 
509  if ( FT_FRAME_ENTER( 20L * woff.num_tables ) )
510  goto Exit;
511 
512  for ( nn = 0; nn < woff.num_tables; nn++ )
513  {
514  WOFF_Table table = tables + nn;
515 
516  table->Tag = FT_GET_TAG4();
517  table->Offset = FT_GET_ULONG();
518  table->CompLength = FT_GET_ULONG();
519  table->OrigLength = FT_GET_ULONG();
520  table->CheckSum = FT_GET_ULONG();
521 
522  FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n",
523  (FT_Char)( table->Tag >> 24 ),
524  (FT_Char)( table->Tag >> 16 ),
525  (FT_Char)( table->Tag >> 8 ),
526  (FT_Char)( table->Tag ),
527  table->Offset,
528  table->CompLength,
529  table->OrigLength,
530  table->CheckSum ));
531 
532  if ( table->Tag <= old_tag )
533  {
534  FT_FRAME_EXIT();
535 
536  FT_ERROR(( "woff_font_open: table tags are not sorted\n" ));
537  error = FT_THROW( Invalid_Table );
538  goto Exit;
539  }
540 
541  old_tag = table->Tag;
542  indices[nn] = table;
543  }
544 
545  FT_FRAME_EXIT();
546 
547  /* Sort by offset. */
548 
549  ft_qsort( indices,
550  woff.num_tables,
551  sizeof ( WOFF_Table ),
552  compare_offsets );
553 
554  /* Check offsets and lengths. */
555 
556  woff_offset = 44 + woff.num_tables * 20L;
557  sfnt_offset = 12 + woff.num_tables * 16L;
558 
559  for ( nn = 0; nn < woff.num_tables; nn++ )
560  {
561  WOFF_Table table = indices[nn];
562 
563 
564  if ( table->Offset != woff_offset ||
565  table->CompLength > woff.length ||
566  table->Offset > woff.length - table->CompLength ||
567  table->OrigLength > woff.totalSfntSize ||
568  sfnt_offset > woff.totalSfntSize - table->OrigLength ||
569  table->CompLength > table->OrigLength )
570  {
571  FT_ERROR(( "woff_font_open: invalid table offsets\n" ));
572  error = FT_THROW( Invalid_Table );
573  goto Exit;
574  }
575 
576  table->OrigOffset = sfnt_offset;
577 
578  /* The offsets must be multiples of 4. */
579  woff_offset += ( table->CompLength + 3 ) & ~3U;
580  sfnt_offset += ( table->OrigLength + 3 ) & ~3U;
581  }
582 
583  /*
584  * Final checks!
585  *
586  * We don't decode and check the metadata block.
587  * We don't check table checksums either.
588  * But other than those, I think we implement all
589  * `MUST' checks from the spec.
590  */
591 
592  if ( woff.metaOffset )
593  {
594  if ( woff.metaOffset != woff_offset ||
595  woff.metaOffset + woff.metaLength > woff.length )
596  {
597  FT_ERROR(( "woff_font_open:"
598  " invalid `metadata' offset or length\n" ));
599  error = FT_THROW( Invalid_Table );
600  goto Exit;
601  }
602 
603  /* We have padding only ... */
604  woff_offset += woff.metaLength;
605  }
606 
607  if ( woff.privOffset )
608  {
609  /* ... if it isn't the last block. */
610  woff_offset = ( woff_offset + 3 ) & ~3U;
611 
612  if ( woff.privOffset != woff_offset ||
613  woff.privOffset + woff.privLength > woff.length )
614  {
615  FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" ));
616  error = FT_THROW( Invalid_Table );
617  goto Exit;
618  }
619 
620  /* No padding for the last block. */
621  woff_offset += woff.privLength;
622  }
623 
624  if ( sfnt_offset != woff.totalSfntSize ||
625  woff_offset != woff.length )
626  {
627  FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" ));
628  error = FT_THROW( Invalid_Table );
629  goto Exit;
630  }
631 
632  /* Now use `totalSfntSize'. */
633  if ( FT_REALLOC( sfnt,
634  12 + woff.num_tables * 16UL,
635  woff.totalSfntSize ) )
636  goto Exit;
637 
638  sfnt_header = sfnt + 12;
639 
640  /* Write the tables. */
641 
642  for ( nn = 0; nn < woff.num_tables; nn++ )
643  {
644  WOFF_Table table = tables + nn;
645 
646 
647  /* Write SFNT table entry. */
648  WRITE_ULONG( sfnt_header, table->Tag );
649  WRITE_ULONG( sfnt_header, table->CheckSum );
650  WRITE_ULONG( sfnt_header, table->OrigOffset );
651  WRITE_ULONG( sfnt_header, table->OrigLength );
652 
653  /* Write table data. */
654  if ( FT_STREAM_SEEK( table->Offset ) ||
655  FT_FRAME_ENTER( table->CompLength ) )
656  goto Exit;
657 
658  if ( table->CompLength == table->OrigLength )
659  {
660  /* Uncompressed data; just copy. */
661  ft_memcpy( sfnt + table->OrigOffset,
662  stream->cursor,
663  table->OrigLength );
664  }
665  else
666  {
667 #ifdef FT_CONFIG_OPTION_USE_ZLIB
668 
669  /* Uncompress with zlib. */
670  FT_ULong output_len = table->OrigLength;
671 
672 
674  sfnt + table->OrigOffset, &output_len,
675  stream->cursor, table->CompLength );
676  if ( error )
677  goto Exit;
678  if ( output_len != table->OrigLength )
679  {
680  FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
681  error = FT_THROW( Invalid_Table );
682  goto Exit;
683  }
684 
685 #else /* !FT_CONFIG_OPTION_USE_ZLIB */
686 
687  error = FT_THROW( Unimplemented_Feature );
688  goto Exit;
689 
690 #endif /* !FT_CONFIG_OPTION_USE_ZLIB */
691  }
692 
693  FT_FRAME_EXIT();
694 
695  /* We don't check whether the padding bytes in the WOFF file are */
696  /* actually '\0'. For the output, however, we do set them properly. */
697  sfnt_offset = table->OrigOffset + table->OrigLength;
698  while ( sfnt_offset & 3 )
699  {
700  sfnt[sfnt_offset] = '\0';
701  sfnt_offset++;
702  }
703  }
704 
705  /* Ok! Finally ready. Swap out stream and return. */
706  FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize );
707  sfnt_stream->memory = stream->memory;
708  sfnt_stream->close = sfnt_stream_close;
709 
711  face->root.stream,
712  ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
713 
714  face->root.stream = sfnt_stream;
715 
716  face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
717 
718  Exit:
719  FT_FREE( tables );
720  FT_FREE( indices );
721 
722  if ( error )
723  {
724  FT_FREE( sfnt );
725  FT_Stream_Close( sfnt_stream );
726  FT_FREE( sfnt_stream );
727  }
728 
729  return error;
730  }
731 
732 
733 #undef WRITE_USHORT
734 #undef WRITE_ULONG
735 
736 
737  /* Fill in face->ttc_header. If the font is not a TTC, it is */
738  /* synthesized into a TTC with one offset table. */
739  static FT_Error
741  TT_Face face )
742  {
743  FT_Memory memory = stream->memory;
744  FT_Error error;
746 
747  static const FT_Frame_Field ttc_header_fields[] =
748  {
749 #undef FT_STRUCTURE
750 #define FT_STRUCTURE TTC_HeaderRec
751 
752  FT_FRAME_START( 8 ),
754  FT_FRAME_LONG( count ), /* this is ULong in the specs */
756  };
757 
758 
759  face->ttc_header.tag = 0;
760  face->ttc_header.version = 0;
761  face->ttc_header.count = 0;
762 
763  retry:
764  offset = FT_STREAM_POS();
765 
766  if ( FT_READ_ULONG( tag ) )
767  return error;
768 
769  if ( tag == TTAG_wOFF )
770  {
771  FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));
772 
773  if ( FT_STREAM_SEEK( offset ) )
774  return error;
775 
777  if ( error )
778  return error;
779 
780  /* Swap out stream and retry! */
781  stream = face->root.stream;
782  goto retry;
783  }
784 
785  if ( tag != 0x00010000UL &&
786  tag != TTAG_ttcf &&
787  tag != TTAG_OTTO &&
788  tag != TTAG_true &&
789  tag != TTAG_typ1 &&
790  tag != TTAG_0xA5kbd &&
791  tag != TTAG_0xA5lst &&
792  tag != 0x00020000UL )
793  {
794  FT_TRACE2(( " not a font using the SFNT container format\n" ));
795  return FT_THROW( Unknown_File_Format );
796  }
797 
798  face->ttc_header.tag = TTAG_ttcf;
799 
800  if ( tag == TTAG_ttcf )
801  {
802  FT_Int n;
803 
804 
805  FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
806 
807  if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
808  return error;
809 
810  FT_TRACE3(( " with %ld subfonts\n",
811  face->ttc_header.count ));
812 
813  if ( face->ttc_header.count == 0 )
814  return FT_THROW( Invalid_Table );
815 
816  /* a rough size estimate: let's conservatively assume that there */
817  /* is just a single table info in each subfont header (12 + 16*1 = */
818  /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
819  /* size of the TTC header plus `28*count' bytes for all subfont */
820  /* headers */
821  if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
822  return FT_THROW( Array_Too_Large );
823 
824  /* now read the offsets of each font in the file */
825  if ( FT_NEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
826  return error;
827 
828  if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
829  return error;
830 
831  for ( n = 0; n < face->ttc_header.count; n++ )
832  face->ttc_header.offsets[n] = FT_GET_ULONG();
833 
834  FT_FRAME_EXIT();
835  }
836  else
837  {
838  FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
839 
840  face->ttc_header.version = 1 << 16;
841  face->ttc_header.count = 1;
842 
843  if ( FT_NEW( face->ttc_header.offsets ) )
844  return error;
845 
846  face->ttc_header.offsets[0] = offset;
847  }
848 
849  return error;
850  }
851 
852 
855  TT_Face face,
856  FT_Int face_instance_index,
857  FT_Int num_params,
859  {
860  FT_Error error;
861  FT_Library library = face->root.driver->root.library;
863  FT_Int face_index;
864 
865 
866  /* for now, parameters are unused */
867  FT_UNUSED( num_params );
868  FT_UNUSED( params );
869 
870 
871  sfnt = (SFNT_Service)face->sfnt;
872  if ( !sfnt )
873  {
875  if ( !sfnt )
876  {
877  FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
878  return FT_THROW( Missing_Module );
879  }
880 
881  face->sfnt = sfnt;
883  }
884 
885  FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
886 
887 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
888  if ( !face->mm )
889  {
890  /* we want the MM interface from the `truetype' module only */
891  FT_Module tt_module = FT_Get_Module( library, "truetype" );
892 
893 
894  face->mm = ft_module_get_service( tt_module,
896  0 );
897  }
898 
899  if ( !face->var )
900  {
901  /* we want the metrics variations interface */
902  /* from the `truetype' module only */
903  FT_Module tt_module = FT_Get_Module( library, "truetype" );
904 
905 
906  face->var = ft_module_get_service( tt_module,
908  0 );
909  }
910 #endif
911 
912  FT_TRACE2(( "SFNT driver\n" ));
913 
915  if ( error )
916  return error;
917 
918  /* Stream may have changed in sfnt_open_font. */
919  stream = face->root.stream;
920 
921  FT_TRACE2(( "sfnt_init_face: %08p, %d\n", face, face_instance_index ));
922 
923  face_index = FT_ABS( face_instance_index ) & 0xFFFF;
924 
925  /* value -(N+1) requests information on index N */
926  if ( face_instance_index < 0 )
927  face_index--;
928 
929  if ( face_index >= face->ttc_header.count )
930  {
931  if ( face_instance_index >= 0 )
932  return FT_THROW( Invalid_Argument );
933  else
934  face_index = 0;
935  }
936 
937  if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
938  return error;
939 
940  /* check whether we have a valid TrueType file */
942  if ( error )
943  return error;
944 
945 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
946  {
947  FT_Memory memory = face->root.memory;
948 
949  FT_ULong fvar_len;
950 
953 
954  FT_UShort num_axes;
955  FT_UShort axis_size;
956  FT_UShort num_instances;
957  FT_UShort instance_size;
958 
959  FT_Int instance_index;
960 
961  FT_Byte* default_values = NULL;
962  FT_Byte* instance_values = NULL;
963 
964 
965  instance_index = FT_ABS( face_instance_index ) >> 16;
966 
967  /* test whether current face is a GX font with named instances */
968  if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) ||
969  fvar_len < 20 ||
970  FT_READ_ULONG( version ) ||
971  FT_READ_USHORT( offset ) ||
972  FT_STREAM_SKIP( 2 ) /* reserved */ ||
973  FT_READ_USHORT( num_axes ) ||
974  FT_READ_USHORT( axis_size ) ||
975  FT_READ_USHORT( num_instances ) ||
976  FT_READ_USHORT( instance_size ) )
977  {
978  version = 0;
979  offset = 0;
980  num_axes = 0;
981  axis_size = 0;
982  num_instances = 0;
983  instance_size = 0;
984  }
985 
986  /* check that the data is bound by the table length */
987  if ( version != 0x00010000UL ||
988  axis_size != 20 ||
989  num_axes == 0 ||
990  /* `num_axes' limit implied by 16-bit `instance_size' */
991  num_axes > 0x3FFE ||
992  !( instance_size == 4 + 4 * num_axes ||
993  instance_size == 6 + 4 * num_axes ) ||
994  /* `num_instances' limit implied by limited range of name IDs */
995  num_instances > 0x7EFF ||
996  offset +
997  axis_size * num_axes +
998  instance_size * num_instances > fvar_len )
999  num_instances = 0;
1000  else
1001  face->variation_support |= TT_FACE_FLAG_VAR_FVAR;
1002 
1003  /*
1004  * As documented in the OpenType specification, an entry for the
1005  * default instance may be omitted in the named instance table. In
1006  * particular this means that even if there is no named instance
1007  * table in the font we actually do have a named instance, namely the
1008  * default instance.
1009  *
1010  * For consistency, we always want the default instance in our list
1011  * of named instances. If it is missing, we try to synthesize it
1012  * later on. Here, we have to adjust `num_instances' accordingly.
1013  */
1014 
1015  if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) &&
1016  !( FT_ALLOC( default_values, num_axes * 4 ) ||
1017  FT_ALLOC( instance_values, num_axes * 4 ) ) )
1018  {
1019  /* the current stream position is 16 bytes after the table start */
1020  FT_ULong array_start = FT_STREAM_POS() - 16 + offset;
1021  FT_ULong default_value_offset, instance_offset;
1022 
1023  FT_Byte* p;
1024  FT_UInt i;
1025 
1026 
1027  default_value_offset = array_start + 8;
1028  p = default_values;
1029 
1030  for ( i = 0; i < num_axes; i++ )
1031  {
1032  (void)FT_STREAM_READ_AT( default_value_offset, p, 4 );
1033 
1034  default_value_offset += axis_size;
1035  p += 4;
1036  }
1037 
1038  instance_offset = array_start + axis_size * num_axes + 4;
1039 
1040  for ( i = 0; i < num_instances; i++ )
1041  {
1042  (void)FT_STREAM_READ_AT( instance_offset,
1043  instance_values,
1044  num_axes * 4 );
1045 
1046  if ( !ft_memcmp( default_values, instance_values, num_axes * 4 ) )
1047  break;
1048 
1049  instance_offset += instance_size;
1050  }
1051 
1052  if ( i == num_instances )
1053  {
1054  /* no default instance in named instance table; */
1055  /* we thus have to synthesize it */
1056  num_instances++;
1057  }
1058  }
1059 
1060  FT_FREE( default_values );
1061  FT_FREE( instance_values );
1062 
1063  /* we don't support Multiple Master CFFs yet; */
1064  /* note that `glyf' or `CFF2' have precedence */
1065  if ( face->goto_table( face, TTAG_glyf, stream, 0 ) &&
1066  face->goto_table( face, TTAG_CFF2, stream, 0 ) &&
1067  !face->goto_table( face, TTAG_CFF, stream, 0 ) )
1068  num_instances = 0;
1069 
1070  /* instance indices in `face_instance_index' start with index 1, */
1071  /* thus `>' and not `>=' */
1072  if ( instance_index > num_instances )
1073  {
1074  if ( face_instance_index >= 0 )
1075  return FT_THROW( Invalid_Argument );
1076  else
1077  num_instances = 0;
1078  }
1079 
1080  face->root.style_flags = (FT_Long)num_instances << 16;
1081  }
1082 #endif
1083 
1084  face->root.num_faces = face->ttc_header.count;
1085  face->root.face_index = face_instance_index;
1086 
1087  return error;
1088  }
1089 
1090 
1091 #define LOAD_( x ) \
1092  do \
1093  { \
1094  FT_TRACE2(( "`" #x "' " )); \
1095  FT_TRACE3(( "-->\n" )); \
1096  \
1097  error = sfnt->load_ ## x( face, stream ); \
1098  \
1099  FT_TRACE2(( "%s\n", ( !error ) \
1100  ? "loaded" \
1101  : FT_ERR_EQ( error, Table_Missing ) \
1102  ? "missing" \
1103  : "failed to load" )); \
1104  FT_TRACE3(( "\n" )); \
1105  } while ( 0 )
1106 
1107 #define LOADM_( x, vertical ) \
1108  do \
1109  { \
1110  FT_TRACE2(( "`%s" #x "' ", \
1111  vertical ? "vertical " : "" )); \
1112  FT_TRACE3(( "-->\n" )); \
1113  \
1114  error = sfnt->load_ ## x( face, stream, vertical ); \
1115  \
1116  FT_TRACE2(( "%s\n", ( !error ) \
1117  ? "loaded" \
1118  : FT_ERR_EQ( error, Table_Missing ) \
1119  ? "missing" \
1120  : "failed to load" )); \
1121  FT_TRACE3(( "\n" )); \
1122  } while ( 0 )
1123 
1124 #define GET_NAME( id, field ) \
1125  do \
1126  { \
1127  error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
1128  if ( error ) \
1129  goto Exit; \
1130  } while ( 0 )
1131 
1132 
1135  TT_Face face,
1136  FT_Int face_instance_index,
1137  FT_Int num_params,
1138  FT_Parameter* params )
1139  {
1140  FT_Error error;
1141 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
1142  FT_Error psnames_error;
1143 #endif
1144  FT_Bool has_outline;
1145  FT_Bool is_apple_sbit;
1146  FT_Bool is_apple_sbix;
1147  FT_Bool ignore_typographic_family = FALSE;
1148  FT_Bool ignore_typographic_subfamily = FALSE;
1149 
1151 
1152  FT_UNUSED( face_instance_index );
1153 
1154 
1155  /* Check parameters */
1156 
1157  {
1158  FT_Int i;
1159 
1160 
1161  for ( i = 0; i < num_params; i++ )
1162  {
1164  ignore_typographic_family = TRUE;
1166  ignore_typographic_subfamily = TRUE;
1167  }
1168  }
1169 
1170  /* Load tables */
1171 
1172  /* We now support two SFNT-based bitmapped font formats. They */
1173  /* are recognized easily as they do not include a `glyf' */
1174  /* table. */
1175  /* */
1176  /* The first format comes from Apple, and uses a table named */
1177  /* `bhed' instead of `head' to store the font header (using */
1178  /* the same format). It also doesn't include horizontal and */
1179  /* vertical metrics tables (i.e. `hhea' and `vhea' tables are */
1180  /* missing). */
1181  /* */
1182  /* The other format comes from Microsoft, and is used with */
1183  /* WinCE/PocketPC. It looks like a standard TTF, except that */
1184  /* it doesn't contain outlines. */
1185  /* */
1186 
1187  FT_TRACE2(( "sfnt_load_face: %08p\n\n", face ));
1188 
1189  /* do we have outlines in there? */
1190 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1191  has_outline = FT_BOOL( face->root.internal->incremental_interface ||
1195 #else
1196  has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) ||
1199 #endif
1200 
1201  is_apple_sbit = 0;
1202  is_apple_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
1203 
1204  /* Apple 'sbix' color bitmaps are rendered scaled and then the 'glyf'
1205  * outline rendered on top. We don't support that yet, so just ignore
1206  * the 'glyf' outline and advertise it as a bitmap-only font. */
1207  if ( is_apple_sbix )
1208  has_outline = FALSE;
1209 
1210  /* if this font doesn't contain outlines, we try to load */
1211  /* a `bhed' table */
1212  if ( !has_outline && sfnt->load_bhed )
1213  {
1214  LOAD_( bhed );
1215  is_apple_sbit = FT_BOOL( !error );
1216  }
1217 
1218  /* load the font header (`head' table) if this isn't an Apple */
1219  /* sbit font file */
1220  if ( !is_apple_sbit || is_apple_sbix )
1221  {
1222  LOAD_( head );
1223  if ( error )
1224  goto Exit;
1225  }
1226 
1227  /* OpenType 1.8.2 introduced limits to this value; */
1228  /* however, they make sense for older SFNT fonts also */
1229  if ( face->header.Units_Per_EM < 16 ||
1230  face->header.Units_Per_EM > 16384 )
1231  {
1232  error = FT_THROW( Invalid_Table );
1233 
1234  goto Exit;
1235  }
1236 
1237  /* the following tables are often not present in embedded TrueType */
1238  /* fonts within PDF documents, so don't check for them. */
1239  LOAD_( maxp );
1240  LOAD_( cmap );
1241 
1242  /* the following tables are optional in PCL fonts -- */
1243  /* don't check for errors */
1244  LOAD_( name );
1245  LOAD_( post );
1246 
1247 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
1248  psnames_error = error;
1249 #endif
1250 
1251  /* do not load the metrics headers and tables if this is an Apple */
1252  /* sbit font file */
1253  if ( !is_apple_sbit )
1254  {
1255  /* load the `hhea' and `hmtx' tables */
1256  LOADM_( hhea, 0 );
1257  if ( !error )
1258  {
1259  LOADM_( hmtx, 0 );
1260  if ( FT_ERR_EQ( error, Table_Missing ) )
1261  {
1262  error = FT_THROW( Hmtx_Table_Missing );
1263 
1264 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1265  /* If this is an incrementally loaded font and there are */
1266  /* overriding metrics, tolerate a missing `hmtx' table. */
1267  if ( face->root.internal->incremental_interface &&
1268  face->root.internal->incremental_interface->funcs->
1269  get_glyph_metrics )
1270  {
1271  face->horizontal.number_Of_HMetrics = 0;
1272  error = FT_Err_Ok;
1273  }
1274 #endif
1275  }
1276  }
1277  else if ( FT_ERR_EQ( error, Table_Missing ) )
1278  {
1279  /* No `hhea' table necessary for SFNT Mac fonts. */
1280  if ( face->format_tag == TTAG_true )
1281  {
1282  FT_TRACE2(( "This is an SFNT Mac font.\n" ));
1283 
1284  has_outline = 0;
1285  error = FT_Err_Ok;
1286  }
1287  else
1288  {
1289  error = FT_THROW( Horiz_Header_Missing );
1290 
1291 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1292  /* If this is an incrementally loaded font and there are */
1293  /* overriding metrics, tolerate a missing `hhea' table. */
1294  if ( face->root.internal->incremental_interface &&
1295  face->root.internal->incremental_interface->funcs->
1296  get_glyph_metrics )
1297  {
1298  face->horizontal.number_Of_HMetrics = 0;
1299  error = FT_Err_Ok;
1300  }
1301 #endif
1302 
1303  }
1304  }
1305 
1306  if ( error )
1307  goto Exit;
1308 
1309  /* try to load the `vhea' and `vmtx' tables */
1310  LOADM_( hhea, 1 );
1311  if ( !error )
1312  {
1313  LOADM_( hmtx, 1 );
1314  if ( !error )
1315  face->vertical_info = 1;
1316  }
1317 
1318  if ( error && FT_ERR_NEQ( error, Table_Missing ) )
1319  goto Exit;
1320 
1321  LOAD_( os2 );
1322  if ( error )
1323  {
1324  /* we treat the table as missing if there are any errors */
1325  face->os2.version = 0xFFFFU;
1326  }
1327  }
1328 
1329  /* the optional tables */
1330 
1331  /* embedded bitmap support */
1332  if ( sfnt->load_eblc )
1333  LOAD_( eblc );
1334 
1335  /* consider the pclt, kerning, and gasp tables as optional */
1336  LOAD_( pclt );
1337  LOAD_( gasp );
1338  LOAD_( kern );
1339 
1340  face->root.num_glyphs = face->max_profile.numGlyphs;
1341 
1342  /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */
1343  /* a WWS-only font face. `WWS' stands for `weight', width', and */
1344  /* `slope', a term used by Microsoft's Windows Presentation */
1345  /* Foundation (WPF). This flag has been introduced in version */
1346  /* 1.5 of the OpenType specification (May 2008). */
1347 
1348  face->root.family_name = NULL;
1349  face->root.style_name = NULL;
1350  if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
1351  {
1352  if ( !ignore_typographic_family )
1353  GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
1354  if ( !face->root.family_name )
1355  GET_NAME( FONT_FAMILY, &face->root.family_name );
1356 
1357  if ( !ignore_typographic_subfamily )
1358  GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
1359  if ( !face->root.style_name )
1360  GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
1361  }
1362  else
1363  {
1364  GET_NAME( WWS_FAMILY, &face->root.family_name );
1365  if ( !face->root.family_name && !ignore_typographic_family )
1366  GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
1367  if ( !face->root.family_name )
1368  GET_NAME( FONT_FAMILY, &face->root.family_name );
1369 
1370  GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
1371  if ( !face->root.style_name && !ignore_typographic_subfamily )
1372  GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
1373  if ( !face->root.style_name )
1374  GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
1375  }
1376 
1377  /* now set up root fields */
1378  {
1379  FT_Face root = &face->root;
1380  FT_Long flags = root->face_flags;
1381 
1382 
1383  /*********************************************************************/
1384  /* */
1385  /* Compute face flags. */
1386  /* */
1387  if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
1388  face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX )
1389  flags |= FT_FACE_FLAG_COLOR; /* color glyphs */
1390 
1391  if ( has_outline == TRUE )
1392  flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
1393 
1394  /* The sfnt driver only supports bitmap fonts natively, thus we */
1395  /* don't set FT_FACE_FLAG_HINTER. */
1396  flags |= FT_FACE_FLAG_SFNT | /* SFNT file format */
1397  FT_FACE_FLAG_HORIZONTAL; /* horizontal data */
1398 
1399 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
1400  if ( !psnames_error &&
1401  face->postscript.FormatType != 0x00030000L )
1403 #endif
1404 
1405  /* fixed width font? */
1406  if ( face->postscript.isFixedPitch )
1408 
1409  /* vertical information? */
1410  if ( face->vertical_info )
1412 
1413  /* kerning available ? */
1414  if ( TT_FACE_HAS_KERNING( face ) )
1416 
1417 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1418  /* Don't bother to load the tables unless somebody asks for them. */
1419  /* No need to do work which will (probably) not be used. */
1420  if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
1421  {
1422  if ( tt_face_lookup_table( face, TTAG_glyf ) != 0 &&
1425  if ( tt_face_lookup_table( face, TTAG_CFF2 ) != 0 )
1427  }
1428 #endif
1429 
1430  root->face_flags = flags;
1431 
1432  /*********************************************************************/
1433  /* */
1434  /* Compute style flags. */
1435  /* */
1436 
1437  flags = 0;
1438  if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
1439  {
1440  /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */
1441  /* indicates an oblique font face. This flag has been */
1442  /* introduced in version 1.5 of the OpenType specification. */
1443 
1444  if ( face->os2.fsSelection & 512 ) /* bit 9 */
1446  else if ( face->os2.fsSelection & 1 ) /* bit 0 */
1448 
1449  if ( face->os2.fsSelection & 32 ) /* bit 5 */
1451  }
1452  else
1453  {
1454  /* this is an old Mac font, use the header field */
1455 
1456  if ( face->header.Mac_Style & 1 )
1458 
1459  if ( face->header.Mac_Style & 2 )
1461  }
1462 
1463  root->style_flags |= flags;
1464 
1465  /*********************************************************************/
1466  /* */
1467  /* Polish the charmaps. */
1468  /* */
1469  /* Try to set the charmap encoding according to the platform & */
1470  /* encoding ID of each charmap. Emulate Unicode charmap if one */
1471  /* is missing. */
1472  /* */
1473 
1474  tt_face_build_cmaps( face ); /* ignore errors */
1475 
1476 
1477  /* set the encoding fields */
1478  {
1479  FT_Int m;
1480 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
1481  FT_Bool has_unicode = FALSE;
1482 #endif
1483 
1484 
1485  for ( m = 0; m < root->num_charmaps; m++ )
1486  {
1487  FT_CharMap charmap = root->charmaps[m];
1488 
1489 
1490  charmap->encoding = sfnt_find_encoding( charmap->platform_id,
1491  charmap->encoding_id );
1492 
1493 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
1494 
1495  if ( charmap->encoding == FT_ENCODING_UNICODE ||
1496  charmap->encoding == FT_ENCODING_MS_SYMBOL ) /* PUA */
1497  has_unicode = TRUE;
1498  }
1499 
1500  /* synthesize Unicode charmap if one is missing */
1501  if ( !has_unicode )
1502  {
1503  FT_CharMapRec cmaprec;
1504 
1505 
1506  cmaprec.face = root;
1508  cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
1509  cmaprec.encoding = FT_ENCODING_UNICODE;
1510 
1511 
1513  NULL, &cmaprec, NULL );
1514  if ( error &&
1515  FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) )
1516  goto Exit;
1517  error = FT_Err_Ok;
1518 
1519 #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
1520 
1521  }
1522  }
1523 
1524 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
1525 
1526  /*
1527  * Now allocate the root array of FT_Bitmap_Size records and
1528  * populate them. Unfortunately, it isn't possible to indicate bit
1529  * depths in the FT_Bitmap_Size record. This is a design error.
1530  */
1531  {
1532  FT_UInt count;
1533 
1534 
1535  count = face->sbit_num_strikes;
1536 
1537  if ( count > 0 )
1538  {
1539  FT_Memory memory = face->root.stream->memory;
1540  FT_UShort em_size = face->header.Units_Per_EM;
1541  FT_Short avgwidth = face->os2.xAvgCharWidth;
1543 
1544  FT_UInt* sbit_strike_map = NULL;
1545  FT_UInt strike_idx, bsize_idx;
1546 
1547 
1548  if ( em_size == 0 || face->os2.version == 0xFFFFU )
1549  {
1550  avgwidth = 1;
1551  em_size = 1;
1552  }
1553 
1554  /* to avoid invalid strike data in the `available_sizes' field */
1555  /* of `FT_Face', we map `available_sizes' indices to strike */
1556  /* indices */
1557  if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
1558  FT_NEW_ARRAY( sbit_strike_map, count ) )
1559  goto Exit;
1560 
1561  bsize_idx = 0;
1562  for ( strike_idx = 0; strike_idx < count; strike_idx++ )
1563  {
1564  FT_Bitmap_Size* bsize = root->available_sizes + bsize_idx;
1565 
1566 
1567  error = sfnt->load_strike_metrics( face, strike_idx, &metrics );
1568  if ( error )
1569  continue;
1570 
1571  bsize->height = (FT_Short)( metrics.height >> 6 );
1572  bsize->width = (FT_Short)(
1573  ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
1574 
1575  bsize->x_ppem = metrics.x_ppem << 6;
1576  bsize->y_ppem = metrics.y_ppem << 6;
1577 
1578  /* assume 72dpi */
1579  bsize->size = metrics.y_ppem << 6;
1580 
1581  /* only use strikes with valid PPEM values */
1582  if ( bsize->x_ppem && bsize->y_ppem )
1583  sbit_strike_map[bsize_idx++] = strike_idx;
1584  }
1585 
1586  /* reduce array size to the actually used elements */
1587  (void)FT_RENEW_ARRAY( sbit_strike_map, count, bsize_idx );
1588 
1589  /* from now on, all strike indices are mapped */
1590  /* using `sbit_strike_map' */
1591  if ( bsize_idx )
1592  {
1593  face->sbit_strike_map = sbit_strike_map;
1594 
1595  root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
1596  root->num_fixed_sizes = (FT_Int)bsize_idx;
1597  }
1598  }
1599  }
1600 
1601 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
1602 
1603  /* a font with no bitmaps and no outlines is scalable; */
1604  /* it has only empty glyphs then */
1605  if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
1606  root->face_flags |= FT_FACE_FLAG_SCALABLE;
1607 
1608 
1609  /*********************************************************************/
1610  /* */
1611  /* Set up metrics. */
1612  /* */
1613  if ( FT_IS_SCALABLE( root ) )
1614  {
1615  /* XXX What about if outline header is missing */
1616  /* (e.g. sfnt wrapped bitmap)? */
1617  root->bbox.xMin = face->header.xMin;
1618  root->bbox.yMin = face->header.yMin;
1619  root->bbox.xMax = face->header.xMax;
1620  root->bbox.yMax = face->header.yMax;
1621  root->units_per_EM = face->header.Units_Per_EM;
1622 
1623 
1624  /* XXX: Computing the ascender/descender/height is very different */
1625  /* from what the specification tells you. Apparently, we */
1626  /* must be careful because */
1627  /* */
1628  /* - not all fonts have an OS/2 table; in this case, we take */
1629  /* the values in the horizontal header. However, these */
1630  /* values very often are not reliable. */
1631  /* */
1632  /* - otherwise, the correct typographic values are in the */
1633  /* sTypoAscender, sTypoDescender & sTypoLineGap fields. */
1634  /* */
1635  /* However, certain fonts have these fields set to 0. */
1636  /* Rather, they have usWinAscent & usWinDescent correctly */
1637  /* set (but with different values). */
1638  /* */
1639  /* As an example, Arial Narrow is implemented through four */
1640  /* files ARIALN.TTF, ARIALNI.TTF, ARIALNB.TTF & ARIALNBI.TTF */
1641  /* */
1642  /* Strangely, all fonts have the same values in their */
1643  /* sTypoXXX fields, except ARIALNB which sets them to 0. */
1644  /* */
1645  /* On the other hand, they all have different */
1646  /* usWinAscent/Descent values -- as a conclusion, the OS/2 */
1647  /* table cannot be used to compute the text height reliably! */
1648  /* */
1649 
1650  /* The ascender and descender are taken from the `hhea' table. */
1651  /* If zero, they are taken from the `OS/2' table. */
1652 
1653  root->ascender = face->horizontal.Ascender;
1654  root->descender = face->horizontal.Descender;
1655 
1656  root->height = root->ascender - root->descender +
1657  face->horizontal.Line_Gap;
1658 
1659  if ( !( root->ascender || root->descender ) )
1660  {
1661  if ( face->os2.version != 0xFFFFU )
1662  {
1663  if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
1664  {
1665  root->ascender = face->os2.sTypoAscender;
1666  root->descender = face->os2.sTypoDescender;
1667 
1668  root->height = root->ascender - root->descender +
1669  face->os2.sTypoLineGap;
1670  }
1671  else
1672  {
1673  root->ascender = (FT_Short)face->os2.usWinAscent;
1674  root->descender = -(FT_Short)face->os2.usWinDescent;
1675 
1676  root->height = root->ascender - root->descender;
1677  }
1678  }
1679  }
1680 
1681  root->max_advance_width =
1682  (FT_Short)face->horizontal.advance_Width_Max;
1683  root->max_advance_height =
1684  (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max
1685  : root->height );
1686 
1687  /* See https://www.microsoft.com/typography/otspec/post.htm -- */
1688  /* Adjust underline position from top edge to centre of */
1689  /* stroke to convert TrueType meaning to FreeType meaning. */
1690  root->underline_position = face->postscript.underlinePosition -
1691  face->postscript.underlineThickness / 2;
1692  root->underline_thickness = face->postscript.underlineThickness;
1693  }
1694 
1695  }
1696 
1697  Exit:
1698  FT_TRACE2(( "sfnt_load_face: done\n" ));
1699 
1700  return error;
1701  }
1702 
1703 
1704 #undef LOAD_
1705 #undef LOADM_
1706 #undef GET_NAME
1707 
1708 
1709  FT_LOCAL_DEF( void )
1711  {
1712  FT_Memory memory;
1714 
1715 
1716  if ( !face )
1717  return;
1718 
1719  memory = face->root.memory;
1720  sfnt = (SFNT_Service)face->sfnt;
1721 
1722  if ( sfnt )
1723  {
1724  /* destroy the postscript names table if it is loaded */
1725  if ( sfnt->free_psnames )
1726  sfnt->free_psnames( face );
1727 
1728  /* destroy the embedded bitmaps table if it is loaded */
1729  if ( sfnt->free_eblc )
1730  sfnt->free_eblc( face );
1731  }
1732 
1733 #ifdef TT_CONFIG_OPTION_BDF
1734  /* freeing the embedded BDF properties */
1735  tt_face_free_bdf_props( face );
1736 #endif
1737 
1738  /* freeing the kerning table */
1740 
1741  /* freeing the collection table */
1742  FT_FREE( face->ttc_header.offsets );
1743  face->ttc_header.count = 0;
1744 
1745  /* freeing table directory */
1746  FT_FREE( face->dir_tables );
1747  face->num_tables = 0;
1748 
1749  {
1751 
1752 
1753  /* simply release the 'cmap' table frame */
1754  FT_FRAME_RELEASE( face->cmap_table );
1755  face->cmap_size = 0;
1756  }
1757 
1758  face->horz_metrics_size = 0;
1759  face->vert_metrics_size = 0;
1760 
1761  /* freeing vertical metrics, if any */
1762  if ( face->vertical_info )
1763  {
1764  FT_FREE( face->vertical.long_metrics );
1765  FT_FREE( face->vertical.short_metrics );
1766  face->vertical_info = 0;
1767  }
1768 
1769  /* freeing the gasp table */
1770  FT_FREE( face->gasp.gaspRanges );
1771  face->gasp.numRanges = 0;
1772 
1773  /* freeing the name table */
1774  if ( sfnt )
1775  sfnt->free_name( face );
1776 
1777  /* freeing family and style name */
1778  FT_FREE( face->root.family_name );
1779  FT_FREE( face->root.style_name );
1780 
1781  /* freeing sbit size table */
1782  FT_FREE( face->root.available_sizes );
1783  FT_FREE( face->sbit_strike_map );
1784  face->root.num_fixed_sizes = 0;
1785 
1786 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1787  FT_FREE( face->postscript_name );
1788  FT_FREE( face->var_postscript_prefix );
1789 #endif
1790 
1791  face->sfnt = NULL;
1792  }
1793 
1794 
1795 /* END */
FT_ULong privLength
Definition: tttypes.h:167
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
#define FT_SERVICE_ID_MULTI_MASTERS
Definition: svmm.h:35
FT_ULong privOffset
Definition: tttypes.h:166
#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
Definition: ftparams.h:69
int FT_Error
Definition: fttypes.h:300
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
#define FT_FRAME_LONG(f)
Definition: ftstream.h:120
FT_Face face
Definition: freetype.h:842
#define GET_NAME(id, field)
Definition: sfobjs.c:1124
signed long FT_Long
Definition: fttypes.h:242
#define TRUE
Definition: types.h:120
SFNT_Interface * SFNT_Service
Definition: sfnt.h:628
FT_UShort platformID
Definition: tttypes.h:272
unsigned long FT_ULong
Definition: fttypes.h:253
FT_UShort encoding_id
Definition: freetype.h:845
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
FT_Pos x_ppem
Definition: freetype.h:378
static BOOL is_english
Definition: run.c:139
#define TTAG_glyf
Definition: tttags.h:61
#define error(str)
Definition: mkdosfs.c:1605
#define FT_FACE_FLAG_COLOR
Definition: freetype.h:1252
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define TTAG_0xA5lst
Definition: tttags.h:113
FT_ULong totalSfntSize
Definition: tttypes.h:160
tt_face_done_kern(TT_Face face)
Definition: ttkern.c:173
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define TT_MS_ID_PRC
Definition: ttnameid.h:251
tt_face_build_cmaps(TT_Face face)
Definition: ttcmap.c:3814
#define TT_MAC_LANGID_ENGLISH
Definition: ttnameid.h:303
signed int FT_Int
Definition: fttypes.h:220
TT_Loader_GotoTableFunc goto_table
Definition: sfnt.h:564
TT_Free_Table_Func free_name
Definition: sfnt.h:583
SFNT_Service sfnt
Definition: ttdriver.c:206
#define TTAG_wOFF
Definition: tttags.h:107
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define FT_ABS(a)
Definition: ftobjs.h:74
struct _root root
#define U(x)
Definition: wordpad.c:44
#define FT_SERVICE_ID_METRICS_VARIATIONS
Definition: svmetric.h:33
GLintptr offset
Definition: glext.h:5920
#define FT_FACE_FLAG_SCALABLE
Definition: freetype.h:1238
#define TT_MS_ID_JOHAB
Definition: ttnameid.h:254
FT_String *(* TT_Name_ConvertFunc)(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:125
GLdouble n
Definition: glext.h:7729
#define TTAG_CFF
Definition: tttags.h:45
#define TTAG_gvar
Definition: tttags.h:64
Definition: ecma_167.h:138
static FT_String * tt_name_ascii_from_other(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:92
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
signed char FT_Char
Definition: fttypes.h:143
#define FT_FACE_FLAG_MULTIPLE_MASTERS
Definition: freetype.h:1246
tt_face_get_name(TT_Face face, FT_UShort nameid, FT_String **name)
Definition: sfobjs.c:132
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:342
#define FT_FACE_FLAG_FIXED_SIZES
Definition: freetype.h:1239
FT_UShort languageID
Definition: tttypes.h:274
#define TT_MS_ID_UNICODE_CS
Definition: font.c:1181
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:125
FT_Library library
Definition: cffdrivr.c:654
FT_ULong stringOffset
Definition: tttypes.h:277
return FT_Err_Ok
Definition: ftbbox.c:511
#define TTAG_OTTO
Definition: tttags.h:88
static char memory[1024 *256]
Definition: process.c:116
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
sfnt_init_face(FT_Stream stream, TT_Face face, FT_Int face_instance_index, FT_Int num_params, FT_Parameter *params)
Definition: sfobjs.c:854
FT_Stream_Close(FT_Stream stream)
Definition: ftstream.c:49
#define TT_PLATFORM_ISO
Definition: ttnameid.h:88
const GLfloat * m
Definition: glext.h:10848
GLint limit
Definition: glext.h:10326
#define TT_PLATFORM_MICROSOFT
Definition: font.c:1174
#define TTAG_0xA5kbd
Definition: tttags.h:110
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
FT_Byte * string
Definition: tttypes.h:282
TT_Load_Table_Func load_font_dir
Definition: sfnt.h:610
#define TTAG_ttcf
Definition: tttags.h:100
ft_module_get_service(FT_Module module, const char *service_id, FT_Bool global)
Definition: ftobjs.c:4880
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
TT_Load_Table_Func load_bhed
Definition: sfnt.h:593
#define ft_qsort
Definition: ftstdlib.h:122
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
static FT_Error sfnt_open_font(FT_Stream stream, TT_Face face)
Definition: sfobjs.c:740
#define FT_GET_TAG4()
Definition: ftstream.h:294
GLenum const GLfloat * params
Definition: glext.h:5645
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_STYLE_FLAG_BOLD
Definition: freetype.h:1518
#define TTAG_true
Definition: tttags.h:98
#define TT_MS_ID_SJIS
Definition: ttnameid.h:250
#define TT_PLATFORM_APPLE_UNICODE
Definition: font.c:1172
r reserved
Definition: btrfs.c:2704
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec
Definition: ttcmap.h:144
#define FT_FACE_FLAG_VERTICAL
Definition: freetype.h:1243
smooth NULL
Definition: ftsmooth.c:416
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:508
static const WCHAR version[]
Definition: asmname.c:64
unsigned char
Definition: typeof.h:29
sfnt_load_face(FT_Stream stream, TT_Face face, FT_Int face_instance_index, FT_Int num_params, FT_Parameter *params)
Definition: sfobjs.c:1134
static FT_Encoding sfnt_find_encoding(int platform_id, int encoding_id)
Definition: sfobjs.c:290
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:493
#define FT_FACE_FLAG_SFNT
Definition: freetype.h:1241
#define FT_FACE_FLAG_FIXED_WIDTH
Definition: freetype.h:1240
FT_UShort num_tables
Definition: tttypes.h:158
#define FT_FRAME_USHORT(f)
Definition: ftstream.h:123
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
FT_ULong metaOrigLength
Definition: tttypes.h:165
#define TTAG_CFF2
Definition: tttags.h:46
static FT_String * tt_name_ascii_from_utf16(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:57
#define FT_STREAM_READ_AT(position, buffer, count)
Definition: ftstream.h:502
#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
Definition: ftparams.h:93
TT_Load_Table_Func load_eblc
Definition: sfnt.h:613
#define FT_READ_ULONG(var)
Definition: ftstream.h:313
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
char FT_String
Definition: fttypes.h:187
#define TT_PLATFORM_MACINTOSH
Definition: font.c:1173
#define FT_HAS_FIXED_SIZES(face)
Definition: freetype.h:1361
#define WRITE_USHORT(p, v)
Definition: sfobjs.c:340
#define FT_FACE_FLAG_HORIZONTAL
Definition: freetype.h:1242
int convert
Definition: msacm.c:1362
if(!(yy_init))
Definition: macro.lex.yy.c:714
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static void Exit(void)
Definition: sock.c:1331
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
static FT_Error woff_open_font(FT_Stream stream, TT_Face face)
Definition: sfobjs.c:397
#define TTAG_fvar
Definition: tttags.h:58
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
TT_Load_Strike_Metrics_Func load_strike_metrics
Definition: sfnt.h:617
static void sfnt_stream_close(FT_Stream stream)
Definition: sfobjs.c:360
FT_Pos y_ppem
Definition: freetype.h:379
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
FT_Short width
Definition: freetype.h:374
TT_Free_Table_Func free_psnames
Definition: sfnt.h:599
#define FT_FACE_FLAG_EXTERNAL_STREAM
Definition: freetype.h:1248
GLbitfield flags
Definition: glext.h:7161
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
#define TT_MS_ID_UCS_4
Definition: ttnameid.h:255
FT_Encoding encoding
Definition: freetype.h:843
enum FT_Encoding_ FT_Encoding
static const WCHAR L[]
Definition: oid.c:1250
unsigned int size
Definition: parse.h:27
Definition: parse.h:22
#define TT_MS_ID_BIG_5
Definition: ttnameid.h:252
signed short FT_Short
Definition: fttypes.h:198
uint32_t entry
Definition: isohybrid.c:63
FT_ULong flavor
Definition: tttypes.h:156
FT_UShort nameID
Definition: tttypes.h:275
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
GLenum GLsizei len
Definition: glext.h:6722
#define FT_BOOL(x)
Definition: fttypes.h:578
#define TTAG_sbix
Definition: tttags.h:94
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define TTAG_typ1
Definition: tttags.h:102
int code
Definition: i386-dis.c:3591
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
FT_Memory memory
Definition: ftsystem.h:341
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:526
ed encoding
Definition: write.c:2847
char string[160]
Definition: util.h:11
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3614
#define TT_MS_ID_SYMBOL_CS
Definition: font.c:1180
#define FT_STREAM_POS()
Definition: ftstream.h:486
sfnt_done_face(TT_Face face)
Definition: sfobjs.c:1710
FT_UShort platform_id
Definition: freetype.h:844
#define FT_REALLOC(ptr, cursz, newsz)
Definition: ftmemory.h:306
#define FT_FRAME_ULONG(f)
Definition: ftstream.h:121
#define ft_memcmp
Definition: ftstdlib.h:81
#define TT_FACE_FLAG_VAR_FVAR
Definition: tttypes.h:1110
FT_Stream_Free(FT_Stream stream, FT_Int external)
Definition: ftobjs.c:246
FT_UShort stringLength
Definition: tttypes.h:276
unsigned int FT_UInt
Definition: fttypes.h:231
FT_ULong metaOffset
Definition: tttypes.h:163
FT_ULong metaLength
Definition: tttypes.h:164
compare_offsets(const void *a, const void *b)
Definition: sfobjs.c:374
#define FT_FACE_FLAG_KERNING
Definition: freetype.h:1244
FT_Gzip_Uncompress(FT_Memory memory, FT_Byte *output, FT_ULong *output_len, const FT_Byte *input, FT_ULong input_len)
Definition: ftgzip.c:798
#define LOAD_(x)
Definition: sfobjs.c:1091
#define LOADM_(x, vertical)
Definition: sfobjs.c:1107
FT_Get_Module(FT_Library library, const char *module_name)
Definition: ftobjs.c:4837
tt_face_lookup_table(TT_Face face, FT_ULong tag)
Definition: ttload.c:56
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
#define FT_GET_ULONG()
Definition: ftstream.h:293
Definition: name.c:36
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
FT_Get_Module_Interface(FT_Library library, const char *mod_name)
Definition: ftobjs.c:4865
#define TT_FACE_HAS_KERNING(face)
Definition: ttkern.h:44
TT_Free_Table_Func free_eblc
Definition: sfnt.h:614
#define const
Definition: zconf.h:230
struct nls_table * tables
Definition: nls_base.c:22
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_STYLE_FLAG_ITALIC
Definition: freetype.h:1517
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
unsigned short FT_UShort
Definition: fttypes.h:209
#define FT_FACE_STREAM(x)
Definition: ftobjs.h:637
FT_ULong Offset
Definition: tttypes.h:199
FT_UShort encodingID
Definition: tttypes.h:273
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
#define FT_FACE_FLAG_GLYPH_NAMES
Definition: freetype.h:1247
GLuint64EXT * result
Definition: glext.h:11304
#define ft_memcpy
Definition: ftstdlib.h:82
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
#define TT_MAC_ID_ROMAN
Definition: ttnameid.h:147
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
#define UL
Definition: tui.h:70
FT_ULong length
Definition: tttypes.h:157
FT_Short height
Definition: freetype.h:373
#define FT_FRAME_START(size)
Definition: ftstream.h:117
#define WRITE_ULONG(p, v)
Definition: sfobjs.c:348
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
FT_Stream_CloseFunc close
Definition: ftsystem.h:339
#define TT_MS_ID_WANSUNG
Definition: ttnameid.h:253
char * tag
Definition: main.c:59