/****************************************************************************
 *
 * afmparse.c
 *
 *   AFM parser (body).
 *
 * Copyright (C) 2006-2020 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 <freetype/freetype.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/psaux.h>

#ifndef T1_CONFIG_OPTION_NO_AFM

#include "afmparse.h"
#include "psconv.h"

#include "psauxerr.h"


  /**************************************************************************
   *
   * AFM_Stream
   *
   * The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib.
   *
   */

  enum
  {
    AFM_STREAM_STATUS_NORMAL,
    AFM_STREAM_STATUS_EOC,
    AFM_STREAM_STATUS_EOL,
    AFM_STREAM_STATUS_EOF
  };


  typedef struct  AFM_StreamRec_
  {
    FT_Byte*  cursor;
    FT_Byte*  base;
    FT_Byte*  limit;

    FT_Int    status;

  } AFM_StreamRec;


#ifndef EOF
#define EOF -1
#endif


  /* this works because empty lines are ignored */
#define AFM_IS_NEWLINE( ch )  ( (ch) == '\r' || (ch) == '\n' )

#define AFM_IS_EOF( ch )      ( (ch) == EOF  || (ch) == '\x1a' )
#define AFM_IS_SPACE( ch )    ( (ch) == ' '  || (ch) == '\t' )

  /* column separator; there is no `column' in the spec actually */
#define AFM_IS_SEP( ch )      ( (ch) == ';' )

#define AFM_GETC()                                                       \
          ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \
                                                   : EOF )

#define AFM_STREAM_KEY_BEGIN( stream )    \
          (char*)( (stream)->cursor - 1 )

#define AFM_STREAM_KEY_LEN( stream, key )           \
          (FT_Offset)( (char*)(stream)->cursor - key - 1 )

#define AFM_STATUS_EOC( stream ) \
          ( (stream)->status >= AFM_STREAM_STATUS_EOC )

#define AFM_STATUS_EOL( stream ) \
          ( (stream)->status >= AFM_STREAM_STATUS_EOL )

