ref: 95867077e8f03476359f313a92013afe73d93ebf
parent: 916838ca68b0069212b2690c53e12d58c6679333
author: Werner Lemberg <[email protected]>
date: Thu Feb 12 03:33:20 EST 2004
* src/cid/cidload.c (cid_face_open): Always allocate face->cid_stream so that we can deallocate it safely. 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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,58 @@
-2003-02-09 Werner Lemberg <[email protected]>
+2004-02-11 Werner Lemberg <[email protected]>
+ * src/cid/cidload.c (cid_face_open): Always allocate
+ face->cid_stream so that we can deallocate it safely.
+
+2004-02-10 Werner Lemberg <[email protected]>
+
+ 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 <[email protected]>
+
* src/cff/cffgload.c (cff_decoder_parse_charstrings)
<cff_op_endchar>: Preserve glyph width before calling
cff_operator_seac.
-2003-02-09 Martin Muskens <[email protected]>
+2004-02-09 Martin Muskens <[email protected]>
* src/cff/cffgload.c (cff_decoder_parse_charstrings): Handle special
first argument for `hintmask' and `cntrmask' operators also.
-2003-02-08 Werner Lemberg <[email protected]>
+2004-02-08 Werner Lemberg <[email protected]>
* 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 <[email protected]>
+2004-02-07 Keith Packard <[email protected]>
* 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 <[email protected]>
+2004-02-07 Werner Lemberg <[email protected]>
* builds/win32/visualc/index.html,
builds/win32/visualc/freetype.dsp,
builds/win32/visualc/freetype.dsw, docs/CHANGES: Updated.
-2003-02-07 Vitaliy Pasternak <[email protected]>
+2004-02-07 Vitaliy Pasternak <[email protected]>
* builds/win32/visualc/freetype.sln,
builds/win32/visualc/freetype.vcproj: New files for VS.NET 2003.
-2003-02-03 Werner Lemberg <[email protected]>
+2004-02-03 Werner Lemberg <[email protected]>
* 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 <[email protected]>
+2004-02-02 Werner Lemberg <[email protected]>
* src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands
outside of /Subrs or /CharStrings. This can happen if there is
--- 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 */
--- 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,9 +623,6 @@
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;
@@ -629,7 +629,7 @@
}
else
{
- face->cid_stream = face->root.stream;
+ *face->cid_stream = *face->root.stream;
face->cid.data_offset = loader.parser.data_offset;
}
--- 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;
}
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -397,8 +397,13 @@
/* 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 ));
error = T1_Err_Invalid_File_Format;
@@ -459,9 +464,15 @@
/* 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",
num_designs ));
@@ -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,9 +552,15 @@
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 ));
error = T1_Err_Invalid_File_Format;
@@ -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,6 +1679,8 @@
else
{
T1_Skip_PS_Token( parser );
+ if ( parser->root.error )
+ goto Exit;
have_integer = 0;
}
@@ -1663,6 +1687,7 @@
T1_Skip_Spaces( parser );
}
+ Exit:
return parser->root.error;
}
@@ -1755,6 +1780,30 @@
keyword_flags );
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 */