* freetype2/include/freetype/internal/psaux.h: New macros

IS_PS_NEWLINE, IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT,
IS_PS_XDIGIT, and IS_PS_BASE85 (from freetype2/src/psaux/psconv.h).
(T1_FieldLocation): Add T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE, and T1_FIELD_LOCATION_BLEND.
(T1_DecoderRec): New fields `buildchar' and `face'.
(IS_PS_TOKEN): New macro.

* freetype2/include/freetype/internal/t1types.h (T1_FaceRec): New
fields `ndv_idx', `cdv_idx', and `len_buildchar'.

* freetype2/include/freetype/t1tables.h (PS_BlendRec): New fields
`default_design_vector' and `num_default_design_vector'.

* freetype2/src/psaux/psconv.h: Move macros IS_PS_NEWLINE,
IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT,
and IS_PS_BASE85 to freetype2/include/freetype/internal/psaux.h.

* freetype2/src/psaux/psobjs.c (ps_parser_to_token_array): Allow
`token' argument to be NULL if we want only to count the number of
tokens.
(ps_tocoordarray): Allow `coords' argument to be NULL if we just
want to skip the array.
(ps_tofixedarray): Allow `values' argument to be NULL if we just
want to skip the array.

* freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add
support for (partially commented out) othersubrs 19-25, 27, and 28.
(t1_decoder_init): Initialize new fields `face' and `buildchar'.
(t1_decoder_done): Release new field `buildchar'.

* freetype2/src/type1/t1load.c (parse_buildchar, parse_private): New
functions.
(t1_keywords): Register them.
(t1_allocate_blend): Updated.
(t1_load_keyword): Handle field types T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE and T1_FIELD_LOCATION_BLEND.
(parse_dict): Remove `keyword_flags' argument.
Use new macro IS_PS_TOKEN.
Changed function so that later PostScript definitions override
earlier ones.
(t1_init_loader): Initialize new field `keywords_encountered'.
(T1_Open_Face): Initialize new fields `ndv_idx', `cdv_idx', and
`len_buildchar'.
Remove `keywords_flags'.

