/****************************************************************************
 *
 * sfobjs.c
 *
 *   SFNT object management (base).
 *
 * Copyright (C) 1996-2023 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * This file is part of the FreeType project, and may only be used,
 * modified, and distributed under the terms of the FreeType project
 * license, LICENSE.TXT.  By continuing to use, modify, or distribute
 * this file you indicate that you have read the license and
 * understand and accept it fully.
 *
 */


#include "sfobjs.h"
#include "ttload.h"
#include "ttcmap.h"
#include "ttkern.h"
#include "sfwoff.h"
#include "sfwoff2.h"
#include <freetype/internal/sfnt.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/ttnameid.h>
#include <freetype/tttags.h>
#include <freetype/internal/services/svpscmap.h>
#include <freetype/ftsnames.h>

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
#include <freetype/internal/services/svmm.h>
#include <freetype/internal/services/svmetric.h>
#endif

#include "sferrors.h"

#ifdef TT_CONFIG_OPTION_BDF
#include "ttbdf.h"
#endif


  /**************************************************************************
   *
   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
   * messages during execution.
   */
#undef  FT_COMPONENT
#define FT_COMPONENT  sfobjs



  /* convert a UTF-16 name entry to ASCII */
  static FT_String*
  tt_name_ascii_from_utf16( TT_Name    entry,
                            FT_Memory  memory )
  {
    FT_String*  string = NULL;
    FT_UInt     len, code, n;
    FT_Byte*    read   = (FT_Byte*)entry->string;
    FT_Error    error;


    len = (FT_UInt)entry->stringLength / 2;

    if ( FT_QNEW_ARRAY( string, len + 1 ) )
      return NULL;

    for ( n = 0; n < len; n++ )
    {
      code = FT_NEXT_USHORT( read );

      if ( code == 0 )
        break;

      if ( code < 32 || code > 127 )
        code = '?';

      string[n] = (char)code;
    }

    string[n] = 0;

    return string;
  }


  /* convert an Apple Roman or symbol name entry to ASCII */
  static FT_String*
  tt_name_ascii_from_other( TT_Name    entry,
                            FT_Memory  memory )
  {
    FT_String*  string = NULL;
    FT_UInt     len, code, n;
    FT_Byte*    read   = (FT_Byte*)entry->string;
    FT_Error    error;


    len = (FT_UInt)entry->stringLength;

    if ( FT_QNEW_ARRAY( string, len + 1 ) )
      return NULL;

    for ( n = 0; n < len; n++ )
    {
      code = *read++;

      if ( code == 0 )
        break;

      if ( code < 32 || code > 127 )
        code = '?';

      string[n] = (char)code;
    }

    string[n] = 0;

    return string;
  }


  typedef FT_String*  (*TT_Name_ConvertFunc)( TT_Name    entry,
                                              FT_Memory  memory );


  /* documentation is in sfnt.h */

  FT_LOCAL_DEF( FT_Error )
  tt_face_get_name( TT_Face      face,
                    FT_UShort    nameid,
                    FT_String**  name )
  {
    FT_Memory   memory = face->root.memory;
    FT_Error    error  = FT_Err_Ok;
    FT_String*  result = NULL;
    FT_UShort   n;
    TT_Name     rec;

    FT_Int  found_apple         = -1;
    FT_Int  found_apple_roman   = -1;
    FT_Int  found_apple_english = -1;
    FT_Int  found_win           = -1;
    FT_Int  found_unicode       = -1;

    FT_Bool  is_english = 0;

    TT_Name_ConvertFunc  convert;


    FT_ASSERT( name );

    rec = face->name_table.names;
    for ( n = 0; n < face->num_names; n++, rec++ )
    {
      /* According to the OpenType 1.3 specification, only Microsoft or  */
      /* Apple platform IDs might be used in the `name' table.  The      */
      /* `Unicode' platform is reserved for the `cmap' table, and the    */
      /* `ISO' one is deprecated.                                        */
      /*                                                                 */
      /* However, the Apple TrueType specification doesn't say the same  */
      /* thing and goes to suggest that all Unicode `name' table entries */
      /* should be coded in UTF-16 (in big-endian format I suppose).     */
      /*                                                                 */
      if ( rec->nameID == nameid && rec->stringLength > 0 )
      {
        switch ( rec->platformID )
        {
        case TT_PLATFORM_APPLE_UNICODE:
        case TT_PLATFORM_ISO:
          /* there is `languageID' to check there.  We should use this */
          /* field only as a last solution when nothing else is        */
          /* available.                                                */
          /*                                                           */
          found_unicode = n;
          break;

        case TT_PLATFORM_MACINTOSH:
          /* This is a bit special because some fonts will use either    */
          /* an English language id, or a Roman encoding id, to indicate */
          /* the English version of its font name.                       */
          /*                                                             */
          if ( rec->languageID == TT_MAC_LANGID_ENGLISH )
            found_apple_english = n;
          else if ( rec->encodingID == TT_MAC_ID_ROMAN )
            found_apple_roman = n;
          break;

        case TT_PLATFORM_MICROSOFT:
          /* we only take a non-English name when there is nothing */
          /* else available in the font                            */
          /*                                                       */
          if ( found_win == -1 || ( rec->languageID & 0x3FF ) == 0x009 )
          {
            switch ( rec->encodingID )
            {
            case TT_MS_ID_SYMBOL_CS:
            case TT_MS_ID_UNICODE_CS:
            case TT_MS_ID_UCS_4:
              is_english = FT_BOOL( ( rec->languageID & 0x3FF ) == 0x009 );
              found_win  = n;
              break;

            default:
              ;
            }
          }
          break;

        default:
          ;
        }
      }
    }

    found_apple = found_apple_roman;
    if ( found_apple_english >= 0 )
      found_apple = found_apple_english;

    /* some fonts contain invalid Unicode or Macintosh formatted entries; */
    /* we will thus favor names encoded in Windows formats if available   */
    /* (provided it is an English name)                                   */
    /*                                                                    */
    convert = NULL;
    if ( found_win >= 0 && !( found_apple >= 0 && !is_english ) )
    {
      rec = face->name_table.names + found_win;
      switch ( rec->encodingID )
      {
        /* all Unicode strings are encoded using UTF-16BE */
      case TT_MS_ID_UNICODE_CS:
      case TT_MS_ID_SYMBOL_CS:
        convert = tt_name_ascii_from_utf16;
        break;

      case TT_MS_ID_UCS_4:
        /* Apparently, if this value is found in a name table entry, it is */
        /* documented as `full Unicode repertoire'.  Experience with the   */
        /* MsGothic font shipped with Windows Vista shows that this really */
        /* means UTF-16 encoded names (UCS-4 values are only used within   */
        /* charmaps).                                                      */
        convert = tt_name_ascii_from_utf16;
        break;

      default:
        ;
      }
    }
    else if ( found_apple >= 0 )
    {
      rec     = face->name_table.names + found_apple;
      convert = tt_name_ascii_from_other;
    }
    else if ( found_unicode >= 0 )
    {
      rec     = face->name_table.names + found_unicode;
      convert = tt_name_ascii_from_utf16;
    }

    if ( rec && convert )
    {
      if ( !rec->string )
      {
        FT_Stream  stream = face->name_table.stream;


        if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) ||
             FT_STREAM_SEEK( rec->stringOffset )              ||
             FT_STREAM_READ( rec->string, rec->stringLength ) )
        {
          FT_FREE( rec->string );
          rec->stringLength = 0;
          result            = NULL;
          goto Exit;
        }
      }

      result = convert( rec, memory );
    }

  Exit:
    *name = result;
    return error;
  }


  static FT_Encoding
  sfnt_find_encoding( int  platform_id,
                      int  encoding_id )
  {
    typedef struct  TEncoding_
    {
      int          platform_id;
      int          encoding_id;
      FT_Encoding  encoding;

    } TEncoding;

    static
    const TEncoding  tt_encodings[] =
    {
      { TT_PLATFORM_ISO,           -1,                  FT_ENCODING_UNICODE },

      { TT_PLATFORM_APPLE_UNICODE, -1,                  FT_ENCODING_UNICODE },

      { TT_PLATFORM_MACINTOSH,     TT_MAC_ID_ROMAN,     FT_ENCODING_APPLE_ROMAN },

      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SYMBOL_CS,  FT_ENCODING_MS_SYMBOL },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UCS_4,      FT_ENCODING_UNICODE },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_UNICODE_CS, FT_ENCODING_UNICODE },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_SJIS,       FT_ENCODING_SJIS },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_PRC,        FT_ENCODING_PRC },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_BIG_5,      FT_ENCODING_BIG5 },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_WANSUNG,    FT_ENCODING_WANSUNG },
      { TT_PLATFORM_MICROSOFT,     TT_MS_ID_JOHAB,      FT_ENCODING_JOHAB }
    };

    const TEncoding  *cur, *limit;


    cur   = tt_encodings;
    limit = cur + sizeof ( tt_encodings ) / sizeof ( tt_encodings[0] );

    for ( ; cur < limit; cur++ )
    {
      if ( cur->platform_id == platform_id )
      {
        if ( cur->encoding_id == encoding_id ||
             cur->encoding_id == -1          )
          return cur->encoding;
      }
    }

    return FT_ENCODING_NONE;
  }


  /* Fill in face->ttc_header.  If the font is not a TTC, it is */
  /* synthesized into a TTC with one offset table.              */
  static FT_Error
  sfnt_open_font( FT_Stream  stream,
                  TT_Face    face,
                  FT_Int*    face_instance_index,
                  FT_Long*   woff2_num_faces )
  {
    FT_Memory  memory = stream->memory;
    FT_Error   error;
    FT_ULong   tag, offset;

    static const FT_Frame_Field  ttc_header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TTC_HeaderRec

      FT_FRAME_START( 8 ),
        FT_FRAME_LONG( version ),
        FT_FRAME_LONG( count   ),  /* this is ULong in the specs */
      FT_FRAME_END
    };

