shithub: freetype+ttf2subf

Download patch

ref: 11cb8c36ed9c75ccf3b80bdb59e9b2a75993a1cd
parent: df9cd975d30c101b9a822b72b7edb7f6b12e54c3
author: Werner Lemberg <[email protected]>
date: Mon Jun 22 12:56:47 EDT 2009

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.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2009-06-22  Werner Lemberg  <[email protected]>
+
+	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  <[email protected]>
 
 	* src/pshinter/pshrec.c: Use PSH_Err_Ok.
--- 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;
 
--- 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
--- 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 */
--- 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--;
--- 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,7 +962,6 @@
           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 */
@@ -952,10 +968,23 @@
           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: "
--- 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 */
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -62,7 +62,12 @@
     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 */
--- 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"
--- 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 */
       }