/****************************************************************************
 *
 * ttload.c
 *
 *   Load the basic TrueType tables, i.e., tables that can be either in
 *   TTF or OTF fonts (body).
 *
 * Copyright (C) 1996-2019 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 <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_TRUETYPE_TAGS_H
#include "ttload.h"

#include "sferrors.h"


  /**************************************************************************
   *
   * 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  ttload


  /**************************************************************************
   *
   * @Function:
   *   tt_face_lookup_table
   *
   * @Description:
   *   Looks for a TrueType table by name.
   *
   * @Input:
   *   face ::
   *     A face object handle.
   *
   *   tag ::
   *     The searched tag.
   *
   * @Return:
   *   A pointer to the table directory entry.  0 if not found.
   */
  FT_LOCAL_DEF( TT_Table  )
  tt_face_lookup_table( TT_Face   face,
                        FT_ULong  tag  )
  {
    TT_Table  entry;
    TT_Table  limit;
#ifdef FT_DEBUG_LEVEL_TRACE
    FT_Bool   zero_length = FALSE;
#endif


    FT_TRACE4(( "tt_face_lookup_table: %08p, `%c%c%c%c' -- ",
                face,
                (FT_Char)( tag >> 24 ),
                (FT_Char)( tag >> 16 ),
                (FT_Char)( tag >> 8  ),
                (FT_Char)( tag       ) ));

    entry = face->dir_tables;
    limit = entry + face->num_tables;

    for ( ; entry < limit; entry++ )
    {
      /* For compatibility with Windows, we consider    */
      /* zero-length tables the same as missing tables. */
      if ( entry->Tag == tag )
      {
        if ( entry->Length != 0 )
        {
          FT_TRACE4(( "found table.\n" ));
          return entry;
        }
#ifdef FT_DEBUG_LEVEL_TRACE
        zero_length = TRUE;
#endif
      }
    }

#ifdef FT_DEBUG_LEVEL_TRACE
    if ( zero_length )
      FT_TRACE4(( "ignoring empty table\n" ));
    else
      FT_TRACE4(( "could not find table\n" ));
#endif

    return NULL;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_goto_table
   *
   * @Description:
   *   Looks for a TrueType table by name, then seek a stream to it.
   *
   * @Input:
   *   face ::
   *     A face object handle.
   *
   *   tag ::
   *     The searched tag.
   *
   *   stream ::
   *     The stream to seek when the table is found.
   *
   * @Output:
   *   length ::
   *     The length of the table if found, undefined otherwise.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_goto_table( TT_Face    face,
                      FT_ULong   tag,
                      FT_Stream  stream,
                      FT_ULong*  length )
  {
    TT_Table  table;
    FT_Error  error;


    table = tt_face_lookup_table( face, tag );
    if ( table )
    {
      if ( length )
        *length = table->Length;

      if ( FT_STREAM_SEEK( table->Offset ) )
        goto Exit;
    }
    else
      error = FT_THROW( Table_Missing );

  Exit:
    return error;
  }


  /* Here, we                                                         */
  /*                                                                  */
  /* - check that `num_tables' is valid (and adjust it if necessary); */
  /*   also return the number of valid table entries                  */
  /*                                                                  */
  /* - look for a `head' table, check its size, and parse it to check */
  /*   whether its `magic' field is correctly set                     */
  /*                                                                  */
  /* - errors (except errors returned by stream handling)             */
  /*                                                                  */
  /*     SFNT_Err_Unknown_File_Format:                                */
  /*       no table is defined in directory, it is not sfnt-wrapped   */
  /*       data                                                       */
  /*     SFNT_Err_Table_Missing:                                      */
  /*       table directory is valid, but essential tables             */
  /*       (head/bhed/SING) are missing                               */
  /*                                                                  */
  static FT_Error
  check_table_dir( SFNT_Header  sfnt,
                   FT_Stream    stream,
                   FT_UShort*   valid )
  {
    FT_Error   error;
    FT_UShort  nn, valid_entries = 0;
    FT_UInt    has_head = 0, has_sing = 0, has_meta = 0;
    FT_ULong   offset = sfnt->offset + 12;

    static const FT_Frame_Field  table_dir_entry_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_TableRec

      FT_FRAME_START( 16 ),
        FT_FRAME_ULONG( Tag ),
        FT_FRAME_ULONG( CheckSum ),
        FT_FRAME_ULONG( Offset ),
        FT_FRAME_ULONG( Length ),
      FT_FRAME_END
    };


    if ( FT_STREAM_SEEK( offset ) )
      goto Exit;

    for ( nn = 0; nn < sfnt->num_tables; nn++ )
    {
      TT_TableRec  table;


      if ( FT_STREAM_READ_FIELDS( table_dir_entry_fields, &table ) )
      {
        nn--;
        FT_TRACE2(( "check_table_dir:"
                    " can read only %d table%s in font (instead of %d)\n",
                    nn, nn == 1 ? "" : "s", sfnt->num_tables ));
        sfnt->num_tables = nn;
        break;
      }

      /* we ignore invalid tables */

      if ( table.Offset > stream->size )
      {
        FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
        continue;
      }
      else if ( table.Length > stream->size - table.Offset )
      {
        /* Some tables have such a simple structure that clipping its     */
        /* contents is harmless.  This also makes FreeType less sensitive */
        /* to invalid table lengths (which programs like Acroread seem to */
        /* ignore in general).                                            */

        if ( table.Tag == TTAG_hmtx ||
             table.Tag == TTAG_vmtx )
          valid_entries++;
        else
        {
          FT_TRACE2(( "check_table_dir: table entry %d invalid\n", nn ));
          continue;
        }
      }
      else
        valid_entries++;

      if ( table.Tag == TTAG_head || table.Tag == TTAG_bhed )
      {
        FT_UInt32  magic;


#ifndef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
        if ( table.Tag == TTAG_head )
#endif
          has_head = 1;

        /*
         * The table length should be 0x36, but certain font tools make it
         * 0x38, so we will just check that it is greater.
         *
         * Note that according to the specification, the table must be
         * padded to 32-bit lengths, but this doesn't apply to the value of
         * its `Length' field!
         *
         */
        if ( table.Length < 0x36 )
        {
          FT_TRACE2(( "check_table_dir:"
                      " `head' or `bhed' table too small\n" ));
          error = FT_THROW( Table_Missing );
          goto Exit;
        }

        if ( FT_STREAM_SEEK( table.Offset + 12 ) ||
             FT_READ_ULONG( magic )              )
          goto Exit;

        if ( magic != 0x5F0F3CF5UL )
          FT_TRACE2(( "check_table_dir:"
                      " invalid magic number in `head' or `bhed' table\n"));

        if ( FT_STREAM_SEEK( offset + ( nn + 1 ) * 16 ) )
          goto Exit;
      }
      else if ( table.Tag == TTAG_SING )
        has_sing = 1;
      else if ( table.Tag == TTAG_META )
        has_meta = 1;
    }

    *valid = valid_entries;

    if ( !valid_entries )
    {
      FT_TRACE2(( "check_table_dir: no valid tables found\n" ));
      error = FT_THROW( Unknown_File_Format );
      goto Exit;
    }

    /* if `sing' and `meta' tables are present, there is no `head' table */
    if ( has_head || ( has_sing && has_meta ) )
    {
      error = FT_Err_Ok;
      goto Exit;
    }
    else
    {
      FT_TRACE2(( "check_table_dir:" ));
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
      FT_TRACE2(( " neither `head', `bhed', nor `sing' table found\n" ));
#else
      FT_TRACE2(( " neither `head' nor `sing' table found\n" ));
#endif
      error = FT_THROW( Table_Missing );
    }

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_font_dir
   *
   * @Description:
   *   Loads the header of a SFNT font file.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     The input stream.
   *
   * @Output:
   *   sfnt ::
   *     The SFNT header.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   *
   * @Note:
   *   The stream cursor must be at the beginning of the font directory.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_font_dir( TT_Face    face,
                         FT_Stream  stream )
  {
    SFNT_HeaderRec  sfnt;
    FT_Error        error;
    FT_Memory       memory = stream->memory;
    FT_UShort       nn, valid_entries = 0;

    static const FT_Frame_Field  offset_table_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  SFNT_HeaderRec

      FT_FRAME_START( 8 ),
        FT_FRAME_USHORT( num_tables ),
        FT_FRAME_USHORT( search_range ),
        FT_FRAME_USHORT( entry_selector ),
        FT_FRAME_USHORT( range_shift ),
      FT_FRAME_END
    };


    FT_TRACE2(( "tt_face_load_font_dir: %08p\n", face ));

    /* read the offset table */

    sfnt.offset = FT_STREAM_POS();

    if ( FT_READ_ULONG( sfnt.format_tag )                    ||
         FT_STREAM_READ_FIELDS( offset_table_fields, &sfnt ) )
      goto Exit;

    /* many fonts don't have these fields set correctly */
#if 0
    if ( sfnt.search_range != 1 << ( sfnt.entry_selector + 4 )        ||
         sfnt.search_range + sfnt.range_shift != sfnt.num_tables << 4 )
      return FT_THROW( Unknown_File_Format );
#endif

    /* load the table directory */

    FT_TRACE2(( "-- Number of tables: %10u\n",    sfnt.num_tables ));
    FT_TRACE2(( "-- Format version:   0x%08lx\n", sfnt.format_tag ));

    if ( sfnt.format_tag != TTAG_OTTO )
    {
      /* check first */
      error = check_table_dir( &sfnt, stream, &valid_entries );
      if ( error )
      {
        FT_TRACE2(( "tt_face_load_font_dir:"
                    " invalid table directory for TrueType\n" ));
        goto Exit;
      }
    }
    else
      valid_entries = sfnt.num_tables;

    face->num_tables = valid_entries;
    face->format_tag = sfnt.format_tag;

    if ( FT_QNEW_ARRAY( face->dir_tables, face->num_tables ) )
      goto Exit;

    if ( FT_STREAM_SEEK( sfnt.offset + 12 )      ||
         FT_FRAME_ENTER( sfnt.num_tables * 16L ) )
      goto Exit;

    FT_TRACE2(( "\n"
                "  tag    offset    length   checksum\n"
                "  ----------------------------------\n" ));

    valid_entries = 0;
    for ( nn = 0; nn < sfnt.num_tables; nn++ )
    {
      TT_TableRec  entry;
      FT_UShort    i;
      FT_Bool      duplicate;


      entry.Tag      = FT_GET_TAG4();
      entry.CheckSum = FT_GET_ULONG();
      entry.Offset   = FT_GET_ULONG();
      entry.Length   = FT_GET_ULONG();

      /* ignore invalid tables that can't be sanitized */

      if ( entry.Offset > stream->size )
        continue;
      else if ( entry.Length > stream->size - entry.Offset )
      {
        if ( entry.Tag == TTAG_hmtx ||
             entry.Tag == TTAG_vmtx )
        {
#ifdef FT_DEBUG_LEVEL_TRACE
          FT_ULong  old_length = entry.Length;
#endif


          /* make metrics table length a multiple of 4 */
          entry.Length = ( stream->size - entry.Offset ) & ~3U;

          FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx"
                      " (sanitized; original length %08lx)",
                      (FT_Char)( entry.Tag >> 24 ),
                      (FT_Char)( entry.Tag >> 16 ),
                      (FT_Char)( entry.Tag >> 8  ),
                      (FT_Char)( entry.Tag       ),
                      entry.Offset,
                      entry.Length,
                      entry.CheckSum,
                      old_length ));
        }
        else
          continue;
      }