#ifndef FT_CONFIG_OPTION_USE_BROTLI
    FT_UNUSED( face_instance_index );
    FT_UNUSED( woff2_num_faces );
#endif


    face->ttc_header.tag     = 0;
    face->ttc_header.version = 0;
    face->ttc_header.count   = 0;

#if defined( FT_CONFIG_OPTION_USE_ZLIB )   || \
    defined( FT_CONFIG_OPTION_USE_BROTLI )
  retry:
#endif

    offset = FT_STREAM_POS();

    if ( FT_READ_ULONG( tag ) )
      return error;

#ifdef FT_CONFIG_OPTION_USE_ZLIB
    if ( tag == TTAG_wOFF )
    {
      FT_TRACE2(( "sfnt_open_font: file is a WOFF; synthesizing SFNT\n" ));

      if ( FT_STREAM_SEEK( offset ) )
        return error;

      error = woff_open_font( stream, face );
      if ( error )
        return error;

      /* Swap out stream and retry! */
      stream = face->root.stream;
      goto retry;
    }
#endif

#ifdef FT_CONFIG_OPTION_USE_BROTLI
    if ( tag == TTAG_wOF2 )
    {
      FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));

      if ( FT_STREAM_SEEK( offset ) )
        return error;

      error = woff2_open_font( stream,
                               face,
                               face_instance_index,
                               woff2_num_faces );
      if ( error )
        return error;

      /* Swap out stream and retry! */
      stream = face->root.stream;
      goto retry;
    }
