Use 16.16 format while parsing Type 1 charstrings.
This fixes Savannah bug #26867. Previously, only integers have been used which can lead to serious rounding errors. However, fractional values are only used internally; after the charstrings (of either Type 1 or 2) have been processed, the resulting coordinates get rounded to integers currently -- before applying scaling. This should be fixed; at the same time a new load flag should be introduced, to be used in combination with FT_LOAD_NO_SCALE, which indicates that font units are returned in 16.16 format. Similarly, the incremental interface should be extended to allow fractional values for metrics. * include/freetype/internal/psaux.h (T1_BuilderRec): Remove `shift' field. * include/freetype/internal/pshints.h (T1_Hints_SetStemFunc, T1_Hints_SetStem3Func): Use FT_Fixed for coordinates. * src/psaux/psobjs.c: Include FT_INTERNAL_CALC_H. (t1_build_add_point): Always convert fixed to integer. * src/psaux/t1decode.c (t1_decoder_parse_charstrings): Use 16.16 format everywhere (except for large integers followed by a `div'). [CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS]: Remove #ifdef and activate code uncoditionally. Add support for random numbers and update remaining code accordingly; this should work now. (t1_operator_seac): Updated. * src/psaux/pshrec.c: Include FT_INTERNAL_CALC_H. (ps_hints_t1stem3, t1_hints_stem): Updated. * src/cid/cidgload.c: Include FT_INTERNAL_CALC_H. (cid_load_glyph) [FT_CONFIG_OPTION_INCREMENTAL], (cid_face_compute_max_advance, cid_slot_load_glyph): Updated. * src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String) [FT_CONFIG_OPTION_INCREMENTAL], (T1_Get_Advances, T1_Load_Glyph): Updated. * src/type1/t1load.c: Include FT_INTERNAL_CALC_H. * src/type1/t1objs.c (T1_Face_Init): Updated.
This commit is contained in:
parent
df9cd975d3
commit
11cb8c36ed
45
ChangeLog
45
ChangeLog
@ -1,3 +1,48 @@
|
||||
2009-06-22 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Use 16.16 format while parsing Type 1 charstrings.
|
||||
This fixes Savannah bug #26867.
|
||||
|
||||
Previously, only integers have been used which can lead to serious
|
||||
rounding errors.
|
||||
|
||||
However, fractional values are only used internally; after the
|
||||
charstrings (of either Type 1 or 2) have been processed, the
|
||||
resulting coordinates get rounded to integers currently -- before
|
||||
applying scaling. This should be fixed; at the same time a new load
|
||||
flag should be introduced, to be used in combination with
|
||||
FT_LOAD_NO_SCALE, which indicates that font units are returned in
|
||||
16.16 format. Similarly, the incremental interface should be
|
||||
extended to allow fractional values for metrics.
|
||||
|
||||
* include/freetype/internal/psaux.h (T1_BuilderRec): Remove `shift'
|
||||
field.
|
||||
* include/freetype/internal/pshints.h (T1_Hints_SetStemFunc,
|
||||
T1_Hints_SetStem3Func): Use FT_Fixed for coordinates.
|
||||
|
||||
* src/psaux/psobjs.c: Include FT_INTERNAL_CALC_H.
|
||||
(t1_build_add_point): Always convert fixed to integer.
|
||||
* src/psaux/t1decode.c (t1_decoder_parse_charstrings):
|
||||
Use 16.16 format everywhere (except for large integers followed by a
|
||||
`div').
|
||||
[CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS]: Remove #ifdef and activate
|
||||
code uncoditionally.
|
||||
Add support for random numbers and update remaining code
|
||||
accordingly; this should work now.
|
||||
(t1_operator_seac): Updated.
|
||||
* src/psaux/pshrec.c: Include FT_INTERNAL_CALC_H.
|
||||
(ps_hints_t1stem3, t1_hints_stem): Updated.
|
||||
|
||||
* src/cid/cidgload.c: Include FT_INTERNAL_CALC_H.
|
||||
(cid_load_glyph) [FT_CONFIG_OPTION_INCREMENTAL],
|
||||
(cid_face_compute_max_advance, cid_slot_load_glyph): Updated.
|
||||
|
||||
* src/type1/t1gload.c (T1_Parse_Glyph_And_Get_Char_String)
|
||||
[FT_CONFIG_OPTION_INCREMENTAL], (T1_Get_Advances, T1_Load_Glyph):
|
||||
Updated.
|
||||
* src/type1/t1load.c: Include FT_INTERNAL_CALC_H.
|
||||
* src/type1/t1objs.c (T1_Face_Init): Updated.
|
||||
|
||||
2009-06-21 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/pshinter/pshrec.c: Use PSH_Err_Ok.
|
||||
|
@ -575,7 +575,6 @@ FT_BEGIN_HEADER
|
||||
T1_ParseState parse_state;
|
||||
FT_Bool load_points;
|
||||
FT_Bool no_recurse;
|
||||
FT_Bool shift;
|
||||
|
||||
FT_Bool metrics_only;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* recorders (specification only). These are used to support native */
|
||||
/* T1/T2 hints in the `type1', `cid', and `cff' font drivers. */
|
||||
/* */
|
||||
/* Copyright 2001, 2002, 2003, 2005, 2006, 2007 by */
|
||||
/* Copyright 2001, 2002, 2003, 2005, 2006, 2007, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -157,7 +157,8 @@ FT_BEGIN_HEADER
|
||||
* 0 for horizontal stems (hstem), 1 for vertical ones (vstem).
|
||||
*
|
||||
* coords ::
|
||||
* Array of 2 integers, used as (position,length) stem descriptor.
|
||||
* Array of 2 coordinates in 16.16 format, used as (position,length)
|
||||
* stem descriptor.
|
||||
*
|
||||
* @note:
|
||||
* Use vertical coordinates (y) for horizontal stems (dim=0). Use
|
||||
@ -175,9 +176,9 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
*/
|
||||
typedef void
|
||||
(*T1_Hints_SetStemFunc)( T1_Hints hints,
|
||||
FT_UInt dimension,
|
||||
FT_Long* coords );
|
||||
(*T1_Hints_SetStemFunc)( T1_Hints hints,
|
||||
FT_UInt dimension,
|
||||
FT_Fixed* coords );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@ -197,8 +198,8 @@ FT_BEGIN_HEADER
|
||||
* 0 for horizontal stems, 1 for vertical ones.
|
||||
*
|
||||
* coords ::
|
||||
* An array of 6 integers, holding 3 (position,length) pairs for the
|
||||
* counter-controlled stems.
|
||||
* An array of 6 values in 16.16 format, holding 3 (position,length)
|
||||
* pairs for the counter-controlled stems.
|
||||
*
|
||||
* @note:
|
||||
* Use vertical coordinates (y) for horizontal stems (dim=0). Use
|
||||
@ -209,9 +210,9 @@ FT_BEGIN_HEADER
|
||||
*
|
||||
*/
|
||||
typedef void
|
||||
(*T1_Hints_SetStem3Func)( T1_Hints hints,
|
||||
FT_UInt dimension,
|
||||
FT_Long* coords );
|
||||
(*T1_Hints_SetStem3Func)( T1_Hints hints,
|
||||
FT_UInt dimension,
|
||||
FT_Fixed* coords );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@ -446,7 +447,7 @@ FT_BEGIN_HEADER
|
||||
* The number of stems.
|
||||
*
|
||||
* coords ::
|
||||
* An array of `count' (position,length) pairs.
|
||||
* An array of `count' (position,length) pairs in 16.16 format.
|
||||
*
|
||||
* @note:
|
||||
* Use vertical coordinates (y) for horizontal stems (dim=0). Use
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* CID-keyed Type1 Glyph Loader (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -22,6 +22,7 @@
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_STREAM_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
|
||||
#include "ciderrs.h"
|
||||
|
||||
@ -51,20 +52,23 @@
|
||||
FT_ULong glyph_length = 0;
|
||||
PSAux_Service psaux = (PSAux_Service)face->psaux;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
FT_Incremental_InterfaceRec *inc =
|
||||
face->root.internal->incremental_interface;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* For incremental fonts get the character data using */
|
||||
/* the callback function. */
|
||||
if ( face->root.internal->incremental_interface )
|
||||
if ( inc )
|
||||
{
|
||||
FT_Data glyph_data;
|
||||
|
||||
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_data(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index,
|
||||
&glyph_data );
|
||||
error = inc->funcs->get_glyph_data( inc->object,
|
||||
glyph_index, &glyph_data );
|
||||
if ( error )
|
||||
goto Exit;
|
||||
|
||||
@ -80,9 +84,7 @@
|
||||
glyph_length );
|
||||
}
|
||||
|
||||
face->root.internal->incremental_interface->funcs->free_glyph_data(
|
||||
face->root.internal->incremental_interface->object,
|
||||
&glyph_data );
|
||||
inc->funcs->free_glyph_data( inc->object, &glyph_data );
|
||||
|
||||
if ( error )
|
||||
goto Exit;
|
||||
@ -163,22 +165,21 @@
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* Incremental fonts can optionally override the metrics. */
|
||||
if ( !error &&
|
||||
face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
|
||||
if ( !error && inc && inc->funcs->get_glyph_metrics )
|
||||
{
|
||||
FT_Incremental_MetricsRec metrics;
|
||||
|
||||
|
||||
metrics.bearing_x = decoder->builder.left_bearing.x;
|
||||
metrics.bearing_y = decoder->builder.left_bearing.y;
|
||||
metrics.advance = decoder->builder.advance.x;
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
decoder->builder.left_bearing.x = metrics.bearing_x;
|
||||
decoder->builder.left_bearing.y = metrics.bearing_y;
|
||||
decoder->builder.advance.x = metrics.advance;
|
||||
metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
|
||||
metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y );
|
||||
metrics.advance = FIXED_TO_INT( decoder->builder.advance.x );
|
||||
|
||||
error = inc->funcs->get_glyph_metrics( inc->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
|
||||
decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
|
||||
decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y );
|
||||
decoder->builder.advance.x = INT_TO_FIXED( metrics.advance );
|
||||
decoder->builder.advance.y = 0;
|
||||
}
|
||||
|
||||
@ -251,7 +252,7 @@
|
||||
/* ignore the error if one occurred - skip to next glyph */
|
||||
}
|
||||
|
||||
*max_advance = decoder.builder.advance.x;
|
||||
*max_advance = FIXED_TO_INT( decoder.builder.advance.x );
|
||||
|
||||
psaux->t1_decoder_funcs->done( &decoder );
|
||||
|
||||
@ -342,8 +343,10 @@
|
||||
FT_Slot_Internal internal = cidglyph->internal;
|
||||
|
||||
|
||||
cidglyph->metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
cidglyph->metrics.horiAdvance = decoder.builder.advance.x;
|
||||
cidglyph->metrics.horiBearingX =
|
||||
FIXED_TO_INT( decoder.builder.left_bearing.x );
|
||||
cidglyph->metrics.horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
@ -357,8 +360,10 @@
|
||||
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.builder.advance.x;
|
||||
cidglyph->linearHoriAdvance = decoder.builder.advance.x;
|
||||
metrics->horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
cidglyph->linearHoriAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
cidglyph->internal->glyph_transformed = 0;
|
||||
|
||||
/* make up vertical ones */
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_INTERNAL_POSTSCRIPT_AUX_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
|
||||
#include "psobjs.h"
|
||||
#include "psconv.h"
|
||||
@ -1551,13 +1552,8 @@
|
||||
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
|
||||
|
||||
|
||||
if ( builder->shift )
|
||||
{
|
||||
x >>= 16;
|
||||
y >>= 16;
|
||||
}
|
||||
point->x = x;
|
||||
point->y = y;
|
||||
point->x = FIXED_TO_INT( x );
|
||||
point->y = FIXED_TO_INT( y );
|
||||
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
|
||||
}
|
||||
outline->n_points++;
|
||||
@ -1666,8 +1662,8 @@
|
||||
|
||||
if ( outline->n_contours > 0 )
|
||||
{
|
||||
/* Don't add contours only consisting of one point, i.e., */
|
||||
/* check whether begin point and last point are the same. */
|
||||
/* Don't add contours only consisting of one point, i.e., */
|
||||
/* check whether the first and the last point is the same. */
|
||||
if ( first == outline->n_points - 1 )
|
||||
{
|
||||
outline->n_contours--;
|
||||
|
@ -253,8 +253,8 @@
|
||||
/* subglyph 1 = accent character */
|
||||
subg->index = achar_index;
|
||||
subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
|
||||
subg->arg1 = (FT_Int)( adx - asb );
|
||||
subg->arg2 = (FT_Int)ady;
|
||||
subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
|
||||
subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
|
||||
|
||||
/* set up remaining glyph fields */
|
||||
glyph->num_subglyphs = 2;
|
||||
@ -338,6 +338,7 @@
|
||||
FT_Int known_othersubr_result_cnt = 0;
|
||||
FT_Int unknown_othersubr_result_cnt = 0;
|
||||
FT_Bool large_int;
|
||||
FT_Fixed seed;
|
||||
|
||||
T1_Hints_Funcs hinter;
|
||||
|
||||
@ -354,6 +355,15 @@
|
||||
#define add_contour t1_builder_add_contour
|
||||
#define close_contour t1_builder_close_contour
|
||||
|
||||
|
||||
/* compute random seed from stack address of parameter */
|
||||
seed = (FT_Fixed)(char*)&seed ^
|
||||
(FT_Fixed)(char*)&decoder ^
|
||||
(FT_Fixed)(char*)&charstring_base;
|
||||
seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
|
||||
if ( seed == 0 )
|
||||
seed = 0x7384;
|
||||
|
||||
/* First of all, initialize the decoder */
|
||||
decoder->top = decoder->stack;
|
||||
decoder->zone = decoder->zones;
|
||||
@ -395,7 +405,7 @@
|
||||
{
|
||||
FT_Long* top = decoder->top;
|
||||
T1_Operator op = op_none;
|
||||
FT_Long value = 0;
|
||||
FT_Int32 value = 0;
|
||||
|
||||
|
||||
FT_ASSERT( known_othersubr_result_cnt == 0 ||
|
||||
@ -552,6 +562,11 @@
|
||||
else
|
||||
large_int = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !large_int )
|
||||
value <<= 16;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -574,6 +589,9 @@
|
||||
else
|
||||
value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
|
||||
}
|
||||
|
||||
if ( !large_int )
|
||||
value <<= 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -621,7 +639,12 @@
|
||||
goto Syntax_Error;
|
||||
}
|
||||
|
||||
FT_TRACE4(( " %ld", value ));
|
||||
#ifdef FT_DEBUG_LEVEL_TRACE
|
||||
if ( large_int )
|
||||
FT_TRACE4(( " %ld", value ));
|
||||
else
|
||||
FT_TRACE4(( " %ld", (FT_Int32)( value >> 16 ) ));
|
||||
#endif
|
||||
|
||||
*top++ = value;
|
||||
decoder->top = top;
|
||||
@ -642,8 +665,8 @@
|
||||
|
||||
top -= 2;
|
||||
|
||||
subr_no = (FT_Int)top[1];
|
||||
arg_cnt = (FT_Int)top[0];
|
||||
subr_no = (FT_Int)( top[1] >> 16 );
|
||||
arg_cnt = (FT_Int)( top[0] >> 16 );
|
||||
|
||||
/***********************************************************/
|
||||
/* */
|
||||
@ -805,12 +828,6 @@
|
||||
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> ) */
|
||||
@ -823,10 +840,10 @@
|
||||
if ( arg_cnt != 1 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[0];
|
||||
idx = (FT_Int)( top[0] >> 16 );
|
||||
|
||||
if ( idx < 0 ||
|
||||
idx + blend->num_designs > decoder->face->len_buildchar )
|
||||
if ( idx < 0 ||
|
||||
idx + blend->num_designs > decoder->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
ft_memcpy( &decoder->buildchar[idx],
|
||||
@ -864,7 +881,7 @@
|
||||
if ( arg_cnt != 2 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] *= top[1]; /* XXX (over|under)flow */
|
||||
top[0] = FT_MulFix( top[0], top[1] );
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
@ -875,13 +892,11 @@
|
||||
if ( arg_cnt != 2 || top[1] == 0 )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
top[0] /= top[1]; /* XXX (over|under)flow */
|
||||
top[0] = FT_DivFix( top[0], top[1] );
|
||||
|
||||
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> */
|
||||
@ -889,10 +904,11 @@
|
||||
FT_Int idx;
|
||||
PS_Blend blend = decoder->blend;
|
||||
|
||||
|
||||
if ( arg_cnt != 2 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[1];
|
||||
idx = (FT_Int)( top[1] >> 16 );
|
||||
|
||||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
@ -909,10 +925,11 @@
|
||||
FT_Int idx;
|
||||
PS_Blend blend = decoder->blend;
|
||||
|
||||
|
||||
if ( arg_cnt != 1 || blend == NULL )
|
||||
goto Unexpected_OtherSubr;
|
||||
|
||||
idx = top[0];
|
||||
idx = (FT_Int)( top[0] >> 16 );
|
||||
|
||||
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
|
||||
goto Unexpected_OtherSubr;
|
||||
@ -945,17 +962,29 @@
|
||||
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();
|
||||
{
|
||||
FT_Fixed Rand;
|
||||
|
||||
|
||||
Rand = seed;
|
||||
if ( Rand >= 0x8000L )
|
||||
Rand++;
|
||||
|
||||
top[0] = Rand;
|
||||
|
||||
seed = FT_MulFix( seed, 0x10000L - seed );
|
||||
if ( seed == 0 )
|
||||
seed += 0x2873;
|
||||
}
|
||||
|
||||
known_othersubr_result_cnt = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
@ -1024,13 +1053,13 @@
|
||||
/* close hints recording session */
|
||||
if ( hinter )
|
||||
{
|
||||
if (hinter->close( hinter->hints, builder->current->n_points ))
|
||||
if ( hinter->close( hinter->hints, builder->current->n_points ) )
|
||||
goto Syntax_Error;
|
||||
|
||||
/* apply hints to the loaded glyph outline now */
|
||||
hinter->apply( hinter->hints,
|
||||
builder->current,
|
||||
(PSH_Globals) builder->hints_globals,
|
||||
(PSH_Globals)builder->hints_globals,
|
||||
decoder->hint_mode );
|
||||
}
|
||||
|
||||
@ -1085,8 +1114,12 @@
|
||||
|
||||
case op_seac:
|
||||
/* return immediately after the processing */
|
||||
return t1operator_seac( decoder, top[0], top[1], top[2],
|
||||
(FT_Int)top[3], (FT_Int)top[4] );
|
||||
return t1operator_seac( decoder,
|
||||
top[0],
|
||||
top[1],
|
||||
top[2],
|
||||
(FT_Int)( top[3] >> 16 ),
|
||||
(FT_Int)( top[4] >> 16 ) );
|
||||
|
||||
case op_sbw:
|
||||
FT_TRACE4(( " sbw" ));
|
||||
@ -1244,19 +1277,13 @@
|
||||
case op_div:
|
||||
FT_TRACE4(( " div" ));
|
||||
|
||||
if ( top[1] )
|
||||
{
|
||||
*top = top[0] / top[1];
|
||||
++top;
|
||||
}
|
||||
else
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" ));
|
||||
goto Syntax_Error;
|
||||
}
|
||||
/* if `large_int' is set, we divide unscaled numbers; */
|
||||
/* otherwise, we divide numbers in 16.16 format -- */
|
||||
/* in both cases, it is the same operation */
|
||||
*top = FT_DivFix( top[0], top[1] );
|
||||
++top;
|
||||
|
||||
large_int = FALSE;
|
||||
|
||||
break;
|
||||
|
||||
case op_callsubr:
|
||||
@ -1266,7 +1293,7 @@
|
||||
|
||||
FT_TRACE4(( " callsubr" ));
|
||||
|
||||
idx = (FT_Int)top[0];
|
||||
idx = (FT_Int)( top[0] >> 16 );
|
||||
if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
|
||||
{
|
||||
FT_ERROR(( "t1_decoder_parse_charstrings: "
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* FreeType PostScript hints recorder (body). */
|
||||
/* */
|
||||
/* Copyright 2001, 2002, 2003, 2004, 2007 by */
|
||||
/* Copyright 2001, 2002, 2003, 2004, 2007, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -20,6 +20,8 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_INTERNAL_OBJECTS_H
|
||||
#include FT_INTERNAL_DEBUG_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
|
||||
#include "pshrec.h"
|
||||
#include "pshalgo.h"
|
||||
|
||||
@ -800,7 +802,7 @@
|
||||
{
|
||||
FT_MEM_ZERO( hints, sizeof ( *hints ) );
|
||||
hints->memory = memory;
|
||||
return 0;
|
||||
return PSH_Err_Ok;
|
||||
}
|
||||
|
||||
|
||||
@ -888,9 +890,9 @@
|
||||
|
||||
/* add one Type1 counter stem to the current hints table */
|
||||
static void
|
||||
ps_hints_t1stem3( PS_Hints hints,
|
||||
FT_Int dimension,
|
||||
FT_Long* stems )
|
||||
ps_hints_t1stem3( PS_Hints hints,
|
||||
FT_Int dimension,
|
||||
FT_Fixed* stems )
|
||||
{
|
||||
FT_Error error = PSH_Err_Ok;
|
||||
|
||||
@ -919,9 +921,10 @@
|
||||
/* add the three stems to our hints/masks table */
|
||||
for ( count = 0; count < 3; count++, stems += 2 )
|
||||
{
|
||||
error = ps_dimension_add_t1stem(
|
||||
dim, (FT_Int)stems[0], (FT_Int)stems[1],
|
||||
memory, &idx[count] );
|
||||
error = ps_dimension_add_t1stem( dim,
|
||||
(FT_Int)FIXED_TO_INT( stems[0] ),
|
||||
(FT_Int)FIXED_TO_INT( stems[1] ),
|
||||
memory, &idx[count] );
|
||||
if ( error )
|
||||
goto Fail;
|
||||
}
|
||||
@ -1124,11 +1127,17 @@
|
||||
}
|
||||
|
||||
static void
|
||||
t1_hints_stem( T1_Hints hints,
|
||||
FT_Int dimension,
|
||||
FT_Long* coords )
|
||||
t1_hints_stem( T1_Hints hints,
|
||||
FT_Int dimension,
|
||||
FT_Fixed* coords )
|
||||
{
|
||||
ps_hints_stem( (PS_Hints)hints, dimension, 1, coords );
|
||||
FT_Pos stems[2];
|
||||
|
||||
|
||||
stems[0] = FIXED_TO_INT( coords[0] );
|
||||
stems[1] = FIXED_TO_INT( coords[1] );
|
||||
|
||||
ps_hints_stem( (PS_Hints)hints, dimension, 1, stems );
|
||||
}
|
||||
|
||||
|
||||
@ -1183,7 +1192,7 @@
|
||||
for ( n = 0; n < count * 2; n++ )
|
||||
{
|
||||
y += coords[n];
|
||||
stems[n] = ( y + 0x8000L ) >> 16;
|
||||
stems[n] = FIXED_TO_INT( y );
|
||||
}
|
||||
|
||||
/* compute lengths */
|
||||
|
@ -62,6 +62,11 @@
|
||||
T1_Font type1 = &face->type1;
|
||||
FT_Error error = T1_Err_Ok;
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
FT_Incremental_InterfaceRec *inc =
|
||||
face->root.internal->incremental_interface;
|
||||
#endif
|
||||
|
||||
|
||||
decoder->font_matrix = type1->font_matrix;
|
||||
decoder->font_offset = type1->font_offset;
|
||||
@ -70,10 +75,9 @@
|
||||
|
||||
/* For incremental fonts get the character data using the */
|
||||
/* callback function. */
|
||||
if ( face->root.internal->incremental_interface )
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_data(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, char_string );
|
||||
if ( inc )
|
||||
error = inc->funcs->get_glyph_data( inc->object,
|
||||
glyph_index, char_string );
|
||||
else
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
@ -92,21 +96,21 @@
|
||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||
|
||||
/* Incremental fonts can optionally override the metrics. */
|
||||
if ( !error && face->root.internal->incremental_interface &&
|
||||
face->root.internal->incremental_interface->funcs->get_glyph_metrics )
|
||||
if ( !error && inc && inc->funcs->get_glyph_metrics )
|
||||
{
|
||||
FT_Incremental_MetricsRec metrics;
|
||||
|
||||
|
||||
metrics.bearing_x = decoder->builder.left_bearing.x;
|
||||
metrics.bearing_y = decoder->builder.left_bearing.y;
|
||||
metrics.advance = decoder->builder.advance.x;
|
||||
error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
|
||||
face->root.internal->incremental_interface->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
decoder->builder.left_bearing.x = metrics.bearing_x;
|
||||
decoder->builder.left_bearing.y = metrics.bearing_y;
|
||||
decoder->builder.advance.x = metrics.advance;
|
||||
metrics.bearing_x = FIXED_TO_INT( decoder->builder.left_bearing.x );
|
||||
metrics.bearing_y = FIXED_TO_INT( decoder->builder.left_bearing.y );
|
||||
metrics.advance = FIXED_TO_INT( decoder->builder.advance.x );
|
||||
|
||||
error = inc->funcs->get_glyph_metrics( inc->object,
|
||||
glyph_index, FALSE, &metrics );
|
||||
|
||||
decoder->builder.left_bearing.x = INT_TO_FIXED( metrics.bearing_x );
|
||||
decoder->builder.left_bearing.y = INT_TO_FIXED( metrics.bearing_y );
|
||||
decoder->builder.advance.x = INT_TO_FIXED( metrics.advance );
|
||||
decoder->builder.advance.y = 0;
|
||||
}
|
||||
|
||||
@ -250,7 +254,7 @@
|
||||
{
|
||||
error = T1_Parse_Glyph( &decoder, first + nn );
|
||||
if ( !error )
|
||||
advances[nn] = decoder.builder.advance.x;
|
||||
advances[nn] = FIXED_TO_INT( decoder.builder.advance.x );
|
||||
else
|
||||
advances[nn] = 0;
|
||||
}
|
||||
@ -368,11 +372,14 @@
|
||||
FT_Slot_Internal internal = glyph->root.internal;
|
||||
|
||||
|
||||
glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
|
||||
glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
glyph->root.metrics.horiBearingX =
|
||||
FIXED_TO_INT( decoder.builder.left_bearing.x );
|
||||
glyph->root.metrics.horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
|
||||
internal->glyph_matrix = font_matrix;
|
||||
internal->glyph_delta = font_offset;
|
||||
internal->glyph_transformed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -382,8 +389,10 @@
|
||||
|
||||
|
||||
/* copy the _unscaled_ advance width */
|
||||
metrics->horiAdvance = decoder.builder.advance.x;
|
||||
glyph->root.linearHoriAdvance = decoder.builder.advance.x;
|
||||
metrics->horiAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
glyph->root.linearHoriAdvance =
|
||||
FIXED_TO_INT( decoder.builder.advance.x );
|
||||
glyph->root.internal->glyph_transformed = 0;
|
||||
|
||||
/* make up vertical ones */
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include FT_CONFIG_CONFIG_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
#include FT_INTERNAL_TYPE1_TYPES_H
|
||||
#include FT_INTERNAL_CALC_H
|
||||
|
||||
#include "t1load.h"
|
||||
#include "t1errors.h"
|
||||
|
@ -4,7 +4,7 @@
|
||||
/* */
|
||||
/* Type 1 objects manager (body). */
|
||||
/* */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
|
||||
/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
|
||||
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
||||
/* */
|
||||
/* This file is part of the FreeType project, and may only be used, */
|
||||
@ -467,7 +467,7 @@
|
||||
|
||||
/* in case of error, keep the standard width */
|
||||
if ( !error )
|
||||
root->max_advance_width = (FT_Short)max_advance;
|
||||
root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance );
|
||||
else
|
||||
error = T1_Err_Ok; /* clear error */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user