diff -r a501f5ec7b34 -r 0f5961910e27 misc/libfreetype/src/psaux/afmparse.c --- a/misc/libfreetype/src/psaux/afmparse.c Tue Jul 16 11:14:27 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,964 +0,0 @@ -/***************************************************************************/ -/* */ -/* afmparse.c */ -/* */ -/* AFM parser (body). */ -/* */ -/* Copyright 2006, 2007, 2008, 2009, 2010 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 -#include FT_FREETYPE_H -#include FT_INTERNAL_POSTSCRIPT_AUX_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_UInt n ) - { - AFM_Stream stream = parser->stream; - char* str; - FT_UInt 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 = 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 ) && - 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 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_Offset 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; - - case AFM_TOKEN_UNKNOWN: - break; - - default: - goto Fail; - } - } - - 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 ); - - - 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; - - - 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; - } - } - - Fail: - return PSaux_Err_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 PSaux_Err_Ok; - - case AFM_TOKEN_UNKNOWN: - break; - - default: - goto Fail; - } - } - - 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_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 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_Offset 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 = 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; - /* fall through since we only support kern data */ - - case AFM_TOKEN_ENDFONTMETRICS: - return PSaux_Err_Ok; - - default: - break; - } - } - - Fail: - FT_FREE( fi->TrackKerns ); - fi->NumTrackKern = 0; - - FT_FREE( fi->KernPairs ); - fi->NumKernPair = 0; - - fi->IsCIDFont = 0; - - return error; - } - - -/* END */