00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <ft2build.h>
00019 #include FT_FREETYPE_H
00020 #include FT_INTERNAL_POSTSCRIPT_AUX_H
00021
00022 #include "afmparse.h"
00023 #include "psconv.h"
00024
00025 #include "psauxerr.h"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 enum
00037 {
00038 AFM_STREAM_STATUS_NORMAL,
00039 AFM_STREAM_STATUS_EOC,
00040 AFM_STREAM_STATUS_EOL,
00041 AFM_STREAM_STATUS_EOF
00042 };
00043
00044
00045 typedef struct AFM_StreamRec_
00046 {
00047 FT_Byte* cursor;
00048 FT_Byte* base;
00049 FT_Byte* limit;
00050
00051 FT_Int status;
00052
00053 } AFM_StreamRec;
00054
00055
00056 #ifndef EOF
00057 #define EOF -1
00058 #endif
00059
00060
00061
00062 #define AFM_IS_NEWLINE( ch ) ( (ch) == '\r' || (ch) == '\n' )
00063
00064 #define AFM_IS_EOF( ch ) ( (ch) == EOF || (ch) == '\x1a' )
00065 #define AFM_IS_SPACE( ch ) ( (ch) == ' ' || (ch) == '\t' )
00066
00067
00068 #define AFM_IS_SEP( ch ) ( (ch) == ';' )
00069
00070 #define AFM_GETC() \
00071 ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \
00072 : EOF )
00073
00074 #define AFM_STREAM_KEY_BEGIN( stream ) \
00075 (char*)( (stream)->cursor - 1 )
00076
00077 #define AFM_STREAM_KEY_LEN( stream, key ) \
00078 ( (char*)(stream)->cursor - key - 1 )
00079
00080 #define AFM_STATUS_EOC( stream ) \
00081 ( (stream)->status >= AFM_STREAM_STATUS_EOC )
00082
00083 #define AFM_STATUS_EOL( stream ) \
00084 ( (stream)->status >= AFM_STREAM_STATUS_EOL )
00085
00086 #define AFM_STATUS_EOF( stream ) \
00087 ( (stream)->status >= AFM_STREAM_STATUS_EOF )
00088
00089
00090 static int
00091 afm_stream_skip_spaces( AFM_Stream stream )
00092 {
00093 int ch = 0;
00094
00095
00096 if ( AFM_STATUS_EOC( stream ) )
00097 return ';';
00098
00099 while ( 1 )
00100 {
00101 ch = AFM_GETC();
00102 if ( !AFM_IS_SPACE( ch ) )
00103 break;
00104 }
00105
00106 if ( AFM_IS_NEWLINE( ch ) )
00107 stream->status = AFM_STREAM_STATUS_EOL;
00108 else if ( AFM_IS_SEP( ch ) )
00109 stream->status = AFM_STREAM_STATUS_EOC;
00110 else if ( AFM_IS_EOF( ch ) )
00111 stream->status = AFM_STREAM_STATUS_EOF;
00112
00113 return ch;
00114 }
00115
00116
00117
00118 static char*
00119 afm_stream_read_one( AFM_Stream stream )
00120 {
00121 char* str;
00122 int ch;
00123
00124
00125 afm_stream_skip_spaces( stream );
00126 if ( AFM_STATUS_EOC( stream ) )
00127 return NULL;
00128
00129 str = AFM_STREAM_KEY_BEGIN( stream );
00130
00131 while ( 1 )
00132 {
00133 ch = AFM_GETC();
00134 if ( AFM_IS_SPACE( ch ) )
00135 break;
00136 else if ( AFM_IS_NEWLINE( ch ) )
00137 {
00138 stream->status = AFM_STREAM_STATUS_EOL;
00139 break;
00140 }
00141 else if ( AFM_IS_SEP( ch ) )
00142 {
00143 stream->status = AFM_STREAM_STATUS_EOC;
00144 break;
00145 }
00146 else if ( AFM_IS_EOF( ch ) )
00147 {
00148 stream->status = AFM_STREAM_STATUS_EOF;
00149 break;
00150 }
00151 }
00152
00153 return str;
00154 }
00155
00156
00157
00158 static char*
00159 afm_stream_read_string( AFM_Stream stream )
00160 {
00161 char* str;
00162 int ch;
00163
00164
00165 afm_stream_skip_spaces( stream );
00166 if ( AFM_STATUS_EOL( stream ) )
00167 return NULL;
00168
00169 str = AFM_STREAM_KEY_BEGIN( stream );
00170
00171
00172 while ( 1 )
00173 {
00174 ch = AFM_GETC();
00175 if ( AFM_IS_NEWLINE( ch ) )
00176 {
00177 stream->status = AFM_STREAM_STATUS_EOL;
00178 break;
00179 }
00180 else if ( AFM_IS_EOF( ch ) )
00181 {
00182 stream->status = AFM_STREAM_STATUS_EOF;
00183 break;
00184 }
00185 }
00186
00187 return str;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 typedef enum AFM_Token_
00199 {
00200 AFM_TOKEN_ASCENDER,
00201 AFM_TOKEN_AXISLABEL,
00202 AFM_TOKEN_AXISTYPE,
00203 AFM_TOKEN_B,
00204 AFM_TOKEN_BLENDAXISTYPES,
00205 AFM_TOKEN_BLENDDESIGNMAP,
00206 AFM_TOKEN_BLENDDESIGNPOSITIONS,
00207 AFM_TOKEN_C,
00208 AFM_TOKEN_CC,
00209 AFM_TOKEN_CH,
00210 AFM_TOKEN_CAPHEIGHT,
00211 AFM_TOKEN_CHARWIDTH,
00212 AFM_TOKEN_CHARACTERSET,
00213 AFM_TOKEN_CHARACTERS,
00214 AFM_TOKEN_DESCENDER,
00215 AFM_TOKEN_ENCODINGSCHEME,
00216 AFM_TOKEN_ENDAXIS,
00217 AFM_TOKEN_ENDCHARMETRICS,
00218 AFM_TOKEN_ENDCOMPOSITES,
00219 AFM_TOKEN_ENDDIRECTION,
00220 AFM_TOKEN_ENDFONTMETRICS,
00221 AFM_TOKEN_ENDKERNDATA,
00222 AFM_TOKEN_ENDKERNPAIRS,
00223 AFM_TOKEN_ENDTRACKKERN,
00224 AFM_TOKEN_ESCCHAR,
00225 AFM_TOKEN_FAMILYNAME,
00226 AFM_TOKEN_FONTBBOX,
00227 AFM_TOKEN_FONTNAME,
00228 AFM_TOKEN_FULLNAME,
00229 AFM_TOKEN_ISBASEFONT,
00230 AFM_TOKEN_ISCIDFONT,
00231 AFM_TOKEN_ISFIXEDPITCH,
00232 AFM_TOKEN_ISFIXEDV,
00233 AFM_TOKEN_ITALICANGLE,
00234 AFM_TOKEN_KP,
00235 AFM_TOKEN_KPH,
00236 AFM_TOKEN_KPX,
00237 AFM_TOKEN_KPY,
00238 AFM_TOKEN_L,
00239 AFM_TOKEN_MAPPINGSCHEME,
00240 AFM_TOKEN_METRICSSETS,
00241 AFM_TOKEN_N,
00242 AFM_TOKEN_NOTICE,
00243 AFM_TOKEN_PCC,
00244 AFM_TOKEN_STARTAXIS,
00245 AFM_TOKEN_STARTCHARMETRICS,
00246 AFM_TOKEN_STARTCOMPOSITES,
00247 AFM_TOKEN_STARTDIRECTION,
00248 AFM_TOKEN_STARTFONTMETRICS,
00249 AFM_TOKEN_STARTKERNDATA,
00250 AFM_TOKEN_STARTKERNPAIRS,
00251 AFM_TOKEN_STARTKERNPAIRS0,
00252 AFM_TOKEN_STARTKERNPAIRS1,
00253 AFM_TOKEN_STARTTRACKKERN,
00254 AFM_TOKEN_STDHW,
00255 AFM_TOKEN_STDVW,
00256 AFM_TOKEN_TRACKKERN,
00257 AFM_TOKEN_UNDERLINEPOSITION,
00258 AFM_TOKEN_UNDERLINETHICKNESS,
00259 AFM_TOKEN_VV,
00260 AFM_TOKEN_VVECTOR,
00261 AFM_TOKEN_VERSION,
00262 AFM_TOKEN_W,
00263 AFM_TOKEN_W0,
00264 AFM_TOKEN_W0X,
00265 AFM_TOKEN_W0Y,
00266 AFM_TOKEN_W1,
00267 AFM_TOKEN_W1X,
00268 AFM_TOKEN_W1Y,
00269 AFM_TOKEN_WX,
00270 AFM_TOKEN_WY,
00271 AFM_TOKEN_WEIGHT,
00272 AFM_TOKEN_WEIGHTVECTOR,
00273 AFM_TOKEN_XHEIGHT,
00274 N_AFM_TOKENS,
00275 AFM_TOKEN_UNKNOWN
00276
00277 } AFM_Token;
00278
00279
00280 static const char* const afm_key_table[N_AFM_TOKENS] =
00281 {
00282 "Ascender",
00283 "AxisLabel",
00284 "AxisType",
00285 "B",
00286 "BlendAxisTypes",
00287 "BlendDesignMap",
00288 "BlendDesignPositions",
00289 "C",
00290 "CC",
00291 "CH",
00292 "CapHeight",
00293 "CharWidth",
00294 "CharacterSet",
00295 "Characters",
00296 "Descender",
00297 "EncodingScheme",
00298 "EndAxis",
00299 "EndCharMetrics",
00300 "EndComposites",
00301 "EndDirection",
00302 "EndFontMetrics",
00303 "EndKernData",
00304 "EndKernPairs",
00305 "EndTrackKern",
00306 "EscChar",
00307 "FamilyName",
00308 "FontBBox",
00309 "FontName",
00310 "FullName",
00311 "IsBaseFont",
00312 "IsCIDFont",
00313 "IsFixedPitch",
00314 "IsFixedV",
00315 "ItalicAngle",
00316 "KP",
00317 "KPH",
00318 "KPX",
00319 "KPY",
00320 "L",
00321 "MappingScheme",
00322 "MetricsSets",
00323 "N",
00324 "Notice",
00325 "PCC",
00326 "StartAxis",
00327 "StartCharMetrics",
00328 "StartComposites",
00329 "StartDirection",
00330 "StartFontMetrics",
00331 "StartKernData",
00332 "StartKernPairs",
00333 "StartKernPairs0",
00334 "StartKernPairs1",
00335 "StartTrackKern",
00336 "StdHW",
00337 "StdVW",
00338 "TrackKern",
00339 "UnderlinePosition",
00340 "UnderlineThickness",
00341 "VV",
00342 "VVector",
00343 "Version",
00344 "W",
00345 "W0",
00346 "W0X",
00347 "W0Y",
00348 "W1",
00349 "W1X",
00350 "W1Y",
00351 "WX",
00352 "WY",
00353 "Weight",
00354 "WeightVector",
00355 "XHeight"
00356 };
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 FT_LOCAL_DEF( FT_Int )
00367 afm_parser_read_vals( AFM_Parser parser,
00368 AFM_Value vals,
00369 FT_UInt n )
00370 {
00371 AFM_Stream stream = parser->stream;
00372 char* str;
00373 FT_UInt i;
00374
00375
00376 if ( n > AFM_MAX_ARGUMENTS )
00377 return 0;
00378
00379 for ( i = 0; i < n; i++ )
00380 {
00381 FT_Offset len;
00382 AFM_Value val = vals + i;
00383
00384
00385 if ( val->type == AFM_VALUE_TYPE_STRING )
00386 str = afm_stream_read_string( stream );
00387 else
00388 str = afm_stream_read_one( stream );
00389
00390 if ( !str )
00391 break;
00392
00393 len = AFM_STREAM_KEY_LEN( stream, str );
00394
00395 switch ( val->type )
00396 {
00397 case AFM_VALUE_TYPE_STRING:
00398 case AFM_VALUE_TYPE_NAME:
00399 {
00400 FT_Memory memory = parser->memory;
00401 FT_Error error;
00402
00403
00404 if ( !FT_QALLOC( val->u.s, len + 1 ) )
00405 {
00406 ft_memcpy( val->u.s, str, len );
00407 val->u.s[len] = '\0';
00408 }
00409 }
00410 break;
00411
00412 case AFM_VALUE_TYPE_FIXED:
00413 val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str,
00414 (FT_Byte*)str + len, 0 );
00415 break;
00416
00417 case AFM_VALUE_TYPE_INTEGER:
00418 val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str,
00419 (FT_Byte*)str + len );
00420 break;
00421
00422 case AFM_VALUE_TYPE_BOOL:
00423 val->u.b = FT_BOOL( len == 4 &&
00424 !ft_strncmp( str, "true", 4 ) );
00425 break;
00426
00427 case AFM_VALUE_TYPE_INDEX:
00428 if ( parser->get_index )
00429 val->u.i = parser->get_index( str, len, parser->user_data );
00430 else
00431 val->u.i = 0;
00432 break;
00433 }
00434 }
00435
00436 return i;
00437 }
00438
00439
00440 FT_LOCAL_DEF( char* )
00441 afm_parser_next_key( AFM_Parser parser,
00442 FT_Bool line,
00443 FT_Offset* len )
00444 {
00445 AFM_Stream stream = parser->stream;
00446 char* key = 0;
00447
00448
00449 if ( line )
00450 {
00451 while ( 1 )
00452 {
00453
00454 if ( !AFM_STATUS_EOL( stream ) )
00455 afm_stream_read_string( stream );
00456
00457 stream->status = AFM_STREAM_STATUS_NORMAL;
00458 key = afm_stream_read_one( stream );
00459
00460
00461 if ( !key &&
00462 !AFM_STATUS_EOF( stream ) &&
00463 AFM_STATUS_EOL( stream ) )
00464 continue;
00465
00466 break;
00467 }
00468 }
00469 else
00470 {
00471 while ( 1 )
00472 {
00473
00474 while ( !AFM_STATUS_EOC( stream ) )
00475 afm_stream_read_one( stream );
00476
00477 stream->status = AFM_STREAM_STATUS_NORMAL;
00478 key = afm_stream_read_one( stream );
00479
00480
00481 if ( !key &&
00482 !AFM_STATUS_EOF( stream ) &&
00483 AFM_STATUS_EOC( stream ) )
00484 continue;
00485
00486 break;
00487 }
00488 }
00489
00490 if ( len )
00491 *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )
00492 : 0;
00493
00494 return key;
00495 }
00496
00497
00498 static AFM_Token
00499 afm_tokenize( const char* key,
00500 FT_Offset len )
00501 {
00502 int n;
00503
00504
00505 for ( n = 0; n < N_AFM_TOKENS; n++ )
00506 {
00507 if ( *( afm_key_table[n] ) == *key )
00508 {
00509 for ( ; n < N_AFM_TOKENS; n++ )
00510 {
00511 if ( *( afm_key_table[n] ) != *key )
00512 return AFM_TOKEN_UNKNOWN;
00513
00514 if ( ft_strncmp( afm_key_table[n], key, len ) == 0 )
00515 return (AFM_Token) n;
00516 }
00517 }
00518 }
00519
00520 return AFM_TOKEN_UNKNOWN;
00521 }
00522
00523
00524 FT_LOCAL_DEF( FT_Error )
00525 afm_parser_init( AFM_Parser parser,
00526 FT_Memory memory,
00527 FT_Byte* base,
00528 FT_Byte* limit )
00529 {
00530 AFM_Stream stream;
00531 FT_Error error;
00532
00533
00534 if ( FT_NEW( stream ) )
00535 return error;
00536
00537 stream->cursor = stream->base = base;
00538 stream->limit = limit;
00539
00540
00541 stream->status = AFM_STREAM_STATUS_EOL;
00542
00543 parser->memory = memory;
00544 parser->stream = stream;
00545 parser->FontInfo = NULL;
00546 parser->get_index = NULL;
00547
00548 return PSaux_Err_Ok;
00549 }
00550
00551
00552 FT_LOCAL( void )
00553 afm_parser_done( AFM_Parser parser )
00554 {
00555 FT_Memory memory = parser->memory;
00556
00557
00558 FT_FREE( parser->stream );
00559 }
00560
00561
00562 FT_LOCAL_DEF( FT_Error )
00563 afm_parser_read_int( AFM_Parser parser,
00564 FT_Int* aint )
00565 {
00566 AFM_ValueRec val;
00567
00568
00569 val.type = AFM_VALUE_TYPE_INTEGER;
00570
00571 if ( afm_parser_read_vals( parser, &val, 1 ) == 1 )
00572 {
00573 *aint = val.u.i;
00574
00575 return PSaux_Err_Ok;
00576 }
00577 else
00578 return PSaux_Err_Syntax_Error;
00579 }
00580
00581
00582 static FT_Error
00583 afm_parse_track_kern( AFM_Parser parser )
00584 {
00585 AFM_FontInfo fi = parser->FontInfo;
00586 AFM_TrackKern tk;
00587 char* key;
00588 FT_Offset len;
00589 int n = -1;
00590
00591
00592 if ( afm_parser_read_int( parser, &fi->NumTrackKern ) )
00593 goto Fail;
00594
00595 if ( fi->NumTrackKern )
00596 {
00597 FT_Memory memory = parser->memory;
00598 FT_Error error;
00599
00600
00601 if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) )
00602 return error;
00603 }
00604
00605 while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
00606 {
00607 AFM_ValueRec shared_vals[5];
00608
00609
00610 switch ( afm_tokenize( key, len ) )
00611 {
00612 case AFM_TOKEN_TRACKKERN:
00613 n++;
00614
00615 if ( n >= fi->NumTrackKern )
00616 goto Fail;
00617
00618 tk = fi->TrackKerns + n;
00619
00620 shared_vals[0].type = AFM_VALUE_TYPE_INTEGER;
00621 shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
00622 shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
00623 shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
00624 shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
00625 if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
00626 goto Fail;
00627
00628 tk->degree = shared_vals[0].u.i;
00629 tk->min_ptsize = shared_vals[1].u.f;
00630 tk->min_kern = shared_vals[2].u.f;
00631 tk->max_ptsize = shared_vals[3].u.f;
00632 tk->max_kern = shared_vals[4].u.f;
00633
00634
00635 if ( tk->degree < 0 && tk->min_kern > 0 )
00636 tk->min_kern = -tk->min_kern;
00637 break;
00638
00639 case AFM_TOKEN_ENDTRACKKERN:
00640 case AFM_TOKEN_ENDKERNDATA:
00641 case AFM_TOKEN_ENDFONTMETRICS:
00642 fi->NumTrackKern = n + 1;
00643 return PSaux_Err_Ok;
00644
00645 case AFM_TOKEN_UNKNOWN:
00646 break;
00647
00648 default:
00649 goto Fail;
00650 }
00651 }
00652
00653 Fail:
00654 return PSaux_Err_Syntax_Error;
00655 }
00656
00657
00658 #undef KERN_INDEX
00659 #define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 )
00660
00661
00662
00663 FT_CALLBACK_DEF( int )
00664 afm_compare_kern_pairs( const void* a,
00665 const void* b )
00666 {
00667 AFM_KernPair kp1 = (AFM_KernPair)a;
00668 AFM_KernPair kp2 = (AFM_KernPair)b;
00669
00670 FT_ULong index1 = KERN_INDEX( kp1->index1, kp1->index2 );
00671 FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 );
00672
00673
00674 if ( index1 > index2 )
00675 return 1;
00676 else if ( index1 < index2 )
00677 return -1;
00678 else
00679 return 0;
00680 }
00681
00682
00683 static FT_Error
00684 afm_parse_kern_pairs( AFM_Parser parser )
00685 {
00686 AFM_FontInfo fi = parser->FontInfo;
00687 AFM_KernPair kp;
00688 char* key;
00689 FT_Offset len;
00690 int n = -1;
00691
00692
00693 if ( afm_parser_read_int( parser, &fi->NumKernPair ) )
00694 goto Fail;
00695
00696 if ( fi->NumKernPair )
00697 {
00698 FT_Memory memory = parser->memory;
00699 FT_Error error;
00700
00701
00702 if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )
00703 return error;
00704 }
00705
00706 while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
00707 {
00708 AFM_Token token = afm_tokenize( key, len );
00709
00710
00711 switch ( token )
00712 {
00713 case AFM_TOKEN_KP:
00714 case AFM_TOKEN_KPX:
00715 case AFM_TOKEN_KPY:
00716 {
00717 FT_Int r;
00718 AFM_ValueRec shared_vals[4];
00719
00720
00721 n++;
00722
00723 if ( n >= fi->NumKernPair )
00724 goto Fail;
00725
00726 kp = fi->KernPairs + n;
00727
00728 shared_vals[0].type = AFM_VALUE_TYPE_INDEX;
00729 shared_vals[1].type = AFM_VALUE_TYPE_INDEX;
00730 shared_vals[2].type = AFM_VALUE_TYPE_INTEGER;
00731 shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
00732 r = afm_parser_read_vals( parser, shared_vals, 4 );
00733 if ( r < 3 )
00734 goto Fail;
00735
00736 kp->index1 = shared_vals[0].u.i;
00737 kp->index2 = shared_vals[1].u.i;
00738 if ( token == AFM_TOKEN_KPY )
00739 {
00740 kp->x = 0;
00741 kp->y = shared_vals[2].u.i;
00742 }
00743 else
00744 {
00745 kp->x = shared_vals[2].u.i;
00746 kp->y = ( token == AFM_TOKEN_KP && r == 4 )
00747 ? shared_vals[3].u.i : 0;
00748 }
00749 }
00750 break;
00751
00752 case AFM_TOKEN_ENDKERNPAIRS:
00753 case AFM_TOKEN_ENDKERNDATA:
00754 case AFM_TOKEN_ENDFONTMETRICS:
00755 fi->NumKernPair = n + 1;
00756 ft_qsort( fi->KernPairs, fi->NumKernPair,
00757 sizeof( AFM_KernPairRec ),
00758 afm_compare_kern_pairs );
00759 return PSaux_Err_Ok;
00760
00761 case AFM_TOKEN_UNKNOWN:
00762 break;
00763
00764 default:
00765 goto Fail;
00766 }
00767 }
00768
00769 Fail:
00770 return PSaux_Err_Syntax_Error;
00771 }
00772
00773
00774 static FT_Error
00775 afm_parse_kern_data( AFM_Parser parser )
00776 {
00777 FT_Error error;
00778 char* key;
00779 FT_Offset len;
00780
00781
00782 while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
00783 {
00784 switch ( afm_tokenize( key, len ) )
00785 {
00786 case AFM_TOKEN_STARTTRACKKERN:
00787 error = afm_parse_track_kern( parser );
00788 if ( error )
00789 return error;
00790 break;
00791
00792 case AFM_TOKEN_STARTKERNPAIRS:
00793 case AFM_TOKEN_STARTKERNPAIRS0:
00794 error = afm_parse_kern_pairs( parser );
00795 if ( error )
00796 return error;
00797 break;
00798
00799 case AFM_TOKEN_ENDKERNDATA:
00800 case AFM_TOKEN_ENDFONTMETRICS:
00801 return PSaux_Err_Ok;
00802
00803 case AFM_TOKEN_UNKNOWN:
00804 break;
00805
00806 default:
00807 goto Fail;
00808 }
00809 }
00810
00811 Fail:
00812 return PSaux_Err_Syntax_Error;
00813 }
00814
00815
00816 static FT_Error
00817 afm_parser_skip_section( AFM_Parser parser,
00818 FT_UInt n,
00819 AFM_Token end_section )
00820 {
00821 char* key;
00822 FT_Offset len;
00823
00824
00825 while ( n-- > 0 )
00826 {
00827 key = afm_parser_next_key( parser, 1, NULL );
00828 if ( !key )
00829 goto Fail;
00830 }
00831
00832 while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
00833 {
00834 AFM_Token token = afm_tokenize( key, len );
00835
00836
00837 if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS )
00838 return PSaux_Err_Ok;
00839 }
00840
00841 Fail:
00842 return PSaux_Err_Syntax_Error;
00843 }
00844
00845
00846 FT_LOCAL_DEF( FT_Error )
00847 afm_parser_parse( AFM_Parser parser )
00848 {
00849 FT_Memory memory = parser->memory;
00850 AFM_FontInfo fi = parser->FontInfo;
00851 FT_Error error = PSaux_Err_Syntax_Error;
00852 char* key;
00853 FT_Offset len;
00854 FT_Int metrics_sets = 0;
00855
00856
00857 if ( !fi )
00858 return PSaux_Err_Invalid_Argument;
00859
00860 key = afm_parser_next_key( parser, 1, &len );
00861 if ( !key || len != 16 ||
00862 ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )
00863 return PSaux_Err_Unknown_File_Format;
00864
00865 while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
00866 {
00867 AFM_ValueRec shared_vals[4];
00868
00869
00870 switch ( afm_tokenize( key, len ) )
00871 {
00872 case AFM_TOKEN_METRICSSETS:
00873 if ( afm_parser_read_int( parser, &metrics_sets ) )
00874 goto Fail;
00875
00876 if ( metrics_sets != 0 && metrics_sets != 2 )
00877 {
00878 error = PSaux_Err_Unimplemented_Feature;
00879
00880 goto Fail;
00881 }
00882 break;
00883
00884 case AFM_TOKEN_ISCIDFONT:
00885 shared_vals[0].type = AFM_VALUE_TYPE_BOOL;
00886 if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
00887 goto Fail;
00888
00889 fi->IsCIDFont = shared_vals[0].u.b;
00890 break;
00891
00892 case AFM_TOKEN_FONTBBOX:
00893 shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
00894 shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
00895 shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
00896 shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
00897 if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 )
00898 goto Fail;
00899
00900 fi->FontBBox.xMin = shared_vals[0].u.f;
00901 fi->FontBBox.yMin = shared_vals[1].u.f;
00902 fi->FontBBox.xMax = shared_vals[2].u.f;
00903 fi->FontBBox.yMax = shared_vals[3].u.f;
00904 break;
00905
00906 case AFM_TOKEN_ASCENDER:
00907 shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
00908 if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
00909 goto Fail;
00910
00911 fi->Ascender = shared_vals[0].u.f;
00912 break;
00913
00914 case AFM_TOKEN_DESCENDER:
00915 shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
00916 if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
00917 goto Fail;
00918
00919 fi->Descender = shared_vals[0].u.f;
00920 break;
00921
00922 case AFM_TOKEN_STARTCHARMETRICS:
00923 {
00924 FT_Int n = 0;
00925
00926
00927 if ( afm_parser_read_int( parser, &n ) )
00928 goto Fail;
00929
00930 error = afm_parser_skip_section( parser, n,
00931 AFM_TOKEN_ENDCHARMETRICS );
00932 if ( error )
00933 return error;
00934 }
00935 break;
00936
00937 case AFM_TOKEN_STARTKERNDATA:
00938 error = afm_parse_kern_data( parser );
00939 if ( error )
00940 goto Fail;
00941
00942
00943 case AFM_TOKEN_ENDFONTMETRICS:
00944 return PSaux_Err_Ok;
00945
00946 default:
00947 break;
00948 }
00949 }
00950
00951 Fail:
00952 FT_FREE( fi->TrackKerns );
00953 fi->NumTrackKern = 0;
00954
00955 FT_FREE( fi->KernPairs );
00956 fi->NumKernPair = 0;
00957
00958 fi->IsCIDFont = 0;
00959
00960 return error;
00961 }
00962
00963
00964