#ifdef FT_DEBUG_LEVEL_TRACE
      else
        FT_TRACE2(( "  %c%c%c%c  %08lx  %08lx  %08lx",
                    (FT_Char)( entry.Tag >> 24 ),
                    (FT_Char)( entry.Tag >> 16 ),
                    (FT_Char)( entry.Tag >> 8  ),
                    (FT_Char)( entry.Tag       ),
                    entry.Offset,
                    entry.Length,
                    entry.CheckSum ));
#endif

      /* ignore duplicate tables – the first one wins */
      duplicate = 0;
      for ( i = 0; i < valid_entries; i++ )
      {
        if ( face->dir_tables[i].Tag == entry.Tag )
        {
          duplicate = 1;
          break;
        }
      }
      if ( duplicate )
      {
        FT_TRACE2(( "  (duplicate, ignored)\n" ));
        continue;
      }
      else
      {
        FT_TRACE2(( "\n" ));

        /* we finally have a valid entry */
        face->dir_tables[valid_entries++] = entry;
      }
    }

    /* final adjustment to number of tables */
    face->num_tables = valid_entries;

    FT_FRAME_EXIT();

    FT_TRACE2(( "table directory loaded\n\n" ));

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_any
   *
   * @Description:
   *   Loads any font table into client memory.
   *
   * @Input:
   *   face ::
   *     The face object to look for.
   *
   *   tag ::
   *     The tag of table to load.  Use the value 0 if you want
   *     to access the whole font file, else set this parameter
   *     to a valid TrueType table tag that you can forge with
   *     the MAKE_TT_TAG macro.
   *
   *   offset ::
   *     The starting offset in the table (or the file if
   *     tag == 0).
   *
   *   length ::
   *     The address of the decision variable:
   *
   *     If length == NULL:
   *       Loads the whole table.  Returns an error if
   *       `offset' == 0!
   *
   *     If *length == 0:
   *       Exits immediately; returning the length of the given
   *       table or of the font file, depending on the value of
   *       `tag'.
   *
   *     If *length != 0:
   *       Loads the next `length' bytes of table or font,
   *       starting at offset `offset' (in table or font too).
   *
   * @Output:
   *   buffer ::
   *     The address of target buffer.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_any( TT_Face    face,
                    FT_ULong   tag,
                    FT_Long    offset,
                    FT_Byte*   buffer,
                    FT_ULong*  length )
  {
    FT_Error   error;
    FT_Stream  stream;
    TT_Table   table;
    FT_ULong   size;


    if ( tag != 0 )
    {
      /* look for tag in font directory */
      table = tt_face_lookup_table( face, tag );
      if ( !table )
      {
        error = FT_THROW( Table_Missing );
        goto Exit;
      }

      offset += table->Offset;
      size    = table->Length;
    }
    else
      /* tag == 0 -- the user wants to access the font file directly */
      size = face->root.stream->size;

    if ( length && *length == 0 )
    {
      *length = size;

      return FT_Err_Ok;
    }

    if ( length )
      size = *length;

    stream = face->root.stream;
    /* the `if' is syntactic sugar for picky compilers */
    if ( FT_STREAM_READ_AT( offset, buffer, size ) )
      goto Exit;

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_generic_header
   *
   * @Description:
   *   Loads the TrueType table `head' or `bhed'.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     The input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  static FT_Error
  tt_face_load_generic_header( TT_Face    face,
                               FT_Stream  stream,
                               FT_ULong   tag )
  {
    FT_Error    error;
    TT_Header*  header;

    static const FT_Frame_Field  header_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_Header

      FT_FRAME_START( 54 ),
        FT_FRAME_ULONG ( Table_Version ),
        FT_FRAME_ULONG ( Font_Revision ),
        FT_FRAME_LONG  ( CheckSum_Adjust ),
        FT_FRAME_LONG  ( Magic_Number ),
        FT_FRAME_USHORT( Flags ),
        FT_FRAME_USHORT( Units_Per_EM ),
        FT_FRAME_ULONG ( Created[0] ),
        FT_FRAME_ULONG ( Created[1] ),
        FT_FRAME_ULONG ( Modified[0] ),
        FT_FRAME_ULONG ( Modified[1] ),
        FT_FRAME_SHORT ( xMin ),
        FT_FRAME_SHORT ( yMin ),
        FT_FRAME_SHORT ( xMax ),
        FT_FRAME_SHORT ( yMax ),
        FT_FRAME_USHORT( Mac_Style ),
        FT_FRAME_USHORT( Lowest_Rec_PPEM ),
        FT_FRAME_SHORT ( Font_Direction ),
        FT_FRAME_SHORT ( Index_To_Loc_Format ),
        FT_FRAME_SHORT ( Glyph_Data_Format ),
      FT_FRAME_END
    };


    error = face->goto_table( face, tag, stream, 0 );
    if ( error )
      goto Exit;

    header = &face->header;

    if ( FT_STREAM_READ_FIELDS( header_fields, header ) )
      goto Exit;

    FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM ));
    FT_TRACE3(( "IndexToLoc:   %4d\n", header->Index_To_Loc_Format ));

  Exit:
    return error;
  }


  FT_LOCAL_DEF( FT_Error )
  tt_face_load_head( TT_Face    face,
                     FT_Stream  stream )
  {
    return tt_face_load_generic_header( face, stream, TTAG_head );
  }


