* 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:
parent
4af3c4d7ee
commit
1a380e02d1
55
ChangeLog
55
ChangeLog
|
@ -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.
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue