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:
parent
d0cb15f1db
commit
52f911a12d
94
ChangeLog
94
ChangeLog
@ -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...
|
||||
|
@ -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>
|
||||
|
@ -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 )
|
||||
|
@ -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,
|
||||
|
@ -51,6 +51,9 @@
|
||||
FT_FACE_LOOKUP_SERVICE( face,
|
||||
*aservice,
|
||||
MULTI_MASTERS );
|
||||
|
||||
if ( aservice )
|
||||
error = FT_Err_Ok;
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -26,6 +26,7 @@
|
||||
{
|
||||
FT_Service_PfrMetrics service;
|
||||
|
||||
|
||||
FT_FACE_LOOKUP_SERVICE( face, service, PFR_METRICS );
|
||||
|
||||
return service;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 )
|
||||
|
@ -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
@ -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 )
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user