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:
Werner Lemberg 2009-06-22 16:56:47 +02:00
parent df9cd975d3
commit 11cb8c36ed
10 changed files with 217 additions and 125 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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--;

View File

@ -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: "

View File

@ -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 */

View File

@ -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 */

View File

@ -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"

View File

@ -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 */
}