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.
diff --git a/ChangeLog b/ChangeLog
index ceb529c..9b8a3c3 100644
--- a/ChangeLog
+++ b/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.
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index d078ac9..cac9f47 100644
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -575,7 +575,6 @@
T1_ParseState parse_state;
FT_Bool load_points;
FT_Bool no_recurse;
- FT_Bool shift;
FT_Bool metrics_only;
diff --git a/include/freetype/internal/pshints.h b/include/freetype/internal/pshints.h
index 4ad3ac5..0c35765 100644
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -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 @@
* 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 @@
*
*/
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 @@
* 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 @@
*
*/
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 @@
* 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
diff --git a/src/cid/cidgload.c b/src/cid/cidgload.c
index 64994b4..f59035f 100644
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -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 */
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index b3f3a70..28cfcc4 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -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--;
diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c
index 47681f8..85d34e4 100644
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -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: "
diff --git a/src/pshinter/pshrec.c b/src/pshinter/pshrec.c
index cfe23f0..8273dab 100644
--- a/src/pshinter/pshrec.c
+++ b/src/pshinter/pshrec.c
@@ -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 */
diff --git a/src/type1/t1gload.c b/src/type1/t1gload.c
index 8462028..01bc4ce 100644
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -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 */
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 2e4700e..d5e7791 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -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"
diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c
index 2f90dd6..df87ffc 100644
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -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 */
}