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

📄 afmparse.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 2 页
字号:
             AFM_STATUS_EOC( stream )  )          continue;        break;      }    }    if ( len )      *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key )                     : 0;    return key;  }  static AFM_Token  afm_tokenize( const char*  key,                FT_UInt      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;    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 PSaux_Err_Ok;  }  FT_LOCAL( void )  afm_parser_done( AFM_Parser  parser )  {    FT_Memory  memory = parser->memory;    FT_FREE( parser->stream );  }  FT_LOCAL_DEF( 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 PSaux_Err_Ok;    }    else      return PSaux_Err_Syntax_Error;  }  static FT_Error  afm_parse_track_kern( AFM_Parser  parser )  {    AFM_FontInfo   fi = parser->FontInfo;    AFM_TrackKern  tk;    char*          key;    FT_UInt        len;    int            n = -1;    if ( afm_parser_read_int( parser, &fi->NumTrackKern ) )        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 >= 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;        /* is this correct? */        if ( tk->degree < 0 && tk->min_kern > 0 )          tk->min_kern = -tk->min_kern;        break;      case AFM_TOKEN_ENDTRACKKERN:      case AFM_TOKEN_ENDKERNDATA:      case AFM_TOKEN_ENDFONTMETRICS:        fi->NumTrackKern = n + 1;        return PSaux_Err_Ok;        break;      case AFM_TOKEN_UNKNOWN:        break;      default:        goto Fail;        break;      }    }  Fail:    return PSaux_Err_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 );    return (int)( index1 - index2 );  }  static FT_Error  afm_parse_kern_pairs( AFM_Parser  parser )  {    AFM_FontInfo  fi = parser->FontInfo;    AFM_KernPair  kp;    char*         key;    FT_UInt       len;    int           n = -1;    if ( afm_parser_read_int( parser, &fi->NumKernPair ) )      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 >= 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;          kp->index1 = shared_vals[0].u.i;          kp->index2 = shared_vals[1].u.i;          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 = n + 1;        ft_qsort( fi->KernPairs, fi->NumKernPair,                  sizeof( AFM_KernPairRec ),                  afm_compare_kern_pairs );        return PSaux_Err_Ok;      case AFM_TOKEN_UNKNOWN:        break;      default:        goto Fail;        break;      }    }  Fail:    return PSaux_Err_Syntax_Error;  }  static FT_Error  afm_parse_kern_data( AFM_Parser  parser )  {    FT_Error  error;    char*     key;    FT_UInt   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 PSaux_Err_Ok;      case AFM_TOKEN_UNKNOWN:        break;      default:        goto Fail;        break;      }    }  Fail:    return PSaux_Err_Syntax_Error;  }  static FT_Error  afm_parser_skip_section( AFM_Parser  parser,                           FT_UInt     n,                           AFM_Token   end_section )  {    char*    key;    FT_UInt  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 PSaux_Err_Ok;    }  Fail:    return PSaux_Err_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  = PSaux_Err_Syntax_Error;    char*         key;    FT_UInt       len;    FT_Int        metrics_sets = 0;    if ( !fi )      return PSaux_Err_Invalid_Argument;    key = afm_parser_next_key( parser, 1, &len );    if ( !key || len != 16                              ||         ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )      return PSaux_Err_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 = PSaux_Err_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;          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;        /* fall through since we only support kern data */      case AFM_TOKEN_ENDFONTMETRICS:        return PSaux_Err_Ok;        break;      default:        break;      }    }  Fail:    FT_FREE( fi->TrackKerns );    fi->NumTrackKern = 0;    FT_FREE( fi->KernPairs );    fi->NumKernPair = 0;    fi->IsCIDFont = 0;    return error;  }/* END */

⌨️ 快捷键说明

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