#endif

    if ( tag != 0x00010000UL &&
         tag != TTAG_ttcf    &&
         tag != TTAG_OTTO    &&
         tag != TTAG_true    &&
         tag != TTAG_typ1    &&
         tag != TTAG_0xA5kbd &&
         tag != TTAG_0xA5lst &&
         tag != 0x00020000UL )
    {
      FT_TRACE2(( "  not a font using the SFNT container format\n" ));
      return FT_THROW( Unknown_File_Format );
    }

    face->ttc_header.tag = TTAG_ttcf;

    if ( tag == TTAG_ttcf )
    {
      FT_Int  n;


      FT_TRACE3(( "sfnt_open_font: file is a collection\n" ));

      if ( FT_STREAM_READ_FIELDS( ttc_header_fields, &face->ttc_header ) )
        return error;

      FT_TRACE3(( "                with %ld subfonts\n",
                  face->ttc_header.count ));

      if ( face->ttc_header.count == 0 )
        return FT_THROW( Invalid_Table );

      /* a rough size estimate: let's conservatively assume that there   */
      /* is just a single table info in each subfont header (12 + 16*1 = */
      /* 28 bytes), thus we have (at least) `12 + 4*count' bytes for the */
      /* size of the TTC header plus `28*count' bytes for all subfont    */
      /* headers                                                         */
      if ( (FT_ULong)face->ttc_header.count > stream->size / ( 28 + 4 ) )
        return FT_THROW( Array_Too_Large );

      /* now read the offsets of each font in the file */
      if ( FT_QNEW_ARRAY( face->ttc_header.offsets, face->ttc_header.count ) )
        return error;

      if ( FT_FRAME_ENTER( face->ttc_header.count * 4L ) )
        return error;

      for ( n = 0; n < face->ttc_header.count; n++ )
        face->ttc_header.offsets[n] = FT_GET_ULONG();

      FT_FRAME_EXIT();
    }
    else
    {
      FT_TRACE3(( "sfnt_open_font: synthesize TTC\n" ));

      face->ttc_header.version = 1 << 16;
      face->ttc_header.count   = 1;

      if ( FT_QNEW( face->ttc_header.offsets ) )
        return error;

      face->ttc_header.offsets[0] = offset;
    }

    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  sfnt_init_face( FT_Stream      stream,
                  TT_Face        face,
                  FT_Int         face_instance_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
  {
    FT_Error      error;
    FT_Library    library         = face->root.driver->root.library;
    SFNT_Service  sfnt;
    FT_Int        face_index;
    FT_Long       woff2_num_faces = 0;


    /* for now, parameters are unused */
    FT_UNUSED( num_params );
    FT_UNUSED( params );


    sfnt = (SFNT_Service)face->sfnt;
    if ( !sfnt )
    {
      sfnt = (SFNT_Service)FT_Get_Module_Interface( library, "sfnt" );
      if ( !sfnt )
      {
        FT_ERROR(( "sfnt_init_face: cannot access `sfnt' module\n" ));
        return FT_THROW( Missing_Module );
      }

      face->sfnt       = sfnt;
      face->goto_table = sfnt->goto_table;
    }

    FT_FACE_FIND_GLOBAL_SERVICE( face, face->psnames, POSTSCRIPT_CMAPS );

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    if ( !face->mm )
    {
      /* we want the MM interface from the `truetype' module only */
      FT_Module  tt_module = FT_Get_Module( library, "truetype" );


      face->mm = ft_module_get_service( tt_module,
                                        FT_SERVICE_ID_MULTI_MASTERS,
                                        0 );
    }

    if ( !face->tt_var )
    {
      /* we want the metrics variations interface */
      /* from the `truetype' module only          */
      FT_Module  tt_module = FT_Get_Module( library, "truetype" );


      face->tt_var = ft_module_get_service( tt_module,
                                            FT_SERVICE_ID_METRICS_VARIATIONS,
                                            0 );
    }

    if ( !face->face_var )
      face->face_var = ft_module_get_service(
                         &face->root.driver->root,
                         FT_SERVICE_ID_METRICS_VARIATIONS,
                         0 );
#endif

    FT_TRACE2(( "SFNT driver\n" ));

    error = sfnt_open_font( stream,
                            face,
                            &face_instance_index,
                            &woff2_num_faces );
    if ( error )
      return error;

    /* Stream may have changed in sfnt_open_font. */
    stream = face->root.stream;

    FT_TRACE2(( "sfnt_init_face: %p (index %d)\n",
                (void *)face,
                face_instance_index ));

    face_index = FT_ABS( face_instance_index ) & 0xFFFF;

    /* value -(N+1) requests information on index N */
    if ( face_instance_index < 0 && face_index > 0 )
      face_index--;

    if ( face_index >= face->ttc_header.count )
    {
      if ( face_instance_index >= 0 )
        return FT_THROW( Invalid_Argument );
      else
        face_index = 0;
    }

    if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) )
      return error;

    /* check whether we have a valid TrueType file */
    error = sfnt->load_font_dir( face, stream );
    if ( error )
      return error;

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    {
      FT_Memory  memory = face->root.memory;

      FT_ULong  fvar_len;

      FT_ULong  version;
      FT_ULong  offset;

      FT_UShort  num_axes;
      FT_UShort  axis_size;
      FT_UShort  num_instances;
      FT_UShort  instance_size;

      FT_Int  instance_index;

      FT_Byte*  default_values  = NULL;
      FT_Byte*  instance_values = NULL;


      instance_index = FT_ABS( face_instance_index ) >> 16;

      /* test whether current face is a GX font with named instances */
      if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) ||
           fvar_len < 20                                          ||
           FT_READ_ULONG( version )                               ||
           FT_READ_USHORT( offset )                               ||
           FT_STREAM_SKIP( 2 ) /* reserved */                     ||
           FT_READ_USHORT( num_axes )                             ||
           FT_READ_USHORT( axis_size )                            ||
           FT_READ_USHORT( num_instances )                        ||
           FT_READ_USHORT( instance_size )                        )
      {
        version       = 0;
        offset        = 0;
        num_axes      = 0;
        axis_size     = 0;
        num_instances = 0;
        instance_size = 0;
      }

      /* check that the data is bound by the table length */
      if ( version != 0x00010000UL                    ||
           axis_size != 20                            ||
           num_axes == 0                              ||
           /* `num_axes' limit implied by 16-bit `instance_size' */
           num_axes > 0x3FFE                          ||
           !( instance_size == 4 + 4 * num_axes ||
              instance_size == 6 + 4 * num_axes )     ||
           /* `num_instances' limit implied by limited range of name IDs */
           num_instances > 0x7EFF                     ||
           offset                          +
             axis_size * num_axes          +
             instance_size * num_instances > fvar_len )
        num_instances = 0;
      else
        face->variation_support |= TT_FACE_FLAG_VAR_FVAR;

      /*
       * As documented in the OpenType specification, an entry for the
       * default instance may be omitted in the named instance table.  In
       * particular this means that even if there is no named instance
       * table in the font we actually do have a named instance, namely the
       * default instance.
       *
       * For consistency, we always want the default instance in our list
       * of named instances.  If it is missing, we try to synthesize it
       * later on.  Here, we have to adjust `num_instances' accordingly.
       */

      if ( ( face->variation_support & TT_FACE_FLAG_VAR_FVAR ) &&
           !( FT_QALLOC(  default_values, num_axes * 4 ) ||
              FT_QALLOC( instance_values, num_axes * 4 ) )     )
      {
        /* the current stream position is 16 bytes after the table start */
        FT_ULong  array_start = FT_STREAM_POS() - 16 + offset;
        FT_ULong  default_value_offset, instance_offset;

        FT_Byte*  p;
        FT_UInt   i;


        default_value_offset = array_start + 8;
        p                    = default_values;

        for ( i = 0; i < num_axes; i++ )
        {
          (void)FT_STREAM_READ_AT( default_value_offset, p, 4 );

          default_value_offset += axis_size;
          p                    += 4;
        }

        instance_offset = array_start + axis_size * num_axes + 4;

        for ( i = 0; i < num_instances; i++ )
        {
          (void)FT_STREAM_READ_AT( instance_offset,
                                   instance_values,
                                   num_axes * 4 );

          if ( !ft_memcmp( default_values, instance_values, num_axes * 4 ) )
            break;

          instance_offset += instance_size;
        }

        /* named instance indices start with value 1 */
        face->var_default_named_instance = i + 1;

        if ( i == num_instances )
        {
          /* no default instance in named instance table; */
          /* we thus have to synthesize it                */
          num_instances++;
        }
      }

      FT_FREE( default_values );
      FT_FREE( instance_values );

      /* we don't support Multiple Master CFFs yet; */
      /* note that `glyf' or `CFF2' have precedence */
      if ( face->goto_table( face, TTAG_glyf, stream, 0 ) &&
           face->goto_table( face, TTAG_CFF2, stream, 0 ) &&
           !face->goto_table( face, TTAG_CFF, stream, 0 ) )
        num_instances = 0;

      /* instance indices in `face_instance_index' start with index 1, */
      /* thus `>' and not `>='                                         */
      if ( instance_index > num_instances )
      {
        if ( face_instance_index >= 0 )
          return FT_THROW( Invalid_Argument );
        else
          num_instances = 0;
      }

      face->root.style_flags = (FT_Long)num_instances << 16;
    }
#endif

    face->root.num_faces  = face->ttc_header.count;
    face->root.face_index = face_instance_index;

    /* `num_faces' for a WOFF2 needs to be handled separately. */
    if ( woff2_num_faces )
      face->root.num_faces = woff2_num_faces;

    return error;
  }


#define LOAD_( x )                                          \
  do                                                        \
  {                                                         \
    FT_TRACE2(( "`" #x "' " ));                             \
    FT_TRACE3(( "-->\n" ));                                 \
                                                            \
    error = sfnt->load_ ## x( face, stream );               \
                                                            \
    FT_TRACE2(( "%s\n", ( !error )                          \
                        ? "loaded"                          \
                        : FT_ERR_EQ( error, Table_Missing ) \
                          ? "missing"                       \
                          : "failed to load" ));            \
    FT_TRACE3(( "\n" ));                                    \
  } while ( 0 )

#define LOADM_( x, vertical )                               \
  do                                                        \
  {                                                         \
    FT_TRACE2(( "`%s" #x "' ",                              \
                vertical ? "vertical " : "" ));             \
    FT_TRACE3(( "-->\n" ));                                 \
                                                            \
    error = sfnt->load_ ## x( face, stream, vertical );     \
                                                            \
    FT_TRACE2(( "%s\n", ( !error )                          \
                        ? "loaded"                          \
                        : FT_ERR_EQ( error, Table_Missing ) \
                          ? "missing"                       \
                          : "failed to load" ));            \
    FT_TRACE3(( "\n" ));                                    \
  } while ( 0 )

#define GET_NAME( id, field )                                   \
  do                                                            \
  {                                                             \
    error = tt_face_get_name( face, TT_NAME_ID_ ## id, field ); \
    if ( error )                                                \
      goto Exit;                                                \
  } while ( 0 )


  FT_LOCAL_DEF( FT_Error )
  sfnt_load_face( FT_Stream      stream,
                  TT_Face        face,
                  FT_Int         face_instance_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
  {
    FT_Error  error;
#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
    FT_Error  psnames_error;
#endif

    FT_Bool  has_outline;
    FT_Bool  is_apple_sbit;

    FT_Bool  has_CBLC;
    FT_Bool  has_CBDT;
    FT_Bool  has_EBLC;
    FT_Bool  has_bloc;
    FT_Bool  has_sbix;

    FT_Bool  ignore_typographic_family    = FALSE;
    FT_Bool  ignore_typographic_subfamily = FALSE;
    FT_Bool  ignore_sbix                  = FALSE;

    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;

    FT_UNUSED( face_instance_index );


    /* Check parameters */

    {
      FT_Int  i;


      for ( i = 0; i < num_params; i++ )
      {
        if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_FAMILY )
          ignore_typographic_family = TRUE;
        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_TYPOGRAPHIC_SUBFAMILY )
          ignore_typographic_subfamily = TRUE;
        else if ( params[i].tag == FT_PARAM_TAG_IGNORE_SBIX )
          ignore_sbix = TRUE;
      }
    }

    /* Load tables */

    /* We now support two SFNT-based bitmapped font formats.  They */
    /* are recognized easily as they do not include a `glyf'       */
    /* table.                                                      */
    /*                                                             */
    /* The first format comes from Apple, and uses a table named   */
    /* `bhed' instead of `head' to store the font header (using    */
    /* the same format).  It also doesn't include horizontal and   */
    /* vertical metrics tables (i.e. `hhea' and `vhea' tables are  */
    /* missing).                                                   */
    /*                                                             */
    /* The other format comes from Microsoft, and is used with     */
    /* WinCE/PocketPC.  It looks like a standard TTF, except that  */
    /* it doesn't contain outlines.                                */
    /*                                                             */

    FT_TRACE2(( "sfnt_load_face: %p\n", (void *)face ));
    FT_TRACE2(( "\n" ));

    /* do we have outlines in there? */
#ifdef FT_CONFIG_OPTION_INCREMENTAL
    has_outline = FT_BOOL( face->root.internal->incremental_interface ||
                           tt_face_lookup_table( face, TTAG_glyf )    ||
                           tt_face_lookup_table( face, TTAG_CFF )     ||
                           tt_face_lookup_table( face, TTAG_CFF2 )    );
#else
    has_outline = FT_BOOL( tt_face_lookup_table( face, TTAG_glyf ) ||
                           tt_face_lookup_table( face, TTAG_CFF )  ||
                           tt_face_lookup_table( face, TTAG_CFF2 ) );
#endif

    /* check which sbit formats are present */
    has_CBLC = !face->goto_table( face, TTAG_CBLC, stream, 0 );
    has_CBDT = !face->goto_table( face, TTAG_CBDT, stream, 0 );
    has_EBLC = !face->goto_table( face, TTAG_EBLC, stream, 0 );
    has_bloc = !face->goto_table( face, TTAG_bloc, stream, 0 );
    has_sbix = !face->goto_table( face, TTAG_sbix, stream, 0 );

    is_apple_sbit = FALSE;

    if ( ignore_sbix )
      has_sbix = FALSE;

    /* if this font doesn't contain outlines, we try to load */
    /* a `bhed' table                                        */
    if ( !has_outline && sfnt->load_bhed )
    {
      LOAD_( bhed );
      is_apple_sbit = FT_BOOL( !error );
    }

    /* load the font header (`head' table) if this isn't an Apple */
    /* sbit font file                                             */
    if ( !is_apple_sbit || has_sbix )
    {
      LOAD_( head );
      if ( error )
        goto Exit;
    }

    /* Ignore outlines for CBLC/CBDT fonts. */
    if ( has_CBLC || has_CBDT )
      has_outline = FALSE;

    /* OpenType 1.8.2 introduced limits to this value;    */
    /* however, they make sense for older SFNT fonts also */
    if ( face->header.Units_Per_EM <    16 ||
         face->header.Units_Per_EM > 16384 )
    {
      error = FT_THROW( Invalid_Table );

      goto Exit;
    }

    /* the following tables are often not present in embedded TrueType */
    /* fonts within PDF documents, so don't check for them.            */
    LOAD_( maxp );
    LOAD_( cmap );

    /* the following tables are optional in PCL fonts -- */
    /* don't check for errors                            */
    LOAD_( name );
    LOAD_( post );

#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
    psnames_error = error;
#endif

    /* do not load the metrics headers and tables if this is an Apple */
    /* sbit font file                                                 */
    if ( !is_apple_sbit )
    {
      /* load the `hhea' and `hmtx' tables */
      LOADM_( hhea, 0 );
      if ( !error )
      {
        LOADM_( hmtx, 0 );
        if ( FT_ERR_EQ( error, Table_Missing ) )
        {
          error = FT_THROW( Hmtx_Table_Missing );

#ifdef FT_CONFIG_OPTION_INCREMENTAL
          /* If this is an incrementally loaded font and there are */
          /* overriding metrics, tolerate a missing `hmtx' table.  */
          if ( face->root.internal->incremental_interface          &&
               face->root.internal->incremental_interface->funcs->
                 get_glyph_metrics                                 )
          {
            face->horizontal.number_Of_HMetrics = 0;
            error                               = FT_Err_Ok;
          }
#endif
        }
      }
      else if ( FT_ERR_EQ( error, Table_Missing ) )
      {
        /* No `hhea' table necessary for SFNT Mac fonts. */
        if ( face->format_tag == TTAG_true )
        {
          FT_TRACE2(( "This is an SFNT Mac font.\n" ));

          has_outline = 0;
          error       = FT_Err_Ok;
        }
        else
        {
          error = FT_THROW( Horiz_Header_Missing );

#ifdef FT_CONFIG_OPTION_INCREMENTAL
          /* If this is an incrementally loaded font and there are */
          /* overriding metrics, tolerate a missing `hhea' table.  */
          if ( face->root.internal->incremental_interface          &&
               face->root.internal->incremental_interface->funcs->
                 get_glyph_metrics                                 )
          {
            face->horizontal.number_Of_HMetrics = 0;
            error                               = FT_Err_Ok;
          }
#endif

        }
      }

      if ( error )
        goto Exit;

      /* try to load the `vhea' and `vmtx' tables */
      LOADM_( hhea, 1 );
      if ( !error )
      {
        LOADM_( hmtx, 1 );
        if ( !error )
          face->vertical_info = 1;
      }

      if ( error && FT_ERR_NEQ( error, Table_Missing ) )
        goto Exit;

      LOAD_( os2 );
      if ( error )
      {
        /* we treat the table as missing if there are any errors */
        face->os2.version = 0xFFFFU;
      }
    }

    /* the optional tables */

    /* embedded bitmap support */
    /* TODO: Replace this clumsy check for all possible sbit tables     */
    /*       with something better (for example, by passing a parameter */
    /*       to suppress 'sbix' loading).                               */
    if ( sfnt->load_eblc                                  &&
         ( has_CBLC || has_EBLC || has_bloc || has_sbix ) )
      LOAD_( eblc );

    /* colored glyph support */
    if ( sfnt->load_cpal )
    {
      LOAD_( cpal );
      LOAD_( colr );
    }

    /* OpenType-SVG glyph support */
    if ( sfnt->load_svg )
      LOAD_( svg );

    /* consider the pclt, kerning, and gasp tables as optional */
    LOAD_( pclt );
    LOAD_( gasp );
    LOAD_( kern );

    face->root.num_glyphs = face->max_profile.numGlyphs;

    /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes  */
    /* a WWS-only font face.  `WWS' stands for `weight', width', and */
    /* `slope', a term used by Microsoft's Windows Presentation      */
    /* Foundation (WPF).  This flag has been introduced in version   */
    /* 1.5 of the OpenType specification (May 2008).                 */

    face->root.family_name = NULL;
    face->root.style_name  = NULL;
    if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 )
    {
      if ( !ignore_typographic_family )
        GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
      if ( !face->root.family_name )
        GET_NAME( FONT_FAMILY, &face->root.family_name );

      if ( !ignore_typographic_subfamily )
        GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
      if ( !face->root.style_name )
        GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
    }
    else
    {
      GET_NAME( WWS_FAMILY, &face->root.family_name );
      if ( !face->root.family_name && !ignore_typographic_family )
        GET_NAME( TYPOGRAPHIC_FAMILY, &face->root.family_name );
      if ( !face->root.family_name )
        GET_NAME( FONT_FAMILY, &face->root.family_name );

      GET_NAME( WWS_SUBFAMILY, &face->root.style_name );
      if ( !face->root.style_name && !ignore_typographic_subfamily )
        GET_NAME( TYPOGRAPHIC_SUBFAMILY, &face->root.style_name );
      if ( !face->root.style_name )
        GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
    }

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    {
      FT_Memory  memory = face->root.memory;


      if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) )
        goto Exit;
    }
#endif

    /* now set up root fields */
    {
      FT_Face  root  = &face->root;
      FT_Long  flags = root->face_flags;


      /**********************************************************************
       *
       * Compute face flags.
       */
      if ( face->sbit_table_type == TT_SBIT_TABLE_TYPE_CBLC ||
           face->sbit_table_type == TT_SBIT_TABLE_TYPE_SBIX ||
           face->colr                                       ||
           face->svg                                        )
        flags |= FT_FACE_FLAG_COLOR;      /* color glyphs */

      if ( has_outline == TRUE )
      {
        /* by default (and for backward compatibility) we handle */
        /* fonts with an 'sbix' table as bitmap-only             */
        if ( has_sbix )
          flags |= FT_FACE_FLAG_SBIX;     /* with 'sbix' bitmaps */
        else
          flags |= FT_FACE_FLAG_SCALABLE; /* scalable outlines */
      }

      /* The sfnt driver only supports bitmap fonts natively, thus we */
      /* don't set FT_FACE_FLAG_HINTER.                               */
      flags |= FT_FACE_FLAG_SFNT       |  /* SFNT file format  */
               FT_FACE_FLAG_HORIZONTAL;   /* horizontal data   */

#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
      if ( !psnames_error                             &&
           face->postscript.FormatType != 0x00030000L )
        flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif

      /* fixed width font? */
      if ( face->postscript.isFixedPitch )
        flags |= FT_FACE_FLAG_FIXED_WIDTH;

      /* vertical information? */
      if ( face->vertical_info )
        flags |= FT_FACE_FLAG_VERTICAL;

      /* kerning available ? */
      if ( TT_FACE_HAS_KERNING( face ) )
        flags |= FT_FACE_FLAG_KERNING;

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
      /* Don't bother to load the tables unless somebody asks for them. */
      /* No need to do work which will (probably) not be used.          */
      if ( face->variation_support & TT_FACE_FLAG_VAR_FVAR )
        flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
#endif

      root->face_flags = flags;

      /**********************************************************************
       *
       * Compute style flags.
       */

      flags = 0;
      if ( has_outline == TRUE && face->os2.version != 0xFFFFU )
      {
        /* We have an OS/2 table; use the `fsSelection' field.  Bit 9 */
        /* indicates an oblique font face.  This flag has been        */
        /* introduced in version 1.5 of the OpenType specification.   */

        if ( face->os2.fsSelection & 512 )       /* bit 9 */
          flags |= FT_STYLE_FLAG_ITALIC;
        else if ( face->os2.fsSelection & 1 )    /* bit 0 */
          flags |= FT_STYLE_FLAG_ITALIC;

        if ( face->os2.fsSelection & 32 )        /* bit 5 */
          flags |= FT_STYLE_FLAG_BOLD;
      }
      else
      {
        /* this is an old Mac font, use the header field */

        if ( face->header.Mac_Style & 1 )
          flags |= FT_STYLE_FLAG_BOLD;

        if ( face->header.Mac_Style & 2 )
          flags |= FT_STYLE_FLAG_ITALIC;
      }

      root->style_flags |= flags;

      /**********************************************************************
       *
       * Polish the charmaps.
       *
       *   Try to set the charmap encoding according to the platform &
       *   encoding ID of each charmap.  Emulate Unicode charmap if one
       *   is missing.
       */

      tt_face_build_cmaps( face );  /* ignore errors */


      /* set the encoding fields */
      {
        FT_Int   m;
#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
        FT_Bool  has_unicode = FALSE;
#endif


        for ( m = 0; m < root->num_charmaps; m++ )
        {
          FT_CharMap  charmap = root->charmaps[m];


          charmap->encoding = sfnt_find_encoding( charmap->platform_id,
                                                  charmap->encoding_id );

#ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES

          if ( charmap->encoding == FT_ENCODING_UNICODE   ||
               charmap->encoding == FT_ENCODING_MS_SYMBOL )  /* PUA */
            has_unicode = TRUE;
        }

        /* synthesize Unicode charmap if one is missing */
        if ( !has_unicode                                &&
             root->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
        {
          FT_CharMapRec  cmaprec;


          cmaprec.face        = root;
          cmaprec.platform_id = TT_PLATFORM_MICROSOFT;
          cmaprec.encoding_id = TT_MS_ID_UNICODE_CS;
          cmaprec.encoding    = FT_ENCODING_UNICODE;


          error = FT_CMap_New( (FT_CMap_Class)&tt_cmap_unicode_class_rec,
                               NULL, &cmaprec, NULL );
          if ( error                                      &&
               FT_ERR_NEQ( error, No_Unicode_Glyph_Name ) &&
               FT_ERR_NEQ( error, Unimplemented_Feature ) )
            goto Exit;
          error = FT_Err_Ok;

#endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */

        }
      }

#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS

      /*
       * Now allocate the root array of FT_Bitmap_Size records and
       * populate them.  Unfortunately, it isn't possible to indicate bit
       * depths in the FT_Bitmap_Size record.  This is a design error.
       */
      {
        FT_UInt  count;


        count = face->sbit_num_strikes;

        if ( count > 0 )
        {
          FT_Memory        memory   = face->root.memory;
          FT_UShort        em_size  = face->header.Units_Per_EM;
          FT_Short         avgwidth = face->os2.xAvgCharWidth;
          FT_Size_Metrics  metrics;

          FT_UInt*  sbit_strike_map = NULL;
          FT_UInt   strike_idx, bsize_idx;


          if ( em_size == 0 || face->os2.version == 0xFFFFU )
          {
            avgwidth = 1;
            em_size = 1;
          }

          /* to avoid invalid strike data in the `available_sizes' field */
          /* of `FT_Face', we map `available_sizes' indices to strike    */
          /* indices                                                     */
          if ( FT_NEW_ARRAY( root->available_sizes, count ) ||
               FT_QNEW_ARRAY( sbit_strike_map, count ) )
            goto Exit;

          bsize_idx = 0;
          for ( strike_idx = 0; strike_idx < count; strike_idx++ )
          {
            FT_Bitmap_Size*  bsize = root->available_sizes + bsize_idx;


            error = sfnt->load_strike_metrics( face, strike_idx, &metrics );
            if ( error )
              continue;

            bsize->height = (FT_Short)( metrics.height >> 6 );
            bsize->width  = (FT_Short)(
              ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size );

            bsize->x_ppem = metrics.x_ppem << 6;
            bsize->y_ppem = metrics.y_ppem << 6;

            /* assume 72dpi */
            bsize->size   = metrics.y_ppem << 6;

            /* only use strikes with valid PPEM values */
            if ( bsize->x_ppem && bsize->y_ppem )
              sbit_strike_map[bsize_idx++] = strike_idx;
          }

          /* reduce array size to the actually used elements */
          FT_MEM_QRENEW_ARRAY( sbit_strike_map, count, bsize_idx );

          /* from now on, all strike indices are mapped */
          /* using `sbit_strike_map'                    */
          if ( bsize_idx )
          {
            face->sbit_strike_map = sbit_strike_map;

            root->face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
            root->num_fixed_sizes = (FT_Int)bsize_idx;
          }
        }
      }

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */

      /* a font with no bitmaps and no outlines is scalable; */
      /* it has only empty glyphs then                       */
      if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) )
        root->face_flags |= FT_FACE_FLAG_SCALABLE;


      /**********************************************************************
       *
       * Set up metrics.
       */
      if ( FT_IS_SCALABLE( root ) ||
           FT_HAS_SBIX( root )    )
      {
        /* XXX What about if outline header is missing */
        /*     (e.g. sfnt wrapped bitmap)?             */
        root->bbox.xMin    = face->header.xMin;
        root->bbox.yMin    = face->header.yMin;
        root->bbox.xMax    = face->header.xMax;
        root->bbox.yMax    = face->header.yMax;
        root->units_per_EM = face->header.Units_Per_EM;


        /*
         * Computing the ascender/descender/height is tricky.
         *
         * The OpenType specification v1.8.3 says:
         *
         *   [OS/2's] sTypoAscender, sTypoDescender and sTypoLineGap fields
         *   are intended to allow applications to lay out documents in a
         *   typographically-correct and portable fashion.
         *
         * This is somewhat at odds with the decades of backwards
         * compatibility, operating systems and applications doing whatever
         * they want, not to mention broken fonts.
         *
         * Not all fonts have an OS/2 table; in this case, we take the values
         * in the horizontal header, although there is nothing stopping the
         * values from being unreliable. Even with a OS/2 table, certain fonts
         * set the sTypoAscender, sTypoDescender and sTypoLineGap fields to 0
         * and instead correctly set usWinAscent and usWinDescent.
         *
         * As an example, Arial Narrow is shipped as four files ARIALN.TTF,
         * ARIALNI.TTF, ARIALNB.TTF and ARIALNBI.TTF. Strangely, all fonts have
         * the same values in their sTypo* fields, except ARIALNB.ttf which
         * sets them to 0. All of them have different usWinAscent/Descent
         * values. The OS/2 table therefore cannot be trusted for computing the
         * text height reliably.
         *
         * As a compromise, do the following:
         *
         * 1. If the OS/2 table exists and the fsSelection bit 7 is set
         *    (USE_TYPO_METRICS), trust the font and use the sTypo* metrics.
         * 2. Otherwise, use the `hhea' table's metrics.
         * 3. If they are zero and the OS/2 table exists,
         *    1. use the OS/2 table's sTypo* metrics if they are non-zero.
         *    2. Otherwise, use the OS/2 table's usWin* metrics.
         */

        if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 128 )
        {
          root->ascender  = face->os2.sTypoAscender;
          root->descender = face->os2.sTypoDescender;
          root->height    = root->ascender - root->descender +
                            face->os2.sTypoLineGap;
        }
        else
        {
          root->ascender  = face->horizontal.Ascender;
          root->descender = face->horizontal.Descender;
          root->height    = root->ascender - root->descender +
                            face->horizontal.Line_Gap;

          if ( !( root->ascender || root->descender ) )
          {
            if ( face->os2.version != 0xFFFFU )
            {
              if ( face->os2.sTypoAscender || face->os2.sTypoDescender )
              {
                root->ascender  = face->os2.sTypoAscender;
                root->descender = face->os2.sTypoDescender;
                root->height    = root->ascender - root->descender +
                                  face->os2.sTypoLineGap;
              }
              else
              {
                root->ascender  =  (FT_Short)face->os2.usWinAscent;
                root->descender = -(FT_Short)face->os2.usWinDescent;
                root->height    =  root->ascender - root->descender;
              }
            }
          }
        }

        root->max_advance_width  =
          (FT_Short)face->horizontal.advance_Width_Max;
        root->max_advance_height =
          (FT_Short)( face->vertical_info ? face->vertical.advance_Height_Max
                                          : root->height );

        /* See https://www.microsoft.com/typography/otspec/post.htm -- */
        /* Adjust underline position from top edge to centre of        */
        /* stroke to convert TrueType meaning to FreeType meaning.     */
        root->underline_position  = face->postscript.underlinePosition -
                                    face->postscript.underlineThickness / 2;
        root->underline_thickness = face->postscript.underlineThickness;
      }

    }

  Exit:
    FT_TRACE2(( "sfnt_load_face: done\n" ));

    return error;
  }