* freetype2/src/type1/t1load.h (T1_LoaderRect): New field
`keywords_encountered'.
(T1_PRIVATE, T1_FONTDIR_AFTER_PRIVATE): New macros.

* freetype2/src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]:
New entries for parsing /NDV, /CDV, and /DesignVector.
This commit is contained in:
Werner Lemberg 2006-07-14 18:28:08 +00:00
parent 4af3c4d7ee
commit 1a380e02d1
10 changed files with 519 additions and 102 deletions

View File

@ -1,3 +1,58 @@
2006-07-14 Jens Claudius <jens.claudius@yahoo.com>
* freetype2/include/freetype/internal/psaux.h: New macros
IS_PS_NEWLINE, IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT,
IS_PS_XDIGIT, and IS_PS_BASE85 (from freetype2/src/psaux/psconv.h).
(T1_FieldLocation): Add T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE, and T1_FIELD_LOCATION_BLEND.
(T1_DecoderRec): New fields `buildchar' and `face'.
(IS_PS_TOKEN): New macro.
* freetype2/include/freetype/internal/t1types.h (T1_FaceRec): New
fields `ndv_idx', `cdv_idx', and `len_buildchar'.
* freetype2/include/freetype/t1tables.h (PS_BlendRec): New fields
`default_design_vector' and `num_default_design_vector'.
* freetype2/src/psaux/psconv.h: Move macros IS_PS_NEWLINE,
IS_PS_SPACE, IS_PS_SPECIAL, IS_PS_DELIM, IS_PS_DIGIT, IS_PS_XDIGIT,
and IS_PS_BASE85 to freetype2/include/freetype/internal/psaux.h.
* freetype2/src/psaux/psobjs.c (ps_parser_to_token_array): Allow
`token' argument to be NULL if we want only to count the number of
tokens.
(ps_tocoordarray): Allow `coords' argument to be NULL if we just
want to skip the array.
(ps_tofixedarray): Allow `values' argument to be NULL if we just
want to skip the array.
* freetype2/src/psaux/t1decode.c (t1_decoder_parse_charstrings): Add
support for (partially commented out) othersubrs 19-25, 27, and 28.
(t1_decoder_init): Initialize new fields `face' and `buildchar'.
(t1_decoder_done): Release new field `buildchar'.
* freetype2/src/type1/t1load.c (parse_buildchar, parse_private): New
functions.
(t1_keywords): Register them.
(t1_allocate_blend): Updated.
(t1_load_keyword): Handle field types T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE and T1_FIELD_LOCATION_BLEND.
(parse_dict): Remove `keyword_flags' argument.
Use new macro IS_PS_TOKEN.
Changed function so that later PostScript definitions override
earlier ones.
(t1_init_loader): Initialize new field `keywords_encountered'.
(T1_Open_Face): Initialize new fields `ndv_idx', `cdv_idx', and
`len_buildchar'.
Remove `keywords_flags'.
* freetype2/src/type1/t1load.h (T1_LoaderRect): New field
`keywords_encountered'.
(T1_PRIVATE, T1_FONTDIR_AFTER_PRIVATE): New macros.
* freetype2/src/type1/t1tokens.h [!T1_CONFIG_OPTION_NO_MM_SUPPORT]:
New entries for parsing /NDV, /CDV, and /DesignVector.
2006-07-07 Werner Lemberg <wl@gnu.org>
Add many checks to protect against malformed PCF files.

View File

@ -199,6 +199,9 @@ FT_BEGIN_HEADER
T1_FIELD_LOCATION_FONT_INFO,
T1_FIELD_LOCATION_PRIVATE,
T1_FIELD_LOCATION_BBOX,
T1_FIELD_LOCATION_LOADER,
T1_FIELD_LOCATION_FACE,
T1_FIELD_LOCATION_BLEND,
/* do not remove */
T1_FIELD_LOCATION_MAX
@ -683,6 +686,10 @@ FT_BEGIN_HEADER
T1_Decoder_Callback parse_callback;
T1_Decoder_FuncsRec funcs;
FT_Int* buildchar;
T1_Face face;
} T1_DecoderRec;
@ -712,8 +719,10 @@ FT_BEGIN_HEADER
} AFM_Parser_FuncsRec;
typedef struct AFM_StreamRec_* AFM_Stream;
/*************************************************************************/
/* */
/* <Struct> */
@ -801,6 +810,57 @@ FT_BEGIN_HEADER
/* backwards-compatible type definition */
typedef PSAux_ServiceRec PSAux_Interface;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** Some convenience functions *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define IS_PS_NEWLINE( ch ) \
( (ch) == '\r' || \
(ch) == '\n' )
#define IS_PS_SPACE( ch ) \
( (ch) == ' ' || \
IS_PS_NEWLINE( ch ) || \
(ch) == '\t' || \
(ch) == '\f' || \
(ch) == '\0' )
#define IS_PS_SPECIAL( ch ) \
( (ch) == '/' || \
(ch) == '(' || (ch) == ')' || \
(ch) == '<' || (ch) == '>' || \
(ch) == '[' || (ch) == ']' || \
(ch) == '{' || (ch) == '}' || \
(ch) == '%' )
#define IS_PS_DELIM( ch ) \
( IS_PS_SPACE( ch ) || \
IS_PS_SPECIAL( ch ) )
#define IS_PS_DIGIT( ch ) \
( (ch) >= '0' && (ch) <= '9' )
#define IS_PS_XDIGIT( ch ) \
( IS_PS_DIGIT( ch ) || \
( (ch) >= 'A' && (ch) <= 'F' ) || \
( (ch) >= 'a' && (ch) <= 'f' ) )
#define IS_PS_BASE85( ch ) \
( (ch) >= '!' && (ch) <= 'u' )
#define IS_PS_TOKEN( cur, limit, token ) \
( (char)(cur)[0] == (token)[0] && \
( (cur) + sizeof ( (token) ) == (limit) || \
( (cur) + sizeof( (token) ) < (limit) && \
IS_PS_DELIM( (cur)[sizeof ( (token) ) - 1] ) ) ) && \
ft_strncmp( (char*)(cur), (token), sizeof ( (token) ) - 1 ) == 0 )
FT_END_HEADER
#endif /* __PSAUX_H__ */

View File

@ -208,6 +208,16 @@ FT_BEGIN_HEADER
/* support for Multiple Masters fonts */
PS_Blend blend;
/* undocumented, optional: indices of subroutines that express */
/* the NormalizeDesignVector and the ConvertDesignVector procedure, */
/* respectively, as Type 2 charstrings; -1 if keywords not present */
FT_Int ndv_idx;
FT_Int cdv_idx;
/* undocumented, optional: has the same meaning as len_buildchar */
/* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25 */
FT_UInt len_buildchar;
/* since version 2.1 - interface to PostScript hinter */
const void* pshinter;

View File

@ -5,7 +5,7 @@
/* Basic Type 1/Type 2 tables definitions and interface (specification */
/* only). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -256,6 +256,15 @@ FT_BEGIN_HEADER
FT_BBox* bboxes [T1_MAX_MM_DESIGNS + 1];
/* since 2.2.2 */
/* undocumented, optional: the default design instance; */
/* corresponds to default_weight_vector -- */
/* num_default_design_vector == 0 means it is not present */
/* in the font and associated metrics files */
FT_UInt default_design_vector[T1_MAX_MM_DESIGNS];
FT_UInt num_default_design_vector;
} PS_BlendRec, *PS_Blend;

View File

@ -63,42 +63,6 @@ FT_BEGIN_HEADER
FT_UShort* seed );
#define IS_PS_NEWLINE( ch ) \
( ( ch ) == '\r' || \
( ch ) == '\n' )
#define IS_PS_SPACE( ch ) \
( ( ch ) == ' ' || \
IS_PS_NEWLINE( ch ) || \
( ch ) == '\t' || \
( ch ) == '\f' || \
( ch ) == '\0' )
#define IS_PS_SPECIAL( ch ) \
( ( ch ) == '/' || \
( ch ) == '(' || \
( ch ) == ')' || \
( ch ) == '<' || \
( ch ) == '>' || \
( ch ) == '[' || \
( ch ) == ']' || \
( ch ) == '{' || \
( ch ) == '}' || \
( ch ) == '%' )
#define IS_PS_DELIM( ch ) \
( IS_PS_SPACE( ch ) || \
IS_PS_SPECIAL( ch ) )
#define IS_PS_DIGIT( ch ) ( ( ch ) >= '0' && ( ch ) <= '9' )
#define IS_PS_XDIGIT( ch ) \
( IS_PS_DIGIT( ( ch ) ) || \
( ( ch ) >= 'A' && ( ch ) <= 'F' ) || \
( ( ch ) >= 'a' && ( ch ) <= 'f' ) )
#define IS_PS_BASE85( ch ) ( ( ch ) >= '!' && ( ch ) <= 'u' )
FT_END_HEADER
#endif /* __PSCONV_H__ */

View File

@ -698,6 +698,9 @@
}
/* NB: `tokens' can be NULL if we only want to count */
/* the number of array elements */
FT_LOCAL_DEF( void )
ps_parser_to_token_array( PS_Parser parser,
T1_Token tokens,
@ -733,7 +736,7 @@
if ( !token.type )
break;
if ( cur < limit )
if ( tokens != NULL && cur < limit )
*cur = token;
cur++;
@ -748,6 +751,8 @@
/* first character must be a delimiter or a part of a number */
/* NB: `coords' can be NULL if we just want to skip the */
/* array; in this case we ignore `max_coords' */
static FT_Int
ps_tocoordarray( FT_Byte* *acur,
@ -780,21 +785,26 @@
/* now, read the coordinates */
while ( cur < limit )
{
FT_Short dummy;
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_coords )
if ( coords != NULL && count >= max_coords )
break;
if ( c == ender )
if ( *cur == ender )
{
cur++;
break;
}
coords[count] =
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( coords != NULL ? &coords[count] : &dummy ) =
(FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
count++;
@ -809,6 +819,8 @@
/* first character must be a delimiter or a part of a number */
/* NB: `values' can be NULL if we just want to skip the */
/* array in this case we ignore `max_values' */
static FT_Int
ps_tofixedarray( FT_Byte* *acur,
@ -842,21 +854,27 @@
/* now, read the values */
while ( cur < limit )
{
FT_Fixed dummy;
/* skip whitespace in front of data */
skip_spaces( &cur, limit );
if ( cur >= limit )
goto Exit;
if ( count >= max_values )
if ( values != NULL && count >= max_values )
break;
if ( c == ender )
if ( *cur == ender )
{
cur++;
break;
}
values[count] = PS_Conv_ToFixed( &cur, limit, power_ten );
/* call PS_Conv_ToFixed() even if coords == NULL */
/* to properly parse number at `cur' */
*( values != NULL ? &values[count] : &dummy ) =
PS_Conv_ToFixed( &cur, limit, power_ten );
count++;
if ( !ender )

View File

@ -348,6 +348,14 @@
hinter = (T1_Hints_Funcs)builder->hints_funcs;
/* a font that reads BuildCharArray without setting */
/* its values first is buggy, but ... */
if ( decoder->face->len_buildchar > 0 )
memset( &decoder->buildchar[0],
0,
sizeof( decoder->buildchar[0] ) *
decoder->face->len_buildchar );
FT_TRACE4(( "\nStart charstring\n" ));
zone->base = charstring_base;
@ -582,12 +590,9 @@
subr_no = (FT_Int)top[1];
arg_cnt = (FT_Int)top[0];
if ( arg_cnt > top - decoder->stack )
goto Stack_Underflow;
/***********************************************************/
/* */
/* remove all operands to callsubr from the stack */
/* remove all operands to callothersubr from the stack */
/* */
/* for handled othersubrs, where we know the number of */
/* arguments, we increase the stack by the value of */
@ -596,11 +601,30 @@
/* for unhandled othersubrs the following pops adjust the */
/* stack pointer as necessary */
if ( arg_cnt > top - decoder->stack )
goto Stack_Underflow;
top -= arg_cnt;
known_othersubr_result_cnt = 0;
unknown_othersubr_result_cnt = 0;
/* XXX TODO: The checks to `arg_count == <whatever>' */
/* might not be correct; an othersubr expects a certain */
/* number of operands on the PostScript stack (as opposed */
/* to the T1 stack) but it doesn't have to put them there */
/* by itself; previous othersubrs might have left the */
/* operands there if they were not followed by an */
/* appropriate number of pops */
/* */
/* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
/* accept a font that contains charstrings like */
/* */
/* 100 200 2 20 callothersubr */
/* 300 1 20 callothersubr pop */
/* */
/* Perhaps this is the reason why BuildCharArray exists. */
switch ( subr_no )
{
case 1: /* start flex feature */
@ -726,6 +750,158 @@
break;
}
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
/* We cannot yet enable these since currently */
/* our T1 stack stores integers which lack the */
/* precision to express the values */
case 19:
/* <idx> 1 19 callothersubr */
/* => replace elements starting from index cvi( <idx> ) */
/* of BuildCharArray with WeightVector */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[0];
if ( idx < 0 ||
idx + blend->num_designs > decoder->face->len_buildchar )
goto Unexpected_OtherSubr;
memcpy( &decoder->buildchar[idx],
blend->weight_vector,
blend->num_designs *
sizeof( blend->weight_vector[ 0 ] ) );
}
break;
case 20:
/* <arg1> <arg2> 2 20 callothersubr pop */
/* ==> push <arg1> + <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] += top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 21:
/* <arg1> <arg2> 2 21 callothersubr pop */
/* ==> push <arg1> - <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] -= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 22:
/* <arg1> <arg2> 2 22 callothersubr pop */
/* ==> push <arg1> * <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] *= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 23:
/* <arg1> <arg2> 2 23 callothersubr pop */
/* ==> push <arg1> / <arg2> onto T1 stack */
if ( arg_cnt != 2 || top[1] == 0 )
goto Unexpected_OtherSubr;
top[0] /= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
case 24:
/* <val> <idx> 2 24 callothersubr */
/* => set BuildCharArray[cvi( <idx> )] = <val> */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 2 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[1];
if ( idx < 0 || (FT_UInt) idx >= decoder->face->len_buildchar )
goto Unexpected_OtherSubr;
decoder->buildchar[idx] = top[0];
}
break;
case 25:
/* <idx> 1 25 callothersubr pop */
/* => push BuildCharArray[cvi( idx )] */
/* onto T1 stack */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[0];
if ( idx < 0 || (FT_UInt) idx >= decoder->face->len_buildchar )
goto Unexpected_OtherSubr;
top[0] = decoder->buildchar[idx];
}
known_othersubr_result_cnt = 1;
break;
#if 0
case 26:
/* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
/* leave mark on T1 stack */
/* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
XXX who has left his mark on the (PostScript) stack ?;
break;
#endif
case 27:
/* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
/* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
/* otherwise push <res2> */
if ( arg_cnt != 4 )
goto Unexpected_OtherSubr;
if ( top[2] > top[3] )
top[0] = top[1];
known_othersubr_result_cnt = 1;
break;
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
case 28:
/* 0 28 callothersubr pop */
/* => push random value from interval [0, 1) onto stack */
if ( arg_cnt != 0 )
goto Unexpected_OtherSubr;
top[0] = FT_rand();
known_othersubr_result_cnt = 1;
break;
#endif
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unknown othersubr [%d %d], wish me luck!\n",
@ -805,8 +981,30 @@
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );
FT_TRACE4(( "\n" ));
/* the compiler should optimize away this empty loop but ... */
#ifdef FT_DEBUG_LEVEL_TRACE
if ( decoder->face->len_buildchar > 0 )
{
FT_UInt i;
FT_TRACE4(( "BuildCharArray = [ " ));
for ( i = 0; i < decoder->face->len_buildchar; ++i )
FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
FT_TRACE4(( "]\n" ));
}
#endif /* FT_DEBUG_LEVEL_TRACE */
FT_TRACE4(( "\n" ));
/* return now! */
FT_TRACE4(( "\n\n" ));
return PSaux_Err_Ok;
case op_hsbw:
@ -1225,6 +1423,10 @@
FT_Render_Mode hint_mode,
T1_Decoder_Callback parse_callback )
{
FT_Error error;
FT_Memory memory = face->memory;
FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
/* retrieve PSNames interface from list of current modules */
@ -1243,6 +1445,18 @@
decoder->psnames = psnames;
}
decoder->face = (T1_Face) face;
if ( decoder->face->len_buildchar > 0 )
{
if ( FT_NEW_ARRAY( decoder->buildchar, decoder->face->len_buildchar ) )
{
FT_ERROR(( "t1_decoder_init: " ));
FT_ERROR(( "cannot allocate memory for BuildCharArray\n" ));
return error;
}
}
t1_builder_init( &decoder->builder, face, size, slot, hinting );
decoder->num_glyphs = (FT_UInt)face->num_glyphs;
@ -1261,7 +1475,12 @@
FT_LOCAL_DEF( void )
t1_decoder_done( T1_Decoder decoder )
{
FT_Memory memory = decoder->face->root.memory;
t1_builder_done( &decoder->builder );
FT_FREE( decoder->buildchar );
}

