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