diff --git a/ChangeLog b/ChangeLog index 01d01ba77..b1b0fdd4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,15 +1,58 @@ -2003-02-09 Werner Lemberg +2004-02-11 Werner Lemberg + + * src/cid/cidload.c (cid_face_open): Always allocate + face->cid_stream so that we can deallocate it safely. + +2004-02-10 Werner Lemberg + + Make the PS parser more tolerant w.r.t. non-standard font data. In + general, an error is only reported in case of a syntax error; a + wrong type is now simply ignored (if possible). To be independent + of the order of various MM-specific keywords, the parse_shared_dict + routine has been removed -- the PS parser is now capable to skip + this data. It no longer fails on parsing e.g. + + dup /WeightVector exch def + + Since the token following /WeightVector isn't `[' (starting an + array) it is simply ignored. + + * include/freetype/fterrdef.h: Define `FT_Err_Ignore' (0xA2) as a + new internal error value. + + * src/type1/t1load.c (parse_blend_axis_types, + parse_blend_design_positions, parse_blend_design_map): Return + T1_Err_Ignore if no proper array is following the keyword. + (parse_weight_vector): Use T1_ToTokenArray, initializing `blend' + structure, if necessary. + Return T1_Err_Ignore if no proper array is following the keyword. + (parse_shared_dict): Removed. + (parse_encoding): Set parser->root.error to return T1_Err_Ignore + if no result can be obtained. + Check for errors before accessing `elements' array. + (t1_keywords): Remove /shareddict. + (parse_dict): Reset error if t1_load_keyword returns T1_Err_Ignore. + Set keyword_flag only in case of success. + Check error code if skipping an unrecognized token. + (T1_Open_Face) [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: Call T1_Done_Blend + if blend commands haven't set up a proper MM font. + + * src/psaux/psobjs.c (ps_parser_load_field_table): Remove special + code for synthetic fonts. + Return PSaux_Err_Ignore if no proper value has been found. + +2004-02-09 Werner Lemberg * src/cff/cffgload.c (cff_decoder_parse_charstrings) : Preserve glyph width before calling cff_operator_seac. -2003-02-09 Martin Muskens +2004-02-09 Martin Muskens * src/cff/cffgload.c (cff_decoder_parse_charstrings): Handle special first argument for `hintmask' and `cntrmask' operators also. -2003-02-08 Werner Lemberg +2004-02-08 Werner Lemberg * builds/unix/configure.in: Call AC_SUBST for `enable_shared', `hardcode_libdir_flag_spec', and `wl'. @@ -22,7 +65,7 @@ * docs/CHANGES: Updated. -2003-02-07 Keith Packard +2004-02-07 Keith Packard * src/bdf/bdfdrivr.c (BDF_Face_Init, BDF_Set_Pixel_Size): Fix computation of various vertical and horizontal metric values. @@ -30,24 +73,24 @@ * src/pcfdrivr.c (PCF_Set_Pixel_Size), src/pcfread (pcf_load_font): Ditto. -2003-02-07 Werner Lemberg +2004-02-07 Werner Lemberg * builds/win32/visualc/index.html, builds/win32/visualc/freetype.dsp, builds/win32/visualc/freetype.dsw, docs/CHANGES: Updated. -2003-02-07 Vitaliy Pasternak +2004-02-07 Vitaliy Pasternak * builds/win32/visualc/freetype.sln, builds/win32/visualc/freetype.vcproj: New files for VS.NET 2003. -2003-02-03 Werner Lemberg +2004-02-03 Werner Lemberg * include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP): Initialize `node'. * src/type1/t1load.c (parse_dict): Initialize `have_integer'. -2003-02-02 Werner Lemberg +2004-02-02 Werner Lemberg * src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands outside of /Subrs or /CharStrings. This can happen if there is diff --git a/include/freetype/fterrdef.h b/include/freetype/fterrdef.h index 4ef606de8..2f73c0858 100644 --- a/include/freetype/fterrdef.h +++ b/include/freetype/fterrdef.h @@ -4,7 +4,7 @@ /* */ /* FreeType error codes (specification). */ /* */ -/* Copyright 2002 by */ +/* Copyright 2002, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -207,6 +207,8 @@ "opcode syntax error" ) FT_ERRORDEF_( Stack_Underflow, 0xA1, \ "argument stack underflow" ) + FT_ERRORDEF_( Ignore, 0xA2, \ + "ignore" ) /* BDF errors */ diff --git a/src/cid/cidload.c b/src/cid/cidload.c index 5b69ba59a..3a418e282 100644 --- a/src/cid/cidload.c +++ b/src/cid/cidload.c @@ -612,6 +612,9 @@ if ( face_index < 0 ) goto Exit; + if ( FT_NEW( face->cid_stream ) ) + goto Exit; + if ( parser->binary_length ) { /* we must convert the data section from hexadecimal to binary */ @@ -620,16 +623,13 @@ parser->data_offset, face ) ) goto Exit; - if ( FT_NEW( face->cid_stream ) ) - goto Exit; - FT_Stream_OpenMemory( face->cid_stream, face->binary_data, parser->binary_length ); face->cid.data_offset = 0; } else { - face->cid_stream = face->root.stream; + *face->cid_stream = *face->root.stream; face->cid.data_offset = loader.parser.data_offset; } diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c index 5ce8721f1..a0c123087 100644 --- a/src/psaux/psobjs.c +++ b/src/psaux/psobjs.c @@ -4,7 +4,7 @@ /* */ /* Auxiliary functions for PostScript fonts (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003 by */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -1280,10 +1280,6 @@ if ( cur >= limit ) break; - /* with synthetic fonts, it is possible to find a field twice */ - if ( *(FT_String**)q ) - break; - if ( field->type == T1_FIELD_TYPE_KEY ) { /* don't include leading `/' */ @@ -1359,7 +1355,7 @@ T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS]; T1_Token token; FT_Int num_elements; - FT_Error error = 0; + FT_Error error = PSaux_Err_Ok; FT_Byte* old_cursor; FT_Byte* old_limit; T1_FieldRec fieldrec = *(T1_Field)field; @@ -1374,8 +1370,10 @@ ps_parser_to_token_array( parser, elements, T1_MAX_TABLE_ELEMENTS, &num_elements ); if ( num_elements < 0 ) - goto Fail; - + { + error = PSaux_Err_Ignore; + goto Exit; + } if ( num_elements > T1_MAX_TABLE_ELEMENTS ) num_elements = T1_MAX_TABLE_ELEMENTS; @@ -1408,10 +1406,6 @@ Exit: return error; - - Fail: - error = PSaux_Err_Invalid_File_Format; - goto Exit; } diff --git a/src/type1/t1load.c b/src/type1/t1load.c index f830484e1..c5bc2a8c6 100644 --- a/src/type1/t1load.c +++ b/src/type1/t1load.c @@ -397,7 +397,12 @@ /* take an array of objects */ T1_ToTokenArray( &loader->parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n", num_axis )); @@ -459,8 +464,14 @@ /* get the array of design tokens -- compute number of designs */ - T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs ); - if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS ) + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) { FT_ERROR(( "parse_blend_design_positions:" )); FT_ERROR(( " incorrect number of designs: %d\n", @@ -472,13 +483,13 @@ { FT_Byte* old_cursor = parser->root.cursor; FT_Byte* old_limit = parser->root.limit; - FT_UInt n; + FT_Int n; blend = face->blend; num_axis = 0; /* make compiler happy */ - for ( n = 0; n < (FT_UInt)num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS]; T1_Token token; @@ -541,8 +552,14 @@ FT_Memory memory = face->root.memory; - T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis ); - if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS ) + T1_ToTokenArray( parser, axis_tokens, + T1_MAX_MM_AXIS, &num_axis ); + if ( num_axis < 0 ) + { + error = T1_Err_Ignore; + goto Exit; + } + if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS ) { FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n", num_axis )); @@ -615,26 +632,46 @@ parse_weight_vector( T1_Face face, T1_Loader loader ) { + T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS]; + FT_Int num_designs; FT_Error error = T1_Err_Ok; T1_Parser parser = &loader->parser; PS_Blend blend = face->blend; - T1_TokenRec master; - FT_UInt n; + T1_Token token; + FT_Int n; FT_Byte* old_cursor; FT_Byte* old_limit; - if ( !blend || blend->num_designs == 0 ) + T1_ToTokenArray( parser, design_tokens, + T1_MAX_MM_DESIGNS, &num_designs ); + if ( num_designs < 0 ) { - FT_ERROR(( "parse_weight_vector: too early!\n" )); + error = T1_Err_Ignore; + goto Exit; + } + if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS ) + { + FT_ERROR(( "parse_weight_vector:" )); + FT_ERROR(( " incorrect number of designs: %d\n", + num_designs )); error = T1_Err_Invalid_File_Format; goto Exit; } - T1_ToToken( parser, &master ); - if ( master.type != T1_TOKEN_TYPE_ARRAY ) + if ( !blend || !blend->num_designs ) { - FT_ERROR(( "parse_weight_vector: incorrect format!\n" )); + error = t1_allocate_blend( face, num_designs, 0 ); + if ( error ) + goto Exit; + blend = face->blend; + } + else if ( blend->num_designs != (FT_UInt)num_designs ) + { + FT_ERROR(( "parse_weight_vector:" + " /BlendDesignPosition and /WeightVector have\n" )); + FT_ERROR(( " " + " different number of elements!\n" )); error = T1_Err_Invalid_File_Format; goto Exit; } @@ -642,12 +679,12 @@ old_cursor = parser->root.cursor; old_limit = parser->root.limit; - /* don't include the delimiting brackets */ - parser->root.cursor = master.start + 1; - parser->root.limit = master.limit - 1; - - for ( n = 0; n < blend->num_designs; n++ ) + for ( n = 0; n < num_designs; n++ ) { + token = design_tokens + n; + parser->root.cursor = token->start; + parser->root.limit = token->limit; + blend->default_weight_vector[n] = blend->weight_vector[n] = T1_ToFixed( parser, 0 ); } @@ -660,23 +697,6 @@ } - /* the keyword `/shareddict' appears in some multiple master fonts */ - /* with a lot of Postscript garbage behind it (that's completely out */ - /* of spec!); we detect it and terminate the parsing */ - /* */ - static void - parse_shared_dict( T1_Face face, - T1_Loader loader ) - { - T1_Parser parser = &loader->parser; - - FT_UNUSED( face ); - - - parser->root.cursor = parser->root.limit; - parser->root.error = 0; - } - #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ @@ -1007,9 +1027,9 @@ parser->root.error = T1_Add_Table( char_table, charcode, cur, len + 1 ); - char_table->elements[charcode][len] = '\0'; if ( parser->root.error ) return; + char_table->elements[charcode][len] = '\0'; n++; } @@ -1041,10 +1061,7 @@ face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1; else - { - FT_ERROR(( "parse_encoding: invalid token!\n" )); - parser->root.error = T1_Err_Invalid_File_Format; - } + parser->root.error = T1_Err_Ignore; } } @@ -1230,8 +1247,8 @@ FT_Byte* base; - /* the format is simple: */ - /* `/glyphname' + binary data */ + /* the format is simple: */ + /* `/glyphname' + binary data */ T1_Skip_Spaces( parser ); @@ -1395,7 +1412,7 @@ /* We take index 0 and add it to the end of the table(s) */ /* and add our own /.notdef glyph to index 0. */ - /* 0 333 hsbw endchar */ + /* 0 333 hsbw endchar */ FT_Byte notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E}; char* notdef_name = (char *)".notdef"; @@ -1469,7 +1486,6 @@ T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map ) T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types ) T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector ) - T1_FIELD_CALLBACK( "shareddict", parse_shared_dict ) #endif { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 } @@ -1640,10 +1656,16 @@ parser->root.error = t1_load_keyword( face, loader, keyword ); - if ( parser->root.error ) - return parser->root.error; + if ( parser->root.error == T1_Err_Ok ) + keyword_flag[0] = 1; + else + { + if ( parser->root.error == T1_Err_Ignore ) + parser->root.error = T1_Err_Ok; + else + return parser->root.error; + } } - keyword_flag[0] = 1; break; } @@ -1657,12 +1679,15 @@ else { T1_Skip_PS_Token( parser ); + if ( parser->root.error ) + goto Exit; have_integer = 0; } T1_Skip_Spaces( parser ); } + Exit: return parser->root.error; } @@ -1756,6 +1781,30 @@ if ( error ) goto Exit; +#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* the following can happen for MM instances; we then treat the */ + /* font as a normal PS font */ + if ( face->blend && + ( !face->blend->num_designs || !face->blend->num_axis ) ) + T1_Done_Blend( face ); + + /* another safety check */ + if ( face->blend ) + { + FT_UInt i; + + + for ( i = 0; i < face->blend->num_axis; i++ ) + if ( !face->blend->design_map[i].num_points ) + { + T1_Done_Blend( face ); + break; + } + } + +#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */ + /* now, propagate the subrs, charstrings, and glyphnames tables */ /* to the Type1 data */ type1->num_glyphs = loader.num_glyphs;