|
|
|
@ -27,6 +27,16 @@ |
|
|
|
|
#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 |
|
|
|
@ -586,21 +596,38 @@ |
|
|
|
|
static FT_Error |
|
|
|
|
afm_parse_track_kern( AFM_Parser parser ) |
|
|
|
|
{ |
|
|
|
|
AFM_FontInfo fi = parser->FontInfo; |
|
|
|
|
AFM_FontInfo fi = parser->FontInfo; |
|
|
|
|
AFM_Stream stream = parser->stream; |
|
|
|
|
AFM_TrackKern tk; |
|
|
|
|
char* key; |
|
|
|
|
FT_Offset len; |
|
|
|
|
int n = -1; |
|
|
|
|
FT_Int tmp; |
|
|
|
|
|
|
|
|
|
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 ( ( 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 ) |
|
|
|
|
{ |
|
|
|
@ -623,7 +650,10 @@ |
|
|
|
|
n++; |
|
|
|
|
|
|
|
|
|
if ( n >= (int)fi->NumTrackKern ) |
|
|
|
|
goto Fail; |
|
|
|
|
{ |
|
|
|
|
FT_ERROR(( "afm_parse_track_kern: too many track kern data\n" )); |
|
|
|
|
goto Fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
tk = fi->TrackKerns + n; |
|
|
|
|
|
|
|
|
@ -633,7 +663,12 @@ |
|
|
|
|
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; |
|
|
|
@ -646,7 +681,19 @@ |
|
|
|
|
case AFM_TOKEN_ENDTRACKKERN: |
|
|
|
|
case AFM_TOKEN_ENDKERNDATA: |
|
|
|
|
case AFM_TOKEN_ENDFONTMETRICS: |
|
|
|
|
fi->NumTrackKern = (FT_UInt)( n + 1 ); |
|
|
|
|
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: |
|
|
|
@ -690,7 +737,8 @@ |
|
|
|
|
static FT_Error |
|
|
|
|
afm_parse_kern_pairs( AFM_Parser parser ) |
|
|
|
|
{ |
|
|
|
|
AFM_FontInfo fi = parser->FontInfo; |
|
|
|
|
AFM_FontInfo fi = parser->FontInfo; |
|
|
|
|
AFM_Stream stream = parser->stream; |
|
|
|
|
AFM_KernPair kp; |
|
|
|
|
char* key; |
|
|
|
|
FT_Offset len; |
|
|
|
@ -702,9 +750,25 @@ |
|
|
|
|
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 ( ( 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 ) |
|
|
|
|
{ |
|
|
|
@ -734,7 +798,10 @@ |
|
|
|
|
n++; |
|
|
|
|
|
|
|
|
|
if ( n >= (int)fi->NumKernPair ) |
|
|
|
|
{ |
|
|
|
|
FT_ERROR(( "afm_parse_kern_pairs: too many kern pairs\n" )); |
|
|
|
|
goto Fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
kp = fi->KernPairs + n; |
|
|
|
|
|
|
|
|
@ -744,7 +811,12 @@ |
|
|
|
|
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; |
|
|
|
@ -766,7 +838,20 @@ |
|
|
|
|
case AFM_TOKEN_ENDKERNPAIRS: |
|
|
|
|
case AFM_TOKEN_ENDKERNDATA: |
|
|
|
|
case AFM_TOKEN_ENDFONTMETRICS: |
|
|
|
|
fi->NumKernPair = (FT_UInt)( n + 1 ); |
|
|
|
|
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 ); |
|
|
|
@ -792,22 +877,43 @@ |
|
|
|
|
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: |
|
|
|
|