#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS

  FT_LOCAL_DEF( FT_Error )
  tt_face_load_bhed( TT_Face    face,
                     FT_Stream  stream )
  {
    return tt_face_load_generic_header( face, stream, TTAG_bhed );
  }

#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_maxp
   *
   * @Description:
   *   Loads the maximum profile into a face object.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     The input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_maxp( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error        error;
    TT_MaxProfile*  maxProfile = &face->max_profile;

    static const FT_Frame_Field  maxp_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_MaxProfile

      FT_FRAME_START( 6 ),
        FT_FRAME_LONG  ( version ),
        FT_FRAME_USHORT( numGlyphs ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  maxp_fields_extra[] =
    {
      FT_FRAME_START( 26 ),
        FT_FRAME_USHORT( maxPoints ),
        FT_FRAME_USHORT( maxContours ),
        FT_FRAME_USHORT( maxCompositePoints ),
        FT_FRAME_USHORT( maxCompositeContours ),
        FT_FRAME_USHORT( maxZones ),
        FT_FRAME_USHORT( maxTwilightPoints ),
        FT_FRAME_USHORT( maxStorage ),
        FT_FRAME_USHORT( maxFunctionDefs ),
        FT_FRAME_USHORT( maxInstructionDefs ),
        FT_FRAME_USHORT( maxStackElements ),
        FT_FRAME_USHORT( maxSizeOfInstructions ),
        FT_FRAME_USHORT( maxComponentElements ),
        FT_FRAME_USHORT( maxComponentDepth ),
      FT_FRAME_END
    };


    error = face->goto_table( face, TTAG_maxp, stream, 0 );
    if ( error )
      goto Exit;

    if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) )
      goto Exit;

    maxProfile->maxPoints             = 0;
    maxProfile->maxContours           = 0;
    maxProfile->maxCompositePoints    = 0;
    maxProfile->maxCompositeContours  = 0;
    maxProfile->maxZones              = 0;
    maxProfile->maxTwilightPoints     = 0;
    maxProfile->maxStorage            = 0;
    maxProfile->maxFunctionDefs       = 0;
    maxProfile->maxInstructionDefs    = 0;
    maxProfile->maxStackElements      = 0;
    maxProfile->maxSizeOfInstructions = 0;
    maxProfile->maxComponentElements  = 0;
    maxProfile->maxComponentDepth     = 0;

    if ( maxProfile->version >= 0x10000L )
    {
      if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) )
        goto Exit;

      /* XXX: an adjustment that is necessary to load certain */
      /*      broken fonts like `Keystrokes MT' :-(           */
      /*                                                      */
      /*   We allocate 64 function entries by default when    */
      /*   the maxFunctionDefs value is smaller.              */

      if ( maxProfile->maxFunctionDefs < 64 )
        maxProfile->maxFunctionDefs = 64;

      /* we add 4 phantom points later */
      if ( maxProfile->maxTwilightPoints > ( 0xFFFFU - 4 ) )
      {
        FT_TRACE0(( "tt_face_load_maxp:"
                    " too much twilight points in `maxp' table;\n"
                    "                  "
                    " some glyphs might be rendered incorrectly\n" ));

        maxProfile->maxTwilightPoints = 0xFFFFU - 4;
      }
    }

    FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs ));

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_name
   *
   * @Description:
   *   Loads the name records.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     The input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_name( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error      error;
    FT_Memory     memory = stream->memory;
    FT_ULong      table_pos, table_len;
    FT_ULong      storage_start, storage_limit;
    TT_NameTable  table;

    static const FT_Frame_Field  name_table_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_NameTableRec

      FT_FRAME_START( 6 ),
        FT_FRAME_USHORT( format ),
        FT_FRAME_USHORT( numNameRecords ),
        FT_FRAME_USHORT( storageOffset ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  name_record_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_NameRec

      /* no FT_FRAME_START */
        FT_FRAME_USHORT( platformID ),
        FT_FRAME_USHORT( encodingID ),
        FT_FRAME_USHORT( languageID ),
        FT_FRAME_USHORT( nameID ),
        FT_FRAME_USHORT( stringLength ),
        FT_FRAME_USHORT( stringOffset ),
      FT_FRAME_END
    };

    static const FT_Frame_Field  langTag_record_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_LangTagRec

      /* no FT_FRAME_START */
        FT_FRAME_USHORT( stringLength ),
        FT_FRAME_USHORT( stringOffset ),
      FT_FRAME_END
    };


    table         = &face->name_table;
    table->stream = stream;

    error = face->goto_table( face, TTAG_name, stream, &table_len );
    if ( error )
      goto Exit;

    table_pos = FT_STREAM_POS();

    if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) )
      goto Exit;

    /* Some popular Asian fonts have an invalid `storageOffset' value (it */
    /* should be at least `6 + 12*numNameRecords').  However, the string  */
    /* offsets, computed as `storageOffset + entry->stringOffset', are    */
    /* valid pointers within the name table...                            */
    /*                                                                    */
    /* We thus can't check `storageOffset' right now.                     */
    /*                                                                    */
    storage_start = table_pos + 6 + 12 * table->numNameRecords;
    storage_limit = table_pos + table_len;

    if ( storage_start > storage_limit )
    {
      FT_ERROR(( "tt_face_load_name: invalid `name' table\n" ));
      error = FT_THROW( Name_Table_Missing );
      goto Exit;
    }

    /* `name' format 1 contains additional language tag records, */
    /* which we load first                                       */
    if ( table->format == 1 )
    {
      if ( FT_STREAM_SEEK( storage_start )            ||
           FT_READ_USHORT( table->numLangTagRecords ) )
        goto Exit;

      storage_start += 2 + 4 * table->numLangTagRecords;

      /* allocate language tag records array */
      if ( FT_NEW_ARRAY( table->langTags, table->numLangTagRecords ) ||
           FT_FRAME_ENTER( table->numLangTagRecords * 4 )            )
        goto Exit;

      /* load language tags */
      {
        TT_LangTag  entry = table->langTags;
        TT_LangTag  limit = entry + table->numLangTagRecords;


        for ( ; entry < limit; entry++ )
        {
          (void)FT_STREAM_READ_FIELDS( langTag_record_fields, entry );

          /* check that the langTag string is within the table */
          entry->stringOffset += table_pos + table->storageOffset;
          if ( entry->stringOffset                       < storage_start ||
               entry->stringOffset + entry->stringLength > storage_limit )
          {
            /* invalid entry; ignore it */
            entry->stringLength = 0;
          }
        }
      }

      FT_FRAME_EXIT();

      (void)FT_STREAM_SEEK( table_pos + 6 );
    }

    /* allocate name records array */
    if ( FT_NEW_ARRAY( table->names, table->numNameRecords ) ||
         FT_FRAME_ENTER( table->numNameRecords * 12 )        )
      goto Exit;

    /* load name records */
    {
      TT_Name  entry = table->names;
      FT_UInt  count = table->numNameRecords;


      for ( ; count > 0; count-- )
      {
        if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) )
          continue;

        /* check that the name is not empty */
        if ( entry->stringLength == 0 )
          continue;

        /* check that the name string is within the table */
        entry->stringOffset += table_pos + table->storageOffset;
        if ( entry->stringOffset                       < storage_start ||
             entry->stringOffset + entry->stringLength > storage_limit )
        {
          /* invalid entry; ignore it */
          continue;
        }

        /* assure that we have a valid language tag ID, and   */
        /* that the corresponding langTag entry is valid, too */
        if ( table->format == 1 && entry->languageID >= 0x8000U )
        {
          if ( entry->languageID - 0x8000U >= table->numLangTagRecords    ||
               !table->langTags[entry->languageID - 0x8000U].stringLength )
          {
            /* invalid entry; ignore it */
            continue;
          }
        }

        entry++;
      }

      /* reduce array size to the actually used elements */
      count = (FT_UInt)( entry - table->names );
      (void)FT_RENEW_ARRAY( table->names,
                            table->numNameRecords,
                            count );
      table->numNameRecords = count;
    }

    FT_FRAME_EXIT();

    /* everything went well, update face->num_names */
    face->num_names = (FT_UShort)table->numNameRecords;

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_free_name
   *
   * @Description:
   *   Frees the name records.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   */
  FT_LOCAL_DEF( void )
  tt_face_free_name( TT_Face  face )
  {
    FT_Memory     memory = face->root.driver->root.memory;
    TT_NameTable  table  = &face->name_table;


    if ( table->names )
    {
      TT_Name  entry = table->names;
      TT_Name  limit = entry + table->numNameRecords;


      for ( ; entry < limit; entry++ )
        FT_FREE( entry->string );

      FT_FREE( table->names );
    }

    if ( table->langTags )
    {
      TT_LangTag  entry = table->langTags;
      TT_LangTag  limit = entry + table->numLangTagRecords;


      for ( ; entry < limit; entry++ )
        FT_FREE( entry->string );

      FT_FREE( table->langTags );
    }

    table->numNameRecords    = 0;
    table->numLangTagRecords = 0;
    table->format            = 0;
    table->storageOffset     = 0;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_cmap
   *
   * @Description:
   *   Loads the cmap directory in a face object.  The cmaps themselves
   *   are loaded on demand in the `ttcmap.c' module.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     A handle to the input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */

  FT_LOCAL_DEF( FT_Error )
  tt_face_load_cmap( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error  error;


    error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size );
    if ( error )
      goto Exit;

    if ( FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) )
      face->cmap_size = 0;

  Exit:
    return error;
  }



  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_os2
   *
   * @Description:
   *   Loads the OS2 table.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     A handle to the input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_os2( TT_Face    face,
                    FT_Stream  stream )
  {
    FT_Error  error;
    TT_OS2*   os2;

    static const FT_Frame_Field  os2_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_OS2

      FT_FRAME_START( 78 ),
        FT_FRAME_USHORT( version ),
        FT_FRAME_SHORT ( xAvgCharWidth ),
        FT_FRAME_USHORT( usWeightClass ),
        FT_FRAME_USHORT( usWidthClass ),
        FT_FRAME_SHORT ( fsType ),
        FT_FRAME_SHORT ( ySubscriptXSize ),
        FT_FRAME_SHORT ( ySubscriptYSize ),
        FT_FRAME_SHORT ( ySubscriptXOffset ),
        FT_FRAME_SHORT ( ySubscriptYOffset ),
        FT_FRAME_SHORT ( ySuperscriptXSize ),
        FT_FRAME_SHORT ( ySuperscriptYSize ),
        FT_FRAME_SHORT ( ySuperscriptXOffset ),
        FT_FRAME_SHORT ( ySuperscriptYOffset ),
        FT_FRAME_SHORT ( yStrikeoutSize ),
        FT_FRAME_SHORT ( yStrikeoutPosition ),
        FT_FRAME_SHORT ( sFamilyClass ),
        FT_FRAME_BYTE  ( panose[0] ),
        FT_FRAME_BYTE  ( panose[1] ),
        FT_FRAME_BYTE  ( panose[2] ),
        FT_FRAME_BYTE  ( panose[3] ),
        FT_FRAME_BYTE  ( panose[4] ),
        FT_FRAME_BYTE  ( panose[5] ),
        FT_FRAME_BYTE  ( panose[6] ),
        FT_FRAME_BYTE  ( panose[7] ),
        FT_FRAME_BYTE  ( panose[8] ),
        FT_FRAME_BYTE  ( panose[9] ),
        FT_FRAME_ULONG ( ulUnicodeRange1 ),
        FT_FRAME_ULONG ( ulUnicodeRange2 ),
        FT_FRAME_ULONG ( ulUnicodeRange3 ),
        FT_FRAME_ULONG ( ulUnicodeRange4 ),
        FT_FRAME_BYTE  ( achVendID[0] ),
        FT_FRAME_BYTE  ( achVendID[1] ),
        FT_FRAME_BYTE  ( achVendID[2] ),
        FT_FRAME_BYTE  ( achVendID[3] ),

        FT_FRAME_USHORT( fsSelection ),
        FT_FRAME_USHORT( usFirstCharIndex ),
        FT_FRAME_USHORT( usLastCharIndex ),
        FT_FRAME_SHORT ( sTypoAscender ),
        FT_FRAME_SHORT ( sTypoDescender ),
        FT_FRAME_SHORT ( sTypoLineGap ),
        FT_FRAME_USHORT( usWinAscent ),
        FT_FRAME_USHORT( usWinDescent ),
      FT_FRAME_END
    };

    /* `OS/2' version 1 and newer */
    static const FT_Frame_Field  os2_fields_extra1[] =
    {
      FT_FRAME_START( 8 ),
        FT_FRAME_ULONG( ulCodePageRange1 ),
        FT_FRAME_ULONG( ulCodePageRange2 ),
      FT_FRAME_END
    };

    /* `OS/2' version 2 and newer */
    static const FT_Frame_Field  os2_fields_extra2[] =
    {
      FT_FRAME_START( 10 ),
        FT_FRAME_SHORT ( sxHeight ),
        FT_FRAME_SHORT ( sCapHeight ),
        FT_FRAME_USHORT( usDefaultChar ),
        FT_FRAME_USHORT( usBreakChar ),
        FT_FRAME_USHORT( usMaxContext ),
      FT_FRAME_END
    };

    /* `OS/2' version 5 and newer */
    static const FT_Frame_Field  os2_fields_extra5[] =
    {
      FT_FRAME_START( 4 ),
        FT_FRAME_USHORT( usLowerOpticalPointSize ),
        FT_FRAME_USHORT( usUpperOpticalPointSize ),
      FT_FRAME_END
    };


    /* We now support old Mac fonts where the OS/2 table doesn't  */
    /* exist.  Simply put, we set the `version' field to 0xFFFF   */
    /* and test this value each time we need to access the table. */
    error = face->goto_table( face, TTAG_OS2, stream, 0 );
    if ( error )
      goto Exit;

    os2 = &face->os2;

    if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) )
      goto Exit;

    os2->ulCodePageRange1        = 0;
    os2->ulCodePageRange2        = 0;
    os2->sxHeight                = 0;
    os2->sCapHeight              = 0;
    os2->usDefaultChar           = 0;
    os2->usBreakChar             = 0;
    os2->usMaxContext            = 0;
    os2->usLowerOpticalPointSize = 0;
    os2->usUpperOpticalPointSize = 0xFFFF;

    if ( os2->version >= 0x0001 )
    {
      /* only version 1 tables */
      if ( FT_STREAM_READ_FIELDS( os2_fields_extra1, os2 ) )
        goto Exit;

      if ( os2->version >= 0x0002 )
      {
        /* only version 2 tables */
        if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) )
          goto Exit;

        if ( os2->version >= 0x0005 )
        {
          /* only version 5 tables */
          if ( FT_STREAM_READ_FIELDS( os2_fields_extra5, os2 ) )
            goto Exit;
        }
      }
    }

    FT_TRACE3(( "sTypoAscender:  %4d\n",   os2->sTypoAscender ));
    FT_TRACE3(( "sTypoDescender: %4d\n",   os2->sTypoDescender ));
    FT_TRACE3(( "usWinAscent:    %4u\n",   os2->usWinAscent ));
    FT_TRACE3(( "usWinDescent:   %4u\n",   os2->usWinDescent ));
    FT_TRACE3(( "fsSelection:    0x%2x\n", os2->fsSelection ));

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_postscript
   *
   * @Description:
   *   Loads the Postscript table.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     A handle to the input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_post( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error        error;
    TT_Postscript*  post = &face->postscript;

    static const FT_Frame_Field  post_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_Postscript

      FT_FRAME_START( 32 ),
        FT_FRAME_LONG ( FormatType ),
        FT_FRAME_LONG ( italicAngle ),
        FT_FRAME_SHORT( underlinePosition ),
        FT_FRAME_SHORT( underlineThickness ),
        FT_FRAME_ULONG( isFixedPitch ),
        FT_FRAME_ULONG( minMemType42 ),
        FT_FRAME_ULONG( maxMemType42 ),
        FT_FRAME_ULONG( minMemType1 ),
        FT_FRAME_ULONG( maxMemType1 ),
      FT_FRAME_END
    };


    error = face->goto_table( face, TTAG_post, stream, 0 );
    if ( error )
      return error;

    if ( FT_STREAM_READ_FIELDS( post_fields, post ) )
      return error;

    /* we don't load the glyph names, we do that in another */
    /* module (ttpost).                                     */

    FT_TRACE3(( "FormatType:   0x%x\n", post->FormatType ));
    FT_TRACE3(( "isFixedPitch:   %s\n", post->isFixedPitch
                                        ? "  yes" : "   no" ));

    return FT_Err_Ok;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_pclt
   *
   * @Description:
   *   Loads the PCL 5 Table.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     A handle to the input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_pclt( TT_Face    face,
                     FT_Stream  stream )
  {
    static const FT_Frame_Field  pclt_fields[] =
    {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  TT_PCLT

      FT_FRAME_START( 54 ),
        FT_FRAME_ULONG ( Version ),
        FT_FRAME_ULONG ( FontNumber ),
        FT_FRAME_USHORT( Pitch ),
        FT_FRAME_USHORT( xHeight ),
        FT_FRAME_USHORT( Style ),
        FT_FRAME_USHORT( TypeFamily ),
        FT_FRAME_USHORT( CapHeight ),
        FT_FRAME_USHORT( SymbolSet ),
        FT_FRAME_BYTES ( TypeFace, 16 ),
        FT_FRAME_BYTES ( CharacterComplement, 8 ),
        FT_FRAME_BYTES ( FileName, 6 ),
        FT_FRAME_CHAR  ( StrokeWeight ),
        FT_FRAME_CHAR  ( WidthType ),
        FT_FRAME_BYTE  ( SerifStyle ),
        FT_FRAME_BYTE  ( Reserved ),
      FT_FRAME_END
    };

    FT_Error  error;
    TT_PCLT*  pclt = &face->pclt;


    /* optional table */
    error = face->goto_table( face, TTAG_PCLT, stream, 0 );
    if ( error )
      goto Exit;

    if ( FT_STREAM_READ_FIELDS( pclt_fields, pclt ) )
      goto Exit;

  Exit:
    return error;
  }


  /**************************************************************************
   *
   * @Function:
   *   tt_face_load_gasp
   *
   * @Description:
   *   Loads the `gasp' table into a face object.
   *
   * @Input:
   *   face ::
   *     A handle to the target face object.
   *
   *   stream ::
   *     The input stream.
   *
   * @Return:
   *   FreeType error code.  0 means success.
   */
  FT_LOCAL_DEF( FT_Error )
  tt_face_load_gasp( TT_Face    face,
                     FT_Stream  stream )
  {
    FT_Error   error;
    FT_Memory  memory = stream->memory;

    FT_UInt        j,num_ranges;
    TT_GaspRange   gaspranges = NULL;


    /* the gasp table is optional */
    error = face->goto_table( face, TTAG_gasp, stream, 0 );
    if ( error )
      goto Exit;

    if ( FT_FRAME_ENTER( 4L ) )
      goto Exit;

    face->gasp.version   = FT_GET_USHORT();
    face->gasp.numRanges = FT_GET_USHORT();

    FT_FRAME_EXIT();

    /* only support versions 0 and 1 of the table */
    if ( face->gasp.version >= 2 )
    {
      face->gasp.numRanges = 0;
      error = FT_THROW( Invalid_Table );
      goto Exit;
    }

    num_ranges = face->gasp.numRanges;
    FT_TRACE3(( "numRanges: %u\n", num_ranges ));

    if ( FT_QNEW_ARRAY( face->gasp.gaspRanges, num_ranges ) ||
         FT_FRAME_ENTER( num_ranges * 4L )                  )
      goto Exit;

    gaspranges = face->gasp.gaspRanges;

    for ( j = 0; j < num_ranges; j++ )
    {
      gaspranges[j].maxPPEM  = FT_GET_USHORT();
      gaspranges[j].gaspFlag = FT_GET_USHORT();

      FT_TRACE3(( "gaspRange %d: rangeMaxPPEM %5d, rangeGaspBehavior 0x%x\n",
                  j,
                  gaspranges[j].maxPPEM,
                  gaspranges[j].gaspFlag ));
    }

    FT_FRAME_EXIT();

  Exit:
    return error;
  }


/* END */