View File

@ -107,6 +107,8 @@
if ( FT_NEW( blend ) )
goto Exit;
blend->num_default_design_vector = 0;
face->blend = blend;
}
@ -877,6 +879,18 @@
}
/* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */
/* we're only interested in the number of array elements */
static void
parse_buildchar( T1_Face face,
T1_Loader loader )
{
face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 );
return;
}
#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
@ -950,6 +964,26 @@
}
break;
case T1_FIELD_LOCATION_LOADER:
dummy_object = loader;
objects = &dummy_object;
max_objects = 0;
break;
case T1_FIELD_LOCATION_FACE:
dummy_object = face;
objects = &dummy_object;
max_objects = 0;
break;
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
case T1_FIELD_LOCATION_BLEND:
dummy_object = face->blend;
objects = &dummy_object;
max_objects = 0;
break;
#endif
default:
dummy_object = &face->type1;
objects = &dummy_object;
@ -969,6 +1003,16 @@
}
static void
parse_private( T1_Face face,
T1_Loader loader )
{
FT_UNUSED( face );
loader->keywords_encountered |= T1_PRIVATE;
}
static int
is_space( FT_Byte c )
{
@ -1681,12 +1725,14 @@
T1_FIELD_CALLBACK( "Encoding", parse_encoding )
T1_FIELD_CALLBACK( "Subrs", parse_subrs )
T1_FIELD_CALLBACK( "CharStrings", parse_charstrings )
T1_FIELD_CALLBACK( "Private", parse_private )
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
T1_FIELD_CALLBACK( "BlendDesignPositions", parse_blend_design_positions )
T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map )
T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types )
T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector )
T1_FIELD_CALLBACK( "BuildCharArray", parse_buildchar )
#endif
{ 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
@ -1701,8 +1747,7 @@
parse_dict( T1_Face face,
T1_Loader loader,
FT_Byte* base,
FT_Long size,
FT_Byte* keyword_flags )
FT_Long size )
{
T1_Parser parser = &loader->parser;
FT_Byte *limit, *start_binary = NULL;
@ -1724,31 +1769,23 @@
cur = parser->root.cursor;
/* cur[5] must be a token delimiter; */
/* eexec encryption is optional, so look for `eexec' */
if ( *cur == 'e' && cur + 5 < limit &&
ft_strncmp( (char*)cur, "eexec", 5 ) == 0 )
/* look for `eexec' */
if ( IS_PS_TOKEN( cur, limit, "eexec" ) )
break;
/* cur[9] must be a token delimiter; */
/* look for `closefile' which ends the eexec section */
else if ( *cur == 'c' && cur + 9 < limit &&
ft_strncmp( (char*)cur, "closefile", 9 ) == 0 )
else if ( IS_PS_TOKEN( cur, limit, "closefile" ) )
break;
#ifdef TO_BE_DONE
/* in a synthetic font the base font starts after a */
/* `FontDictionary' token that is placed after a Private dict */
/* cur[13] must be a token delimiter */
else if ( *cur == 'F' && cur + 13 < limit &&
ft_strncmp( (char*)cur, "FontDirectory", 13 ) == 0 )
else if ( IS_PS_TOKEN( cur, limit, "FontDirectory" ) )
{
if ( loader->private_encountered )
loader->fontdir_after_private = 1;
if ( loader->keywords_encountered & T1_PRIVATE )
loader->keywords_encountered |=
T1_FONTDIR_AFTER_PRIVATE;
parser->root.cursor += 13;
}
#endif
/* check whether we have an integer */
else if ( ft_isdigit( *cur ) )
@ -1807,8 +1844,7 @@
if ( len > 0 && len < 22 && parser->root.cursor < limit )
{
/* now compare the immediate name to the keyword table */
T1_Field keyword = (T1_Field)t1_keywords;
FT_Byte* keyword_flag = keyword_flags;
T1_Field keyword = (T1_Field)t1_keywords;
for (;;)
@ -1824,21 +1860,28 @@
len == (FT_PtrDist)ft_strlen( (const char *)name ) &&
ft_memcmp( cur, name, len ) == 0 )
{
/* We found it -- run the parsing callback! */
/* We only record the first instance of any */
/* field to deal adequately with synthetic */
/* fonts; /Subrs and /CharStrings are */
/* handled specially. */
if ( keyword_flag[0] == 0 ||
ft_strcmp( (const char*)name, "Subrs" ) == 0 ||
ft_strcmp( (const char*)name, "CharStrings" ) == 0 )
/* We found it -- run the parsing callback! */
/* We record every instance of every field */
/* (until we reach the base font of a */
/* synthetic font) to deal adequately with */
/* multiple master fonts; this is also */
/* necessary because later PostScript */
/* definitions override earlier ones */
/* Once we encounter `FontDirectory' after */
/* `/Private', we know that this is a synthetic */
/* font; except for `/CharStrings' we are not */
/* interested in anything that follows this */
/* `FontDirectory' */
if ( !( loader->keywords_encountered &
T1_FONTDIR_AFTER_PRIVATE ) ||
ft_strcmp((const char*)name, "CharStrings") == 0 )
{
parser->root.error = t1_load_keyword( face,
loader,
keyword );
if ( parser->root.error == T1_Err_Ok )
keyword_flag[0] = 1;
else
if ( parser->root.error != T1_Err_Ok )
{
if ( FT_ERROR_BASE( parser->root.error ) == FT_Err_Ignore )
parser->root.error = T1_Err_Ok;
@ -1850,7 +1893,6 @@
}
keyword++;
keyword_flag++;
}
}
@ -1883,12 +1925,13 @@
loader->num_chars = 0;
/* initialize the tables -- simply set their `init' field to 0 */
loader->encoding_table.init = 0;
loader->charstrings.init = 0;
loader->glyph_names.init = 0;
loader->subrs.init = 0;
loader->swap_table.init = 0;
loader->fontdata = 0;
loader->encoding_table.init = 0;
loader->charstrings.init = 0;
loader->glyph_names.init = 0;
loader->subrs.init = 0;
loader->swap_table.init = 0;
loader->fontdata = 0;
loader->keywords_encountered = 0;
}
@ -1918,7 +1961,6 @@
T1_Font type1 = &face->type1;
PS_Private priv = &type1->private_dict;
FT_Error error;
FT_Byte keyword_flags[T1_FIELD_COUNT];
PSAux_Service psaux = (PSAux_Service)face->psaux;
@ -1926,6 +1968,10 @@
t1_init_loader( &loader, face );
/* default values */
face->ndv_idx = -1;
face->cdv_idx = -1;
face->len_buildchar = 0;
priv->blue_shift = 7;
priv->blue_fuzz = 1;
priv->lenIV = 4;
@ -1940,16 +1986,8 @@
if ( error )
goto Exit;
{
FT_UInt n;
for ( n = 0; n < T1_FIELD_COUNT; n++ )
keyword_flags[n] = 0;
}
error = parse_dict( face, &loader, parser->base_dict, parser->base_len,
keyword_flags );
error = parse_dict( face, &loader,
parser->base_dict, parser->base_len );
if ( error )
goto Exit;
@ -1957,9 +1995,8 @@
if ( error )
goto Exit;
error = parse_dict( face, &loader, parser->private_dict,
parser->private_len,
keyword_flags );
error = parse_dict( face, &loader,
parser->private_dict, parser->private_len );
if ( error )
goto Exit;
@ -1968,6 +2005,19 @@
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
if ( face->blend &&
face->blend->num_default_design_vector != 0 &&
face->blend->num_default_design_vector != face->blend->num_axis )
{
/* we don't use it currently so just warn, reset, and ignore */
FT_ERROR(( "T1_Open_Face(): /DesignVector contains %u entries "
"while there are %u axes.\n",
face->blend->num_default_design_vector,
face->blend->num_axis ));
face->blend->num_default_design_vector = 0;
}
/* the following can happen for MM instances; we then treat the */
/* font as a normal PS font */
if ( face->blend &&

View File

@ -4,7 +4,7 @@
/* */
/* Type 1 font loader (specification). */
/* */
/* Copyright 1996-2001, 2002, 2004 by */
/* Copyright 1996-2001, 2002, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -48,9 +48,18 @@ FT_BEGIN_HEADER
PS_TableRec subrs;
FT_Bool fontdata;
FT_UInt keywords_encountered; /* T1_LOADER_ENCOUNTERED_XXX */
} T1_LoaderRec, *T1_Loader;
/* treatment of some keywords differs depending on whether */
/* they preceed or follow certain other keywords */
#define T1_PRIVATE ( 1 << 0 )
#define T1_FONTDIR_AFTER_PRIVATE ( 1 << 1 )
FT_LOCAL( FT_Error )
T1_Open_Face( T1_Face face );

View File

@ -4,7 +4,7 @@
/* */
/* Type 1 tokenizer (specification). */
/* */
/* Copyright 1996-2001, 2002, 2003, 2004 by */
/* Copyright 1996-2001, 2002, 2003, 2004, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@ -73,6 +73,7 @@
T1_FIELD_NUM ( "FontType", font_type )
T1_FIELD_FIXED( "StrokeWidth", stroke_width )
#undef FT_STRUCTURE
#define FT_STRUCTURE FT_BBox
#undef T1CODE
@ -81,4 +82,26 @@
T1_FIELD_BBOX("FontBBox", xMin )
#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
#undef FT_STRUCTURE
#define FT_STRUCTURE T1_FaceRec
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_FACE
T1_FIELD_NUM ( "NDV", ndv_idx )
T1_FIELD_NUM ( "CDV", cdv_idx )
#undef FT_STRUCTURE
#define FT_STRUCTURE PS_BlendRec
#undef T1CODE
#define T1CODE T1_FIELD_LOCATION_BLEND
T1_FIELD_NUM_TABLE( "DesignVector", default_design_vector, T1_MAX_MM_DESIGNS )
#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
/* END */