Heavy modification of the PS parser to handle comments and strings

correctly.  This doesn't slow down the loading of PS fonts
significantly since charstrings aren't affected.

* include/freetype/config/ftstdlib.h (ft_xdigit): Renamed to...
(ft_isxdigit): This.  Updated all callers.
(ft_isdigit): New alias to `isdigit'.

* include/freetype/internal/psaux.h (PS_Parser_FuncsRec): Renamed
`skip_alpha' to `skip_PS_token'.
Add parameter to `to_bytes' and change some argument types.

* src/psaux/psauxmod.c (ps_parser_funcs): Updated.
* src/psaux/psobjs.c (ft_char_table): New array to map character
codes (ASCII and EBCDIC) of digits to numbers.
(OP): New auxiliary macro holding either `>=' or `<' depending on
the character encoding.
(skip_comment): New function.
(skip_spaces): Use it.
(skip_alpha): Removed.
(skip_literal_string, skip_string): New functions.
(ps_parser_skip_PS_token): New function.  This is a better
replacement of...
(ps_parser_skip_alpha): Removed.
(ps_parser_to_token, ps+parser_to_token_array): Updated.
(T1Radix): Rewritten, using `ft_char_table'.
(t1_toint): Renamed to...
(ps_toint): This.  Update all callers.
Use `ft_char_table'.
(ps_tobytes): Add parameter to handle delimiters and change some
argument types.
Use `ft_char_table'.
(t1_tofixed): Renamed to...
(ps_tofixed): This.  Update all callers.
Use `ft_char_table'.
(t1_tocoordarray): Renamed and updated to...
(ps_tocoordarray): This.  Update all callers.
(t1_tofixedarray): Renamed and updated to...
(ps_tofixedarray): This.  Update all callers.
(t1_tobool): Renamed to...
(ps_tobool): This.  Update all callers.
(ps_parser_load_field): Updated.
(ps_parser_load_field_table): Use `T1_MAX_TABLE_ELEMENTS'
everywhere.
(ps_parser_to_int, ps_parser_to_fixed, ps_parser_to_coord_array,
ps_parser_to_fixed_array): Skip spaces.  Updated.
(ps_parser_to_bytes): Add parameter to handle delimiters and change
some argument types.  Updated.
* src/psaux/psobjs.h: Updated.

* src/cid/cidload.c (cid_parse_dict): Updated.
* src/cid/cidparse.c (cid_parser_new): Check whether the `StartData'
token was really found.
* src/cid/cidparse.h (cid_parser_skip_alpha): Updated and renamed
to...
(cid_parser_skip_PS_token): This.

* src/type1/t1parse.h (T1_ParserRec): Use `FT_Bool' for boolean
fields.
(T1_Skip_Alpha): Replaced with...
(T1_Skip_PS_Token): This new macro.
* src/type1/t1parse.c (hexa_value): Removed.
(T1_Get_Private_Dict): Use `ft_isxdigit' and
`psaux->ps_parser_funcs_to_bytes' for handling ASCII hexadecimal
encoding.
After decrypting, replace the four random bytes at the beginning
with whitespace.
* src/type1/t1load.c (t1_allocate_blend): Use proper error values.
(parser_blend_design_positions, parse_blend_design_map,
parse_weight_vector): Updated.
(is_space): Handle `\f' also.
(is_name_char): Removed.
(read_binary_data): Updated.
(parse_encoding): Use `ft_isdigit'.
Updated.
(parse_subrs): Updated.
(TABLE_EXTEND): New macro.
(parse_charstrings): Updated.
Provide a workaround for buggy fonts which have more entries in the
/CharStrings dictionary then expected; the function now adds some
slots and skips entries which still exceed the new limit.
(parse_dict): Updated.
Terminate on the token `closefile'.

