⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 afmparse.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************//*                                                                         *//*  afmparse.c                                                             *//*                                                                         *//*    AFM parser (body).                                                   *//*                                                                         *//*  Copyright 2006 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_FREETYPE_H#include FT_INTERNAL_POSTSCRIPT_AUX_H#include FT_INTERNAL_DEBUG_H#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 )       \          ( (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;    int    ch;    afm_stream_skip_spaces( stream );    if ( AFM_STATUS_EOC( stream ) )      return NULL;    str = AFM_STREAM_KEY_BEGIN( stream );    while ( 1 )    {      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;    int    ch;    afm_stream_skip_spaces( stream );    if ( AFM_STATUS_EOL( stream ) )      return NULL;    str = AFM_STREAM_KEY_BEGIN( stream );    /* scan to eol */    while ( 1 )    {      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_UInt    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_UInt*    len )  {    AFM_Stream  stream = parser->stream;    char*       key    = 0;  /* 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 ) &&

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -