From 27a4f9c4ac45ff65f941964f7351b64b1e6a9f35 Mon Sep 17 00:00:00 2001 From: scuri Date: Tue, 20 Oct 2009 17:20:18 +0000 Subject: *** empty log message *** --- src/freetype2/psaux/afmparse.c | 38 +++-- src/freetype2/psaux/afmparse.h | 4 +- src/freetype2/psaux/psauxmod.h | 4 + src/freetype2/psaux/psconv.c | 22 ++- src/freetype2/psaux/psconv.h | 6 +- src/freetype2/psaux/psobjs.c | 89 +++++----- src/freetype2/psaux/psobjs.h | 2 +- src/freetype2/psaux/t1cmap.c | 26 ++- src/freetype2/psaux/t1decode.c | 365 ++++++++++++++++++++++++++--------------- 9 files changed, 343 insertions(+), 213 deletions(-) (limited to 'src/freetype2/psaux') diff --git a/src/freetype2/psaux/afmparse.c b/src/freetype2/psaux/afmparse.c index 0528fe6..91a17e2 100644 --- a/src/freetype2/psaux/afmparse.c +++ b/src/freetype2/psaux/afmparse.c @@ -4,7 +4,7 @@ /* */ /* AFM parser (body). */ /* */ -/* Copyright 2006, 2007 by */ +/* Copyright 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,7 +18,6 @@ #include #include FT_FREETYPE_H #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "afmparse.h" #include "psconv.h" @@ -367,11 +366,11 @@ FT_LOCAL_DEF( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ) + FT_UInt n ) { AFM_Stream stream = parser->stream; char* str; - FT_Int i; + FT_UInt i; if ( n > AFM_MAX_ARGUMENTS ) @@ -379,7 +378,7 @@ for ( i = 0; i < n; i++ ) { - FT_UInt len; + FT_Offset len; AFM_Value val = vals + i; @@ -441,7 +440,7 @@ FT_LOCAL_DEF( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ) + FT_Offset* len ) { AFM_Stream stream = parser->stream; char* key = 0; /* make stupid compiler happy */ @@ -489,7 +488,7 @@ } if ( len ) - *len = ( key ) ? AFM_STREAM_KEY_LEN( stream, key ) + *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key ) : 0; return key; @@ -498,7 +497,7 @@ static AFM_Token afm_tokenize( const char* key, - FT_UInt len ) + FT_Offset len ) { int n; @@ -586,7 +585,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_TrackKern tk; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -672,7 +671,12 @@ FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 ); - return (int)( index1 - index2 ); + if ( index1 > index2 ) + return 1; + else if ( index1 < index2 ) + return -1; + else + return 0; } @@ -682,7 +686,7 @@ AFM_FontInfo fi = parser->FontInfo; AFM_KernPair kp; char* key; - FT_UInt len; + FT_Offset len; int n = -1; @@ -770,9 +774,9 @@ static FT_Error afm_parse_kern_data( AFM_Parser parser ) { - FT_Error error; - char* key; - FT_UInt len; + FT_Error error; + char* key; + FT_Offset len; while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 ) @@ -814,8 +818,8 @@ FT_UInt n, AFM_Token end_section ) { - char* key; - FT_UInt len; + char* key; + FT_Offset len; while ( n-- > 0 ) @@ -846,7 +850,7 @@ AFM_FontInfo fi = parser->FontInfo; FT_Error error = PSaux_Err_Syntax_Error; char* key; - FT_UInt len; + FT_Offset len; FT_Int metrics_sets = 0; diff --git a/src/freetype2/psaux/afmparse.h b/src/freetype2/psaux/afmparse.h index c2fce75..de2a530 100644 --- a/src/freetype2/psaux/afmparse.h +++ b/src/freetype2/psaux/afmparse.h @@ -71,13 +71,13 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Int ) afm_parser_read_vals( AFM_Parser parser, AFM_Value vals, - FT_Int n ); + FT_UInt n ); /* read the next key from the next line or column */ FT_LOCAL( char* ) afm_parser_next_key( AFM_Parser parser, FT_Bool line, - FT_UInt* len ); + FT_Offset* len ); FT_END_HEADER diff --git a/src/freetype2/psaux/psauxmod.h b/src/freetype2/psaux/psauxmod.h index 92ac056..35e042d 100644 --- a/src/freetype2/psaux/psauxmod.h +++ b/src/freetype2/psaux/psauxmod.h @@ -26,6 +26,10 @@ FT_BEGIN_HEADER +#ifdef FT_CONFIG_OPTION_PIC +#error "this module does not support PIC yet" +#endif + FT_EXPORT_VAR( const FT_Module_Class ) psaux_driver_class; diff --git a/src/freetype2/psaux/psconv.c b/src/freetype2/psaux/psconv.c index 3bbeab6..1531d8f 100644 --- a/src/freetype2/psaux/psconv.c +++ b/src/freetype2/psaux/psconv.c @@ -4,7 +4,7 @@ /* */ /* Some convenience conversions (body). */ /* */ -/* Copyright 2006 by */ +/* Copyright 2006, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -18,10 +18,8 @@ #include #include FT_INTERNAL_POSTSCRIPT_AUX_H -#include FT_INTERNAL_DEBUG_H #include "psconv.h" -#include "psobjs.h" #include "psauxerr.h" @@ -187,10 +185,18 @@ if ( c < 0 || c >= 10 ) break; - if ( divider < 10000000L ) + if ( !integral && power_ten > 0 ) { + power_ten--; decimal = decimal * 10 + c; - divider *= 10; + } + else + { + if ( divider < 10000000L ) + { + decimal = decimal * 10 + c; + divider *= 10; + } } } } @@ -233,7 +239,7 @@ PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -328,7 +334,7 @@ PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ) + FT_Offset n ) { FT_Byte* p; FT_UInt r = 0; @@ -417,7 +423,7 @@ PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ) { FT_Byte* p; diff --git a/src/freetype2/psaux/psconv.h b/src/freetype2/psaux/psconv.h index e511241..84854ba 100644 --- a/src/freetype2/psaux/psconv.h +++ b/src/freetype2/psaux/psconv.h @@ -46,20 +46,20 @@ FT_BEGIN_HEADER PS_Conv_StringDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); #endif FT_LOCAL( FT_UInt ) PS_Conv_ASCIIHexDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n ); + FT_Offset n ); FT_LOCAL( FT_UInt ) PS_Conv_EexecDecode( FT_Byte** cursor, FT_Byte* limit, FT_Byte* buffer, - FT_UInt n, + FT_Offset n, FT_UShort* seed ); diff --git a/src/freetype2/psaux/psobjs.c b/src/freetype2/psaux/psobjs.c index 9570856..fe8398a 100644 --- a/src/freetype2/psaux/psobjs.c +++ b/src/freetype2/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -19,6 +19,7 @@ #include #include FT_INTERNAL_POSTSCRIPT_AUX_H #include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_CALC_H #include "psobjs.h" #include "psconv.h" @@ -169,17 +170,23 @@ void* object, FT_PtrDist length ) { - if ( idx < 0 || idx > table->max_elems ) + if ( idx < 0 || idx >= table->max_elems ) { FT_ERROR(( "ps_table_add: invalid index\n" )); return PSaux_Err_Invalid_Argument; } + if ( length < 0 ) + { + FT_ERROR(( "ps_table_add: invalid length\n" )); + return PSaux_Err_Invalid_Argument; + } + /* grow the base block if needed */ if ( table->cursor + length > table->capacity ) { FT_Error error; - FT_Offset new_size = table->capacity; + FT_Offset new_size = table->capacity; FT_Long in_offset; @@ -376,7 +383,7 @@ /* skip octal escape or ignore backslash */ for ( i = 0; i < 3 && cur < limit; ++i ) { - if ( ! IS_OCTAL_DIGIT( *cur ) ) + if ( !IS_OCTAL_DIGIT( *cur ) ) break; ++cur; @@ -558,8 +565,8 @@ cur++; if ( cur >= limit || *cur != '>' ) /* >> */ { - FT_ERROR(( "ps_parser_skip_PS_token: " - "unexpected closing delimiter `>'\n" )); + FT_ERROR(( "ps_parser_skip_PS_token:" + " unexpected closing delimiter `>'\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -584,9 +591,10 @@ Exit: if ( cur == parser->cursor ) { - FT_ERROR(( "ps_parser_skip_PS_token: " - "current token is `%c', which is self-delimiting " - "but invalid at this point\n", + FT_ERROR(( "ps_parser_skip_PS_token:" + " current token is `%c' which is self-delimiting\n" + " " + " but invalid at this point\n", *cur )); error = PSaux_Err_Invalid_File_Format; @@ -1147,8 +1155,10 @@ } else { - FT_ERROR(( "ps_parser_load_field: expected a name or string " - "but found token of type %d instead\n", + FT_ERROR(( "ps_parser_load_field:" + " expected a name or string\n" + " " + " but found token of type %d instead\n", token.type )); error = PSaux_Err_Invalid_File_Format; goto Exit; @@ -1185,8 +1195,8 @@ if ( result < 0 ) { - FT_ERROR(( "ps_parser_load_field: " - "expected four integers in bounding box\n" )); + FT_ERROR(( "ps_parser_load_field:" + " expected four integers in bounding box\n" )); error = PSaux_Err_Invalid_File_Format; goto Exit; } @@ -1259,8 +1269,9 @@ old_cursor = parser->cursor; old_limit = parser->limit; - /* we store the elements count if necessary */ - if ( field->type != T1_FIELD_TYPE_BBOX ) + /* we store the elements count if necessary; */ + /* we further assume that `count_offset' can't be zero */ + if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 ) *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) = (FT_Byte)num_elements; @@ -1302,7 +1313,7 @@ FT_LOCAL_DEF( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ) { @@ -1483,12 +1494,6 @@ builder->hints_funcs = glyph->internal->glyph_hints; } - if ( size ) - { - builder->scale_x = size->metrics.x_scale; - builder->scale_y = size->metrics.y_scale; - } - builder->pos_x = 0; builder->pos_y = 0; @@ -1550,16 +1555,9 @@ FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points; - if ( builder->shift ) - { - x >>= 16; - y >>= 16; - } - point->x = x; - point->y = y; + point->x = FIXED_TO_INT( x ); + point->y = FIXED_TO_INT( y ); *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC ); - - builder->last = *point; } outline->n_points++; } @@ -1640,27 +1638,24 @@ t1_builder_close_contour( T1_Builder builder ) { FT_Outline* outline = builder->current; + FT_Int first; if ( !outline ) return; - /* XXXX: We must not include the last point in the path if it */ - /* is located on the first point. */ + first = outline->n_contours <= 1 + ? 0 : outline->contours[outline->n_contours - 2] + 1; + + /* We must not include the last point in the path if it */ + /* is located on the first point. */ if ( outline->n_points > 1 ) { - FT_Int first = 0; FT_Vector* p1 = outline->points + first; FT_Vector* p2 = outline->points + outline->n_points - 1; FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1; - if ( outline->n_contours > 1 ) - { - first = outline->contours[outline->n_contours - 2] + 1; - p1 = outline->points + first; - } - /* `delete' last point only if it coincides with the first */ /* point and it is not a control point (which can happen). */ if ( p1->x == p2->x && p1->y == p2->y ) @@ -1669,8 +1664,18 @@ } if ( outline->n_contours > 0 ) - outline->contours[outline->n_contours - 1] = - (short)( outline->n_points - 1 ); + { + /* Don't add contours only consisting of one point, i.e., */ + /* check whether the first and the last point is the same. */ + if ( first == outline->n_points - 1 ) + { + outline->n_contours--; + outline->n_points--; + } + else + outline->contours[outline->n_contours - 1] = + (short)( outline->n_points - 1 ); + } } diff --git a/src/freetype2/psaux/psobjs.h b/src/freetype2/psaux/psobjs.h index c2cbf2c..e380c60 100644 --- a/src/freetype2/psaux/psobjs.h +++ b/src/freetype2/psaux/psobjs.h @@ -111,7 +111,7 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) ps_parser_to_bytes( PS_Parser parser, FT_Byte* bytes, - FT_Long max_bytes, + FT_Offset max_bytes, FT_Long* pnum_bytes, FT_Bool delimiters ); diff --git a/src/freetype2/psaux/t1cmap.c b/src/freetype2/psaux/t1cmap.c index 2934686..f933e4d 100644 --- a/src/freetype2/psaux/t1cmap.c +++ b/src/freetype2/psaux/t1cmap.c @@ -4,7 +4,7 @@ /* */ /* Type 1 character map support (body). */ /* */ -/* Copyright 2002, 2003, 2006 by */ +/* Copyright 2002, 2003, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -95,7 +95,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_std_char_next( T1_CMapStd cmap, FT_UInt32 *pchar_code ) { @@ -135,7 +135,9 @@ (FT_CMap_InitFunc) t1_cmap_standard_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -154,7 +156,9 @@ (FT_CMap_InitFunc) t1_cmap_expert_init, (FT_CMap_DoneFunc) t1_cmap_std_done, (FT_CMap_CharIndexFunc)t1_cmap_std_char_index, - (FT_CMap_CharNextFunc) t1_cmap_std_char_next + (FT_CMap_CharNextFunc) t1_cmap_std_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -175,7 +179,7 @@ cmap->first = encoding->code_first; - cmap->count = (FT_UInt)( encoding->code_last - cmap->first + 1 ); + cmap->count = (FT_UInt)( encoding->code_last - cmap->first ); cmap->indices = encoding->char_index; FT_ASSERT( cmap->indices != NULL ); @@ -209,7 +213,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_custom_char_next( T1_CMapCustom cmap, FT_UInt32 *pchar_code ) { @@ -245,7 +249,9 @@ (FT_CMap_InitFunc) t1_cmap_custom_init, (FT_CMap_DoneFunc) t1_cmap_custom_done, (FT_CMap_CharIndexFunc)t1_cmap_custom_char_index, - (FT_CMap_CharNextFunc) t1_cmap_custom_char_next + (FT_CMap_CharNextFunc) t1_cmap_custom_char_next, + + NULL, NULL, NULL, NULL, NULL }; @@ -306,7 +312,7 @@ } - FT_CALLBACK_DEF( FT_UInt ) + FT_CALLBACK_DEF( FT_UInt32 ) t1_cmap_unicode_char_next( PS_Unicodes unicodes, FT_UInt32 *pchar_code ) { @@ -326,7 +332,9 @@ (FT_CMap_InitFunc) t1_cmap_unicode_init, (FT_CMap_DoneFunc) t1_cmap_unicode_done, (FT_CMap_CharIndexFunc)t1_cmap_unicode_char_index, - (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next + (FT_CMap_CharNextFunc) t1_cmap_unicode_char_next, + + NULL, NULL, NULL, NULL, NULL }; diff --git a/src/freetype2/psaux/t1decode.c b/src/freetype2/psaux/t1decode.c index f790643..b3245a6 100644 --- a/src/freetype2/psaux/t1decode.c +++ b/src/freetype2/psaux/t1decode.c @@ -4,7 +4,7 @@ /* */ /* PostScript Type 1 decoding routines (body). */ /* */ -/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ +/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -17,6 +17,7 @@ #include +#include FT_INTERNAL_CALC_H #include FT_INTERNAL_DEBUG_H #include FT_INTERNAL_POSTSCRIPT_HINTS_H #include FT_OUTLINE_H @@ -144,7 +145,8 @@ FT_String* name = (FT_String*)decoder->glyph_names[n]; - if ( name && name[0] == glyph_name[0] && + if ( name && + name[0] == glyph_name[0] && ft_strcmp( name, glyph_name ) == 0 ) return n; } @@ -193,6 +195,16 @@ #endif FT_Vector left_bearing, advance; +#ifdef FT_CONFIG_OPTION_INCREMENTAL + T1_Face face = (T1_Face)decoder->builder.face; +#endif + + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } /* seac weirdness */ adx += decoder->builder.left_bearing.x; @@ -201,18 +213,29 @@ /* include an encoding. How can we deal with these? */ if ( decoder->glyph_names == 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " glyph names table not available in this font!\n" )); + FT_ERROR(( "t1operator_seac:" + " glyph names table not available in this font\n" )); return PSaux_Err_Syntax_Error; } - bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); - achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); +#ifdef FT_CONFIG_OPTION_INCREMENTAL + if ( face->root.internal->incremental_interface ) + { + /* the caller must handle the font encoding also */ + bchar_index = bchar; + achar_index = achar; + } + else +#endif + { + bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar ); + achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar ); + } if ( bchar_index < 0 || achar_index < 0 ) { - FT_ERROR(( "t1operator_seac:" )); - FT_ERROR(( " invalid seac character code arguments\n" )); + FT_ERROR(( "t1operator_seac:" + " invalid seac character code arguments\n" )); return PSaux_Err_Syntax_Error; } @@ -243,8 +266,8 @@ /* subglyph 1 = accent character */ subg->index = achar_index; subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES; - subg->arg1 = (FT_Int)( adx - asb ); - subg->arg2 = (FT_Int)ady; + subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb ); + subg->arg2 = (FT_Int)FIXED_TO_INT( ady ); /* set up remaining glyph fields */ glyph->num_subglyphs = 2; @@ -260,7 +283,10 @@ FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */ + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, bchar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -278,7 +304,11 @@ /* Now load `achar' on top of */ /* the base outline */ + + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = t1_decoder_parse_glyph( decoder, achar_index ); + decoder->seac = FALSE; if ( error ) goto Exit; @@ -327,9 +357,15 @@ FT_Pos x, y, orig_x, orig_y; FT_Int known_othersubr_result_cnt = 0; FT_Int unknown_othersubr_result_cnt = 0; + FT_Bool large_int; + FT_Fixed seed; T1_Hints_Funcs hinter; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_Bool bol = TRUE; +#endif + /* we don't want to touch the source code -- use macro trick */ #define start_point t1_builder_start_point @@ -339,6 +375,16 @@ #define add_contour t1_builder_add_contour #define close_contour t1_builder_close_contour + + /* compute random seed from stack address of parameter */ + seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^ + (FT_PtrDist)(char*)&decoder ^ + (FT_PtrDist)(char*)&charstring_base ) & + FT_ULONG_MAX ) ; + seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL; + if ( seed == 0 ) + seed = 0x7384; + /* First of all, initialize the decoder */ decoder->top = decoder->stack; decoder->zone = decoder->zones; @@ -351,15 +397,15 @@ /* a font that reads BuildCharArray without setting */ /* its values first is buggy, but ... */ FT_ASSERT( ( decoder->len_buildchar == 0 ) == - ( decoder->buildchar == NULL ) ); + ( decoder->buildchar == NULL ) ); if ( decoder->len_buildchar > 0 ) - memset( &decoder->buildchar[0], - 0, - sizeof( decoder->buildchar[0] ) * - decoder->len_buildchar ); + ft_memset( &decoder->buildchar[0], + 0, + sizeof( decoder->buildchar[0] ) * decoder->len_buildchar ); - FT_TRACE4(( "\nStart charstring\n" )); + FT_TRACE4(( "\n" + "Start charstring\n" )); zone->base = charstring_base; limit = zone->limit = charstring_base + charstring_len; @@ -374,18 +420,26 @@ if ( hinter ) hinter->open( hinter->hints ); + large_int = FALSE; + /* now, execute loop */ while ( ip < limit ) { FT_Long* top = decoder->top; T1_Operator op = op_none; - FT_Long value = 0; + FT_Int32 value = 0; FT_ASSERT( known_othersubr_result_cnt == 0 || unknown_othersubr_result_cnt == 0 ); - FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( bol ) + { + FT_TRACE5(( " (%d)", decoder->top - decoder->stack )); + bol = FALSE; + } +#endif /*********************************************************************/ /* */ @@ -456,8 +510,8 @@ case 12: if ( ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+EOF)\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+EOF)\n" )); goto Syntax_Error; } @@ -492,8 +546,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid escape (12+%d)\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid escape (12+%d)\n", ip[-1] )); goto Syntax_Error; } @@ -502,42 +556,69 @@ case 255: /* four bytes integer */ if ( ip + 4 > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } - value = (FT_Int32)( ((FT_Long)ip[0] << 24) | - ((FT_Long)ip[1] << 16) | - ((FT_Long)ip[2] << 8 ) | - ip[3] ); + value = (FT_Int32)( ( (FT_Long)ip[0] << 24 ) | + ( (FT_Long)ip[1] << 16 ) | + ( (FT_Long)ip[2] << 8 ) | + ip[3] ); ip += 4; + + /* According to the specification, values > 32000 or < -32000 must */ + /* be followed by a `div' operator to make the result be in the */ + /* range [-32000;32000]. We expect that the second argument of */ + /* `div' is not a large number. Additionally, we don't handle */ + /* stuff like ` div div' or */ + /* div div'. This is probably not allowed */ + /* anyway. */ + if ( value > 32000 || value < -32000 ) + { + if ( large_int ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + } + else + large_int = TRUE; + } + else + { + if ( !large_int ) + value <<= 16; + } + break; default: if ( ip[-1] >= 32 ) { if ( ip[-1] < 247 ) - value = (FT_Long)ip[-1] - 139; + value = (FT_Int32)ip[-1] - 139; else { if ( ++ip > limit ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected EOF in integer\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected EOF in integer\n" )); goto Syntax_Error; } if ( ip[-2] < 251 ) - value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; + value = ( ( (FT_Int32)ip[-2] - 247 ) << 8 ) + ip[-1] + 108; else - value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); + value = -( ( ( (FT_Int32)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 ); } + + if ( !large_int ) + value <<= 16; } else { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid byte (%d)\n", ip[-1] )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid byte (%d)\n", ip[-1] )); goto Syntax_Error; } } @@ -559,6 +640,14 @@ } } + if ( large_int && !( op == op_none || op == op_div ) ) + { + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no `div' after large integer\n" )); + + large_int = FALSE; + } + /*********************************************************************/ /* */ /* Push value on stack, or process operator */ @@ -568,11 +657,16 @@ { if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow\n" )); goto Syntax_Error; } - FT_TRACE4(( " %ld", value )); +#ifdef FT_DEBUG_LEVEL_TRACE + if ( large_int ) + FT_TRACE4(( " %ld", value )); + else + FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) )); +#endif *top++ = value; decoder->top = top; @@ -583,15 +677,18 @@ FT_Int arg_cnt; - FT_TRACE4(( " callothersubr" )); +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( " callothersubr\n" )); + bol = TRUE; +#endif if ( top - decoder->stack < 2 ) goto Stack_Underflow; top -= 2; - subr_no = (FT_Int)top[1]; - arg_cnt = (FT_Int)top[0]; + subr_no = (FT_Int)( top[1] >> 16 ); + arg_cnt = (FT_Int)( top[0] >> 16 ); /***********************************************************/ /* */ @@ -668,8 +765,8 @@ if ( decoder->flex_state == 0 || decoder->num_flex_vectors != 7 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unexpected flex end\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected flex end\n" )); goto Syntax_Error; } @@ -685,7 +782,6 @@ if ( hinter ) hinter->reset( hinter->hints, builder->current->n_points ); - break; case 12: @@ -708,16 +804,16 @@ if ( !blend ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected multiple masters operator!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected multiple masters operator\n" )); goto Syntax_Error; } num_points = (FT_UInt)subr_no - 13 + ( subr_no == 18 ); if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "incorrect number of mm arguments\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " incorrect number of multiple masters arguments\n" )); goto Syntax_Error; } @@ -753,12 +849,6 @@ break; } -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS - - /* We cannot yet enable these since currently */ - /* our T1 stack stores integers which lack the */ - /* precision to express the values */ - case 19: /* 1 19 callothersubr */ /* => replace elements starting from index cvi( ) */ @@ -771,16 +861,16 @@ if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); - if ( idx < 0 || - idx + blend->num_designs > decoder->face->len_buildchar ) + if ( idx < 0 || + idx + blend->num_designs > decoder->len_buildchar ) goto Unexpected_OtherSubr; - memcpy( &decoder->buildchar[idx], - blend->weight_vector, - blend->num_designs * - sizeof( blend->weight_vector[ 0 ] ) ); + ft_memcpy( &decoder->buildchar[idx], + blend->weight_vector, + blend->num_designs * + sizeof( blend->weight_vector[0] ) ); } break; @@ -812,7 +902,7 @@ if ( arg_cnt != 2 ) goto Unexpected_OtherSubr; - top[0] *= top[1]; /* XXX (over|under)flow */ + top[0] = FT_MulFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; @@ -823,24 +913,23 @@ if ( arg_cnt != 2 || top[1] == 0 ) goto Unexpected_OtherSubr; - top[0] /= top[1]; /* XXX (over|under)flow */ + top[0] = FT_DivFix( top[0], top[1] ); known_othersubr_result_cnt = 1; break; -#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */ - case 24: - /* 2 24 callothersubr */ - /* => set BuildCharArray[cvi( )] = */ + /* 2 24 callothersubr */ + /* ==> set BuildCharArray[cvi( )] = */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 2 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[1]; + idx = (FT_Int)( top[1] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -850,17 +939,18 @@ break; case 25: - /* 1 25 callothersubr pop */ - /* => push BuildCharArray[cvi( idx )] */ - /* onto T1 stack */ + /* 1 25 callothersubr pop */ + /* ==> push BuildCharArray[cvi( idx )] */ + /* onto T1 stack */ { FT_Int idx; PS_Blend blend = decoder->blend; + if ( arg_cnt != 1 || blend == NULL ) goto Unexpected_OtherSubr; - idx = top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar ) goto Unexpected_OtherSubr; @@ -876,13 +966,13 @@ /* mark ==> set BuildCharArray[cvi( )] = , */ /* leave mark on T1 stack */ /* ==> set BuildCharArray[cvi( )] = */ - XXX who has left his mark on the (PostScript) stack ?; + XXX which routine has left its mark on the (PostScript) stack?; break; #endif case 27: /* 4 27 callothersubr pop */ - /* ==> push onto T1 stack if <= , */ + /* ==> push onto T1 stack if <= , */ /* otherwise push */ if ( arg_cnt != 4 ) goto Unexpected_OtherSubr; @@ -893,28 +983,40 @@ known_othersubr_result_cnt = 1; break; -#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS case 28: /* 0 28 callothersubr pop */ /* => push random value from interval [0, 1) onto stack */ if ( arg_cnt != 0 ) goto Unexpected_OtherSubr; - top[0] = FT_rand(); + { + FT_Fixed Rand; + + + Rand = seed; + if ( Rand >= 0x8000L ) + Rand++; + + top[0] = Rand; + + seed = FT_MulFix( seed, 0x10000L - seed ); + if ( seed == 0 ) + seed += 0x2873; + } + known_othersubr_result_cnt = 1; break; -#endif default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unknown othersubr [%d %d], wish me luck!\n", + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unknown othersubr [%d %d], wish me luck\n", arg_cnt, subr_no )); unknown_othersubr_result_cnt = arg_cnt; break; Unexpected_OtherSubr: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid othersubr [%d %d]!\n", arg_cnt, subr_no )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid othersubr [%d %d]\n", arg_cnt, subr_no )); goto Syntax_Error; } @@ -951,9 +1053,9 @@ default: if ( top - decoder->stack != num_args ) - FT_TRACE0(( "t1_decoder_parse_charstrings: " - "too much operands on the stack " - "(seen %d, expected %d)\n", + FT_TRACE0(( "t1_decoder_parse_charstrings:" + " too much operands on the stack" + " (seen %d, expected %d)\n", top - decoder->stack, num_args )); break; } @@ -965,28 +1067,26 @@ switch ( op ) { case op_endchar: - FT_TRACE4(( " endchar" )); + FT_TRACE4(( " endchar\n" )); close_contour( builder ); /* close hints recording session */ if ( hinter ) { - if (hinter->close( hinter->hints, builder->current->n_points )) + if ( hinter->close( hinter->hints, builder->current->n_points ) ) goto Syntax_Error; /* apply hints to the loaded glyph outline now */ hinter->apply( hinter->hints, builder->current, - (PSH_Globals) builder->hints_globals, + (PSH_Globals)builder->hints_globals, decoder->hint_mode ); } /* add current outline to the glyph slot */ FT_GlyphLoader_Add( builder->loader ); - FT_TRACE4(( "\n" )); - /* the compiler should optimize away this empty loop but ... */ #ifdef FT_DEBUG_LEVEL_TRACE @@ -1020,8 +1120,8 @@ builder->advance.x = top[1]; builder->advance.y = 0; - orig_x = builder->last.x = x = builder->pos_x + top[0]; - orig_y = builder->last.y = y = builder->pos_y; + orig_x = x = builder->pos_x + top[0]; + orig_y = y = builder->pos_y; FT_UNUSED( orig_y ); @@ -1034,9 +1134,12 @@ break; case op_seac: - /* return immediately after the processing */ - return t1operator_seac( decoder, top[0], top[1], top[2], - (FT_Int)top[3], (FT_Int)top[4] ); + return t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); case op_sbw: FT_TRACE4(( " sbw" )); @@ -1048,8 +1151,8 @@ builder->advance.x = top[2]; builder->advance.y = top[3]; - builder->last.x = x = builder->pos_x + top[0]; - builder->last.y = y = builder->pos_y + top[1]; + x = builder->pos_x + top[0]; + y = builder->pos_y + top[1]; /* the `metrics_only' indicates that we only want to compute */ /* the glyph's metrics (lsb + advance width), not load the */ @@ -1062,10 +1165,11 @@ case op_closepath: FT_TRACE4(( " closepath" )); - close_contour( builder ); - if ( !( builder->parse_state == T1_Parse_Have_Path || - builder->parse_state == T1_Parse_Have_Moveto ) ) - goto Syntax_Error; + /* if there is no path, `closepath' is a no-op */ + if ( builder->parse_state == T1_Parse_Have_Path || + builder->parse_state == T1_Parse_Have_Moveto ) + close_contour( builder ); + builder->parse_state = T1_Parse_Have_Width; break; @@ -1134,7 +1238,7 @@ break; case op_rrcurveto: - FT_TRACE4(( " rcurveto" )); + FT_TRACE4(( " rrcurveto" )); if ( start_point( builder, x, y ) || check_points( builder, 3 ) ) @@ -1193,16 +1297,13 @@ case op_div: FT_TRACE4(( " div" )); - if ( top[1] ) - { - *top = top[0] / top[1]; - ++top; - } - else - { - FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" )); - goto Syntax_Error; - } + /* if `large_int' is set, we divide unscaled numbers; */ + /* otherwise, we divide numbers in 16.16 format -- */ + /* in both cases, it is the same operation */ + *top = FT_DivFix( top[0], top[1] ); + ++top; + + large_int = FALSE; break; case op_callsubr: @@ -1212,18 +1313,18 @@ FT_TRACE4(( " callsubr" )); - idx = (FT_Int)top[0]; + idx = (FT_Int)( top[0] >> 16 ); if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invalid subrs index\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invalid subrs index\n" )); goto Syntax_Error; } if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "too many nested subrs\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " too many nested subrs\n" )); goto Syntax_Error; } @@ -1250,8 +1351,8 @@ if ( !zone->base ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "invoking empty subrs!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " invoking empty subrs\n" )); goto Syntax_Error; } @@ -1273,8 +1374,8 @@ if ( unknown_othersubr_result_cnt == 0 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " - "no more operands for othersubr!\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " no more operands for othersubr\n" )); goto Syntax_Error; } @@ -1287,7 +1388,8 @@ if ( zone <= decoder->zones ) { - FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected return\n" )); goto Syntax_Error; } @@ -1311,7 +1413,6 @@ /* top[0] += builder->left_bearing.y; */ hinter->stem( hinter->hints, 1, top ); } - break; case op_hstem3: @@ -1320,19 +1421,17 @@ /* record horizontal counter-controlled hints */ if ( hinter ) hinter->stem3( hinter->hints, 1, top ); - break; case op_vstem: FT_TRACE4(( " vstem" )); - /* record vertical hint */ + /* record vertical hint */ if ( hinter ) { top[0] += orig_x; hinter->stem( hinter->hints, 0, top ); } - break; case op_vstem3: @@ -1362,9 +1461,8 @@ /* known_othersubr_result_cnt != 0 is already handled above */ if ( decoder->flex_state != 1 ) { - FT_ERROR(( "t1_decoder_parse_charstrings: " )); - FT_ERROR(( "unexpected `setcurrentpoint'\n" )); - + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unexpected `setcurrentpoint'\n" )); goto Syntax_Error; } else @@ -1377,8 +1475,8 @@ break; default: - FT_ERROR(( "t1_decoder_parse_charstrings: " - "unhandled opcode %d\n", op )); + FT_ERROR(( "t1_decoder_parse_charstrings:" + " unhandled opcode %d\n", op )); goto Syntax_Error; } @@ -1389,6 +1487,11 @@ decoder->top = top; +#ifdef FT_DEBUG_LEVEL_TRACE + FT_TRACE4(( "\n" )); + bol = TRUE; +#endif + } /* general operator processing */ } /* while ip < limit */ @@ -1437,8 +1540,8 @@ FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { - FT_ERROR(( "t1_decoder_init: " )); - FT_ERROR(( "the `psnames' module is not available\n" )); + FT_ERROR(( "t1_decoder_init:" + " the `psnames' module is not available\n" )); return PSaux_Err_Unimplemented_Feature; } -- cgit v1.2.3