* src/type42/t42parse.c (T1_Skip_Alpha): Replaced with...
(T1_Skip_PS_Token): This new macro.  Updated all callers.
(t42_parse_encoding): Use `ft_isdigit'.


* src/base/ftmm.c (ft_face_get_mm_service): Return FT_Err_OK if
success.
This commit is contained in:
Werner Lemberg 2003-10-07 05:49:41 +00:00
parent d07f15f282
commit fc7177d2e1
16 changed files with 1045 additions and 662 deletions

View File

@ -1,3 +1,97 @@
2003-10-06 Werner Lemberg <wl@gnu.org>
Heavy modification of the PS parser to handle comments and strings
correctly. This doesn't slow down the loading of PS fonts
significantly since charstrings aren't affected.
* include/freetype/config/ftstdlib.h (ft_xdigit): Renamed to...
(ft_isxdigit): This. Updated all callers.
(ft_isdigit): New alias to `isdigit'.
* include/freetype/internal/psaux.h (PS_Parser_FuncsRec): Renamed
`skip_alpha' to `skip_PS_token'.
Add parameter to `to_bytes' and change some argument types.
* src/psaux/psauxmod.c (ps_parser_funcs): Updated.
* src/psaux/psobjs.c (ft_char_table): New array to map character
codes (ASCII and EBCDIC) of digits to numbers.
(OP): New auxiliary macro holding either `>=' or `<' depending on
the character encoding.
(skip_comment): New function.
(skip_spaces): Use it.
(skip_alpha): Removed.
(skip_literal_string, skip_string): New functions.
(ps_parser_skip_PS_token): New function. This is a better
replacement of...
(ps_parser_skip_alpha): Removed.
(ps_parser_to_token, ps+parser_to_token_array): Updated.
(T1Radix): Rewritten, using `ft_char_table'.
(t1_toint): Renamed to...
(ps_toint): This. Update all callers.
Use `ft_char_table'.
(ps_tobytes): Add parameter to handle delimiters and change some
argument types.
Use `ft_char_table'.
(t1_tofixed): Renamed to...
(ps_tofixed): This. Update all callers.
Use `ft_char_table'.
(t1_tocoordarray): Renamed and updated to...
(ps_tocoordarray): This. Update all callers.
(t1_tofixedarray): Renamed and updated to...
(ps_tofixedarray): This. Update all callers.
(t1_tobool): Renamed to...
(ps_tobool): This. Update all callers.
(ps_parser_load_field): Updated.
(ps_parser_load_field_table): Use `T1_MAX_TABLE_ELEMENTS'
everywhere.
(ps_parser_to_int, ps_parser_to_fixed, ps_parser_to_coord_array,
ps_parser_to_fixed_array): Skip spaces. Updated.
(ps_parser_to_bytes): Add parameter to handle delimiters and change
some argument types. Updated.
* src/psaux/psobjs.h: Updated.
* src/cid/cidload.c (cid_parse_dict): Updated.
* src/cid/cidparse.c (cid_parser_new): Check whether the `StartData'
token was really found.
* src/cid/cidparse.h (cid_parser_skip_alpha): Updated and renamed
to...
(cid_parser_skip_PS_token): This.
* src/type1/t1parse.h (T1_ParserRec): Use `FT_Bool' for boolean
fields.
(T1_Skip_Alpha): Replaced with...
(T1_Skip_PS_Token): This new macro.
* src/type1/t1parse.c (hexa_value): Removed.
(T1_Get_Private_Dict): Use `ft_isxdigit' and
`psaux->ps_parser_funcs_to_bytes' for handling ASCII hexadecimal
encoding.
After decrypting, replace the four random bytes at the beginning
with whitespace.
* src/type1/t1load.c (t1_allocate_blend): Use proper error values.
(parser_blend_design_positions, parse_blend_design_map,
parse_weight_vector): Updated.
(is_space): Handle `\f' also.
(is_name_char): Removed.
(read_binary_data): Updated.
(parse_encoding): Use `ft_isdigit'.
Updated.
(parse_subrs): Updated.
(TABLE_EXTEND): New macro.
(parse_charstrings): Updated.
Provide a workaround for buggy fonts which have more entries in the
/CharStrings dictionary then expected; the function now adds some
slots and skips entries which still exceed the new limit.
(parse_dict): Updated.
Terminate on the token `closefile'.
* src/type42/t42parse.c (T1_Skip_Alpha): Replaced with...
(T1_Skip_PS_Token): This new macro. Updated all callers.
(t42_parse_encoding): Use `ft_isdigit'.
* src/base/ftmm.c (ft_face_get_mm_service): Return FT_Err_OK if
success.
2003-10-05 Werner Lemberg <wl@gnu.org>
* include/freetype/ftmodule.h: Renamed to...

View File

@ -5,7 +5,7 @@
/* ANSI-specific library and header configuration file (specification */
/* only). */
/* */
/* Copyright 2002 by */
/* Copyright 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -73,10 +73,11 @@
#include <ctype.h>
#define ft_isalnum isalnum
#define ft_isupper isupper
#define ft_islower islower
#define ft_xdigit isxdigit
#define ft_isalnum isalnum
#define ft_isupper isupper
#define ft_islower islower
#define ft_isdigit isdigit
#define ft_isxdigit isxdigit
#include <string.h>

View File

@ -5,7 +5,7 @@
/* Support for the FT_Outline type used to store glyph shapes of */
/* most scalable font formats (specification). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -391,32 +391,33 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @enum: FT_Orientation
* @enum:
* FT_Orientation
*
* @description:
* a list of values used to describe an outline's contour orientation
* A list of values used to describe an outline's contour orientation.
*
* The TrueType and Postscript specifications used different conventions
* to determine wether outline contours should be filled or unfilled.
* The TrueType and Postscript specifications use different conventions
* to determine whether outline contours should be filled or unfilled.
*
* @values:
* FT_ORIENTATION_TRUETYPE ::
* according to the TrueType specification, clockwise contours must
* be filled, and counter-clockwise ones must be unfilled
* According to the TrueType specification, clockwise contours must
* be filled, and counter-clockwise ones must be unfilled.
*
* FT_ORIENTATION_POSTSCRIPT ::
* according to the Postscript specification, counter-clockwise contours
* must be filled, and clockwise ones must be unfilled
* According to the Postscript specification, counter-clockwise contours
* must be filled, and clockwise ones must be unfilled.
*
* FT_ORIENTATION_FILL_RIGHT ::
* this is identical to @FT_ORIENTATION_TRUETYPE, but is used to
* This is identical to @FT_ORIENTATION_TRUETYPE, but is used to
* remember that in TrueType, everything that is to the right of
* the drawing direction of a contour must be filled.
*
* FT_ORIENTATION_FILL_LEFT ::
* this is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to
* This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to
* remember that in Postscript, everything that is to the left of
* the drawing direction of a contour must be filled
* the drawing direction of a contour must be filled.
*/
typedef enum
{
@ -430,22 +431,24 @@ FT_BEGIN_HEADER
/**************************************************************************
*
* @function: FT_Outline_Get_Orientation
* @function:
* FT_Outline_Get_Orientation
*
* @description:
* this function analyzes a glyph outline and tries to compute its
* fill orientation (see @FT_Orientation). This is done by computing
* This function analyzes a glyph outline and tries to compute its
* fill orientation (see @FT_Orientation). This is done by computing
* the direction of each global horizontal and/or vertical extrema
* within the outline.
*
* note that this will return @FT_ORIENTATION_TRUETYPE for empty
* Note that this will return @FT_ORIENTATION_TRUETYPE for empty
* outlines.
*
* @input:
* outline :: handle to source outline
* outline ::
* A handle to the source outline.
*
* @return:
* orientation
* The orientation.
*
*/
FT_EXPORT( FT_Orientation )

View File

@ -330,18 +330,20 @@ FT_BEGIN_HEADER
void
(*skip_spaces)( PS_Parser parser );
void
(*skip_alpha)( PS_Parser parser );
(*skip_PS_token)( PS_Parser parser );
FT_Long
(*to_int)( PS_Parser parser );
FT_Fixed
(*to_fixed)( PS_Parser parser,
FT_Int power_ten );
FT_Error
(*to_bytes)( PS_Parser parser,
FT_Byte* bytes,
FT_Int max_bytes,
FT_Int* pnum_bytes );
FT_Long max_bytes,
FT_Long* pnum_bytes,
FT_Bool delimiters );
FT_Int
(*to_coord_array)( PS_Parser parser,

View File

@ -51,6 +51,9 @@
FT_FACE_LOOKUP_SERVICE( face,
*aservice,
MULTI_MASTERS );
if ( aservice )
error = FT_Err_Ok;
}
return error;

View File

@ -26,6 +26,7 @@
{
FT_Service_PfrMetrics service;
FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );
return service;

View File

@ -39,7 +39,7 @@
/* read a single offset */
FT_LOCAL_DEF( FT_Long )
cid_get_offset( FT_Byte** start,
cid_get_offset( FT_Byte* *start,
FT_Byte offsize )
{
FT_Long result;
@ -164,9 +164,9 @@
temp_scale = ABS( temp[3] );
/* Set Units per EM based on FontMatrix values. We set the value to */
/* Set units per EM based on FontMatrix values. We set the value to */
/* `1000/temp_scale', because temp_scale was already multiplied by */
/* 1000 (in t1_tofixed(), from psobjs.c). */
/* 1000 (in `t1_tofixed', from psobjs.c). */
root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L,
FT_DivFix( temp_scale, 1000 ) ) );
@ -258,38 +258,57 @@
parser->root.cursor = base;
parser->root.limit = base + size;
parser->root.error = 0;
parser->root.error = CID_Err_Ok;
{
FT_Byte* cur = base;
FT_Byte* limit = cur + size;
for ( ; cur < limit; cur++ )
for (;;)
{
/* look for `%ADOBeginFontDict' */
if ( *cur == '%' && cur + 20 < limit &&
ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )
{
cur += 17;
FT_Byte* newlimit;
/* if /FDArray was found, then cid->num_dicts is > 0, and */
/* we can start increasing parser->num_dict */
if ( face->cid.num_dicts > 0 )
parser->num_dict++;
parser->root.cursor = cur;
cid_parser_skip_spaces( parser );
if ( parser->root.cursor >= limit )
newlimit = limit - 1 - 17;
else
newlimit = parser->root.cursor - 17;
/* look for `%ADOBeginFontDict' */
for ( ; cur < newlimit; cur++ )
{
if ( *cur == '%' &&
ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )
{
/* if /FDArray was found, then cid->num_dicts is > 0, and */
/* we can start increasing parser->num_dict */
if ( face->cid.num_dicts > 0 )
parser->num_dict++;
}
}
cur = parser->root.cursor;
/* no error can occur in cid_parser_skip_spaces */
if ( cur >= limit )
break;
cid_parser_skip_PS_token( parser );
if ( parser->root.cursor >= limit || parser->root.error )
break;
/* look for immediates */
else if ( *cur == '/' && cur + 2 < limit )
if ( *cur == '/' && cur + 2 < limit )
{
FT_PtrDist len;
cur++;
parser->root.cursor = cur;
cid_parser_skip_alpha( parser );
len = parser->root.cursor - cur;
if ( len > 0 && len < 22 )
{
/* now compare the immediate name to the keyword table */
@ -303,10 +322,7 @@
name = (FT_Byte*)keyword->ident;
if ( !name )
{
cid_parser_skip_alpha( parser );
break;
}
if ( cur[0] == name[0] &&
len == ft_strlen( (const char*)name ) )
@ -321,14 +337,11 @@
if ( n >= len )
{
/* we found it - run the parsing callback */
cid_parser_skip_spaces( parser );
parser->root.error = cid_load_keyword( face,
loader,
keyword );
if ( parser->root.error )
return parser->root.error;
cur = parser->root.cursor;
break;
}
}
@ -336,6 +349,8 @@
}
}
}
cur = parser->root.cursor;
}
}
return parser->root.error;

