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