1/****************************************************************************
2 *
3 * sfdriver.c
4 *
5 * High-level SFNT driver interface (body).
6 *
7 * Copyright (C) 1996-2019 by
8 * David Turner, Robert Wilhelm, and Werner Lemberg.
9 *
10 * This file is part of the FreeType project, and may only be used,
11 * modified, and distributed under the terms of the FreeType project
12 * license, LICENSE.TXT. By continuing to use, modify, or distribute
13 * this file you indicate that you have read the license and
14 * understand and accept it fully.
15 *
16 */
17
18
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_SFNT_H
22#include FT_INTERNAL_OBJECTS_H
23#include FT_TRUETYPE_IDS_H
24
25#include "sfdriver.h"
26#include "ttload.h"
27#include "sfobjs.h"
28
29#include "sferrors.h"
30
31#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
32#include "ttsbit.h"
33#endif
34
35#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
36#include "ttcolr.h"
37#include "ttcpal.h"
38#endif
39
40#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
41#include "ttpost.h"
42#endif
43
44#ifdef TT_CONFIG_OPTION_BDF
45#include "ttbdf.h"
46#include FT_SERVICE_BDF_H
47#endif
48
49#include "ttcmap.h"
50#include "ttkern.h"
51#include "ttmtx.h"
52
53#include FT_SERVICE_GLYPH_DICT_H
54#include FT_SERVICE_POSTSCRIPT_NAME_H
55#include FT_SERVICE_SFNT_H
56#include FT_SERVICE_TT_CMAP_H
57
58#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
59#include FT_MULTIPLE_MASTERS_H
60#include FT_SERVICE_MULTIPLE_MASTERS_H
61#endif
62
63
64 /**************************************************************************
65 *
66 * The macro FT_COMPONENT is used in trace mode. It is an implicit
67 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
68 * messages during execution.
69 */
70#undef FT_COMPONENT
71#define FT_COMPONENT sfdriver
72
73
74 /*
75 * SFNT TABLE SERVICE
76 *
77 */
78
79 static void*
80 get_sfnt_table( TT_Face face,
81 FT_Sfnt_Tag tag )
82 {
83 void* table;
84
85
86 switch ( tag )
87 {
88 case FT_SFNT_HEAD:
89 table = &face->header;
90 break;
91
92 case FT_SFNT_HHEA:
93 table = &face->horizontal;
94 break;
95
96 case FT_SFNT_VHEA:
97 table = face->vertical_info ? &face->vertical : NULL;
98 break;
99
100 case FT_SFNT_OS2:
101 table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2;
102 break;
103
104 case FT_SFNT_POST:
105 table = &face->postscript;
106 break;
107
108 case FT_SFNT_MAXP:
109 table = &face->max_profile;
110 break;
111
112 case FT_SFNT_PCLT:
113 table = face->pclt.Version ? &face->pclt : NULL;
114 break;
115
116 default:
117 table = NULL;
118 }
119
120 return table;
121 }
122
123
124 static FT_Error
125 sfnt_table_info( TT_Face face,
126 FT_UInt idx,
127 FT_ULong *tag,
128 FT_ULong *offset,
129 FT_ULong *length )
130 {
131 if ( !offset || !length )
132 return FT_THROW( Invalid_Argument );
133
134 if ( !tag )
135 *length = face->num_tables;
136 else
137 {
138 if ( idx >= face->num_tables )
139 return FT_THROW( Table_Missing );
140
141 *tag = face->dir_tables[idx].Tag;
142 *offset = face->dir_tables[idx].Offset;
143 *length = face->dir_tables[idx].Length;
144 }
145
146 return FT_Err_Ok;
147 }
148
149
150 FT_DEFINE_SERVICE_SFNT_TABLEREC(
151 sfnt_service_sfnt_table,
152
153 (FT_SFNT_TableLoadFunc)tt_face_load_any, /* load_table */
154 (FT_SFNT_TableGetFunc) get_sfnt_table, /* get_table */
155 (FT_SFNT_TableInfoFunc)sfnt_table_info /* table_info */
156 )
157
158
159#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
160
161 /*
162 * GLYPH DICT SERVICE
163 *
164 */
165
166 static FT_Error
167 sfnt_get_glyph_name( FT_Face face,
168 FT_UInt glyph_index,
169 FT_Pointer buffer,
170 FT_UInt buffer_max )
171 {
172 FT_String* gname;
173 FT_Error error;
174
175
176 error = tt_face_get_ps_name( (TT_Face)face, glyph_index, &gname );
177 if ( !error )
178 FT_STRCPYN( buffer, gname, buffer_max );
179
180 return error;
181 }
182
183
184 static FT_UInt
185 sfnt_get_name_index( FT_Face face,
186 FT_String* glyph_name )
187 {
188 TT_Face ttface = (TT_Face)face;
189
190 FT_UInt i, max_gid = FT_UINT_MAX;
191
192
193 if ( face->num_glyphs < 0 )
194 return 0;
195 else if ( (FT_ULong)face->num_glyphs < FT_UINT_MAX )
196 max_gid = (FT_UInt)face->num_glyphs;
197 else
198 FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
199 FT_UINT_MAX, face->num_glyphs ));
200
201 for ( i = 0; i < max_gid; i++ )
202 {
203 FT_String* gname;
204 FT_Error error = tt_face_get_ps_name( ttface, i, &gname );
205
206
207 if ( error )
208 continue;
209
210 if ( !ft_strcmp( glyph_name, gname ) )
211 return i;
212 }
213
214 return 0;
215 }
216
217
218 FT_DEFINE_SERVICE_GLYPHDICTREC(
219 sfnt_service_glyph_dict,
220
221 (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name, /* get_name */
222 (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index /* name_index */
223 )
224
225#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
226
227
228 /*
229 * POSTSCRIPT NAME SERVICE
230 *
231 */
232
233 /* an array representing allowed ASCII characters in a PS string */
234 static const unsigned char sfnt_ps_map[16] =
235 {
236 /* 4 0 C 8 */
237 0x00, 0x00, /* 0x00: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */
238 0x00, 0x00, /* 0x10: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */
239 0xDE, 0x7C, /* 0x20: 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 0 */
240 0xFF, 0xAF, /* 0x30: 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 */
241 0xFF, 0xFF, /* 0x40: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */
242 0xFF, 0xD7, /* 0x50: 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 */
243 0xFF, 0xFF, /* 0x60: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 */
244 0xFF, 0x57 /* 0x70: 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 */
245 };
246
247
248 static int
249 sfnt_is_postscript( int c )
250 {
251 unsigned int cc;
252
253
254 if ( c < 0 || c >= 0x80 )
255 return 0;
256
257 cc = (unsigned int)c;
258
259 return sfnt_ps_map[cc >> 3] & ( 1 << ( cc & 0x07 ) );
260 }
261
262
263#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
264
265 /* Only ASCII letters and digits are taken for a variation font */
266 /* instance's PostScript name. */
267 /* */
268 /* `ft_isalnum' is a macro, but we need a function here, thus */
269 /* this definition. */
270 static int
271 sfnt_is_alphanumeric( int c )
272 {
273 return ft_isalnum( c );
274 }
275
276
277 /* the implementation of MurmurHash3 is taken and adapted from */
278 /* https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp */
279
280#define ROTL32( x, r ) ( x << r ) | ( x >> ( 32 - r ) )
281
282
283 static FT_UInt32
284 fmix32( FT_UInt32 h )
285 {
286 h ^= h >> 16;
287 h *= 0x85ebca6b;
288 h ^= h >> 13;
289 h *= 0xc2b2ae35;
290 h ^= h >> 16;
291
292 return h;
293 }
294
295
296 static void
297 murmur_hash_3_128( const void* key,
298 const unsigned int len,
299 FT_UInt32 seed,
300 void* out )
301 {
302 const FT_Byte* data = (const FT_Byte*)key;
303 const int nblocks = (int)len / 16;
304
305 FT_UInt32 h1 = seed;
306 FT_UInt32 h2 = seed;
307 FT_UInt32 h3 = seed;
308 FT_UInt32 h4 = seed;
309
310 const FT_UInt32 c1 = 0x239b961b;
311 const FT_UInt32 c2 = 0xab0e9789;
312 const FT_UInt32 c3 = 0x38b34ae5;
313 const FT_UInt32 c4 = 0xa1e38b93;
314
315 const FT_UInt32* blocks = (const FT_UInt32*)( data + nblocks * 16 );
316
317 int i;
318
319
320 for( i = -nblocks; i; i++ )
321 {
322 FT_UInt32 k1 = blocks[i * 4 + 0];
323 FT_UInt32 k2 = blocks[i * 4 + 1];
324 FT_UInt32 k3 = blocks[i * 4 + 2];
325 FT_UInt32 k4 = blocks[i * 4 + 3];
326
327
328 k1 *= c1;
329 k1 = ROTL32( k1, 15 );
330 k1 *= c2;
331 h1 ^= k1;
332
333 h1 = ROTL32( h1, 19 );
334 h1 += h2;
335 h1 = h1 * 5 + 0x561ccd1b;
336
337 k2 *= c2;
338 k2 = ROTL32( k2, 16 );
339 k2 *= c3;
340 h2 ^= k2;
341
342 h2 = ROTL32( h2, 17 );
343 h2 += h3;
344 h2 = h2 * 5 + 0x0bcaa747;
345
346 k3 *= c3;
347 k3 = ROTL32( k3, 17 );
348 k3 *= c4;
349 h3 ^= k3;
350
351 h3 = ROTL32( h3, 15 );
352 h3 += h4;
353 h3 = h3 * 5 + 0x96cd1c35;
354
355 k4 *= c4;
356 k4 = ROTL32( k4, 18 );
357 k4 *= c1;
358 h4 ^= k4;
359
360 h4 = ROTL32( h4, 13 );
361 h4 += h1;
362 h4 = h4 * 5 + 0x32ac3b17;
363 }
364
365 {
366 const FT_Byte* tail = (const FT_Byte*)( data + nblocks * 16 );
367
368 FT_UInt32 k1 = 0;
369 FT_UInt32 k2 = 0;
370 FT_UInt32 k3 = 0;
371 FT_UInt32 k4 = 0;
372
373
374 switch ( len & 15 )
375 {
376 case 15:
377 k4 ^= (FT_UInt32)tail[14] << 16;
378 case 14:
379 k4 ^= (FT_UInt32)tail[13] << 8;
380 case 13:
381 k4 ^= (FT_UInt32)tail[12];
382 k4 *= c4;
383 k4 = ROTL32( k4, 18 );
384 k4 *= c1;
385 h4 ^= k4;
386
387 case 12:
388 k3 ^= (FT_UInt32)tail[11] << 24;
389 case 11:
390 k3 ^= (FT_UInt32)tail[10] << 16;
391 case 10:
392 k3 ^= (FT_UInt32)tail[9] << 8;
393 case 9:
394 k3 ^= (FT_UInt32)tail[8];
395 k3 *= c3;
396 k3 = ROTL32( k3, 17 );
397 k3 *= c4;
398 h3 ^= k3;
399
400 case 8:
401 k2 ^= (FT_UInt32)tail[7] << 24;
402 case 7:
403 k2 ^= (FT_UInt32)tail[6] << 16;
404 case 6:
405 k2 ^= (FT_UInt32)tail[5] << 8;
406 case 5:
407 k2 ^= (FT_UInt32)tail[4];
408 k2 *= c2;
409 k2 = ROTL32( k2, 16 );
410 k2 *= c3;
411 h2 ^= k2;
412
413 case 4:
414 k1 ^= (FT_UInt32)tail[3] << 24;
415 case 3:
416 k1 ^= (FT_UInt32)tail[2] << 16;
417 case 2:
418 k1 ^= (FT_UInt32)tail[1] << 8;
419 case 1:
420 k1 ^= (FT_UInt32)tail[0];
421 k1 *= c1;
422 k1 = ROTL32( k1, 15 );
423 k1 *= c2;
424 h1 ^= k1;
425 }
426 }
427
428 h1 ^= len;
429 h2 ^= len;
430 h3 ^= len;
431 h4 ^= len;
432
433 h1 += h2;
434 h1 += h3;
435 h1 += h4;
436
437 h2 += h1;
438 h3 += h1;
439 h4 += h1;
440
441 h1 = fmix32( h1 );
442 h2 = fmix32( h2 );
443 h3 = fmix32( h3 );
444 h4 = fmix32( h4 );
445
446 h1 += h2;
447 h1 += h3;
448 h1 += h4;
449
450 h2 += h1;
451 h3 += h1;
452 h4 += h1;
453
454 ((FT_UInt32*)out)[0] = h1;
455 ((FT_UInt32*)out)[1] = h2;
456 ((FT_UInt32*)out)[2] = h3;
457 ((FT_UInt32*)out)[3] = h4;
458 }
459
460
461#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
462
463
464 typedef int (*char_type_func)( int c );
465
466
467 /* Handling of PID/EID 3/0 and 3/1 is the same. */
468#define IS_WIN( n ) ( (n)->platformID == 3 && \
469 ( (n)->encodingID == 1 || (n)->encodingID == 0 ) )
470
471#define IS_APPLE( n ) ( (n)->platformID == 1 && \
472 (n)->encodingID == 0 )
473
474 static char*
475 get_win_string( FT_Memory memory,
476 FT_Stream stream,
477 TT_Name entry,
478 char_type_func char_type,
479 FT_Bool report_invalid_characters )
480 {
481 FT_Error error = FT_Err_Ok;
482
483 char* result = NULL;
484 FT_String* r;
485 FT_Char* p;
486 FT_UInt len;
487
488 FT_UNUSED( error );
489
490
491 if ( FT_ALLOC( result, entry->stringLength / 2 + 1 ) )
492 return NULL;
493
494 if ( FT_STREAM_SEEK( entry->stringOffset ) ||
495 FT_FRAME_ENTER( entry->stringLength ) )
496 goto get_win_string_error;
497
498 r = (FT_String*)result;
499 p = (FT_Char*)stream->cursor;
500
501 for ( len = entry->stringLength / 2; len > 0; len--, p += 2 )
502 {
503 if ( p[0] == 0 && char_type( p[1] ) )
504 *r++ = p[1];
505 else
506 {
507 if ( report_invalid_characters )
508 FT_TRACE0(( "get_win_string:"
509 " Character 0x%X invalid in PS name string\n",
510 ((unsigned)p[0])*256 + (unsigned)p[1] ));
511 break;
512 }
513 }
514 if ( !len )
515 *r = '\0';
516
517 FT_FRAME_EXIT();
518
519 if ( !len )
520 return result;
521
522 get_win_string_error:
523 FT_FREE( result );
524
525 entry->stringLength = 0;
526 entry->stringOffset = 0;
527 FT_FREE( entry->string );
528
529 return NULL;
530 }
531
532
533 static char*
534 get_apple_string( FT_Memory memory,
535 FT_Stream stream,
536 TT_Name entry,
537 char_type_func char_type,
538 FT_Bool report_invalid_characters )
539 {
540 FT_Error error = FT_Err_Ok;
541
542 char* result = NULL;
543 FT_String* r;
544 FT_Char* p;
545 FT_UInt len;
546
547 FT_UNUSED( error );
548
549
550 if ( FT_ALLOC( result, entry->stringLength + 1 ) )
551 return NULL;
552
553 if ( FT_STREAM_SEEK( entry->stringOffset ) ||
554 FT_FRAME_ENTER( entry->stringLength ) )
555 goto get_apple_string_error;
556
557 r = (FT_String*)result;
558 p = (FT_Char*)stream->cursor;
559
560 for ( len = entry->stringLength; len > 0; len--, p++ )
561 {
562 if ( char_type( *p ) )
563 *r++ = *p;
564 else
565 {
566 if ( report_invalid_characters )
567 FT_TRACE0(( "get_apple_string:"
568 " Character `%c' (0x%X) invalid in PS name string\n",
569 *p, *p ));
570 break;
571 }
572 }
573 if ( !len )
574 *r = '\0';
575
576 FT_FRAME_EXIT();
577
578 if ( !len )
579 return result;
580
581 get_apple_string_error:
582 FT_FREE( result );
583
584 entry->stringOffset = 0;
585 entry->stringLength = 0;
586 FT_FREE( entry->string );
587
588 return NULL;
589 }
590
591
592 static FT_Bool
593 sfnt_get_name_id( TT_Face face,
594 FT_UShort id,
595 FT_Int *win,
596 FT_Int *apple )
597 {
598 FT_Int n;
599
600
601 *win = -1;
602 *apple = -1;
603
604 for ( n = 0; n < face->num_names; n++ )
605 {
606 TT_Name name = face->name_table.names + n;
607
608
609 if ( name->nameID == id && name->stringLength > 0 )
610 {
611 if ( IS_WIN( name ) && ( name->languageID == 0x409 || *win == -1 ) )
612 *win = n;
613
614 if ( IS_APPLE( name ) && ( name->languageID == 0 || *apple == -1 ) )
615 *apple = n;
616 }
617 }
618
619 return ( *win >= 0 ) || ( *apple >= 0 );
620 }
621
622
623#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
624
625 /*
626 The maximum length of an axis value descriptor.
627
628 We need 65536 different values for the decimal fraction; this fits
629 nicely into five decimal places. Consequently, it consists of
630
631 . the minus sign if the number is negative,
632 . up to five characters for the digits before the decimal point,
633 . the decimal point if there is a fractional part, and
634 . up to five characters for the digits after the decimal point.
635
636 We also need one byte for the leading `_' character and up to four
637 bytes for the axis tag.
638 */
639#define MAX_VALUE_DESCRIPTOR_LEN ( 1 + 5 + 1 + 5 + 1 + 4 )
640
641
642 /* the maximum length of PostScript font names */
643#define MAX_PS_NAME_LEN 127
644
645
646 /*
647 * Find the shortest decimal representation of a 16.16 fixed point
648 * number. The function fills `buf' with the result, returning a pointer
649 * to the position after the representation's last byte.
650 */
651
652 static char*
653 fixed2float( FT_Int fixed,
654 char* buf )
655 {
656 char* p;
657 char* q;
658 char tmp[5];
659
660 FT_Int int_part;
661 FT_Int frac_part;
662
663 FT_Int i;
664
665
666 p = buf;
667
668 if ( fixed == 0 )
669 {
670 *p++ = '0';
671 return p;
672 }
673
674 if ( fixed < 0 )
675 {
676 *p++ = '-';
677 fixed = NEG_INT( fixed );
678 }
679
680 int_part = ( fixed >> 16 ) & 0xFFFF;
681 frac_part = fixed & 0xFFFF;
682
683 /* get digits of integer part (in reverse order) */
684 q = tmp;
685 while ( int_part > 0 )
686 {
687 *q++ = '0' + int_part % 10;
688 int_part /= 10;
689 }
690
691 /* copy digits in correct order to buffer */
692 while ( q > tmp )
693 *p++ = *--q;
694
695 if ( !frac_part )
696 return p;
697
698 /* save position of point */
699 q = p;
700 *p++ = '.';
701
702 /* apply rounding */
703 frac_part = frac_part * 10 + 5;
704
705 /* get digits of fractional part */
706 for ( i = 0; i < 5; i++ )
707 {
708 *p++ = '0' + (char)( frac_part / 0x10000L );
709
710 frac_part %= 0x10000L;
711 if ( !frac_part )
712 break;
713
714 frac_part *= 10;
715 }
716
717 /*
718 If the remainder stored in `frac_part' (after the last FOR loop) is
719 smaller than 34480*10, the resulting decimal value minus 0.00001 is
720 an equivalent representation of `fixed'.
721
722 The above FOR loop always finds the larger of the two values; I
723 verified this by iterating over all possible fixed point numbers.
724
725 If the remainder is 17232*10, both values are equally good, and we
726 take the next even number (following IEEE 754's `round to nearest,
727 ties to even' rounding rule).
728
729 If the remainder is smaller than 17232*10, the lower of the two
730 numbers is nearer to the exact result (values 17232 and 34480 were
731 also found by testing all possible fixed point values).
732
733 We use this to find a shorter decimal representation. If not ending
734 with digit zero, we take the representation with less error.
735 */
736 p--;
737 if ( p - q == 5 ) /* five digits? */
738 {
739 /* take the representation that has zero as the last digit */
740 if ( frac_part < 34480 * 10 &&
741 *p == '1' )
742 *p = '0';
743
744 /* otherwise use the one with less error */
745 else if ( frac_part == 17232 * 10 &&
746 *p & 1 )
747 *p -= 1;
748
749 else if ( frac_part < 17232 * 10 &&
750 *p != '0' )
751 *p -= 1;
752 }
753
754 /* remove trailing zeros */
755 while ( *p == '0' )
756 *p-- = '\0';
757
758 return p + 1;
759 }
760
761
762 static const char hexdigits[16] =
763 {
764 '0', '1', '2', '3', '4', '5', '6', '7',
765 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
766 };
767
768
769 static const char*
770 sfnt_get_var_ps_name( TT_Face face )
771 {
772 FT_Error error;
773 FT_Memory memory = face->root.memory;
774
775 FT_Service_MultiMasters mm = (FT_Service_MultiMasters)face->mm;
776
777 FT_UInt num_coords;
778 FT_Fixed* coords;
779 FT_MM_Var* mm_var;
780
781 FT_Int found, win, apple;
782 FT_UInt i, j;
783
784 char* result = NULL;
785 char* p;
786
787
788 if ( !face->var_postscript_prefix )
789 {
790 FT_UInt len;
791
792
793 /* check whether we have a Variations PostScript Name Prefix */
794 found = sfnt_get_name_id( face,
795 TT_NAME_ID_VARIATIONS_PREFIX,
796 &win,
797 &apple );
798 if ( !found )
799 {
800 /* otherwise use the typographic family name */
801 found = sfnt_get_name_id( face,
802 TT_NAME_ID_TYPOGRAPHIC_FAMILY,
803 &win,
804 &apple );
805 }
806
807 if ( !found )
808 {
809 /* as a last resort we try the family name; note that this is */
810 /* not in the Adobe TechNote, but GX fonts (which predate the */
811 /* TechNote) benefit from this behaviour */
812 found = sfnt_get_name_id( face,
813 TT_NAME_ID_FONT_FAMILY,
814 &win,
815 &apple );
816 }
817
818 if ( !found )
819 {
820 FT_TRACE0(( "sfnt_get_var_ps_name:"
821 " Can't construct PS name prefix for font instances\n" ));
822 return NULL;
823 }
824
825 /* prefer Windows entries over Apple */
826 if ( win != -1 )
827 result = get_win_string( face->root.memory,
828 face->name_table.stream,
829 face->name_table.names + win,
830 sfnt_is_alphanumeric,
831 0 );
832 if ( !result && apple != -1 )
833 result = get_apple_string( face->root.memory,
834 face->name_table.stream,
835 face->name_table.names + apple,
836 sfnt_is_alphanumeric,
837 0 );
838
839 if ( !result )
840 {
841 FT_TRACE0(( "sfnt_get_var_ps_name:"
842 " No valid PS name prefix for font instances found\n" ));
843 return NULL;
844 }
845
846 len = ft_strlen( result );
847
848 /* sanitize if necessary; we reserve space for 36 bytes (a 128bit */
849 /* checksum as a hex number, preceded by `-' and followed by three */
850 /* ASCII dots, to be used if the constructed PS name would be too */
851 /* long); this is also sufficient for a single instance */
852 if ( len > MAX_PS_NAME_LEN - ( 1 + 32 + 3 ) )
853 {
854 len = MAX_PS_NAME_LEN - ( 1 + 32 + 3 );
855 result[len] = '\0';
856
857 FT_TRACE0(( "sfnt_get_var_ps_name:"
858 " Shortening variation PS name prefix\n"
859 " "
860 " to %d characters\n", len ));
861 }
862
863 face->var_postscript_prefix = result;
864 face->var_postscript_prefix_len = len;
865 }
866
867 mm->get_var_blend( FT_FACE( face ),
868 &num_coords,
869 &coords,
870 NULL,
871 &mm_var );
872
873 if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) &&
874 !FT_IS_VARIATION( FT_FACE( face ) ) )
875 {
876 SFNT_Service sfnt = (SFNT_Service)face->sfnt;
877
878 FT_Long instance = ( ( face->root.face_index & 0x7FFF0000L ) >> 16 ) - 1;
879 FT_UInt psid = mm_var->namedstyle[instance].psid;
880
881 char* ps_name = NULL;
882
883
884 /* try first to load the name string with index `postScriptNameID' */
885 if ( psid == 6 ||
886 ( psid > 255 && psid < 32768 ) )
887 (void)sfnt->get_name( face, (FT_UShort)psid, &ps_name );
888
889 if ( ps_name )
890 {
891 result = ps_name;
892 p = result + ft_strlen( result ) + 1;
893
894 goto check_length;
895 }
896 else
897 {
898 /* otherwise construct a name using `subfamilyNameID' */
899 FT_UInt strid = mm_var->namedstyle[instance].strid;
900
901 char* subfamily_name;
902 char* s;
903
904
905 (void)sfnt->get_name( face, (FT_UShort)strid, &subfamily_name );
906
907 if ( !subfamily_name )
908 {
909 FT_TRACE1(( "sfnt_get_var_ps_name:"
910 " can't construct named instance PS name;\n"
911 " "
912 " trying to construct normal instance PS name\n" ));
913 goto construct_instance_name;
914 }
915
916 /* after the prefix we have character `-' followed by the */
917 /* subfamily name (using only characters a-z, A-Z, and 0-9) */
918 if ( FT_ALLOC( result, face->var_postscript_prefix_len +
919 1 + ft_strlen( subfamily_name ) + 1 ) )
920 return NULL;
921
922 ft_strcpy( result, face->var_postscript_prefix );
923
924 p = result + face->var_postscript_prefix_len;
925 *p++ = '-';
926
927 s = subfamily_name;
928 while ( *s )
929 {
930 if ( ft_isalnum( *s ) )
931 *p++ = *s;
932 s++;
933 }
934 *p++ = '\0';
935
936 FT_FREE( subfamily_name );
937 }
938 }
939 else
940 {
941 FT_Var_Axis* axis;
942
943
944 construct_instance_name:
945 axis = mm_var->axis;
946
947 if ( FT_ALLOC( result,
948 face->var_postscript_prefix_len +
949 num_coords * MAX_VALUE_DESCRIPTOR_LEN + 1 ) )
950 return NULL;
951
952 p = result;
953
954 ft_strcpy( p, face->var_postscript_prefix );
955 p += face->var_postscript_prefix_len;
956
957 for ( i = 0; i < num_coords; i++, coords++, axis++ )
958 {
959 char t;
960
961
962 /* omit axis value descriptor if it is identical */
963 /* to the default axis value */
964 if ( *coords == axis->def )
965 continue;
966
967 *p++ = '_';
968 p = fixed2float( *coords, p );
969
970 t = (char)( axis->tag >> 24 );
971 if ( t != ' ' && ft_isalnum( t ) )
972 *p++ = t;
973 t = (char)( axis->tag >> 16 );
974 if ( t != ' ' && ft_isalnum( t ) )
975 *p++ = t;
976 t = (char)( axis->tag >> 8 );
977 if ( t != ' ' && ft_isalnum( t ) )
978 *p++ = t;
979 t = (char)axis->tag;
980 if ( t != ' ' && ft_isalnum( t ) )
981 *p++ = t;
982 }
983 }
984
985 check_length:
986 if ( p - result > MAX_PS_NAME_LEN )
987 {
988 /* the PS name is too long; replace the part after the prefix with */
989 /* a checksum; we use MurmurHash 3 with a hash length of 128 bit */
990
991 FT_UInt32 seed = 123456789;
992
993 FT_UInt32 hash[4];
994 FT_UInt32* h;
995
996
997 murmur_hash_3_128( result, p - result, seed, hash );
998
999 p = result + face->var_postscript_prefix_len;
1000 *p++ = '-';
1001
1002 /* we convert the hash value to hex digits from back to front */
1003 p += 32 + 3;
1004 h = hash + 3;
1005
1006 *p-- = '\0';
1007 *p-- = '.';
1008 *p-- = '.';
1009 *p-- = '.';
1010
1011 for ( i = 0; i < 4; i++, h-- )
1012 {
1013 FT_UInt32 v = *h;
1014
1015
1016 for ( j = 0; j < 8; j++ )
1017 {
1018 *p-- = hexdigits[v & 0xF];
1019 v >>= 4;
1020 }
1021 }
1022 }
1023
1024 return result;
1025 }
1026
1027#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1028
1029
1030 static const char*
1031 sfnt_get_ps_name( TT_Face face )
1032 {
1033 FT_Int found, win, apple;
1034 const char* result = NULL;
1035
1036
1037 if ( face->postscript_name )
1038 return face->postscript_name;
1039
1040#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1041 if ( face->blend &&
1042 ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1043 FT_IS_VARIATION( FT_FACE( face ) ) ) )
1044 {
1045 face->postscript_name = sfnt_get_var_ps_name( face );
1046 return face->postscript_name;
1047 }
1048#endif
1049
1050 /* scan the name table to see whether we have a Postscript name here, */
1051 /* either in Macintosh or Windows platform encodings */
1052 found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple );
1053 if ( !found )
1054 return NULL;
1055
1056 /* prefer Windows entries over Apple */
1057 if ( win != -1 )
1058 result = get_win_string( face->root.memory,
1059 face->name_table.stream,
1060 face->name_table.names + win,
1061 sfnt_is_postscript,
1062 1 );
1063 if ( !result && apple != -1 )
1064 result = get_apple_string( face->root.memory,
1065 face->name_table.stream,
1066 face->name_table.names + apple,
1067 sfnt_is_postscript,
1068 1 );
1069
1070 face->postscript_name = result;
1071
1072 return result;
1073 }
1074
1075
1076 FT_DEFINE_SERVICE_PSFONTNAMEREC(
1077 sfnt_service_ps_name,
1078
1079 (FT_PsName_GetFunc)sfnt_get_ps_name /* get_ps_font_name */
1080 )
1081
1082
1083 /*
1084 * TT CMAP INFO
1085 */
1086 FT_DEFINE_SERVICE_TTCMAPSREC(
1087 tt_service_get_cmap_info,
1088
1089 (TT_CMap_Info_GetFunc)tt_get_cmap_info /* get_cmap_info */
1090 )
1091
1092
1093#ifdef TT_CONFIG_OPTION_BDF
1094
1095 static FT_Error
1096 sfnt_get_charset_id( TT_Face face,
1097 const char* *acharset_encoding,
1098 const char* *acharset_registry )
1099 {
1100 BDF_PropertyRec encoding, registry;
1101 FT_Error error;
1102
1103
1104 /* XXX: I don't know whether this is correct, since
1105 * tt_face_find_bdf_prop only returns something correct if we have
1106 * previously selected a size that is listed in the BDF table.
1107 * Should we change the BDF table format to include single offsets
1108 * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
1109 */
1110 error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
1111 if ( !error )
1112 {
1113 error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
1114 if ( !error )
1115 {
1116 if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
1117 encoding.type == BDF_PROPERTY_TYPE_ATOM )
1118 {
1119 *acharset_encoding = encoding.u.atom;
1120 *acharset_registry = registry.u.atom;
1121 }
1122 else
1123 error = FT_THROW( Invalid_Argument );
1124 }
1125 }
1126
1127 return error;
1128 }
1129
1130
1131 FT_DEFINE_SERVICE_BDFRec(
1132 sfnt_service_bdf,
1133
1134 (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id, /* get_charset_id */
1135 (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop /* get_property */
1136 )
1137
1138
1139#endif /* TT_CONFIG_OPTION_BDF */
1140
1141
1142 /*
1143 * SERVICE LIST
1144 */
1145
1146#if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
1147 FT_DEFINE_SERVICEDESCREC5(
1148 sfnt_services,
1149
1150 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
1151 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
1152 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict,
1153 FT_SERVICE_ID_BDF, &sfnt_service_bdf,
1154 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
1155#elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
1156 FT_DEFINE_SERVICEDESCREC4(
1157 sfnt_services,
1158
1159 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
1160 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
1161 FT_SERVICE_ID_GLYPH_DICT, &sfnt_service_glyph_dict,
1162 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
1163#elif defined TT_CONFIG_OPTION_BDF
1164 FT_DEFINE_SERVICEDESCREC4(
1165 sfnt_services,
1166
1167 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
1168 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
1169 FT_SERVICE_ID_BDF, &sfnt_service_bdf,
1170 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
1171#else
1172 FT_DEFINE_SERVICEDESCREC3(
1173 sfnt_services,
1174
1175 FT_SERVICE_ID_SFNT_TABLE, &sfnt_service_sfnt_table,
1176 FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &sfnt_service_ps_name,
1177 FT_SERVICE_ID_TT_CMAP, &tt_service_get_cmap_info )
1178#endif
1179
1180
1181 FT_CALLBACK_DEF( FT_Module_Interface )
1182 sfnt_get_interface( FT_Module module,
1183 const char* module_interface )
1184 {
1185 FT_UNUSED( module );
1186
1187 return ft_service_list_lookup( sfnt_services, module_interface );
1188 }
1189
1190
1191#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
1192#define PUT_EMBEDDED_BITMAPS( a ) a
1193#else
1194#define PUT_EMBEDDED_BITMAPS( a ) NULL
1195#endif
1196
1197#ifdef TT_CONFIG_OPTION_COLOR_LAYERS
1198#define PUT_COLOR_LAYERS( a ) a
1199#else
1200#define PUT_COLOR_LAYERS( a ) NULL
1201#endif
1202
1203#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
1204#define PUT_PS_NAMES( a ) a
1205#else
1206#define PUT_PS_NAMES( a ) NULL
1207#endif
1208
1209 FT_DEFINE_SFNT_INTERFACE(
1210 sfnt_interface,
1211
1212 tt_face_goto_table, /* TT_Loader_GotoTableFunc goto_table */
1213
1214 sfnt_init_face, /* TT_Init_Face_Func init_face */
1215 sfnt_load_face, /* TT_Load_Face_Func load_face */
1216 sfnt_done_face, /* TT_Done_Face_Func done_face */
1217 sfnt_get_interface, /* FT_Module_Requester get_interface */
1218
1219 tt_face_load_any, /* TT_Load_Any_Func load_any */
1220
1221 tt_face_load_head, /* TT_Load_Table_Func load_head */
1222 tt_face_load_hhea, /* TT_Load_Metrics_Func load_hhea */
1223 tt_face_load_cmap, /* TT_Load_Table_Func load_cmap */
1224 tt_face_load_maxp, /* TT_Load_Table_Func load_maxp */
1225 tt_face_load_os2, /* TT_Load_Table_Func load_os2 */
1226 tt_face_load_post, /* TT_Load_Table_Func load_post */
1227
1228 tt_face_load_name, /* TT_Load_Table_Func load_name */
1229 tt_face_free_name, /* TT_Free_Table_Func free_name */
1230
1231 tt_face_load_kern, /* TT_Load_Table_Func load_kern */
1232 tt_face_load_gasp, /* TT_Load_Table_Func load_gasp */
1233 tt_face_load_pclt, /* TT_Load_Table_Func load_init */
1234
1235 /* see `ttload.h' */
1236 PUT_EMBEDDED_BITMAPS( tt_face_load_bhed ),
1237 /* TT_Load_Table_Func load_bhed */
1238 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit_image ),
1239 /* TT_Load_SBit_Image_Func load_sbit_image */
1240
1241 /* see `ttpost.h' */
1242 PUT_PS_NAMES( tt_face_get_ps_name ),
1243 /* TT_Get_PS_Name_Func get_psname */
1244 PUT_PS_NAMES( tt_face_free_ps_names ),
1245 /* TT_Free_Table_Func free_psnames */
1246
1247 /* since version 2.1.8 */
1248 tt_face_get_kerning, /* TT_Face_GetKerningFunc get_kerning */
1249
1250 /* since version 2.2 */
1251 tt_face_load_font_dir, /* TT_Load_Table_Func load_font_dir */
1252 tt_face_load_hmtx, /* TT_Load_Metrics_Func load_hmtx */
1253
1254 /* see `ttsbit.h' and `sfnt.h' */
1255 PUT_EMBEDDED_BITMAPS( tt_face_load_sbit ),
1256 /* TT_Load_Table_Func load_eblc */
1257 PUT_EMBEDDED_BITMAPS( tt_face_free_sbit ),
1258 /* TT_Free_Table_Func free_eblc */
1259
1260 PUT_EMBEDDED_BITMAPS( tt_face_set_sbit_strike ),
1261 /* TT_Set_SBit_Strike_Func set_sbit_strike */
1262 PUT_EMBEDDED_BITMAPS( tt_face_load_strike_metrics ),
1263 /* TT_Load_Strike_Metrics_Func load_strike_metrics */
1264
1265 PUT_COLOR_LAYERS( tt_face_load_cpal ),
1266 /* TT_Load_Table_Func load_cpal */
1267 PUT_COLOR_LAYERS( tt_face_load_colr ),
1268 /* TT_Load_Table_Func load_colr */
1269 PUT_COLOR_LAYERS( tt_face_free_cpal ),
1270 /* TT_Free_Table_Func free_cpal */
1271 PUT_COLOR_LAYERS( tt_face_free_colr ),
1272 /* TT_Free_Table_Func free_colr */
1273 PUT_COLOR_LAYERS( tt_face_palette_set ),
1274 /* TT_Set_Palette_Func set_palette */
1275 PUT_COLOR_LAYERS( tt_face_get_colr_layer ),
1276 /* TT_Get_Colr_Layer_Func get_colr_layer */
1277 PUT_COLOR_LAYERS( tt_face_colr_blend_layer ),
1278 /* TT_Blend_Colr_Func colr_blend */
1279
1280 tt_face_get_metrics, /* TT_Get_Metrics_Func get_metrics */
1281
1282 tt_face_get_name, /* TT_Get_Name_Func get_name */
1283 sfnt_get_name_id /* TT_Get_Name_ID_Func get_name_id */
1284 )
1285
1286
1287 FT_DEFINE_MODULE(
1288 sfnt_module_class,
1289
1290 0, /* not a font driver or renderer */
1291 sizeof ( FT_ModuleRec ),
1292
1293 "sfnt", /* driver name */
1294 0x10000L, /* driver version 1.0 */
1295 0x20000L, /* driver requires FreeType 2.0 or higher */
1296
1297 (const void*)&sfnt_interface, /* module specific interface */
1298
1299 (FT_Module_Constructor)NULL, /* module_init */
1300 (FT_Module_Destructor) NULL, /* module_done */
1301 (FT_Module_Requester) sfnt_get_interface /* get_interface */
1302 )
1303
1304
1305/* END */
1306