#define AFM_STATUS_EOF( stream ) \
          ( (stream)->status >= AFM_STREAM_STATUS_EOF )


  static int
  afm_stream_skip_spaces( AFM_Stream  stream )
  {
    int  ch = 0;  /* make stupid compiler happy */


    if ( AFM_STATUS_EOC( stream ) )
      return ';';

    while ( 1 )
    {
      ch = AFM_GETC();
      if ( !AFM_IS_SPACE( ch ) )
        break;
    }

    if ( AFM_IS_NEWLINE( ch ) )
      stream->status = AFM_STREAM_STATUS_EOL;
    else if ( AFM_IS_SEP( ch ) )
      stream->status = AFM_STREAM_STATUS_EOC;
    else if ( AFM_IS_EOF( ch ) )
      stream->status = AFM_STREAM_STATUS_EOF;

    return ch;
  }


  /* read a key or value in current column */
  static char*
  afm_stream_read_one( AFM_Stream  stream )
  {
    char*  str;


    afm_stream_skip_spaces( stream );
    if ( AFM_STATUS_EOC( stream ) )
      return NULL;

    str = AFM_STREAM_KEY_BEGIN( stream );

    while ( 1 )
    {
      int  ch = AFM_GETC();


      if ( AFM_IS_SPACE( ch ) )
        break;
      else if ( AFM_IS_NEWLINE( ch ) )
      {
        stream->status = AFM_STREAM_STATUS_EOL;
        break;
      }
      else if ( AFM_IS_SEP( ch ) )
      {
        stream->status = AFM_STREAM_STATUS_EOC;
        break;
      }
      else if ( AFM_IS_EOF( ch ) )
      {
        stream->status = AFM_STREAM_STATUS_EOF;
        break;
      }
    }

    return str;
  }


  /* read a string (i.e., read to EOL) */
  static char*
  afm_stream_read_string( AFM_Stream  stream )
  {
    char*  str;


    afm_stream_skip_spaces( stream );
    if ( AFM_STATUS_EOL( stream ) )
      return NULL;

    str = AFM_STREAM_KEY_BEGIN( stream );

    /* scan to eol */
    while ( 1 )
    {
      int  ch = AFM_GETC();


      if ( AFM_IS_NEWLINE( ch ) )
      {
        stream->status = AFM_STREAM_STATUS_EOL;
        break;
      }
      else if ( AFM_IS_EOF( ch ) )
      {
        stream->status = AFM_STREAM_STATUS_EOF;
        break;
      }
    }

    return str;
  }


  /**************************************************************************
   *
   * AFM_Parser
   *
   */

  /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */
  typedef enum  AFM_Token_
  {
    AFM_TOKEN_ASCENDER,
    AFM_TOKEN_AXISLABEL,
    AFM_TOKEN_AXISTYPE,
    AFM_TOKEN_B,
    AFM_TOKEN_BLENDAXISTYPES,
    AFM_TOKEN_BLENDDESIGNMAP,
    AFM_TOKEN_BLENDDESIGNPOSITIONS,
    AFM_TOKEN_C,
    AFM_TOKEN_CC,
    AFM_TOKEN_CH,
    AFM_TOKEN_CAPHEIGHT,
    AFM_TOKEN_CHARWIDTH,
    AFM_TOKEN_CHARACTERSET,
    AFM_TOKEN_CHARACTERS,
    AFM_TOKEN_DESCENDER,
    AFM_TOKEN_ENCODINGSCHEME,
    AFM_TOKEN_ENDAXIS,
    AFM_TOKEN_ENDCHARMETRICS,
    AFM_TOKEN_ENDCOMPOSITES,
    AFM_TOKEN_ENDDIRECTION,
    AFM_TOKEN_ENDFONTMETRICS,
    AFM_TOKEN_ENDKERNDATA,
    AFM_TOKEN_ENDKERNPAIRS,
    AFM_TOKEN_ENDTRACKKERN,
    AFM_TOKEN_ESCCHAR,
    AFM_TOKEN_FAMILYNAME,
    AFM_TOKEN_FONTBBOX,
    AFM_TOKEN_FONTNAME,
    AFM_TOKEN_FULLNAME,
    AFM_TOKEN_ISBASEFONT,
    AFM_TOKEN_ISCIDFONT,
    AFM_TOKEN_ISFIXEDPITCH,
    AFM_TOKEN_ISFIXEDV,
    AFM_TOKEN_ITALICANGLE,
    AFM_TOKEN_KP,
    AFM_TOKEN_KPH,
    AFM_TOKEN_KPX,
    AFM_TOKEN_KPY,
    AFM_TOKEN_L,
    AFM_TOKEN_MAPPINGSCHEME,
    AFM_TOKEN_METRICSSETS,
    AFM_TOKEN_N,
    AFM_TOKEN_NOTICE,
    AFM_TOKEN_PCC,
    AFM_TOKEN_STARTAXIS,
    AFM_TOKEN_STARTCHARMETRICS,
    AFM_TOKEN_STARTCOMPOSITES,
    AFM_TOKEN_STARTDIRECTION,
    AFM_TOKEN_STARTFONTMETRICS,
    AFM_TOKEN_STARTKERNDATA,
    AFM_TOKEN_STARTKERNPAIRS,
    AFM_TOKEN_STARTKERNPAIRS0,
    AFM_TOKEN_STARTKERNPAIRS1,
    AFM_TOKEN_STARTTRACKKERN,
    AFM_TOKEN_STDHW,
    AFM_TOKEN_STDVW,
    AFM_TOKEN_TRACKKERN,
    AFM_TOKEN_UNDERLINEPOSITION,
    AFM_TOKEN_UNDERLINETHICKNESS,
    AFM_TOKEN_VV,
    AFM_TOKEN_VVECTOR,
    AFM_TOKEN_VERSION,
    AFM_TOKEN_W,
    AFM_TOKEN_W0,
    AFM_TOKEN_W0X,
    AFM_TOKEN_W0Y,
    AFM_TOKEN_W1,
    AFM_TOKEN_W1X,
    AFM_TOKEN_W1Y,
    AFM_TOKEN_WX,
    AFM_TOKEN_WY,
    AFM_TOKEN_WEIGHT,
    AFM_TOKEN_WEIGHTVECTOR,
    AFM_TOKEN_XHEIGHT,
    N_AFM_TOKENS,
    AFM_TOKEN_UNKNOWN

  } AFM_Token;


  static const char*  const afm_key_table[N_AFM_TOKENS] =
  {
    "Ascender",
    "AxisLabel",
    "AxisType",
    "B",
    "BlendAxisTypes",
    "BlendDesignMap",
    "BlendDesignPositions",
    "C",
    "CC",
    "CH",
    "CapHeight",
    "CharWidth",
    "CharacterSet",
    "Characters",
    "Descender",
    "EncodingScheme",
    "EndAxis",
    "EndCharMetrics",
    "EndComposites",
    "EndDirection",
    "EndFontMetrics",
    "EndKernData",
    "EndKernPairs",
    "EndTrackKern",
    "EscChar",
    "FamilyName",
    "FontBBox",
    "FontName",
    "FullName",
    "IsBaseFont",
    "IsCIDFont",
    "IsFixedPitch",
    "IsFixedV",
    "ItalicAngle",
    "KP",
    "KPH",
    "KPX",
    "KPY",
    "L",
    "MappingScheme",
    "MetricsSets",
    "N",
    "Notice",
    "PCC",
    "StartAxis",
    "StartCharMetrics",
    "StartComposites",
    "StartDirection",
    "StartFontMetrics",
    "StartKernData",
    "StartKernPairs",
    "StartKernPairs0",
    "StartKernPairs1",
    "StartTrackKern",
    "StdHW",
    "StdVW",
    "TrackKern",
    "UnderlinePosition",
    "UnderlineThickness",
    "VV",
    "VVector",
    "Version",
    "W",
    "W0",
    "W0X",
    "W0Y",
    "W1",
    "W1X",
    "W1Y",
    "WX",
    "WY",
    "Weight",
    "WeightVector",
    "XHeight"
  };


  /*
   * `afm_parser_read_vals' and `afm_parser_next_key' provide
   * high-level operations to an AFM_Stream.  The rest of the
   * parser functions should use them without accessing the
   * AFM_Stream directly.
   */

  FT_LOCAL_DEF( FT_Int )
  afm_parser_read_vals( AFM_Parser  parser,
                        AFM_Value   vals,
                        FT_Int      n )
  {
    AFM_Stream  stream = parser->stream;
    char*       str;
    FT_Int      i;


    if ( n > AFM_MAX_ARGUMENTS )
      return 0;

    for ( i = 0; i < n; i++ )
    {
      FT_Offset  len;
      AFM_Value  val = vals + i;


      if ( val->type == AFM_VALUE_TYPE_STRING )
        str = afm_stream_read_string( stream );
      else
        str = afm_stream_read_one( stream );

      if ( !str )
        break;

      len = AFM_STREAM_KEY_LEN( stream, str );

      switch ( val->type )
      {
      case AFM_VALUE_TYPE_STRING:
      case AFM_VALUE_TYPE_NAME:
        {
          FT_Memory  memory = parser->memory;
          FT_Error   error;


          if ( !FT_QALLOC( val->u.s, len + 1 ) )
          {
            ft_memcpy( val->u.s, str, len );
            val->u.s[len] = '\0';
          }
        }
        break;

      case AFM_VALUE_TYPE_FIXED:
        val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str,
                                    (FT_Byte*)str + len, 0 );
        break;

      case AFM_VALUE_TYPE_INTEGER:
        val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str,
                                  (FT_Byte*)str + len );
        break;

      case AFM_VALUE_TYPE_BOOL:
        val->u.b = FT_BOOL( len == 4                      &&
                            !ft_strncmp( str, "true", 4 ) );
        break;

      case AFM_VALUE_TYPE_INDEX:
        if ( parser->get_index )
          val->u.i = parser->get_index( str, len, parser->user_data );
        else
          val->u.i = 0;
        break;
      }
    }

    return i;
  }


  FT_LOCAL_DEF( char* )
  afm_parser_next_key( AFM_Parser  parser,
                       FT_Bool     line,
                       FT_Offset*  len )
  {
    AFM_Stream  stream = parser->stream;
    char*       key    = NULL;  /* make stupid compiler happy */


    if ( line )
    {
      while ( 1 )
      {
        /* skip current line */
        if ( !AFM_STATUS_EOL( stream ) )
          afm_stream_read_string( stream );

        stream->status = AFM_STREAM_STATUS_NORMAL;
        key = afm_stream_read_one( stream );

        /* skip empty line */
        if ( !key                      &&
             !AFM_STATUS_EOF( stream ) &&
             AFM_STATUS_EOL( stream )  )
          continue;

        break;
      }
    }
    else
    {
      while ( 1 )
      {
        /* skip current column */
        while ( !AFM_STATUS_EOC( stream ) )
          afm_stream_read_one( stream );

        stream->status = AFM_STREAM_STATUS_NORMAL;
        key = afm_stream_read_one( stream );

        /* skip empty column */
        if ( !key                      &&
             !AFM_STATUS_EOF( stream ) &&
             AFM_STATUS_EOC( stream )  )
          continue;

        break;
      }
    }

    if ( len )
      *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )
                     : 0;

    return key;
  }


  static AFM_Token
  afm_tokenize( const char*  key,
                FT_Offset    len )
  {
    int  n;


    for ( n = 0; n < N_AFM_TOKENS; n++ )
    {
      if ( *( afm_key_table[n] ) == *key )
      {
        for ( ; n < N_AFM_TOKENS; n++ )
        {
          if ( *( afm_key_table[n] ) != *key )
            return AFM_TOKEN_UNKNOWN;

          if ( ft_strncmp( afm_key_table[n], key, len ) == 0 )
            return (AFM_Token) n;
        }
      }
    }

    return AFM_TOKEN_UNKNOWN;
  }


  FT_LOCAL_DEF( FT_Error )
  afm_parser_init( AFM_Parser  parser,
                   FT_Memory   memory,
                   FT_Byte*    base,
                   FT_Byte*    limit )
  {
    AFM_Stream  stream = NULL;
    FT_Error    error;


    if ( FT_NEW( stream ) )
      return error;

    stream->cursor = stream->base = base;
    stream->limit  = limit;

    /* don't skip the first line during the first call */
    stream->status = AFM_STREAM_STATUS_EOL;

    parser->memory    = memory;
    parser->stream    = stream;
    parser->FontInfo  = NULL;
    parser->get_index = NULL;

    return FT_Err_Ok;
  }


  FT_LOCAL( void )
  afm_parser_done( AFM_Parser  parser )
  {
    FT_Memory  memory = parser->memory;


    FT_FREE( parser->stream );
  }


  static FT_Error
  afm_parser_read_int( AFM_Parser  parser,
                       FT_Int*     aint )
  {
    AFM_ValueRec  val;


    val.type = AFM_VALUE_TYPE_INTEGER;

    if ( afm_parser_read_vals( parser, &val, 1 ) == 1 )
    {
      *aint = val.u.i;

      return FT_Err_Ok;
    }
    else
      return FT_THROW( Syntax_Error );
  }


  static FT_Error
  afm_parse_track_kern( AFM_Parser  parser )
  {
    AFM_FontInfo   fi = parser->FontInfo;
    AFM_TrackKern  tk;
    char*          key;
    FT_Offset      len;
    int            n = -1;
    FT_Int         tmp;


    if ( afm_parser_read_int( parser, &tmp ) )
        goto Fail;

    if ( tmp < 0 )
      goto Fail;

    fi->NumTrackKern = (FT_UInt)tmp;

    if ( fi->NumTrackKern )
    {
      FT_Memory  memory = parser->memory;
      FT_Error   error;


      if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) )
        return error;
    }

    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      AFM_ValueRec  shared_vals[5];


      switch ( afm_tokenize( key, len ) )
      {
      case AFM_TOKEN_TRACKKERN:
        n++;

        if ( n >= (int)fi->NumTrackKern )
          goto Fail;

        tk = fi->TrackKerns + n;

        shared_vals[0].type = AFM_VALUE_TYPE_INTEGER;
        shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
        if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
          goto Fail;

        tk->degree     = shared_vals[0].u.i;
        tk->min_ptsize = shared_vals[1].u.f;
        tk->min_kern   = shared_vals[2].u.f;
        tk->max_ptsize = shared_vals[3].u.f;
        tk->max_kern   = shared_vals[4].u.f;

        break;

      case AFM_TOKEN_ENDTRACKKERN:
      case AFM_TOKEN_ENDKERNDATA:
      case AFM_TOKEN_ENDFONTMETRICS:
        fi->NumTrackKern = (FT_UInt)( n + 1 );
        return FT_Err_Ok;

      case AFM_TOKEN_UNKNOWN:
        break;

      default:
        goto Fail;
      }
    }

  Fail:
    return FT_THROW( Syntax_Error );
  }