#undef LOAD_
#undef LOADM_
#undef GET_NAME


  FT_LOCAL_DEF( void )
  sfnt_done_face( TT_Face  face )
  {
    FT_Memory     memory;
    SFNT_Service  sfnt;


    if ( !face )
      return;

    memory = face->root.memory;
    sfnt   = (SFNT_Service)face->sfnt;

    if ( sfnt )
    {
      /* destroy the postscript names table if it is loaded */
      if ( sfnt->free_psnames )
        sfnt->free_psnames( face );

      /* destroy the embedded bitmaps table if it is loaded */
      if ( sfnt->free_eblc )
        sfnt->free_eblc( face );

      /* destroy color table data if it is loaded */
      if ( sfnt->free_cpal )
      {
        sfnt->free_cpal( face );
        sfnt->free_colr( face );
      }

#ifdef FT_CONFIG_OPTION_SVG
      /* free SVG data */
      if ( sfnt->free_svg )
        sfnt->free_svg( face );
#endif
    }

#ifdef TT_CONFIG_OPTION_BDF
    /* freeing the embedded BDF properties */
    tt_face_free_bdf_props( face );
#endif

    /* freeing the kerning table */
    tt_face_done_kern( face );

    /* freeing the collection table */
    FT_FREE( face->ttc_header.offsets );
    face->ttc_header.count = 0;

    /* freeing table directory */
    FT_FREE( face->dir_tables );
    face->num_tables = 0;

    {
      FT_Stream  stream = FT_FACE_STREAM( face );


      /* simply release the 'cmap' table frame */
      FT_FRAME_RELEASE( face->cmap_table );
      face->cmap_size = 0;
    }

    face->horz_metrics_size = 0;
    face->vert_metrics_size = 0;

    /* freeing vertical metrics, if any */
    if ( face->vertical_info )
    {
      FT_FREE( face->vertical.long_metrics  );
      FT_FREE( face->vertical.short_metrics );
      face->vertical_info = 0;
    }

    /* freeing the gasp table */
    FT_FREE( face->gasp.gaspRanges );
    face->gasp.numRanges = 0;

    /* freeing the name table */
    if ( sfnt )
      sfnt->free_name( face );

    /* freeing family and style name */
    FT_FREE( face->root.family_name );
    FT_FREE( face->root.style_name );

    /* freeing sbit size table */
    FT_FREE( face->root.available_sizes );
    FT_FREE( face->sbit_strike_map );
    face->root.num_fixed_sizes = 0;

    FT_FREE( face->postscript_name );

#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
    FT_FREE( face->var_postscript_prefix );
    FT_FREE( face->non_var_style_name );
#endif

    /* freeing glyph color palette data */
    FT_FREE( face->palette_data.palette_name_ids );
    FT_FREE( face->palette_data.palette_flags );
    FT_FREE( face->palette_data.palette_entry_name_ids );
    FT_FREE( face->palette );

    face->sfnt = NULL;
  }


/* END */
