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