(root)/
freetype-2.13.2/
src/
sfnt/
sfobjs.c
       1  /****************************************************************************
       2   *
       3   * sfobjs.c
       4   *
       5   *   SFNT object management (base).
       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 "sfobjs.h"
      20  #include "ttload.h"
      21  #include "ttcmap.h"
      22  #include "ttkern.h"
      23  #include "sfwoff.h"
      24  #include "sfwoff2.h"
      25  #include <freetype/internal/sfnt.h>
      26  #include <freetype/internal/ftdebug.h>
      27  #include <freetype/ttnameid.h>
      28  #include <freetype/tttags.h>
      29  #include <freetype/internal/services/svpscmap.h>
      30  #include <freetype/ftsnames.h>
      31  
      32  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
      33  #include <freetype/internal/services/svmm.h>
      34  #include <freetype/internal/services/svmetric.h>
      35  #endif
      36  
      37  #include "sferrors.h"
      38  
      39  #ifdef TT_CONFIG_OPTION_BDF
      40  #include "ttbdf.h"
      41  #endif
      42  
      43  
      44    /**************************************************************************
      45     *
      46     * The macro FT_COMPONENT is used in trace mode.  It is an implicit
      47     * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
      48     * messages during execution.
      49     */
      50  #undef  FT_COMPONENT
      51  #define FT_COMPONENT  sfobjs
      52  
      53  
      54  
      55    /* convert a UTF-16 name entry to ASCII */
      56    static FT_String*
      57    tt_name_ascii_from_utf16( TT_Name    entry,
      58                              FT_Memory  memory )
      59    {
      60      FT_String*  string = NULL;
      61      FT_UInt     len, code, n;
      62      FT_Byte*    read   = (FT_Byte*)entry->string;
      63      FT_Error    error;
      64  
      65  
      66      len = (FT_UInt)entry->stringLength / 2;
      67  
      68      if ( FT_QNEW_ARRAY( string, len + 1 ) )
      69        return NULL;
      70  
      71      for ( n = 0; n < len; n++ )
      72      {
      73        code = FT_NEXT_USHORT( read );
      74  
      75        if ( code == 0 )
      76          break;
      77  
      78        if ( code < 32 || code > 127 )
      79          code = '?';
      80  
      81        string[n] = (char)code;
      82      }
      83  
      84      string[n] = 0;
      85  
      86      return string;
      87    }
      88  
      89  
      90    /* convert an Apple Roman or symbol name entry to ASCII */
      91    static FT_String*
      92    tt_name_ascii_from_other( TT_Name    entry,
      93                              FT_Memory  memory )
      94    {
      95      FT_String*  string = NULL;
      96      FT_UInt     len, code, n;
      97      FT_Byte*    read   = (FT_Byte*)entry->string;
      98      FT_Error    error;
      99  
     100  
     101      len = (FT_UInt)entry->stringLength;
     102  
     103      if ( FT_QNEW_ARRAY( string, len + 1 ) )
     104        return NULL;
     105  
     106      for ( n = 0; n < len; n++ )
     107      {
     108        code = *read++;
     109  
     110        if ( code == 0 )
     111          break;
     112  
     113        if ( code < 32 || code > 127 )
     114          code = '?';
     115  
     116        string[n] = (char)code;
     117      }
     118  
     119      string[n] = 0;
     120  
     121      return string;
     122    }
     123  
     124  
     125    typedef FT_String*  (*TT_Name_ConvertFunc)( TT_Name    entry,
     126                                                FT_Memory  memory );
     127  
     128  
     129    /* documentation is in sfnt.h */
     130  
     131    FT_LOCAL_DEF( FT_Error )
     132    tt_face_get_name( TT_Face      face,
     133                      FT_UShort    nameid,
     134                      FT_String**  name )
     135    {
     136      FT_Memory   memory = face->root.memory;
     137      FT_Error    error  = FT_Err_Ok;
     138      FT_String*  result = NULL;
     139      FT_UShort   n;
     140      TT_Name     rec;
     141  
     142      FT_Int  found_apple         = -1;
     143      FT_Int  found_apple_roman   = -1;
     144      FT_Int  found_apple_english = -1;
     145      FT_Int  found_win           = -1;
     146      FT_Int  found_unicode       = -1;
     147  
     148      FT_Bool  is_english = 0;
     149  
     150      TT_Name_ConvertFunc  convert;
     151  
     152  
     153      FT_ASSERT( name );
     154  
     155      rec = face->name_table.names;
     156      for ( n = 0; n < face->num_names; n++, rec++ )
     157      {
     158        /* According to the OpenType 1.3 specification, only Microsoft or  */
     159        /* Apple platform IDs might be used in the `name' table.  The      */
     160        /* `Unicode' platform is reserved for the `cmap' table, and the    */
     161        /* `ISO' one is deprecated.                                        */
     162        /*                                                                 */
     163        /* However, the Apple TrueType specification doesn't say the same  */
     164        /* thing and goes to suggest that all Unicode `name' table entries */
     165        /* should be coded in UTF-16 (in big-endian format I suppose).     */
     166        /*                                                                 */
     167        if ( rec->nameID == nameid && rec->stringLength > 0 )
     168        {
     169          switch ( rec->platformID )
     170          {
     171          case TT_PLATFORM_APPLE_UNICODE:
     172          case TT_PLATFORM_ISO:
     173            /* there is `languageID' to check there.  We should use this */
     174            /* field only as a last solution when nothing else is        */
     175            /* available.                                                */
     176            /*                                                           */
     177            found_unicode = n;
     178            break;
     179  
     180          case TT_PLATFORM_MACINTOSH:
     181            /* This is a bit special because some fonts will use either    */
     182            /* an English language id, or a Roman encoding id, to indicate */
     183            /* the English version of its font name.                       */
     184            /*                                                             */
     185            if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
     186              found_apple_english = n;
     187            else if ( rec->encodingID == TT_MAC_ID_ROMAN )
     188              found_apple_roman = n;
     189            break;
     190  
     191          case TT_PLATFORM_MICROSOFT:
     192            /* we only take a non-English name when there is nothing */
     193            /* else available in the font                            */
     194            /*                                                       */
     195            if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )
     196            {
     197              switch ( rec->encodingID )
     198              {
     199              case TT_MS_ID_SYMBOL_CS:
     200              case TT_MS_ID_UNICODE_CS:
     201              case TT_MS_ID_UCS_4:
     202                is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
     203                found_win  = n;
     204                break;
     205  
     206              default:
     207                ;
     208              }
     209            }
     210            break;
     211  
     212          default:
     213            ;
     214          }
     215        }
     216      }
     217  
     218      found_apple = found_apple_roman;
     219      if ( found_apple_english >= 0 )
     220        found_apple = found_apple_english;
     221  
     222      /* some fonts contain invalid Unicode or Macintosh formatted entries; */
     223      /* we will thus favor names encoded in Windows formats if available   */
     224      /* (provided it is an English name)                                   */
     225      /*                                                                    */
     226      convert = NULL;
     227      if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )
     228      {
     229        rec = face->name_table.names + found_win;
     230        switch ( rec->encodingID )
     231        {
     232          /* all Unicode strings are encoded using UTF-16BE */
     233        case TT_MS_ID_UNICODE_CS:
     234        case TT_MS_ID_SYMBOL_CS:
     235          convert = tt_name_ascii_from_utf16;
     236          break;
     237  
     238        case TT_MS_ID_UCS_4:
     239          /* Apparently, if this value is found in a name table entry, it is */
     240          /* documented as `full Unicode repertoire'.  Experience with the   */
     241          /* MsGothic font shipped with Windows Vista shows that this really */
     242          /* means UTF-16 encoded names (UCS-4 values are only used within   */
     243          /* charmaps).                                                      */
     244          convert = tt_name_ascii_from_utf16;
     245          break;
     246  
     247        default:
     248          ;
     249        }
     250      }
     251      else if ( found_apple >= 0 )
     252      {
     253        rec     = face->name_table.names + found_apple;
     254        convert = tt_name_ascii_from_other;
     255      }
     256      else if ( found_unicode >= 0 )
     257      {
     258        rec     = face->name_table.names + found_unicode;
     259        convert = tt_name_ascii_from_utf16;
     260      }
     261  
     262      if ( rec && convert )
     263      {
     264        if ( !rec->string )
     265        {
     266          FT_Stream  stream = face->name_table.stream;
     267  
     268  
     269          if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
     270               FT_STREAM_SEEK( rec->stringOffset )              ||
     271               FT_STREAM_READ( rec->string, rec->stringLength ) )
     272          {
     273            FT_FREE( rec->string );
     274            rec->stringLength = 0;
     275            result            = NULL;
     276            goto Exit;
     277          }
     278        }
     279  
     280        result = convert( rec, memory );
     281      }
     282  
     283    Exit:
     284      *name = result;
     285      return error;
     286    }
     287  
     288  
     289    static FT_Encoding
     290    sfnt_find_encoding( int  platform_id,
     291                        int  encoding_id )
     292    {
     293      typedef struct  TEncoding_
     294      {
     295        int          platform_id;
     296        int          encoding_id;
     297        FT_Encoding  encoding;
     298  
     299      } TEncoding;
     300  
     301      static
     302      const TEncoding  tt_encodings[] =
     303      {
     304        { TT_PLATFORM_ISO,           -1,                  FT_ENCODING_UNICODE },
     305  
     306        { TT_PLATFORM_APPLE_UNICODE, -1,                  FT_ENCODING_UNICODE },
     307  
     308        { TT_PLATFORM_MACINTOSH,     TT_MAC_ID_ROMAN,     FT_ENCODING_APPLE_ROMAN },
     309  
     310        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SYMBOL_CS,  FT_ENCODING_MS_SYMBOL },
     311        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UCS_4,      FT_ENCODING_UNICODE },
     312        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
     313        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SJIS,       FT_ENCODING_SJIS },
     314        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_PRC,        FT_ENCODING_PRC },
     315        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_BIG_5,      FT_ENCODING_BIG5 },
     316        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_WANSUNG,    FT_ENCODING_WANSUNG },
     317        { TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,      FT_ENCODING_JOHAB }
     318      };
     319  
     320      const TEncoding  *cur, *limit;
     321  
     322  
     323      cur   = tt_encodings;
     324      limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );
     325  
     326      for ( ; cur < limit; cur++ )
     327      {
     328        if ( cur->platform_id == platform_id )
     329        {
     330          if ( cur->encoding_id == encoding_id ||
     331               cur->encoding_id == -1          )
     332            return cur->encoding;
     333        }
     334      }
     335  
     336      return FT_ENCODING_NONE;
     337    }
     338  
     339  
     340    /* Fill in face->ttc_header.  If the font is not a TTC, it is */
     341    /* synthesized into a TTC with one offset table.              */
     342    static FT_Error
     343    sfnt_open_font( FT_Stream  stream,
     344                    TT_Face    face,
     345                    FT_Int*    face_instance_index,
     346                    FT_Long*   woff2_num_faces )
     347    {
     348      FT_Memory  memory = stream->memory;
     349      FT_Error   error;
     350      FT_ULong   tag, offset;
     351  
     352      static const FT_Frame_Field  ttc_header_fields[] =
     353      {
     354  #undef  FT_STRUCTURE
     355  #define FT_STRUCTURE  TTC_HeaderRec
     356  
     357        FT_FRAME_START( 8 ),
     358          FT_FRAME_LONG( version ),
     359          FT_FRAME_LONG( count   ),  /* this is ULong in the specs */
     360        FT_FRAME_END
     361      };
     362  
     363  #ifndef FT_CONFIG_OPTION_USE_BROTLI
     364      FT_UNUSED( face_instance_index );
     365      FT_UNUSED( woff2_num_faces );
     366  #endif
     367  
     368  
     369      face->ttc_header.tag     = 0;
     370      face->ttc_header.version = 0;
     371      face->ttc_header.count   = 0;
     372  
     373  #if defined( FT_CONFIG_OPTION_USE_ZLIB )   || \
     374      defined( FT_CONFIG_OPTION_USE_BROTLI )
     375    retry:
     376  #endif
     377  
     378      offset = FT_STREAM_POS();
     379  
     380      if ( FT_READ_ULONG( tag ) )
     381        return error;
     382  
     383  #ifdef FT_CONFIG_OPTION_USE_ZLIB
     384      if ( tag == TTAG_wOFF )
     385      {
     386        FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));
     387  
     388        if ( FT_STREAM_SEEK( offset ) )
     389          return error;
     390  
     391        error = woff_open_font( stream, face );
     392        if ( error )
     393          return error;
     394  
     395        /* Swap out stream and retry! */
     396        stream = face->root.stream;
     397        goto retry;
     398      }
     399  #endif
     400  
     401  #ifdef FT_CONFIG_OPTION_USE_BROTLI
     402      if ( tag == TTAG_wOF2 )
     403      {
     404        FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));
     405  
     406        if ( FT_STREAM_SEEK( offset ) )
     407          return error;
     408  
     409        error = woff2_open_font( stream,
     410                                 face,
     411                                 face_instance_index,
     412                                 woff2_num_faces );
     413        if ( error )
     414          return error;
     415  
     416        /* Swap out stream and retry! */
     417        stream = face->root.stream;
     418        goto retry;
     419      }
     420  #endif
     421  
     422      if ( tag != 0x00010000UL &&
     423           tag != TTAG_ttcf    &&
     424           tag != TTAG_OTTO    &&
     425           tag != TTAG_true    &&
     426           tag != TTAG_typ1    &&
     427           tag != TTAG_0xA5kbd &&
     428           tag != TTAG_0xA5lst &&
     429           tag != 0x00020000UL )
     430      {
     431        FT_TRACE2(( "  not a font using the SFNT container format\n" ));
     432        return FT_THROW( Unknown_File_Format );
     433      }
     434  
     435      face->ttc_header.tag = TTAG_ttcf;
     436  
     437      if ( tag == TTAG_ttcf )
     438      {
     439        FT_Int  n;
     440  
     441  
     442        FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));
     443  
     444        if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
     445          return error;
     446  
     447        FT_TRACE3(( "                with %ld subfonts\n",
     448                    face->ttc_header.count ));
     449  
     450        if ( face->ttc_header.count == 0 )
     451          return FT_THROW( Invalid_Table );
     452  
     453        /* a rough size estimate: let's conservatively assume that there   */
     454        /* is just a single table info in each subfont header (12 + 16*1 = */
     455        /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
     456        /* size of the TTC header plus `28*count' bytes for all subfont    */
     457        /* headers                                                         */
     458        if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
     459          return FT_THROW( Array_Too_Large );
     460  
     461        /* now read the offsets of each font in the file */
     462        if ( FT_QNEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
     463          return error;
     464  
     465        if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
     466          return error;
     467  
     468        for ( n = 0; n < face->ttc_header.count; n++ )
     469          face->ttc_header.offsets[n] = FT_GET_ULONG();
     470  
     471        FT_FRAME_EXIT();
     472      }
     473      else
     474      {
     475        FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));
     476  
     477        face->ttc_header.version = 1 << 16;
     478        face->ttc_header.count   = 1;
     479  
     480        if ( FT_QNEW( face->ttc_header.offsets ) )
     481          return error;
     482  
     483        face->ttc_header.offsets[0] = offset;
     484      }
     485  
     486      return error;
     487    }
     488  
     489  
     490    FT_LOCAL_DEF( FT_Error )
     491    sfnt_init_face( FT_Stream      stream,
     492                    TT_Face        face,
     493                    FT_Int         face_instance_index,
     494                    FT_Int         num_params,
     495                    FT_Parameter*  params )
     496    {
     497      FT_Error      error;
     498      FT_Library    library         = face->root.driver->root.library;
     499      SFNT_Service  sfnt;
     500      FT_Int        face_index;
     501      FT_Long       woff2_num_faces = 0;
     502  
     503  
     504      /* for now, parameters are unused */
     505      FT_UNUSED( num_params );
     506      FT_UNUSED( params );
     507  
     508  
     509      sfnt = (SFNT_Service)face->sfnt;
     510      if ( !sfnt )
     511      {
     512        sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
     513        if ( !sfnt )
     514        {
     515          FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
     516          return FT_THROW( Missing_Module );
     517        }
     518  
     519        face->sfnt       = sfnt;
     520        face->goto_table = sfnt->goto_table;
     521      }
     522  
     523      FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );
     524  
     525  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     526      if ( !face->mm )
     527      {
     528        /* we want the MM interface from the `truetype' module only */
     529        FT_Module  tt_module = FT_Get_Module( library, "truetype" );
     530  
     531  
     532        face->mm = ft_module_get_service( tt_module,
     533                                          FT_SERVICE_ID_MULTI_MASTERS,
     534                                          0 );
     535      }
     536  
     537      if ( !face->tt_var )
     538      {
     539        /* we want the metrics variations interface */
     540        /* from the `truetype' module only          */
     541        FT_Module  tt_module = FT_Get_Module( library, "truetype" );
     542  
     543  
     544        face->tt_var = ft_module_get_service( tt_module,
     545                                              FT_SERVICE_ID_METRICS_VARIATIONS,
     546                                              0 );
     547      }
     548  
     549      if ( !face->face_var )
     550        face->face_var = ft_module_get_service(
     551                           &face->root.driver->root,
     552                           FT_SERVICE_ID_METRICS_VARIATIONS,
     553                           0 );
     554  #endif
     555  
     556      FT_TRACE2(( "SFNT driver\n" ));
     557  
     558      error = sfnt_open_font( stream,
     559                              face,
     560                              &face_instance_index,
     561                              &woff2_num_faces );
     562      if ( error )
     563        return error;
     564  
     565      /* Stream may have changed in sfnt_open_font. */
     566      stream = face->root.stream;
     567  
     568      FT_TRACE2(( "sfnt_init_face: %p (index %d)\n",
     569                  (void *)face,
     570                  face_instance_index ));
     571  
     572      face_index = FT_ABS( face_instance_index ) & 0xFFFF;
     573  
     574      /* value -(N+1) requests information on index N */
     575      if ( face_instance_index < 0 && face_index > 0 )
     576        face_index--;
     577  
     578      if ( face_index >= face->ttc_header.count )
     579      {
     580        if ( face_instance_index >= 0 )
     581          return FT_THROW( Invalid_Argument );
     582        else
     583          face_index = 0;
     584      }
     585  
     586      if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
     587        return error;
     588  
     589      /* check whether we have a valid TrueType file */
     590      error = sfnt->load_font_dir( face, stream );
     591      if ( error )
     592        return error;
     593  
     594  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     595      {
     596        FT_Memory  memory = face->root.memory;
     597  
     598        FT_ULong  fvar_len;
     599  
     600        FT_ULong  version;
     601        FT_ULong  offset;
     602  
     603        FT_UShort  num_axes;
     604        FT_UShort  axis_size;
     605        FT_UShort  num_instances;
     606        FT_UShort  instance_size;
     607  
     608        FT_Int  instance_index;
     609  
     610        FT_Byte*  default_values  = NULL;
     611        FT_Byte*  instance_values = NULL;
     612  
     613  
     614        instance_index = FT_ABS( face_instance_index ) >> 16;
     615  
     616        /* test whether current face is a GX font with named instances */
     617        if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) ||
     618             fvar_len < 20                                          ||
     619             FT_READ_ULONG( version )                               ||
     620             FT_READ_USHORT( offset )                               ||
     621             FT_STREAM_SKIP( 2 ) /* reserved */                     ||
     622             FT_READ_USHORT( num_axes )                             ||
     623             FT_READ_USHORT( axis_size )                            ||
     624             FT_READ_USHORT( num_instances )                        ||
     625             FT_READ_USHORT( instance_size )                        )
     626        {
     627          version       = 0;
     628          offset        = 0;
     629          num_axes      = 0;
     630          axis_size     = 0;
     631          num_instances = 0;
     632          instance_size = 0;
     633        }
     634  
     635        /* check that the data is bound by the table length */
     636        if ( version != 0x00010000UL                    ||
     637             axis_size != 20                            ||
     638             num_axes == 0                              ||
     639             /* `num_axes' limit implied by 16-bit `instance_size' */
     640             num_axes > 0x3FFE                          ||
     641             !( instance_size == 4 + 4 * num_axes ||
     642                instance_size == 6 + 4 * num_axes )     ||
     643             /* `num_instances' limit implied by limited range of name IDs */
     644             num_instances > 0x7EFF                     ||
     645             offset                          +
     646               axis_size * num_axes          +
     647               instance_size * num_instances > fvar_len )
     648          num_instances = 0;
     649        else
     650          face->variation_support |= TT_FACE_FLAG_VAR_FVAR;
     651  
     652        /*
     653         * As documented in the OpenType specification, an entry for the
     654         * default instance may be omitted in the named instance table.  In
     655         * particular this means that even if there is no named instance
     656         * table in the font we actually do have a named instance, namely the
     657         * default instance.
     658         *
     659         * For consistency, we always want the default instance in our list
     660         * of named instances.  If it is missing, we try to synthesize it
     661         * later on.  Here, we have to adjust `num_instances' accordingly.
     662         */
     663  
     664        if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) &&
     665             !( FT_QALLOC(  default_values, num_axes * 4 ) ||
     666                FT_QALLOC( instance_values, num_axes * 4 ) )     )
     667        {
     668          /* the current stream position is 16 bytes after the table start */
     669          FT_ULong  array_start = FT_STREAM_POS() - 16 + offset;
     670          FT_ULong  default_value_offset, instance_offset;
     671  
     672          FT_Byte*  p;
     673          FT_UInt   i;
     674  
     675  
     676          default_value_offset = array_start + 8;
     677          p                    = default_values;
     678  
     679          for ( i = 0; i < num_axes; i++ )
     680          {
     681            (void)FT_STREAM_READ_AT( default_value_offset, p, 4 );
     682  
     683            default_value_offset += axis_size;
     684            p                    += 4;
     685          }
     686  
     687          instance_offset = array_start + axis_size * num_axes + 4;
     688  
     689          for ( i = 0; i < num_instances; i++ )
     690          {
     691            (void)FT_STREAM_READ_AT( instance_offset,
     692                                     instance_values,
     693                                     num_axes * 4 );
     694  
     695            if ( !ft_memcmp( default_values, instance_values, num_axes * 4 ) )
     696              break;
     697  
     698            instance_offset += instance_size;
     699          }
     700  
     701          /* named instance indices start with value 1 */
     702          face->var_default_named_instance = i + 1;
     703  
     704          if ( i == num_instances )
     705          {
     706            /* no default instance in named instance table; */
     707            /* we thus have to synthesize it                */
     708            num_instances++;
     709          }
     710        }
     711  
     712        FT_FREE( default_values );
     713        FT_FREE( instance_values );
     714  
     715        /* we don't support Multiple Master CFFs yet; */
     716        /* note that `glyf' or `CFF2' have precedence */
     717        if ( face->goto_table( face, TTAG_glyf, stream, 0 ) &&
     718             face->goto_table( face, TTAG_CFF2, stream, 0 ) &&
     719             !face->goto_table( face, TTAG_CFF, stream, 0 ) )
     720          num_instances = 0;
     721  
     722        /* instance indices in `face_instance_index' start with index 1, */
     723        /* thus `>' and not `>='                                         */
     724        if ( instance_index > num_instances )
     725        {
     726          if ( face_instance_index >= 0 )
     727            return FT_THROW( Invalid_Argument );
     728          else
     729            num_instances = 0;
     730        }
     731  
     732        face->root.style_flags = (FT_Long)num_instances << 16;
     733      }
     734  #endif
     735  
     736      face->root.num_faces  = face->ttc_header.count;
     737      face->root.face_index = face_instance_index;
     738  
     739      /* `num_faces' for a WOFF2 needs to be handled separately. */
     740      if ( woff2_num_faces )
     741        face->root.num_faces = woff2_num_faces;
     742  
     743      return error;
     744    }
     745  
     746  
     747  #define LOAD_( x )                                          \
     748    do                                                        \
     749    {                                                         \
     750      FT_TRACE2(( "`" #x "' " ));                             \
     751      FT_TRACE3(( "-->\n" ));                                 \
     752                                                              \
     753      error = sfnt->load_ ## x( face, stream );               \
     754                                                              \
     755      FT_TRACE2(( "%s\n", ( !error )                          \
     756                          ? "loaded"                          \
     757                          : FT_ERR_EQ( error, Table_Missing ) \
     758                            ? "missing"                       \
     759                            : "failed to load" ));            \
     760      FT_TRACE3(( "\n" ));                                    \
     761    } while ( 0 )
     762  
     763  #define LOADM_( x, vertical )                               \
     764    do                                                        \
     765    {                                                         \
     766      FT_TRACE2(( "`%s" #x "' ",                              \
     767                  vertical ? "vertical " : "" ));             \
     768      FT_TRACE3(( "-->\n" ));                                 \
     769                                                              \
     770      error = sfnt->load_ ## x( face, stream, vertical );     \
     771                                                              \
     772      FT_TRACE2(( "%s\n", ( !error )                          \
     773                          ? "loaded"                          \
     774                          : FT_ERR_EQ( error, Table_Missing ) \
     775                            ? "missing"                       \
     776                            : "failed to load" ));            \
     777      FT_TRACE3(( "\n" ));                                    \
     778    } while ( 0 )
     779  
     780  #define GET_NAME( id, field )                                   \
     781    do                                                            \
     782    {                                                             \
     783      error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
     784      if ( error )                                                \
     785        goto Exit;                                                \
     786    } while ( 0 )
     787  
     788  
     789    FT_LOCAL_DEF( FT_Error )
     790    sfnt_load_face( FT_Stream      stream,
     791                    TT_Face        face,
     792                    FT_Int         face_instance_index,
     793                    FT_Int         num_params,
     794                    FT_Parameter*  params )
     795    {
     796      FT_Error  error;
     797  #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
     798      FT_Error  psnames_error;
     799  #endif
     800  
     801      FT_Bool  has_outline;
     802      FT_Bool  is_apple_sbit;
     803  
     804      FT_Bool  has_CBLC;
     805      FT_Bool  has_CBDT;
     806      FT_Bool  has_EBLC;
     807      FT_Bool  has_bloc;
     808      FT_Bool  has_sbix;
     809  
     810      FT_Bool  ignore_typographic_family    = FALSE;
     811      FT_Bool  ignore_typographic_subfamily = FALSE;
     812      FT_Bool  ignore_sbix                  = FALSE;
     813  
     814      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
     815  
     816      FT_UNUSED( face_instance_index );
     817  
     818  
     819      /* Check parameters */
     820  
     821      {
     822        FT_Int  i;
     823  
     824  
     825        for ( i = 0; i < num_params; i++ )
     826        {
     827          if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY )
     828            ignore_typographic_family = TRUE;
     829          else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY )
     830            ignore_typographic_subfamily = TRUE;
     831          else if ( params[i].tag == FT_PARAM_TAG_IGNORE_SBIX )
     832            ignore_sbix = TRUE;
     833        }
     834      }
     835  
     836      /* Load tables */
     837  
     838      /* We now support two SFNT-based bitmapped font formats.  They */
     839      /* are recognized easily as they do not include a `glyf'       */
     840      /* table.                                                      */
     841      /*                                                             */
     842      /* The first format comes from Apple, and uses a table named   */
     843      /* `bhed' instead of `head' to store the font header (using    */
     844      /* the same format).  It also doesn't include horizontal and   */
     845      /* vertical metrics tables (i.e. `hhea' and `vhea' tables are  */
     846      /* missing).                                                   */
     847      /*                                                             */
     848      /* The other format comes from Microsoft, and is used with     */
     849      /* WinCE/PocketPC.  It looks like a standard TTF, except that  */
     850      /* it doesn't contain outlines.                                */
     851      /*                                                             */
     852  
     853      FT_TRACE2(( "sfnt_load_face: %p\n", (void *)face ));
     854      FT_TRACE2(( "\n" ));
     855  
     856      /* do we have outlines in there? */
     857  #ifdef FT_CONFIG_OPTION_INCREMENTAL
     858      has_outline = FT_BOOL( face->root.internal->incremental_interface ||
     859                             tt_face_lookup_table( face, TTAG_glyf )    ||
     860                             tt_face_lookup_table( face, TTAG_CFF )     ||
     861                             tt_face_lookup_table( face, TTAG_CFF2 )    );
     862  #else
     863      has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) ||
     864                             tt_face_lookup_table( face, TTAG_CFF )  ||
     865                             tt_face_lookup_table( face, TTAG_CFF2 ) );
     866  #endif
     867  
     868      /* check which sbit formats are present */
     869      has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
     870      has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
     871      has_EBLC = !face->goto_table( face, TTAG_EBLC, stream, 0 );
     872      has_bloc = !face->goto_table( face, TTAG_bloc, stream, 0 );
     873      has_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );
     874  
     875      is_apple_sbit = FALSE;
     876  
     877      if ( ignore_sbix )
     878        has_sbix = FALSE;
     879  
     880      /* if this font doesn't contain outlines, we try to load */
     881      /* a `bhed' table                                        */
     882      if ( !has_outline && sfnt->load_bhed )
     883      {
     884        LOAD_( bhed );
     885        is_apple_sbit = FT_BOOL( !error );
     886      }
     887  
     888      /* load the font header (`head' table) if this isn't an Apple */
     889      /* sbit font file                                             */
     890      if ( !is_apple_sbit || has_sbix )
     891      {
     892        LOAD_( head );
     893        if ( error )
     894          goto Exit;
     895      }
     896  
     897      /* Ignore outlines for CBLC/CBDT fonts. */
     898      if ( has_CBLC || has_CBDT )
     899        has_outline = FALSE;
     900  
     901      /* OpenType 1.8.2 introduced limits to this value;    */
     902      /* however, they make sense for older SFNT fonts also */
     903      if ( face->header.Units_Per_EM <    16 ||
     904           face->header.Units_Per_EM > 16384 )
     905      {
     906        error = FT_THROW( Invalid_Table );
     907  
     908        goto Exit;
     909      }
     910  
     911      /* the following tables are often not present in embedded TrueType */
     912      /* fonts within PDF documents, so don't check for them.            */
     913      LOAD_( maxp );
     914      LOAD_( cmap );
     915  
     916      /* the following tables are optional in PCL fonts -- */
     917      /* don't check for errors                            */
     918      LOAD_( name );
     919      LOAD_( post );
     920  
     921  #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
     922      psnames_error = error;
     923  #endif
     924  
     925      /* do not load the metrics headers and tables if this is an Apple */
     926      /* sbit font file                                                 */
     927      if ( !is_apple_sbit )
     928      {
     929        /* load the `hhea' and `hmtx' tables */
     930        LOADM_( hhea, 0 );
     931        if ( !error )
     932        {
     933          LOADM_( hmtx, 0 );
     934          if ( FT_ERR_EQ( error, Table_Missing ) )
     935          {
     936            error = FT_THROW( Hmtx_Table_Missing );
     937  
     938  #ifdef FT_CONFIG_OPTION_INCREMENTAL
     939            /* If this is an incrementally loaded font and there are */
     940            /* overriding metrics, tolerate a missing `hmtx' table.  */
     941            if ( face->root.internal->incremental_interface          &&
     942                 face->root.internal->incremental_interface->funcs->
     943                   get_glyph_metrics                                 )
     944            {
     945              face->horizontal.number_Of_HMetrics = 0;
     946              error                               = FT_Err_Ok;
     947            }
     948  #endif
     949          }
     950        }
     951        else if ( FT_ERR_EQ( error, Table_Missing ) )
     952        {
     953          /* No `hhea' table necessary for SFNT Mac fonts. */
     954          if ( face->format_tag == TTAG_true )
     955          {
     956            FT_TRACE2(( "This is an SFNT Mac font.\n" ));
     957  
     958            has_outline = 0;
     959            error       = FT_Err_Ok;
     960          }
     961          else
     962          {
     963            error = FT_THROW( Horiz_Header_Missing );
     964  
     965  #ifdef FT_CONFIG_OPTION_INCREMENTAL
     966            /* If this is an incrementally loaded font and there are */
     967            /* overriding metrics, tolerate a missing `hhea' table.  */
     968            if ( face->root.internal->incremental_interface          &&
     969                 face->root.internal->incremental_interface->funcs->
     970                   get_glyph_metrics                                 )
     971            {
     972              face->horizontal.number_Of_HMetrics = 0;
     973              error                               = FT_Err_Ok;
     974            }
     975  #endif
     976  
     977          }
     978        }
     979  
     980        if ( error )
     981          goto Exit;
     982  
     983        /* try to load the `vhea' and `vmtx' tables */
     984        LOADM_( hhea, 1 );
     985        if ( !error )
     986        {
     987          LOADM_( hmtx, 1 );
     988          if ( !error )
     989            face->vertical_info = 1;
     990        }
     991  
     992        if ( error && FT_ERR_NEQ( error, Table_Missing ) )
     993          goto Exit;
     994  
     995        LOAD_( os2 );
     996        if ( error )
     997        {
     998          /* we treat the table as missing if there are any errors */
     999          face->os2.version = 0xFFFFU;
    1000        }
    1001      }
    1002  
    1003      /* the optional tables */
    1004  
    1005      /* embedded bitmap support */
    1006      /* TODO: Replace this clumsy check for all possible sbit tables     */
    1007      /*       with something better (for example, by passing a parameter */
    1008      /*       to suppress 'sbix' loading).                               */
    1009      if ( sfnt->load_eblc                                  &&
    1010           ( has_CBLC || has_EBLC || has_bloc || has_sbix ) )
    1011        LOAD_( eblc );
    1012  
    1013      /* colored glyph support */
    1014      if ( sfnt->load_cpal )
    1015      {
    1016        LOAD_( cpal );
    1017        LOAD_( colr );
    1018      }
    1019  
    1020      /* OpenType-SVG glyph support */
    1021      if ( sfnt->load_svg )
    1022        LOAD_( svg );
    1023  
    1024      /* consider the pclt, kerning, and gasp tables as optional */
    1025      LOAD_( pclt );
    1026      LOAD_( gasp );
    1027      LOAD_( kern );
    1028  
    1029      face->root.num_glyphs = face->max_profile.numGlyphs;
    1030  
    1031      /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes  */
    1032      /* a WWS-only font face.  `WWS' stands for `weight', width', and */
    1033      /* `slope', a term used by Microsoft's Windows Presentation      */
    1034      /* Foundation (WPF).  This flag has been introduced in version   */
    1035      /* 1.5 of the OpenType specification (May 2008).                 */
    1036  
    1037      face->root.family_name = NULL;
    1038      face->root.style_name  = NULL;
    1039      if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
    1040      {
    1041        if ( !ignore_typographic_family )
    1042          GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
    1043        if ( !face->root.family_name )
    1044          GET_NAME( FONT_FAMILY, &face->root.family_name );
    1045  
    1046        if ( !ignore_typographic_subfamily )
    1047          GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
    1048        if ( !face->root.style_name )
    1049          GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
    1050      }
    1051      else
    1052      {
    1053        GET_NAME( WWS_FAMILY, &face->root.family_name );
    1054        if ( !face->root.family_name && !ignore_typographic_family )
    1055          GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
    1056        if ( !face->root.family_name )
    1057          GET_NAME( FONT_FAMILY, &face->root.family_name );
    1058  
    1059        GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
    1060        if ( !face->root.style_name && !ignore_typographic_subfamily )
    1061          GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
    1062        if ( !face->root.style_name )
    1063          GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
    1064      }
    1065  
    1066  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    1067      {
    1068        FT_Memory  memory = face->root.memory;
    1069  
    1070  
    1071        if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) )
    1072          goto Exit;
    1073      }
    1074  #endif
    1075  
    1076      /* now set up root fields */
    1077      {
    1078        FT_Face  root  = &face->root;
    1079        FT_Long  flags = root->face_flags;
    1080  
    1081  
    1082        /**********************************************************************
    1083         *
    1084         * Compute face flags.
    1085         */
    1086        if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
    1087             face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ||
    1088             face->colr                                       ||
    1089             face->svg                                        )
    1090          flags |= FT_FACE_FLAG_COLOR;      /* color glyphs */
    1091  
    1092        if ( has_outline == TRUE )
    1093        {
    1094          /* by default (and for backward compatibility) we handle */
    1095          /* fonts with an 'sbix' table as bitmap-only             */
    1096          if ( has_sbix )
    1097            flags |= FT_FACE_FLAG_SBIX;     /* with 'sbix' bitmaps */
    1098          else
    1099            flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
    1100        }
    1101  
    1102        /* The sfnt driver only supports bitmap fonts natively, thus we */
    1103        /* don't set FT_FACE_FLAG_HINTER.                               */
    1104        flags |= FT_FACE_FLAG_SFNT       |  /* SFNT file format  */
    1105                 FT_FACE_FLAG_HORIZONTAL;   /* horizontal data   */
    1106  
    1107  #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
    1108        if ( !psnames_error                             &&
    1109             face->postscript.FormatType != 0x00030000L )
    1110          flags |= FT_FACE_FLAG_GLYPH_NAMES;
    1111  #endif
    1112  
    1113        /* fixed width font? */
    1114        if ( face->postscript.isFixedPitch )
    1115          flags |= FT_FACE_FLAG_FIXED_WIDTH;
    1116  
    1117        /* vertical information? */
    1118        if ( face->vertical_info )
    1119          flags |= FT_FACE_FLAG_VERTICAL;
    1120  
    1121        /* kerning available ? */
    1122        if ( TT_FACE_HAS_KERNING( face ) )
    1123          flags |= FT_FACE_FLAG_KERNING;
    1124  
    1125  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    1126        /* Don't bother to load the tables unless somebody asks for them. */
    1127        /* No need to do work which will (probably) not be used.          */
    1128        if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
    1129          flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
    1130  #endif
    1131  
    1132        root->face_flags = flags;
    1133  
    1134        /**********************************************************************
    1135         *
    1136         * Compute style flags.
    1137         */
    1138  
    1139        flags = 0;
    1140        if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
    1141        {
    1142          /* We have an OS/2 table; use the `fsSelection' field.  Bit 9 */
    1143          /* indicates an oblique font face.  This flag has been        */
    1144          /* introduced in version 1.5 of the OpenType specification.   */
    1145  
    1146          if ( face->os2.fsSelection & 512 )       /* bit 9 */
    1147            flags |= FT_STYLE_FLAG_ITALIC;
    1148          else if ( face->os2.fsSelection & 1 )    /* bit 0 */
    1149            flags |= FT_STYLE_FLAG_ITALIC;
    1150  
    1151          if ( face->os2.fsSelection & 32 )        /* bit 5 */
    1152            flags |= FT_STYLE_FLAG_BOLD;
    1153        }
    1154        else
    1155        {
    1156          /* this is an old Mac font, use the header field */
    1157  
    1158          if ( face->header.Mac_Style & 1 )
    1159            flags |= FT_STYLE_FLAG_BOLD;
    1160  
    1161          if ( face->header.Mac_Style & 2 )
    1162            flags |= FT_STYLE_FLAG_ITALIC;
    1163        }
    1164  
    1165        root->style_flags |= flags;
    1166  
    1167        /**********************************************************************
    1168         *
    1169         * Polish the charmaps.
    1170         *
    1171         *   Try to set the charmap encoding according to the platform &
    1172         *   encoding ID of each charmap.  Emulate Unicode charmap if one
    1173         *   is missing.
    1174         */
    1175  
    1176        tt_face_build_cmaps( face );  /* ignore errors */
    1177  
    1178  
    1179        /* set the encoding fields */
    1180        {
    1181          FT_Int   m;
    1182  #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
    1183          FT_Bool  has_unicode = FALSE;
    1184  #endif
    1185  
    1186  
    1187          for ( m = 0; m < root->num_charmaps; m++ )
    1188          {
    1189            FT_CharMap  charmap = root->charmaps[m];
    1190  
    1191  
    1192            charmap->encoding = sfnt_find_encoding( charmap->platform_id,
    1193                                                    charmap->encoding_id );
    1194  
    1195  #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
    1196  
    1197            if ( charmap->encoding == FT_ENCODING_UNICODE   ||
    1198                 charmap->encoding == FT_ENCODING_MS_SYMBOL )  /* PUA */
    1199              has_unicode = TRUE;
    1200          }
    1201  
    1202          /* synthesize Unicode charmap if one is missing */
    1203          if ( !has_unicode                                &&
    1204               root->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
    1205          {
    1206            FT_CharMapRec  cmaprec;
    1207  
    1208  
    1209            cmaprec.face        = root;
    1210            cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
    1211            cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
    1212            cmaprec.encoding    = FT_ENCODING_UNICODE;
    1213  
    1214  
    1215            error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec,
    1216                                 NULL, &cmaprec, NULL );
    1217            if ( error                                      &&
    1218                 FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
    1219                 FT_ERR_NEQ( error, Unimplemented_Feature ) )
    1220              goto Exit;
    1221            error = FT_Err_Ok;
    1222  
    1223  #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
    1224  
    1225          }
    1226        }
    1227  
    1228  #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
    1229  
    1230        /*
    1231         * Now allocate the root array of FT_Bitmap_Size records and
    1232         * populate them.  Unfortunately, it isn't possible to indicate bit
    1233         * depths in the FT_Bitmap_Size record.  This is a design error.
    1234         */
    1235        {
    1236          FT_UInt  count;
    1237  
    1238  
    1239          count = face->sbit_num_strikes;
    1240  
    1241          if ( count > 0 )
    1242          {
    1243            FT_Memory        memory   = face->root.memory;
    1244            FT_UShort        em_size  = face->header.Units_Per_EM;
    1245            FT_Short         avgwidth = face->os2.xAvgCharWidth;
    1246            FT_Size_Metrics  metrics;
    1247  
    1248            FT_UInt*  sbit_strike_map = NULL;
    1249            FT_UInt   strike_idx, bsize_idx;
    1250  
    1251  
    1252            if ( em_size == 0 || face->os2.version == 0xFFFFU )
    1253            {
    1254              avgwidth = 1;
    1255              em_size = 1;
    1256            }
    1257  
    1258            /* to avoid invalid strike data in the `available_sizes' field */
    1259            /* of `FT_Face', we map `available_sizes' indices to strike    */
    1260            /* indices                                                     */
    1261            if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
    1262                 FT_QNEW_ARRAY( sbit_strike_map, count ) )
    1263              goto Exit;
    1264  
    1265            bsize_idx = 0;
    1266            for ( strike_idx = 0; strike_idx < count; strike_idx++ )
    1267            {
    1268              FT_Bitmap_Size*  bsize = root->available_sizes + bsize_idx;
    1269  
    1270  
    1271              error = sfnt->load_strike_metrics( face, strike_idx, &metrics );
    1272              if ( error )
    1273                continue;
    1274  
    1275              bsize->height = (FT_Short)( metrics.height >> 6 );
    1276              bsize->width  = (FT_Short)(
    1277                ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );
    1278  
    1279              bsize->x_ppem = metrics.x_ppem << 6;
    1280              bsize->y_ppem = metrics.y_ppem << 6;
    1281  
    1282              /* assume 72dpi */
    1283              bsize->size   = metrics.y_ppem << 6;
    1284  
    1285              /* only use strikes with valid PPEM values */
    1286              if ( bsize->x_ppem && bsize->y_ppem )
    1287                sbit_strike_map[bsize_idx++] = strike_idx;
    1288            }
    1289  
    1290            /* reduce array size to the actually used elements */
    1291            FT_MEM_QRENEW_ARRAY( sbit_strike_map, count, bsize_idx );
    1292  
    1293            /* from now on, all strike indices are mapped */
    1294            /* using `sbit_strike_map'                    */
    1295            if ( bsize_idx )
    1296            {
    1297              face->sbit_strike_map = sbit_strike_map;
    1298  
    1299              root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
    1300              root->num_fixed_sizes = (FT_Int)bsize_idx;
    1301            }
    1302          }
    1303        }
    1304  
    1305  #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
    1306  
    1307        /* a font with no bitmaps and no outlines is scalable; */
    1308        /* it has only empty glyphs then                       */
    1309        if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
    1310          root->face_flags |= FT_FACE_FLAG_SCALABLE;
    1311  
    1312  
    1313        /**********************************************************************
    1314         *
    1315         * Set up metrics.
    1316         */
    1317        if ( FT_IS_SCALABLE( root ) ||
    1318             FT_HAS_SBIX( root )    )
    1319        {
    1320          /* XXX What about if outline header is missing */
    1321          /*     (e.g. sfnt wrapped bitmap)?             */
    1322          root->bbox.xMin    = face->header.xMin;
    1323          root->bbox.yMin    = face->header.yMin;
    1324          root->bbox.xMax    = face->header.xMax;
    1325          root->bbox.yMax    = face->header.yMax;
    1326          root->units_per_EM = face->header.Units_Per_EM;
    1327  
    1328  
    1329          /*
    1330           * Computing the ascender/descender/height is tricky.
    1331           *
    1332           * The OpenType specification v1.8.3 says:
    1333           *
    1334           *   [OS/2's] sTypoAscender, sTypoDescender and sTypoLineGap fields
    1335           *   are intended to allow applications to lay out documents in a
    1336           *   typographically-correct and portable fashion.
    1337           *
    1338           * This is somewhat at odds with the decades of backwards
    1339           * compatibility, operating systems and applications doing whatever
    1340           * they want, not to mention broken fonts.
    1341           *
    1342           * Not all fonts have an OS/2 table; in this case, we take the values
    1343           * in the horizontal header, although there is nothing stopping the
    1344           * values from being unreliable. Even with a OS/2 table, certain fonts
    1345           * set the sTypoAscender, sTypoDescender and sTypoLineGap fields to 0
    1346           * and instead correctly set usWinAscent and usWinDescent.
    1347           *
    1348           * As an example, Arial Narrow is shipped as four files ARIALN.TTF,
    1349           * ARIALNI.TTF, ARIALNB.TTF and ARIALNBI.TTF. Strangely, all fonts have
    1350           * the same values in their sTypo* fields, except ARIALNB.ttf which
    1351           * sets them to 0. All of them have different usWinAscent/Descent
    1352           * values. The OS/2 table therefore cannot be trusted for computing the
    1353           * text height reliably.
    1354           *
    1355           * As a compromise, do the following:
    1356           *
    1357           * 1. If the OS/2 table exists and the fsSelection bit 7 is set
    1358           *    (USE_TYPO_METRICS), trust the font and use the sTypo* metrics.
    1359           * 2. Otherwise, use the `hhea' table's metrics.
    1360           * 3. If they are zero and the OS/2 table exists,
    1361           *    1. use the OS/2 table's sTypo* metrics if they are non-zero.
    1362           *    2. Otherwise, use the OS/2 table's usWin* metrics.
    1363           */
    1364  
    1365          if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 128 )
    1366          {
    1367            root->ascender  = face->os2.sTypoAscender;
    1368            root->descender = face->os2.sTypoDescender;
    1369            root->height    = root->ascender - root->descender +
    1370                              face->os2.sTypoLineGap;
    1371          }
    1372          else
    1373          {
    1374            root->ascender  = face->horizontal.Ascender;
    1375            root->descender = face->horizontal.Descender;
    1376            root->height    = root->ascender - root->descender +
    1377                              face->horizontal.Line_Gap;
    1378  
    1379            if ( !( root->ascender || root->descender ) )
    1380            {
    1381              if ( face->os2.version != 0xFFFFU )
    1382              {
    1383                if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
    1384                {
    1385                  root->ascender  = face->os2.sTypoAscender;
    1386                  root->descender = face->os2.sTypoDescender;
    1387                  root->height    = root->ascender - root->descender +
    1388                                    face->os2.sTypoLineGap;
    1389                }
    1390                else
    1391                {
    1392                  root->ascender  =  (FT_Short)face->os2.usWinAscent;
    1393                  root->descender = -(FT_Short)face->os2.usWinDescent;
    1394                  root->height    =  root->ascender - root->descender;
    1395                }
    1396              }
    1397            }
    1398          }
    1399  
    1400          root->max_advance_width  =
    1401            (FT_Short)face->horizontal.advance_Width_Max;
    1402          root->max_advance_height =
    1403            (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max
    1404                                            : root->height );
    1405  
    1406          /* See https://www.microsoft.com/typography/otspec/post.htm -- */
    1407          /* Adjust underline position from top edge to centre of        */
    1408          /* stroke to convert TrueType meaning to FreeType meaning.     */
    1409          root->underline_position  = face->postscript.underlinePosition -
    1410                                      face->postscript.underlineThickness / 2;
    1411          root->underline_thickness = face->postscript.underlineThickness;
    1412        }
    1413  
    1414      }
    1415  
    1416    Exit:
    1417      FT_TRACE2(( "sfnt_load_face: done\n" ));
    1418  
    1419      return error;
    1420    }
    1421  
    1422  
    1423  #undef LOAD_
    1424  #undef LOADM_
    1425  #undef GET_NAME
    1426  
    1427  
    1428    FT_LOCAL_DEF( void )
    1429    sfnt_done_face( TT_Face  face )
    1430    {
    1431      FT_Memory     memory;
    1432      SFNT_Service  sfnt;
    1433  
    1434  
    1435      if ( !face )
    1436        return;
    1437  
    1438      memory = face->root.memory;
    1439      sfnt   = (SFNT_Service)face->sfnt;
    1440  
    1441      if ( sfnt )
    1442      {
    1443        /* destroy the postscript names table if it is loaded */
    1444        if ( sfnt->free_psnames )
    1445          sfnt->free_psnames( face );
    1446  
    1447        /* destroy the embedded bitmaps table if it is loaded */
    1448        if ( sfnt->free_eblc )
    1449          sfnt->free_eblc( face );
    1450  
    1451        /* destroy color table data if it is loaded */
    1452        if ( sfnt->free_cpal )
    1453        {
    1454          sfnt->free_cpal( face );
    1455          sfnt->free_colr( face );
    1456        }
    1457  
    1458  #ifdef FT_CONFIG_OPTION_SVG
    1459        /* free SVG data */
    1460        if ( sfnt->free_svg )
    1461          sfnt->free_svg( face );
    1462  #endif
    1463      }
    1464  
    1465  #ifdef TT_CONFIG_OPTION_BDF
    1466      /* freeing the embedded BDF properties */
    1467      tt_face_free_bdf_props( face );
    1468  #endif
    1469  
    1470      /* freeing the kerning table */
    1471      tt_face_done_kern( face );
    1472  
    1473      /* freeing the collection table */
    1474      FT_FREE( face->ttc_header.offsets );
    1475      face->ttc_header.count = 0;
    1476  
    1477      /* freeing table directory */
    1478      FT_FREE( face->dir_tables );
    1479      face->num_tables = 0;
    1480  
    1481      {
    1482        FT_Stream  stream = FT_FACE_STREAM( face );
    1483  
    1484  
    1485        /* simply release the 'cmap' table frame */
    1486        FT_FRAME_RELEASE( face->cmap_table );
    1487        face->cmap_size = 0;
    1488      }
    1489  
    1490      face->horz_metrics_size = 0;
    1491      face->vert_metrics_size = 0;
    1492  
    1493      /* freeing vertical metrics, if any */
    1494      if ( face->vertical_info )
    1495      {
    1496        FT_FREE( face->vertical.long_metrics  );
    1497        FT_FREE( face->vertical.short_metrics );
    1498        face->vertical_info = 0;
    1499      }
    1500  
    1501      /* freeing the gasp table */
    1502      FT_FREE( face->gasp.gaspRanges );
    1503      face->gasp.numRanges = 0;
    1504  
    1505      /* freeing the name table */
    1506      if ( sfnt )
    1507        sfnt->free_name( face );
    1508  
    1509      /* freeing family and style name */
    1510      FT_FREE( face->root.family_name );
    1511      FT_FREE( face->root.style_name );
    1512  
    1513      /* freeing sbit size table */
    1514      FT_FREE( face->root.available_sizes );
    1515      FT_FREE( face->sbit_strike_map );
    1516      face->root.num_fixed_sizes = 0;
    1517  
    1518      FT_FREE( face->postscript_name );
    1519  
    1520  #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    1521      FT_FREE( face->var_postscript_prefix );
    1522      FT_FREE( face->non_var_style_name );
    1523  #endif
    1524  
    1525      /* freeing glyph color palette data */
    1526      FT_FREE( face->palette_data.palette_name_ids );
    1527      FT_FREE( face->palette_data.palette_flags );
    1528      FT_FREE( face->palette_data.palette_entry_name_ids );
    1529      FT_FREE( face->palette );
    1530  
    1531      face->sfnt = NULL;
    1532    }
    1533  
    1534  
    1535  /* END */