#undef  KERN_INDEX
#define KERN_INDEX( g1, g2 )  ( ( (FT_ULong)g1 << 16 ) | g2 )


  /* compare two kerning pairs */
  FT_CALLBACK_DEF( int )
  afm_compare_kern_pairs( const void*  a,
                          const void*  b )
  {
    AFM_KernPair  kp1 = (AFM_KernPair)a;
    AFM_KernPair  kp2 = (AFM_KernPair)b;

    FT_ULong  index1 = KERN_INDEX( kp1->index1, kp1->index2 );
    FT_ULong  index2 = KERN_INDEX( kp2->index1, kp2->index2 );


    if ( index1 > index2 )
      return 1;
    else if ( index1 < index2 )
      return -1;
    else
      return 0;
  }


  static FT_Error
  afm_parse_kern_pairs( AFM_Parser  parser )
  {
    AFM_FontInfo  fi = parser->FontInfo;
    AFM_KernPair  kp;
    char*         key;
    FT_Offset     len;
    int           n = -1;
    FT_Int        tmp;


    if ( afm_parser_read_int( parser, &tmp ) )
      goto Fail;

    if ( tmp < 0 )
      goto Fail;

    fi->NumKernPair = (FT_UInt)tmp;

    if ( fi->NumKernPair )
    {
      FT_Memory  memory = parser->memory;
      FT_Error   error;


      if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )
        return error;
    }

    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      AFM_Token  token = afm_tokenize( key, len );


      switch ( token )
      {
      case AFM_TOKEN_KP:
      case AFM_TOKEN_KPX:
      case AFM_TOKEN_KPY:
        {
          FT_Int        r;
          AFM_ValueRec  shared_vals[4];


          n++;

          if ( n >= (int)fi->NumKernPair )
            goto Fail;

          kp = fi->KernPairs + n;

          shared_vals[0].type = AFM_VALUE_TYPE_INDEX;
          shared_vals[1].type = AFM_VALUE_TYPE_INDEX;
          shared_vals[2].type = AFM_VALUE_TYPE_INTEGER;
          shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
          r = afm_parser_read_vals( parser, shared_vals, 4 );
          if ( r < 3 )
            goto Fail;

          /* index values can't be negative */
          kp->index1 = shared_vals[0].u.u;
          kp->index2 = shared_vals[1].u.u;
          if ( token == AFM_TOKEN_KPY )
          {
            kp->x = 0;
            kp->y = shared_vals[2].u.i;
          }
          else
          {
            kp->x = shared_vals[2].u.i;
            kp->y = ( token == AFM_TOKEN_KP && r == 4 )
                      ? shared_vals[3].u.i : 0;
          }
        }
        break;

      case AFM_TOKEN_ENDKERNPAIRS:
      case AFM_TOKEN_ENDKERNDATA:
      case AFM_TOKEN_ENDFONTMETRICS:
        fi->NumKernPair = (FT_UInt)( n + 1 );
        ft_qsort( fi->KernPairs, fi->NumKernPair,
                  sizeof ( AFM_KernPairRec ),
                  afm_compare_kern_pairs );
        return FT_Err_Ok;

      case AFM_TOKEN_UNKNOWN:
        break;

      default:
        goto Fail;
      }
    }

  Fail:
    return FT_THROW( Syntax_Error );
  }


  static FT_Error
  afm_parse_kern_data( AFM_Parser  parser )
  {
    FT_Error   error;
    char*      key;
    FT_Offset  len;


    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      switch ( afm_tokenize( key, len ) )
      {
      case AFM_TOKEN_STARTTRACKKERN:
        error = afm_parse_track_kern( parser );
        if ( error )
          return error;
        break;

      case AFM_TOKEN_STARTKERNPAIRS:
      case AFM_TOKEN_STARTKERNPAIRS0:
        error = afm_parse_kern_pairs( parser );
        if ( error )
          return error;
        break;

      case AFM_TOKEN_ENDKERNDATA:
      case AFM_TOKEN_ENDFONTMETRICS:
        return FT_Err_Ok;

      case AFM_TOKEN_UNKNOWN:
        break;

      default:
        goto Fail;
      }
    }

  Fail:
    return FT_THROW( Syntax_Error );
  }


  static FT_Error
  afm_parser_skip_section( AFM_Parser  parser,
                           FT_Int      n,
                           AFM_Token   end_section )
  {
    char*      key;
    FT_Offset  len;


    while ( n-- > 0 )
    {
      key = afm_parser_next_key( parser, 1, NULL );
      if ( !key )
        goto Fail;
    }

    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      AFM_Token  token = afm_tokenize( key, len );


      if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS )
        return FT_Err_Ok;
    }

  Fail:
    return FT_THROW( Syntax_Error );
  }


  FT_LOCAL_DEF( FT_Error )
  afm_parser_parse( AFM_Parser  parser )
  {
    FT_Memory     memory = parser->memory;
    AFM_FontInfo  fi     = parser->FontInfo;
    FT_Error      error  = FT_ERR( Syntax_Error );
    char*         key;
    FT_Offset     len;
    FT_Int        metrics_sets = 0;


    if ( !fi )
      return FT_THROW( Invalid_Argument );

    key = afm_parser_next_key( parser, 1, &len );
    if ( !key || len != 16                              ||
         ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )
      return FT_THROW( Unknown_File_Format );

    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      AFM_ValueRec  shared_vals[4];


      switch ( afm_tokenize( key, len ) )
      {
      case AFM_TOKEN_METRICSSETS:
        if ( afm_parser_read_int( parser, &metrics_sets ) )
          goto Fail;

        if ( metrics_sets != 0 && metrics_sets != 2 )
        {
          error = FT_THROW( Unimplemented_Feature );

          goto Fail;
        }
        break;

      case AFM_TOKEN_ISCIDFONT:
        shared_vals[0].type = AFM_VALUE_TYPE_BOOL;
        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
          goto Fail;

        fi->IsCIDFont = shared_vals[0].u.b;
        break;

      case AFM_TOKEN_FONTBBOX:
        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
        shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
        if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 )
          goto Fail;

        fi->FontBBox.xMin = shared_vals[0].u.f;
        fi->FontBBox.yMin = shared_vals[1].u.f;
        fi->FontBBox.xMax = shared_vals[2].u.f;
        fi->FontBBox.yMax = shared_vals[3].u.f;
        break;

      case AFM_TOKEN_ASCENDER:
        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
          goto Fail;

        fi->Ascender = shared_vals[0].u.f;
        break;

      case AFM_TOKEN_DESCENDER:
        shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
        if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
          goto Fail;

        fi->Descender = shared_vals[0].u.f;
        break;

      case AFM_TOKEN_STARTCHARMETRICS:
        {
          FT_Int  n = 0;


          if ( afm_parser_read_int( parser, &n ) )
            goto Fail;

          error = afm_parser_skip_section( parser, n,
                                           AFM_TOKEN_ENDCHARMETRICS );
          if ( error )
            return error;
        }
        break;

      case AFM_TOKEN_STARTKERNDATA:
        error = afm_parse_kern_data( parser );
        if ( error )
          goto Fail;
        /* we only support kern data, so ... */
        /* fall through                      */

      case AFM_TOKEN_ENDFONTMETRICS:
        return FT_Err_Ok;

      default:
        break;
      }
    }

  Fail:
    FT_FREE( fi->TrackKerns );
    fi->NumTrackKern = 0;

    FT_FREE( fi->KernPairs );
    fi->NumKernPair = 0;

    fi->IsCIDFont = 0;

    return error;
  }

#else /* T1_CONFIG_OPTION_NO_AFM */

  /* ANSI C doesn't like empty source files */
  typedef int  _afm_parse_dummy;

#endif /* T1_CONFIG_OPTION_NO_AFM */


/* END */
