ReactOS 0.4.15-dev-7788-g1ad9096
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,
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;
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
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 {
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 */
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 ) ||
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 ) ||
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 {
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
546
547 /* Sort by offset. */
548
550 woff.num_tables,
551 sizeof ( WOFF_Table ),
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 {
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
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;
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:
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
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
856 FT_Int face_instance_index,
857 FT_Int num_params,
859 {
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 ||
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,
1139 {
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;
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 {
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 )
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 */
#define read
Definition: acwin.h:96
struct outqueuenode * head
Definition: adnsresfilter.c:66
struct _root root
FT_Library library
Definition: cffdrivr.c:654
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR version[]
Definition: asmname.c:66
#define TT_MS_ID_UNICODE_CS
Definition: font.c:1181
#define TT_PLATFORM_MICROSOFT
Definition: font.c:1174
#define TT_PLATFORM_MACINTOSH
Definition: font.c:1173
#define TT_MS_ID_SYMBOL_CS
Definition: font.c:1180
#define TT_PLATFORM_APPLE_UNICODE
Definition: font.c:1172
unsigned char
Definition: typeof.h:29
r reserved
Definition: btrfs.c:3006
struct nls_table * tables
Definition: nls_base.c:22
#define FT_FACE_FLAG_KERNING
Definition: freetype.h:1244
#define FT_FACE_FLAG_SFNT
Definition: freetype.h:1241
#define FT_STYLE_FLAG_ITALIC
Definition: freetype.h:1517
#define FT_FACE_FLAG_FIXED_SIZES
Definition: freetype.h:1239
#define FT_FACE_FLAG_SCALABLE
Definition: freetype.h:1238
#define FT_FACE_FLAG_FIXED_WIDTH
Definition: freetype.h:1240
#define FT_HAS_FIXED_SIZES(face)
Definition: freetype.h:1361
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
#define FT_FACE_FLAG_VERTICAL
Definition: freetype.h:1243
#define FT_FACE_FLAG_EXTERNAL_STREAM
Definition: freetype.h:1248
#define FT_FACE_FLAG_GLYPH_NAMES
Definition: freetype.h:1247
enum FT_Encoding_ FT_Encoding
#define FT_FACE_FLAG_COLOR
Definition: freetype.h:1252
#define FT_FACE_FLAG_MULTIPLE_MASTERS
Definition: freetype.h:1246
#define FT_STYLE_FLAG_BOLD
Definition: freetype.h:1518
#define FT_FACE_FLAG_HORIZONTAL
Definition: freetype.h:1242
return FT_Err_Ok
Definition: ftbbox.c:511
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
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 FT_REALLOC(ptr, cursz, newsz)
Definition: ftmemory.h:306
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
#define FT_NEW(ptr)
Definition: ftmemory.h:331
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:303
#define FT_FREE(ptr)
Definition: ftmemory.h:329
#define FT_RENEW_ARRAY(ptr, curcnt, newcnt)
Definition: ftmemory.h:336
#define FT_QNEW_ARRAY(ptr, count)
Definition: ftmemory.h:342
FT_Get_Module(FT_Library library, const char *module_name)
Definition: ftobjs.c:4837
#define FT_ABS(a)
Definition: ftobjs.h:74
ft_module_get_service(FT_Module module, const char *service_id, FT_Bool global)
Definition: ftobjs.c:4880
#define FT_FACE_STREAM(x)
Definition: ftobjs.h:637
FT_CMap_New(FT_CMap_Class clazz, FT_Pointer init_data, FT_CharMap charmap, FT_CMap *acmap)
Definition: ftobjs.c:3614
FT_Get_Module_Interface(FT_Library library, const char *mod_name)
Definition: ftobjs.c:4865
#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY
Definition: ftparams.h:69
#define FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY
Definition: ftparams.h:93
#define FT_FACE_FIND_GLOBAL_SERVICE(face, ptr, id)
Definition: ftserv.h:125
#define ft_memcpy
Definition: ftstdlib.h:82
#define ft_memcmp
Definition: ftstdlib.h:81
#define ft_qsort
Definition: ftstdlib.h:122
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
#define FT_FRAME_END
Definition: ftstream.h:118
#define FT_GET_ULONG()
Definition: ftstream.h:293
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:526
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_READ_ULONG(var)
Definition: ftstream.h:313
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
#define FT_STREAM_POS()
Definition: ftstream.h:486
FT_Stream_Close(FT_Stream stream)
Definition: ftstream.c:49
#define FT_FRAME_ULONG(f)
Definition: ftstream.h:121
#define FT_GET_TAG4()
Definition: ftstream.h:294
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define FT_STREAM_READ_FIELDS(fields, object)
Definition: ftstream.h:508
#define FT_STREAM_SKIP(distance)
Definition: ftstream.h:493
#define FT_STREAM_READ_AT(position, buffer, count)
Definition: ftstream.h:502
FT_Stream_Free(FT_Stream stream, FT_Int external)
Definition: ftobjs.c:246
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
#define FT_FRAME_START(size)
Definition: ftstream.h:117
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
#define FT_FRAME_USHORT(f)
Definition: ftstream.h:123
#define FT_FRAME_LONG(f)
Definition: ftstream.h:120
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
signed char FT_Char
Definition: fttypes.h:143
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
int FT_Error
Definition: fttypes.h:300
signed long FT_Long
Definition: fttypes.h:242
#define FT_ERR_NEQ(x, e)
Definition: fttypes.h:593
unsigned short FT_UShort
Definition: fttypes.h:209
char FT_String
Definition: fttypes.h:187
signed short FT_Short
Definition: fttypes.h:198
unsigned int FT_UInt
Definition: fttypes.h:231
#define FT_BOOL(x)
Definition: fttypes.h:578
signed int FT_Int
Definition: fttypes.h:220
FxCollectionEntry * cur
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum const GLvoid * indices
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
Definition: glext.h:11745
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLint limit
Definition: glext.h:10326
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLuint64EXT * result
Definition: glext.h:11304
GLintptr offset
Definition: glext.h:5920
const GLfloat * m
Definition: glext.h:10848
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
uint32_t entry
Definition: isohybrid.c:63
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
char string[160]
Definition: util.h:11
static char memory[1024 *256]
Definition: process.c:116
static BOOL is_english
Definition: run.c:155
int convert
Definition: msacm.c:1374
SFNT_Interface * SFNT_Service
Definition: sfnt.h:628
#define WRITE_ULONG(p, v)
Definition: sfobjs.c:348
compare_offsets(const void *a, const void *b)
Definition: sfobjs.c:374
static void sfnt_stream_close(FT_Stream stream)
Definition: sfobjs.c:360
#define LOADM_(x, vertical)
Definition: sfobjs.c:1107
FT_String *(* TT_Name_ConvertFunc)(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:125
#define GET_NAME(id, field)
Definition: sfobjs.c:1124
tt_face_get_name(TT_Face face, FT_UShort nameid, FT_String **name)
Definition: sfobjs.c:132
static FT_String * tt_name_ascii_from_utf16(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:57
#define LOAD_(x)
Definition: sfobjs.c:1091
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
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_Error woff_open_font(FT_Stream stream, TT_Face face)
Definition: sfobjs.c:397
sfnt_done_face(TT_Face face)
Definition: sfobjs.c:1710
static FT_Encoding sfnt_find_encoding(int platform_id, int encoding_id)
Definition: sfobjs.c:290
static FT_Error sfnt_open_font(FT_Stream stream, TT_Face face)
Definition: sfobjs.c:740
#define WRITE_USHORT(p, v)
Definition: sfobjs.c:340
static FT_String * tt_name_ascii_from_other(TT_Name entry, FT_Memory memory)
Definition: sfobjs.c:92
static void Exit(void)
Definition: sock.c:1330
FT_Pos y_ppem
Definition: freetype.h:379
FT_Pos x_ppem
Definition: freetype.h:378
FT_Short width
Definition: freetype.h:374
FT_Short height
Definition: freetype.h:373
FT_Face face
Definition: freetype.h:842
FT_Encoding encoding
Definition: freetype.h:843
FT_UShort platform_id
Definition: freetype.h:844
FT_UShort encoding_id
Definition: freetype.h:845
FT_Memory memory
Definition: ftsystem.h:341
FT_Stream_CloseFunc close
Definition: ftsystem.h:339
TT_Free_Table_Func free_eblc
Definition: sfnt.h:614
TT_Free_Table_Func free_name
Definition: sfnt.h:583
TT_Load_Strike_Metrics_Func load_strike_metrics
Definition: sfnt.h:617
TT_Load_Table_Func load_eblc
Definition: sfnt.h:613
TT_Load_Table_Func load_font_dir
Definition: sfnt.h:610
TT_Free_Table_Func free_psnames
Definition: sfnt.h:599
TT_Load_Table_Func load_bhed
Definition: sfnt.h:593
TT_Loader_GotoTableFunc goto_table
Definition: sfnt.h:564
FT_ULong stringOffset
Definition: tttypes.h:277
FT_Byte * string
Definition: tttypes.h:282
FT_UShort languageID
Definition: tttypes.h:274
FT_UShort stringLength
Definition: tttypes.h:276
FT_UShort encodingID
Definition: tttypes.h:273
FT_UShort platformID
Definition: tttypes.h:272
FT_UShort nameID
Definition: tttypes.h:275
FT_ULong privOffset
Definition: tttypes.h:166
FT_UShort num_tables
Definition: tttypes.h:158
FT_ULong metaLength
Definition: tttypes.h:164
FT_ULong privLength
Definition: tttypes.h:167
FT_ULong metaOrigLength
Definition: tttypes.h:165
FT_ULong length
Definition: tttypes.h:157
FT_ULong flavor
Definition: tttypes.h:156
FT_ULong metaOffset
Definition: tttypes.h:163
FT_ULong totalSfntSize
Definition: tttypes.h:160
FT_ULong Offset
Definition: tttypes.h:199
Definition: inflate.c:139
Definition: name.c:39
Definition: parse.h:23
unsigned int size
Definition: parse.h:27
Definition: ecma_167.h:138
#define FT_SERVICE_ID_METRICS_VARIATIONS
Definition: svmetric.h:33
#define FT_SERVICE_ID_MULTI_MASTERS
Definition: svmm.h:35
tt_face_build_cmaps(TT_Face face)
Definition: ttcmap.c:3814
FT_CALLBACK_TABLE const TT_CMap_ClassRec tt_cmap_unicode_class_rec
Definition: ttcmap.h:144
SFNT_Service sfnt
Definition: ttdriver.c:206
tt_face_done_kern(TT_Face face)
Definition: ttkern.c:173
#define TT_FACE_HAS_KERNING(face)
Definition: ttkern.h:44
tt_face_lookup_table(TT_Face face, FT_ULong tag)
Definition: ttload.c:56
#define TT_MS_ID_WANSUNG
Definition: ttnameid.h:253
#define TT_MS_ID_PRC
Definition: ttnameid.h:251
#define TT_MS_ID_SJIS
Definition: ttnameid.h:250
#define TT_MAC_LANGID_ENGLISH
Definition: ttnameid.h:303
#define TT_MAC_ID_ROMAN
Definition: ttnameid.h:147
#define TT_MS_ID_BIG_5
Definition: ttnameid.h:252
#define TT_PLATFORM_ISO
Definition: ttnameid.h:88
#define TT_MS_ID_UCS_4
Definition: ttnameid.h:255
#define TT_MS_ID_JOHAB
Definition: ttnameid.h:254
#define TTAG_true
Definition: tttags.h:98
#define TTAG_0xA5kbd
Definition: tttags.h:110
#define TTAG_0xA5lst
Definition: tttags.h:113
#define TTAG_fvar
Definition: tttags.h:58
#define TTAG_OTTO
Definition: tttags.h:88
#define TTAG_wOFF
Definition: tttags.h:107
#define TTAG_typ1
Definition: tttags.h:102
#define TTAG_gvar
Definition: tttags.h:64
#define TTAG_sbix
Definition: tttags.h:94
#define TTAG_ttcf
Definition: tttags.h:100
#define TTAG_CFF2
Definition: tttags.h:46
#define TTAG_glyf
Definition: tttags.h:61
#define TTAG_CFF
Definition: tttags.h:45
@ TT_SBIT_TABLE_TYPE_CBLC
Definition: tttypes.h:1090
@ TT_SBIT_TABLE_TYPE_SBIX
Definition: tttypes.h:1091
#define TT_FACE_FLAG_VAR_FVAR
Definition: tttypes.h:1110
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
static char * encoding
Definition: xmllint.c:155
#define const
Definition: zconf.h:233