/****************************************************************************
 *
 * afmparse.c
 *
 *   AFM parser (body).
 *
 * Copyright (C) 2006-2021 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 <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"


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


  /**************************************************************************
   *
   * 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_Stream     stream = parser->stream;
    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 )
    {
      FT_ERROR(( "afm_parse_track_kern: invalid number of track kerns\n" ));
      goto Fail;
    }

    fi->NumTrackKern = (FT_UInt)tmp;
    FT_TRACE3(( "afm_parse_track_kern: %u track kern%s expected\n",
                fi->NumTrackKern,
                fi->NumTrackKern == 1 ? "" : "s" ));

    /* Rough sanity check: The minimum line length of the `TrackKern` */
    /* command is 20 characters (including the EOL character).        */
    if ( (FT_ULong)( stream->limit - stream->cursor ) / 20 <
           fi->NumTrackKern )
    {
      FT_ERROR(( "afm_parse_track_kern:"
                 " number of track kern entries exceeds stream size\n" ));
      goto Fail;
    }

    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 )
          {
            FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" ));
            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 )
        {
          FT_ERROR(( "afm_parse_track_kern:"
                     " insufficient number of parameters for entry %d\n",
                     n ));
          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:
        tmp = n + 1;
        if ( (FT_UInt)tmp != fi->NumTrackKern )
        {
          FT_TRACE1(( "afm_parse_track_kern: %s%d track kern entr%s seen\n",
                      tmp == 0 ? "" : "only ",
                      tmp,
                      tmp == 1 ? "y" : "ies" ));
          fi->NumTrackKern = (FT_UInt)tmp;
        }
        else
          FT_TRACE3(( "afm_parse_track_kern: %d track kern entr%s seen\n",
                      tmp,
                      tmp == 1 ? "y" : "ies" ));
        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_COMPARE_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_Stream    stream = parser->stream;
    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 )
    {
      FT_ERROR(( "afm_parse_kern_pairs: invalid number of kern pairs\n" ));
      goto Fail;
    }

    fi->NumKernPair = (FT_UInt)tmp;
    FT_TRACE3(( "afm_parse_kern_pairs: %u kern pair%s expected\n",
                fi->NumKernPair,
                fi->NumKernPair == 1 ? "" : "s" ));

    /* Rough sanity check: The minimum line length of the `KP`,    */
    /* `KPH`,`KPX`, and `KPY` commands is 10 characters (including */
    /* the EOL character).                                         */
    if ( (FT_ULong)( stream->limit - stream->cursor ) / 10 <
           fi->NumKernPair )
    {
      FT_ERROR(( "afm_parse_kern_pairs:"
                 " number of kern pairs exceeds stream size\n" ));
      goto Fail;
    }

    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 )
          {
            FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" ));
            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 )
          {
            FT_ERROR(( "afm_parse_kern_pairs:"
                       " insufficient number of parameters for entry %d\n",
                       n ));
            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:
        tmp = n + 1;
        if ( (FT_UInt)tmp != fi->NumKernPair )
        {
          FT_TRACE1(( "afm_parse_kern_pairs: %s%d kern pair%s seen\n",
                      tmp == 0 ? "" : "only ",
                      tmp,
                      tmp == 1 ? "" : "s" ));
          fi->NumKernPair = (FT_UInt)tmp;
        }
        else
          FT_TRACE3(( "afm_parse_kern_pairs: %d kern pair%s seen\n",
                      tmp,
                      tmp == 1 ? "" : "s" ));

        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;

    int  have_trackkern = 0;
    int  have_kernpairs = 0;


    while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
    {
      switch ( afm_tokenize( key, len ) )
      {
      case AFM_TOKEN_STARTTRACKKERN:
        if ( have_trackkern )
        {
          FT_ERROR(( "afm_parse_kern_data:"
                     " invalid second horizontal track kern section\n" ));
          goto Fail;
        }

        error = afm_parse_track_kern( parser );
        if ( error )
          return error;

        have_trackkern = 1;
        break;

      case AFM_TOKEN_STARTKERNPAIRS:
      case AFM_TOKEN_STARTKERNPAIRS0:
        if ( have_kernpairs )
        {
          FT_ERROR(( "afm_parse_kern_data:"
                     " invalid second horizontal kern pair section\n" ));
          goto Fail;
        }

        error = afm_parse_kern_pairs( parser );
        if ( error )
          return error;

        have_kernpairs = 1;
        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 */