View File

@ -4,7 +4,7 @@
/* */
/* CID-keyed Type1 parser (body). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -58,6 +58,7 @@
FT_ULong base_offset, offset, ps_len;
FT_Byte buffer[256 + 10];
FT_Int buff_len;
FT_Byte *cur, *limit;
FT_MEM_ZERO( parser, sizeof ( *parser ) );
@ -67,7 +68,7 @@
base_offset = FT_STREAM_POS();
/* first of all, check the font format in the header */
/* first of all, check the font format in the header */
if ( FT_FRAME_ENTER( 31 ) )
goto Exit;
@ -82,15 +83,17 @@
if ( error )
goto Exit;
/* now, read the rest of the file, until we find a `StartData' */
Again:
/* now, read the rest of the file until we find a `StartData' */
buff_len = 256;
for (;;)
{
FT_Byte *p, *limit = buffer + 256;
FT_Byte* p;
FT_ULong top_position;
/* fill input buffer */
limit = buffer + 256;
buff_len -= 256;
if ( buff_len > 0 )
FT_MEM_MOVE( buffer, limit, buff_len );
@ -101,7 +104,7 @@
goto Exit;
top_position = FT_STREAM_POS() - buff_len;
buff_len = 256 + 10;
buff_len = 256 + 10;
/* look for `StartData' */
for ( p = buffer; p < limit; p++ )
@ -116,12 +119,12 @@
}
Found:
/* we have found the start of the binary data. We will now */
/* rewind and extract the frame of corresponding to the Postscript */
/* section */
/* we have found the start of the binary data. We will now */
/* rewind and extract the frame corresponding to the PostScript */
/* section */
ps_len = offset - base_offset;
if ( FT_STREAM_SEEK( base_offset ) ||
if ( FT_STREAM_SEEK( base_offset ) ||
FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
goto Exit;
@ -132,6 +135,32 @@
parser->root.limit = parser->root.cursor + ps_len;
parser->num_dict = -1;
/* finally we check whether `StartData' was real -- it could be */
/* in a comment or string */
limit = parser->root.limit;
cur = parser->root.cursor;
while ( cur < limit )
{
if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
{
limit = parser->root.limit;
cur = parser->root.cursor;
goto Exit;
}
cid_parser_skip_PS_token( parser );
cid_parser_skip_spaces ( parser );
cur = parser->root.cursor;
}
/* we haven't found the correct `StartData'; go back and continue */
/* searching */
FT_FRAME_RELEASE( parser->postscript );
if ( !FT_STREAM_SEEK( offset ) )
goto Again;
Exit:
return error;
}

View File

@ -4,7 +4,7 @@
/* */
/* CID-keyed Type1 parser (specification). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -87,8 +87,10 @@ FT_BEGIN_HEADER
/* */
/*************************************************************************/
#define cid_parser_skip_spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
#define cid_parser_skip_alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root )
#define cid_parser_skip_spaces( p ) \
(p)->root.funcs.skip_spaces( &(p)->root )
#define cid_parser_skip_PS_token( p ) \
(p)->root.funcs.skip_PS_token( &(p)->root )
#define cid_parser_to_int( p ) (p)->root.funcs.to_int( &(p)->root )
#define cid_parser_to_fixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t )

View File

@ -39,7 +39,7 @@
ps_parser_init,
ps_parser_done,
ps_parser_skip_spaces,
ps_parser_skip_alpha,
ps_parser_skip_PS_token,
ps_parser_to_int,
ps_parser_to_fixed,
ps_parser_to_bytes,

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,7 @@ FT_BEGIN_HEADER
ps_parser_skip_spaces( PS_Parser parser );
FT_LOCAL( void )
ps_parser_skip_alpha( PS_Parser parser );
ps_parser_skip_PS_token( PS_Parser parser );
FT_LOCAL( void )
ps_parser_to_token( PS_Parser parser,
@ -111,8 +111,9 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
ps_parser_to_bytes( PS_Parser parser,
FT_Byte* bytes,
FT_Int max_bytes,
FT_Int* pnum_bytes );
FT_Long max_bytes,
FT_Long* pnum_bytes,
FT_Bool delimiters );
FT_LOCAL( FT_Fixed )

View File

@ -41,11 +41,10 @@
/* */
/* All other common cases are handled very simply. The matching rules */
/* are defined in the file `t1tokens.h' through the use of several */
/* macros calls PARSE_XXX. */
/* */
/* This file is included twice here; the first time to generate parsing */
/* callback functions, the second to generate a table of keywords (with */
/* pointers to the associated callback). */
/* macros calls PARSE_XXX. This file is included twice here; the first */
/* time to generate parsing callback functions, the second time to */
/* generate a table of keywords (with pointers to the associated */
/* callback functions). */
/* */
/* The function `parse_dict' simply scans *linearly* a given dictionary */
/* (either the top-level or private one) and calls the appropriate */
@ -71,7 +70,6 @@
#include "t1errors.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@ -100,7 +98,7 @@
{
PS_Blend blend;
FT_Memory memory = face->root.memory;
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
blend = face->blend;
@ -174,7 +172,7 @@
return error;
Fail:
error = -1;
error = T1_Err_Invalid_File_Format;
goto Exit;
}
@ -205,8 +203,10 @@
axis->minimum = map->design_points[0];
axis->maximum = map->design_points[map->num_points - 1];
}
error = 0;
error = T1_Err_Ok;
}
return error;
}
@ -253,6 +253,7 @@
error = T1_Err_Ok;
}
return error;
}
@ -289,7 +290,7 @@
FT_Fixed p_design = designs[p];
/* exact match ? */
/* exact match? */
if ( design == p_design )
{
the_blend = blends[p];
@ -305,7 +306,7 @@
before = p;
}
/* now, interpolate if needed */
/* now interpolate if necessary */
if ( before < 0 )
the_blend = blends[0];
@ -386,9 +387,9 @@
parse_blend_axis_types( T1_Face face,
T1_Loader loader )
{
T1_TokenRec axis_tokens[ T1_MAX_MM_AXIS ];
T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
FT_Int n, num_axis;
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
PS_Blend blend;
FT_Memory memory;
@ -448,16 +449,16 @@
parse_blend_design_positions( T1_Face face,
T1_Loader loader )
{
T1_TokenRec design_tokens[ T1_MAX_MM_DESIGNS ];
T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
FT_Int num_designs;
FT_Int num_axis;
T1_Parser parser = &loader->parser;
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
PS_Blend blend;
/* get the array of design tokens - compute number of designs */
/* 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 )
{
@ -479,15 +480,15 @@
for ( n = 0; n < (FT_UInt)num_designs; n++ )
{
T1_TokenRec axis_tokens[ T1_MAX_MM_DESIGNS ];
T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS];
T1_Token token;
FT_Int axis, n_axis;
/* read axis/coordinates tokens */
token = design_tokens + n;
parser->root.cursor = token->start - 1;
parser->root.limit = token->limit + 1;
parser->root.cursor = token->start;
parser->root.limit = token->limit;
T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
if ( n == 0 )
@ -505,7 +506,7 @@
goto Exit;
}
/* now, read each axis token into the design position */
/* now read each axis token into the design position */
for ( axis = 0; axis < n_axis; axis++ )
{
T1_Token token2 = axis_tokens + axis;
@ -530,7 +531,7 @@
parse_blend_design_map( T1_Face face,
T1_Loader loader )
{
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
T1_Parser parser = &loader->parser;
PS_Blend blend;
T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
@ -548,6 +549,7 @@
error = T1_Err_Invalid_File_Format;
goto Exit;
}
old_cursor = parser->root.cursor;
old_limit = parser->root.limit;
@ -556,29 +558,22 @@
goto Exit;
blend = face->blend;
/* now, read each axis design map */
/* now read each axis design map */
for ( n = 0; n < num_axis; n++ )
{
PS_DesignMap map = blend->design_map + n;
T1_Token token;
T1_Token axis_token;
T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
FT_Int p, num_points;
token = axis_tokens + n;
parser->root.cursor = token->start;
parser->root.limit = token->limit;
axis_token = axis_tokens + n;
/* count the number of map points */
{
FT_Byte* ptr = token->start;
FT_Byte* limit = token->limit;
parser->root.cursor = axis_token->start;
parser->root.limit = axis_token->limit;
T1_ToTokenArray( parser, point_tokens,
T1_MAX_MM_MAP_POINTS, &num_points );
num_points = 0;
for ( ; ptr < limit; ptr++ )
if ( ptr[0] == '[' )
num_points++;
}
if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
{
FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
@ -594,6 +589,15 @@
for ( p = 0; p < num_points; p++ )
{
T1_Token point_token;
point_token = point_tokens + p;
/* don't include delimiting brackets */
parser->root.cursor = point_token->start + 1;
parser->root.limit = point_token->limit - 1;
map->design_points[p] = T1_ToInt( parser );
map->blend_points [p] = T1_ToFixed( parser, 0 );
}
@ -611,7 +615,7 @@
parse_weight_vector( T1_Face face,
T1_Loader loader )
{
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
T1_Parser parser = &loader->parser;
PS_Blend blend = face->blend;
T1_TokenRec master;
@ -638,8 +642,9 @@
old_cursor = parser->root.cursor;
old_limit = parser->root.limit;
parser->root.cursor = master.start;
parser->root.limit = master.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++ )
{
@ -675,6 +680,8 @@
#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
/*************************************************************************/
/*************************************************************************/
/***** *****/
@ -683,15 +690,6 @@
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* First of all, define the token field static variables. This is a set */
/* of T1_FieldRec variables used later. */
/* */
/*************************************************************************/
static FT_Error
t1_load_keyword( T1_Face face,
T1_Loader loader,
@ -774,32 +772,12 @@
static int
is_space( FT_Byte c )
{
return ( c == ' ' || c == '\t' || c == '\r' || c == '\n' );
return ( c == ' ' || c == '\t' ||
c == '\r' || c == '\n' || c == '\f' ||
c == '\0' );
}
static int
is_name_char( FT_Byte c )
{
/* Note: PostScript allows any non-delimiting, non-whitespace */
/* in a name (PS Ref Manual, 3rd Ed, p31) */
/* PostScript delimiters include (,),<,>,[,],{,},/ and % */
return ( c != '(' &&
c != ')' &&
c != '<' &&
c != '>' &&
c != '[' &&
c != ']' &&
c != '{' &&
c != '}' &&
c != '/' &&
c != '%' &&
! is_space( c )
);
}
static int
read_binary_data( T1_Parser parser,
FT_Long* size,
@ -815,14 +793,14 @@
/* */
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
if ( cur < limit && (FT_Byte)( *cur - '0' ) < 10 )
if ( cur < limit && ft_isdigit( *cur ) )
{
*size = T1_ToInt( parser );
T1_Skip_Spaces( parser );
T1_Skip_Alpha ( parser ); /* `RD' or `-|' or something else */
T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */
/* there is only one whitespace char after the */
/* `RD' or `-|' token */
@ -838,9 +816,8 @@
}
/* we will now define the routines used to handle */
/* the `/Encoding', `/Subrs', and `/CharStrings' */
/* dictionaries */
/* We now define the routines to handle the `/Encoding', `/Subrs', */
/* and `/CharStrings' dictionaries. */
static void
parse_font_matrix( T1_Face face,
@ -855,7 +832,7 @@
if ( matrix->xx || matrix->yx )
/* with synthetic fonts, it's possible we get here twice */
/* with synthetic fonts it is possible we get here twice */
return;
(void)T1_ToFixedArray( parser, 6, temp, 3 );
@ -895,28 +872,25 @@
parse_encoding( T1_Face face,
T1_Loader loader )
{
T1_Parser parser = &loader->parser;
FT_Byte* cur = parser->root.cursor;
FT_Byte* limit = parser->root.limit;
T1_Parser parser = &loader->parser;
FT_Byte* cur;
FT_Byte* limit = parser->root.limit;
PSAux_Service psaux = (PSAux_Service)face->psaux;
PSAux_Service psaux = (PSAux_Service)face->psaux;
/* skip whitespace */
while ( is_space( *cur ) )
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
if ( cur >= limit )
{
cur++;
if ( cur >= limit )
{
FT_ERROR(( "parse_encoding: out of bounds!\n" ));
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
FT_ERROR(( "parse_encoding: out of bounds!\n" ));
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
/* if we have a number, then the encoding is an array, */
/* and we must load it now */
if ( (FT_Byte)( *cur - '0' ) < 10 )
if ( ft_isdigit( *cur ) )
{
T1_Encoding encode = &face->type1.encoding;
FT_Int count, n;
@ -926,18 +900,19 @@
if ( encode->char_index )
/* with synthetic fonts, it's possible we get here twice */
/* with synthetic fonts it is possible we get here twice */
return;
/* read the number of entries in the encoding, should be 256 */
/* read the number of entries in the encoding; should be 256 */
count = (FT_Int)T1_ToInt( parser );
if ( parser->root.error )
T1_Skip_Spaces( parser );
if ( parser->root.cursor >= limit )
return;
/* we use a T1_Table to store our charnames */
loader->num_chars = encode->num_chars = count;
if ( FT_NEW_ARRAY( encode->char_index, count ) ||
FT_NEW_ARRAY( encode->char_name, count ) ||
if ( FT_NEW_ARRAY( encode->char_index, count ) ||
FT_NEW_ARRAY( encode->char_name, count ) ||
FT_SET_ERROR( psaux->ps_table_funcs->init(
char_table, count, memory ) ) )
{
@ -954,86 +929,74 @@
T1_Add_Table( char_table, n, notdef, 8 );
}
/* Now, we will need to read a record of the form */
/* Now we need to read a record of the form */
/* ... charcode /charname ... for each entry in our table */
/* */
/* We simply look for a number followed by an immediate */
/* name. Note that this ignores correctly the sequence */
/* that is often seen in type1 fonts: */
/* that is often seen in Type 1 fonts: */
/* */
/* 0 1 255 { 1 index exch /.notdef put } for dup */
/* */
/* used to clean the encoding array before anything else. */
/* */
/* We stop when we encounter a `def'. */
cur = parser->root.cursor;
limit = parser->root.limit;
n = 0;
n = 0;
for ( ; cur < limit; )
while ( parser->root.cursor < limit )
{
FT_Byte c;
c = *cur;
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
/* we stop when we encounter a `def' */
if ( c == 'd' && cur + 3 < limit )
if ( *cur == 'd' && cur + 3 < limit )
{
if ( cur[1] == 'e' &&
cur[2] == 'f' &&
is_space( cur[-1] ) &&
is_space( cur[3] ) )
if ( cur[1] == 'e' &&
cur[2] == 'f' &&
is_space( cur[3] ) )
{
FT_TRACE6(( "encoding end\n" ));
cur += 3;
break;
}
}
/* otherwise, we must find a number before anything else */
if ( (FT_Byte)( c - '0' ) < 10 )
if ( ft_isdigit( *cur ) )
{
FT_Int charcode;
parser->root.cursor = cur;
charcode = (FT_Int)T1_ToInt( parser );
cur = parser->root.cursor;
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
/* skip whitespace */
while ( cur < limit && is_space( *cur ) )
cur++;
if ( cur < limit && *cur == '/' )
if ( *cur == '/' && cur + 2 < limit )
{
/* bingo, we have an immediate name -- it must be a */
/* character name */
FT_Byte* cur2 = cur + 1;
FT_PtrDist len;
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
cur++;
len = cur2 - cur - 1;
parser->root.cursor = cur;
T1_Skip_PS_Token( parser );
len = parser->root.cursor - cur;
parser->root.error = T1_Add_Table( char_table, charcode,
cur + 1, len + 1 );
cur, len + 1 );
char_table->elements[charcode][len] = '\0';
if ( parser->root.error )
return;
cur = cur2;
}
}
else
cur++;
T1_Skip_PS_Token( parser );
}
face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
parser->root.cursor = cur;
}
/* Otherwise, we should have either `StandardEncoding', */
/* `ExpertEncoding', or `ISOLatin1Encoding' */
else
@ -1063,35 +1026,38 @@
parse_subrs( T1_Face face,
T1_Loader loader )
{
T1_Parser parser = &loader->parser;
PS_Table table = &loader->subrs;
FT_Memory memory = parser->root.memory;
FT_Error error;
FT_Int n;
T1_Parser parser = &loader->parser;
PS_Table table = &loader->subrs;
FT_Memory memory = parser->root.memory;
FT_Error error;
FT_Int n;
PSAux_Service psaux = (PSAux_Service)face->psaux;
if ( loader->num_subrs )
/* with synthetic fonts, it's possible we get here twice */
/* with synthetic fonts it is possible we get here twice */
return;
if ( parser->root.cursor + 2 > parser->root.limit &&
parser->root.cursor[0] == '[' &&
parser->root.cursor[1] == ']' )
T1_Skip_Spaces( parser );
/* test for empty array */
if ( parser->root.cursor < parser->root.limit &&
*parser->root.cursor == '[' )
{
/* empty array */
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
if ( parser->root.cursor >= parser->root.limit ||
*parser->root.cursor != ']' )
parser->root.error = T1_Err_Invalid_File_Format;
return;
}
loader->num_subrs = (FT_Int)T1_ToInt( parser );
if ( parser->root.error )
return;
/* position the parser right before the `dup' of the first subr */
T1_Skip_Spaces( parser );
T1_Skip_Alpha( parser ); /* `array' */
T1_Skip_Spaces( parser );
T1_Skip_PS_Token( parser ); /* `array' */
T1_Skip_Spaces ( parser );
/* initialize subrs array */
error = psaux->ps_table_funcs->init( table, loader->num_subrs, memory );
@ -1113,6 +1079,8 @@
if ( ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
break;
T1_Skip_PS_Token( parser ); /* `dup' */
idx = T1_ToInt( parser );
if ( !read_binary_data( parser, &size, &base ) )
@ -1122,14 +1090,13 @@
/* (bound to `noaccess put') or by two separate tokens: */
/* `noaccess' & `put'. We position the parser right */
/* before the next `dup', if any. */
T1_Skip_Spaces( parser );
T1_Skip_Alpha( parser ); /* `NP' or `I' or `noaccess' */
T1_Skip_Spaces( parser );
T1_Skip_PS_Token( parser ); /* `NP' or `I' or `noaccess' */
T1_Skip_Spaces ( parser );
if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
{
T1_Skip_Alpha( parser ); /* skip `put' */
T1_Skip_Spaces( parser );
T1_Skip_PS_Token( parser ); /* skip `put' */
T1_Skip_Spaces ( parser );
}
/* some fonts use a value of -1 for lenIV to indicate that */
@ -1164,6 +1131,9 @@
}
#define TABLE_EXTEND 5
static void
parse_charstrings( T1_Face face,
T1_Loader loader )
@ -1185,25 +1155,24 @@
if ( loader->num_glyphs )
/* with synthetic fonts, it's possible we get here twice */
/* with synthetic fonts it is possible we get here twice */
return;
loader->num_glyphs = (FT_Int)T1_ToInt( parser );
if ( parser->root.error )
return;
/* initialize tables (leaving room for addition of .notdef, */
/* if necessary). */
/* initialize tables, leaving room for addition of .notdef, */
/* if necessary, and a few other glyphs to handle buggy */
/* fonts which have more glyphs than specified. */
error = psaux->ps_table_funcs->init( code_table,
loader->num_glyphs + 1,
memory );
error = psaux->ps_table_funcs->init(
code_table, loader->num_glyphs + 1 + TABLE_EXTEND, memory );
if ( error )
goto Fail;
error = psaux->ps_table_funcs->init( name_table,
loader->num_glyphs + 1,
memory );
error = psaux->ps_table_funcs->init(
name_table, loader->num_glyphs + 1 + TABLE_EXTEND, memory );
if ( error )
goto Fail;
@ -1235,29 +1204,34 @@
break;
/* we stop when we find a `def' or `end' keyword */
if ( *cur == 'd' &&
cur + 3 < limit &&
cur[1] == 'e' &&
cur[2] == 'f' )
break;
if ( cur + 3 < limit && is_space( cur[3] ) )
{
if ( cur[0] == 'd' &&
cur[1] == 'e' &&
cur[2] == 'f' )
break;
if ( *cur == 'e' &&
cur + 3 < limit &&
cur[1] == 'n' &&
cur[2] == 'd' )
break;
if ( cur[0] == 'e' &&
cur[1] == 'n' &&
cur[2] == 'd' )
break;
}
if ( *cur != '/' )
T1_Skip_Alpha( parser );
T1_Skip_PS_Token( parser );
else
{
FT_Byte* cur2 = cur + 1;
FT_PtrDist len;
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
len = cur2 - cur - 1;
T1_Skip_PS_Token( parser );
if ( cur >= limit )
{
error = T1_Err_Invalid_File_Format;
goto Fail;
}
len = parser->root.cursor - cur;
error = T1_Add_Table( name_table, n, cur + 1, len + 1 );
if ( error )
@ -1274,11 +1248,11 @@
notdef_found = 1;
}
parser->root.cursor = cur2;
if ( !read_binary_data( parser, &size, &base ) )
return;
if ( face->type1.private_dict.lenIV >= 0 )
if ( face->type1.private_dict.lenIV >= 0 &&
n < loader->num_glyphs + TABLE_EXTEND )
{
FT_Byte* temp;
@ -1299,8 +1273,6 @@
goto Fail;
n++;
if ( n >= loader->num_glyphs )
break;
}
}
@ -1311,11 +1283,11 @@
(const char*)name_table->elements[0] ) &&
notdef_found )
{
/* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
/* name and code entries to swap_table. Then place notdef_index name */
/* and code entries into swap_table. Then swap name and code */
/* entries at indices notdef_index and 0 using values stored in */
/* swap_table. */
/* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */
/* name and code entries to swap_table. Then place notdef_index */
/* name and code entries into swap_table. Then swap name and code */
/* entries at indices notdef_index and 0 using values stored in */
/* swap_table. */
/* Index 0 name */
error = T1_Add_Table( swap_table, 0,
@ -1426,6 +1398,14 @@
}
/*************************************************************************/
/* */
/* Define the token field static variables. This is a set of */
/* T1_FieldRec variables. */
/* */
/*************************************************************************/
static
const T1_FieldRec t1_keywords[] =
{
@ -1462,120 +1442,134 @@
FT_Byte* keyword_flags )
{
T1_Parser parser = &loader->parser;
FT_Byte* limit;
parser->root.cursor = base;
parser->root.limit = base + size;
parser->root.error = 0;
parser->root.error = T1_Err_Ok;
limit = parser->root.limit;
while ( parser->root.cursor < limit )
{
FT_Byte* cur = base;
FT_Byte* limit = cur + size;
FT_Byte* cur;
for ( ; cur < limit; cur++ )
T1_Skip_Spaces( parser );
cur = parser->root.cursor;
/* look for `FontDirectory', which causes problems for some fonts */
if ( *cur == 'F' && cur + 25 < limit &&
ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
{
/* look for `FontDirectory', which causes problems on some fonts */
if ( *cur == 'F' && cur + 25 < limit &&
ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
FT_Byte* cur2;
/* skip the `FontDirectory' keyword */
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
cur = cur2 = parser->root.cursor;
/* look up the `known' keyword */
while ( cur < limit )
{
FT_Byte* cur2;
if ( *cur == 'k' && cur + 5 < limit &&
ft_strncmp( (char*)cur, "known", 5 ) )
break;
/* skip the `FontDirectory' keyword */
cur += 13;
cur2 = cur;
/* lookup the `known' keyword */
while ( cur < limit && *cur != 'k' &&
ft_strncmp( (char*)cur, "known", 5 ) )
cur++;
if ( cur < limit )
{
T1_TokenRec token;
/* skip the `known' keyword and the token following it */
cur += 5;
loader->parser.root.cursor = cur;
T1_ToToken( &loader->parser, &token );
/* if the last token was an array, skip it! */
if ( token.type == T1_TOKEN_TYPE_ARRAY )
cur2 = parser->root.cursor;
}
cur = cur2;
T1_Skip_PS_Token( parser );
T1_Skip_Spaces ( parser );
cur = parser->root.cursor;
}
/* look for immediates */
else if ( *cur == '/' && cur + 2 < limit )
if ( cur < limit )
{
FT_Byte* cur2;
FT_PtrDist len;
T1_TokenRec token;
cur++;
cur2 = cur;
while ( cur2 < limit && is_name_char( *cur2 ) )
cur2++;
/* skip the `known' keyword and the token following it */
T1_Skip_PS_Token( parser );
T1_ToToken( parser, &token );
len = cur2 - cur;
if ( len > 0 && len < 22 )
/* if the last token was an array, skip it! */
if ( token.type == T1_TOKEN_TYPE_ARRAY )
cur2 = parser->root.cursor;
}
parser->root.cursor = cur2;
}
/* look for `closefile' which ends the eexec section */
else if ( *cur == 'c' && cur + 9 < limit &&
ft_strncmp( (char*)cur, "closefile", 9 ) == 0 )
break;
/* look for immediates */
else if ( *cur == '/' && cur + 2 < limit )
{
FT_PtrDist len;
cur++;
parser->root.cursor = cur;
T1_Skip_PS_Token( parser );
len = parser->root.cursor - cur;
if ( len > 0 && len < 22 )
{
/* now compare the immediate name to the keyword table */
T1_Field keyword = (T1_Field)t1_keywords;
FT_Byte* keyword_flag = keyword_flags;
for (;;)
{
FT_Byte* name;
name = (FT_Byte*)keyword->ident;
if ( !name )
{
/* now, compare the immediate name to the keyword table */
T1_Field keyword = (T1_Field)t1_keywords;
FT_Byte* keyword_flag = keyword_flags;
T1_Skip_PS_Token( parser );
break;
}
if ( cur[0] == name[0] &&
len == ft_strlen( (const char*)name ) )
{
FT_PtrDist n;
for (;;)
{
FT_Byte* name;
name = (FT_Byte*)keyword->ident;
if ( !name )
for ( n = 1; n < len; n++ )
if ( cur[n] != name[n] )
break;
if ( cur[0] == name[0] &&
len == ft_strlen( (const char*)name ) )
if ( n >= len )
{
/* We found it -- run the parsing callback! */
/* We only record the first instance of any */
/* field to deal adequately with synthetic fonts */
if ( keyword_flag[0] == 0 )
{
FT_PtrDist n;
for ( n = 1; n < len; n++ )
if ( cur[n] != name[n] )
break;
if ( n >= len )
{
/* we found it -- run the parsing callback! */
parser->root.cursor = cur2;
T1_Skip_Spaces( parser );
/* we only record the first instance of any */
/* field to deal adequately with synthetic fonts */
if ( keyword_flag[0] == 0 )
{
parser->root.error = t1_load_keyword( face,
loader,
keyword );
if ( parser->root.error )
return parser->root.error;
}
keyword_flag[0] = 1;
cur = parser->root.cursor;
break;
}
parser->root.error = t1_load_keyword( face,
loader,
keyword );
if ( parser->root.error )
return parser->root.error;
}
keyword++;
keyword_flag++;
keyword_flag[0] = 1;
break;
}
}
keyword++;
keyword_flag++;
}
}
}
else
T1_Skip_PS_Token( parser );
}
return parser->root.error;
}
@ -1742,16 +1736,21 @@
if ( ft_strcmp( (const char*)".notdef",
(const char*)glyph_name ) != 0 )
{
if ( charcode < min_char ) min_char = charcode;
if ( charcode > max_char ) max_char = charcode;
if ( charcode < min_char )
min_char = charcode;
if ( charcode > max_char )
max_char = charcode;
}
break;
}
}
}
/* Yes, this happens: Certain PDF-embedded fonts have only a ".notdef"
* glyph defined!
/*
* Yes, this happens: Certain PDF-embedded fonts have only a
* `.notdef' glyph defined!
*/
if ( min_char > max_char )
{
min_char = 0;

View File

@ -104,7 +104,7 @@
FT_Long size;
psaux->ps_parser_funcs->init( &parser->root,0, 0, memory );
psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
parser->stream = stream;
parser->base_len = 0;
@ -219,36 +219,13 @@
}
/* return the value of an hexadecimal digit */
static int
hexa_value( char c )
{
unsigned int d;
d = (unsigned int)( c - '0' );
if ( d <= 9 )
return (int)d;
d = (unsigned int)( c - 'a' );
if ( d <= 5 )
return (int)( d + 10 );
d = (unsigned int)( c - 'A' );
if ( d <= 5 )
return (int)( d + 10 );
return -1;
}
FT_LOCAL_DEF( FT_Error )
T1_Get_Private_Dict( T1_Parser parser,
PSAux_Service psaux )
{
FT_Stream stream = parser->stream;
FT_Memory memory = parser->root.memory;
FT_Error error = 0;
FT_Error error = T1_Err_Ok;
FT_Long size;
@ -302,7 +279,8 @@
break;
}
if ( FT_STREAM_READ( parser->private_dict + parser->private_len, size ) )
if ( FT_STREAM_READ( parser->private_dict + parser->private_len,
size ) )
goto Fail;
parser->private_len += size;
@ -310,9 +288,9 @@
}
else
{
/* we have already `loaded' the whole PFA font file into memory; */
/* We have already `loaded' the whole PFA font file into memory; */
/* if this is a memory resource, allocate a new block to hold */
/* the private dict. Otherwise, simply overwrite into the base */
/* the private dict. Otherwise, simply overwrite into the base */
/* dictionary block in the heap. */
/* first of all, look at the `eexec' keyword */
@ -330,7 +308,7 @@
if ( cur[1] == 'e' && cur[2] == 'x' &&
cur[3] == 'e' && cur[4] == 'c' )
{
cur += 6; /* we skip the newling after the `eexec' */
cur += 6; /* we skip the newline after the `eexec' */
/* XXX: Some fonts use DOS-linefeeds, i.e. \r\n; we need to */
/* skip the extra \n if we find it */
@ -379,51 +357,38 @@
/* the `eexec' keyword); if they all are hexadecimal digits, then */
/* we have a case of ASCII storage */
if ( ( hexa_value( cur[0] ) | hexa_value( cur[1] ) |
hexa_value( cur[2] ) | hexa_value( cur[3] ) ) < 0 )
/* binary encoding -- `simply' copy the private dict */
FT_MEM_COPY( parser->private_dict, cur, size );
else
if ( ft_isxdigit( cur[0] ) && ft_isxdigit( cur[1] ) &&
ft_isxdigit( cur[2] ) && ft_isxdigit( cur[3] ) )
{
/* ASCII hexadecimal encoding */
FT_Byte* write;
FT_Int count;
FT_Long len;
write = parser->private_dict;
count = 0;
for ( ;cur < limit; cur++ )
{
int hex1;
/* check for newline */
if ( cur[0] == '\r' || cur[0] == '\n' )
continue;
/* exit if we have a non-hexadecimal digit that isn't a newline */
hex1 = hexa_value( cur[0] );
if ( hex1 < 0 || cur + 1 >= limit )
break;
/* otherwise, store byte */
*write++ = (FT_Byte)( ( hex1 << 4 ) | hexa_value( cur[1] ) );
count++;
cur++;
}
parser->root.cursor = cur;
(void)psaux->ps_parser_funcs->to_bytes( &parser->root,
parser->private_dict,
parser->private_len,
&len,
0 );
parser->private_len = len;
/* put a safeguard */
parser->private_len = write - parser->private_dict;
*write++ = 0;
parser->private_dict[len] = '\0';
}
else
/* binary encoding -- copy the private dict */
FT_MEM_COPY( parser->private_dict, cur, size );
}
/* we now decrypt the encoded binary private dictionary */
psaux->t1_decrypt( parser->private_dict, parser->private_len, 55665U );
/* replace the four random bytes at the beginning with whitespace */
parser->private_dict[0] = ' ';
parser->private_dict[1] = ' ';
parser->private_dict[2] = ' ';
parser->private_dict[3] = ' ';
parser->root.base = parser->private_dict;
parser->root.cursor = parser->private_dict;
parser->root.limit = parser->root.cursor + parser->private_len;

View File

@ -4,7 +4,7 @@
/* */
/* Type 1 parser (specification). */
/* */
/* Copyright 1996-2001, 2002 by */
/* Copyright 1996-2001, 2002, 2003 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -69,9 +69,9 @@ FT_BEGIN_HEADER
FT_Byte* private_dict;
FT_Long private_len;
FT_Byte in_pfb;
FT_Byte in_memory;
FT_Byte single_block;
FT_Bool in_pfb;
FT_Bool in_memory;
FT_Bool single_block;
} T1_ParserRec, *T1_Parser;
@ -91,8 +91,8 @@ FT_BEGIN_HEADER
} while ( 0 )
#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root )
#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root )
#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root )
#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t )

View File

@ -111,8 +111,8 @@
(p)->funcs.release( p ); \
} while ( 0 )
#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
#define T1_Skip_Alpha( p ) (p)->root.funcs.skip_alpha ( &(p)->root )
#define T1_Skip_Spaces( p ) (p)->root.funcs.skip_spaces( &(p)->root )
#define T1_Skip_PS_Token( p ) (p)->root.funcs.skip_PS_token( &(p)->root )
#define T1_ToInt( p ) (p)->root.funcs.to_int( &(p)->root )
#define T1_ToFixed( p, t ) (p)->root.funcs.to_fixed( &(p)->root, t )
@ -318,7 +318,7 @@
/* if we have a number, then the encoding is an array, */
/* and we must load it now */
if ( (FT_Byte)( *cur - '0' ) < 10 )
if ( ft_isdigit( *cur ) )
{
T1_Encoding encode = &face->type1.encoding;
FT_Int count, n;
@ -394,7 +394,7 @@
}
/* otherwise, we must find a number before anything else */
if ( (FT_Byte)( c - '0' ) < 10 )
if ( ft_isdigit( c ) )
{
FT_Int charcode;
@ -571,7 +571,7 @@
}
default:
if ( !ft_xdigit( *cur ) || !ft_xdigit( *(cur + 1) ) )
if ( !ft_isxdigit( *cur ) || !ft_isxdigit( *(cur + 1) ) )
{
FT_ERROR(( "t42_parse_sfnts: found non-hex characters in string" ));
error = T42_Err_Invalid_File_Format;
@ -705,7 +705,7 @@
break;
if ( *cur != '/' )
T1_Skip_Alpha( parser );
T1_Skip_PS_Token( parser );
else
{
FT_Byte* cur2 = cur + 1;