shithub: freetype+ttf2subf

Download patch

ref: 27c322e9835b8fec7e5f65a012f56e1c64fc9879
parent: dcb61e478566a67134a16195ca462730c1bb1030
author: David Turner <[email protected]>
date: Mon Jul 8 18:26:11 EDT 2002

* include/freetype/freetype.h, src/base/ftobjs.h,
    freetype/internal/ftobjs.h, freetype/internal/psaux.h,
    freetype/internal/pshints.h, src/psaux/t1decode.c, src/cff/cffgload.h,
    src/cff/cffgload.c, src/pshinter/pshalgo1.h, src/pshinter/pshalgo1.c,
    src/pshinter/pshalgo2.h, src/pshinter/pshalgo2.c, src/pshinter/pshalgo3.h,
    src/pshinter/pshalgo3.c: Adding support for hinter-specific bit flags,
    and the new FT_Set_Hint_Flags high-level API

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2002-07-07  Owen Taylor  <[email protected]>
+
+    * include/freetype/freetype.h, src/base/ftobjs.h,
+    freetype/internal/ftobjs.h, freetype/internal/psaux.h,
+    freetype/internal/pshints.h, src/psaux/t1decode.c, src/cff/cffgload.h,
+    src/cff/cffgload.c, src/pshinter/pshalgo1.h, src/pshinter/pshalgo1.c,
+    src/pshinter/pshalgo2.h, src/pshinter/pshalgo2.c, src/pshinter/pshalgo3.h,
+    src/pshinter/pshalgo3.c: Adding support for hinter-specific bit flags,
+    and the new FT_Set_Hint_Flags high-level API
+
 2002-07-04  David Turner  <[email protected]>
 
     * src/pfr/pfrobjs.c (pfr_slot_load): fixed a small bug that returned
@@ -5,7 +15,7 @@
     metrics resolution
 
     * src/autohint/ahhint.c: removing compiler warnings
-    
+
     * src/autohint/ahglyph.c: slight improvements to the serif detection
     code. More work is needed though..
 
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -2775,6 +2775,65 @@
                        FT_Matrix*  matrix );
 
 
+
+  /*@***********************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Hint_Flags                                                  */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A function used to set a number of flags that are used to control  */
+  /*    the hinting process when glyphs are loaded.                        */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    face   :: A handle to the source face object.                      */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    flags  :: A set of bit flags that control the hinting process      */
+  /*              see the FT_HINT_XXX constants for details.               */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    The interpretation of the flags depends on the hinter module in    */
+  /*    use. Not all modules will support all flags                        */
+  /*                                                                       */
+  FT_EXPORT( void )
+  FT_Set_Hint_Flags( FT_Face     face,
+                     FT_ULong    hint_flags );
+
+
+  /*@***********************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_HINT_NO_INTEGER_STEM                                            */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+  /*    snapping of stem widths to integer values                          */
+  /*                                                                       */
+#define FT_HINT_NO_INTEGER_STEM 1
+
+  /*@***********************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_HINT_NO_HSTEM_ALIGN                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+  /*    alignment of horizontal stems with the pixel grid.                 */
+  /*                                                                       */
+#define FT_HINT_NO_HSTEM_ALIGN 2
+
+  /*@***********************************************************************/
+  /*                                                                       */
+  /* <Constant>                                                            */
+  /*    FT_HINT_NO_VSTEM_ALIGN                                             */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A bit-field constant, used with FT_Set_Hint_Flags() to to suppress */
+  /*    alignment of vertical stems with the pixel grid                    */
+  /*                                                                       */
+#define FT_HINT_NO_VSTEM_ALIGN 4
+
   /* */
 
 FT_END_HEADER
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -291,6 +291,9 @@
   /*    transform_flags  :: Some flags used to classify the transform.     */
   /*                        Only used by the convenience functions.        */
   /*                                                                       */
+  /*    hint_flags       :: Some flags used to change the hinters'         */
+  /*                        behaviour. Only used for debugging for now     */
+  /*                                                                       */
   /*    postscript_name  :: Postscript font name for this face.            */
   /*                                                                       */
   typedef struct  FT_Face_InternalRec_
@@ -301,6 +304,8 @@
     FT_Matrix    transform_matrix;
     FT_Vector    transform_delta;
     FT_Int       transform_flags;
+
+    FT_UInt32    hint_flags;
 
     const char*  postscript_name;
 
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -142,10 +142,10 @@
   typedef struct PS_ParserRec_*  PS_Parser;
 
   typedef struct T1_TokenRec_*   T1_Token;
-  
+
   typedef struct T1_FieldRec_*   T1_Field;
 
-  
+
   /* simple enumeration type used to identify token types */
   typedef enum  T1_TokenType_
   {
@@ -388,7 +388,7 @@
     FT_Memory  memory;
 
     PS_Parser_FuncsRec  funcs;
-    
+
   } PS_ParserRec;
 
 
@@ -544,7 +544,7 @@
     void*           hints_globals;  /* hinter-specific */
 
     T1_Builder_FuncsRec  funcs;
-    
+
   } T1_BuilderRec;
 
 
@@ -613,7 +613,7 @@
     (*parse_charstrings)( T1_Decoder  decoder,
                           FT_Byte*    base,
                           FT_UInt     len );
-                          
+
   } T1_Decoder_FuncsRec;
 
 
@@ -645,9 +645,11 @@
 
     PS_Blend             blend;       /* for multiple master support */
 
+    FT_UInt32            hint_flags;
+
     T1_Decoder_Callback  parse_callback;
     T1_Decoder_FuncsRec  funcs;
-    
+
   } T1_DecoderRec;
 
 
@@ -667,9 +669,9 @@
     FT_CMap_Class  expert;
     FT_CMap_Class  custom;
     FT_CMap_Class  unicode;
-  
+
   } T1_CMap_ClassesRec;
-  
+
 
   /*************************************************************************/
   /*************************************************************************/
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -267,6 +267,8 @@
   /*                                                                       */
   /*   globals :: The hinter globals for this font.                        */
   /*                                                                       */
+  /*   hint_flags :: hinter bit flags                                      */
+  /*                                                                       */
   /* @return:                                                              */
   /*   FreeType error code.  0 means success.                              */
   /*                                                                       */
@@ -280,7 +282,8 @@
   typedef FT_Error
   (*T1_Hints_ApplyFunc)( T1_Hints     hints,
                          FT_Outline*  outline,
-                         PSH_Globals  globals );
+                         PSH_Globals  globals,
+                         FT_UInt32    hint_flags );
 
 
   /*************************************************************************/
@@ -545,6 +548,8 @@
   /*                                                                       */
   /*    globals :: The hinter globals for this font.                       */
   /*                                                                       */
+  /*    hint_flags :: hinter bit flags                                     */
+  /*                                                                       */
   /* @return:                                                              */
   /*   FreeType error code.  0 means success.                              */
   /*                                                                       */
@@ -558,7 +563,8 @@
   typedef FT_Error
   (*T2_Hints_ApplyFunc)( T2_Hints     hints,
                          FT_Outline*  outline,
-                         PSH_Globals  globals );
+                         PSH_Globals  globals,
+                         FT_UInt32    hint_flags );
 
 
   /*************************************************************************/
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -380,6 +380,23 @@
   }
 
 
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( void )
+  FT_Set_Hint_Flags( FT_Face     face,
+                     FT_ULong    flags )
+  {
+    FT_Face_Internal  internal;
+
+    if ( !face )
+      return;
+
+    internal = face->internal;
+
+    internal->hint_flags = (FT_UInt)flags;
+  }
+
+
   static FT_Renderer
   ft_lookup_glyph_renderer( FT_GlyphSlot  slot );
 
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -246,6 +246,7 @@
       builder->current = &loader->current.outline;
       FT_GlyphLoader_Rewind( loader );
 
+      builder->hint_flags    = FT_FACE(face)->internal->hint_flags;
       builder->hints_globals = 0;
       builder->hints_funcs   = 0;
 
@@ -1676,7 +1677,8 @@
             /* apply hints to the loaded glyph outline now */
             hinter->apply( hinter->hints,
                            builder->current,
-                           (PSH_Globals)builder->hints_globals );
+                           (PSH_Globals)builder->hints_globals,
+                           builder->hint_flags );
           }
 
           /* add current outline to the glyph slot */
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -114,6 +114,8 @@
     FT_Error        error;         /* only used for memory errors */
     FT_Bool         metrics_only;
 
+    FT_UInt32       hint_flags;
+
     void*           hints_funcs;    /* hinter-specific */
     void*           hints_globals;  /* hinter-specific */
 
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -752,7 +752,8 @@
             /* 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_flags );
           }
 
           /* add current outline to the glyph slot */
@@ -1146,6 +1147,7 @@
 
     decoder->num_glyphs     = face->num_glyphs;
     decoder->glyph_names    = glyph_names;
+    decoder->hint_flags     = face->internal->hint_flags;
     decoder->blend          = blend;
     decoder->parse_callback = parse_callback;
 
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -744,12 +744,15 @@
   FT_Error
   ps1_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals )
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags )
   {
     PSH1_Hint_TableRec  hints;
     FT_Error            error = 0;
     FT_Int              dimension;
 
+
+    FT_UNUSED( hint_flags );
 
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
--- a/src/pshinter/pshalgo1.h
+++ b/src/pshinter/pshalgo1.h
@@ -88,7 +88,8 @@
   extern FT_Error
   ps1_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals );
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags );
 
 
 #ifdef DEBUG_HINTER
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -1494,7 +1494,8 @@
   FT_Error
   ps2_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals )
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags )
   {
     PSH2_GlyphRec  glyphrec;
     PSH2_Glyph     glyph = &glyphrec;
@@ -1504,6 +1505,7 @@
 #endif
     FT_Int         dimension;
 
+    FT_UNUSED( hint_flags );
 
 #ifdef DEBUG_HINTER
     memory = globals->memory;
--- a/src/pshinter/pshalgo2.h
+++ b/src/pshinter/pshalgo2.h
@@ -190,7 +190,8 @@
   extern FT_Error
   ps2_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals );
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags );
 
 
 FT_END_HEADER
--- a/src/pshinter/pshalgo3.c
+++ b/src/pshinter/pshalgo3.c
@@ -34,9 +34,9 @@
 
 #undef  SNAP_STEMS
 #undef  ONLY_ALIGN_Y
-      
 
 
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -359,11 +359,11 @@
 
   static FT_Fixed
   psh3_hint_snap_stem_side_delta ( FT_Fixed pos,
-				   FT_Fixed len )
+                                   FT_Fixed len )
   {
     FT_Fixed delta1 = ( ( pos + 32 ) & -64 ) - pos;
     FT_Fixed delta2 = ( ( pos + len + 32 ) & -64  ) - pos - len;
-	      
+
     if ( ABS( delta1 ) <= ABS( delta2 ) )
     {
       return delta1;
@@ -378,7 +378,8 @@
   static void
   psh3_hint_align( PSH3_Hint    hint,
                    PSH_Globals  globals,
-                   FT_Int       dimension )
+                   FT_Int       dimension,
+                   FT_UInt32    hint_flags )
   {
     PSH_Dimension  dim   = &globals->dimension[dimension];
     FT_Fixed       scale = dim->scale_mult;
@@ -390,22 +391,38 @@
       FT_Pos  pos = FT_MulFix( hint->org_pos, scale ) + delta;
       FT_Pos  len = FT_MulFix( hint->org_len, scale );
 
-#ifdef SNAP_STEMS
-      FT_Pos  fit_center;
-      FT_Pos  fit_len;
-
+      FT_Pos            fit_center;
+      FT_Pos            fit_len;
       PSH_AlignmentRec  align;
 
-      /* compute fitted width/height */
-      fit_len = 0;
-      if ( hint->org_len )
+
+      /* ignore stem alignments when requested through the hint flags */
+      if ( ( dimension == 0 && ( hint_flags & FT_HINT_NO_VSTEM_ALIGN ) != 0 ) ||
+           ( dimension == 1 && ( hint_flags & FT_HINT_NO_HSTEM_ALIGN ) != 0 ) )
       {
-        fit_len = psh_dimension_snap_width( dim, hint->org_len );
-        if ( fit_len < 64 )
-          fit_len = 64;
-        else
-          fit_len = ( fit_len + 32 ) & -64;
+        hint->cur_pos = pos;
+        hint->cur_len = len;
+
+        psh3_hint_set_fitted( hint );
+        return;
+          }
+
+      /* perform stem snapping when requested */
+      if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
+      {
+        /* compute fitted width/height */
+        fit_len = 0;
+        if ( hint->org_len )
+        {
+          fit_len = psh_dimension_snap_width( dim, hint->org_len );
+          if ( fit_len < 64 )
+            fit_len = 64;
+          else
+            fit_len = ( fit_len + 32 ) & -64;
+        }
       }
+      else
+        fit_len = len;
 
       hint->cur_len = fit_len;
 
@@ -450,7 +467,7 @@
 
             /* ensure that parent is already fitted */
             if ( !psh3_hint_is_fitted( parent ) )
-              psh3_hint_align( parent, globals, dimension );
+              psh3_hint_align( parent, globals, dimension, hint_flags );
 
             par_org_center = parent->org_pos + ( parent->org_len / 2);
             par_cur_center = parent->cur_pos + ( parent->cur_len / 2);
@@ -457,175 +474,106 @@
             cur_org_center = hint->org_pos   + ( hint->org_len   / 2);
 
             cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
-#if 0
-            if ( cur_delta >= 0 )
-              cur_delta = ( cur_delta + 16 ) & -64;
-            else
-              cur_delta = -( (-cur_delta + 16 ) & -64 );
-#endif
-            pos = par_cur_center + cur_delta - ( len >> 1 );
+            pos       = par_cur_center + cur_delta - ( len >> 1 );
           }
 
-          /* normal processing */
-          if ( ( fit_len / 64 ) & 1 )
+          if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
           {
-            /* odd number of pixels */
-            fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
+            /* normal processing */
+            if ( ( fit_len / 64 ) & 1 )
+            {
+              /* odd number of pixels */
+              fit_center = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;
+            }
+            else
+            {
+              /* even number of pixels */
+              fit_center = ( pos + ( len >> 1 ) + 32 ) & -64;
+            }
+            hint->cur_pos = fit_center - ( fit_len >> 1 );
           }
           else
           {
-            /* even number of pixels */
-            fit_center = ( pos + ( len >> 1 ) + 32 ) & -64;
-          }
+            /* Stems less than one pixel wide are easy - we want to
+             * make them as dark as possible, so they must fall within
+             * one pixel. If the stem is split between two pixels
+             * then snap the edge that is nearer to the pixel boundary
+             * to the pixel boundary
+             */
+            if (len <= 64)
+            {
+              if ( ( pos + len + 63 ) / 64  != pos / 64 + 1 )
+                pos += psh3_hint_snap_stem_side_delta ( pos, len );
+            }
+            /* Position stems other to minimize the amount of mid-grays.
+             * There are, in general, two positions that do this,
+             * illustrated as A) and B) below.
+             *
+             *   +                   +                   +                   +
+             *
+             * A)             |--------------------------------|
+             * B)   |--------------------------------|
+             * C)       |--------------------------------|
+             *
+             * Position A) (split the excess stem equally) should be better
+             * for stems of width N + f where f < 0.5
+             *
+             * Position B) (split the deficiency equally) should be better
+             * for stems of width N + f where f > 0.5
+             *
+             * It turns out though that minimizing the total number of touched
+             * pixels is also important, so position C), with one edge
+             * aligned with a pixel boundary is actually preferable
+             * to A). There are also more possible positions for C) than
+             * for A) or B), so there will be less distortion of the overall
+             * character shape.
+             */
+            else
+            {
+              FT_Fixed frac_len = len & 63;
+              FT_Fixed center = pos + ( len >> 1 );
 
-          hint->cur_pos = fit_center - ( fit_len >> 1 );
-        }
-      }
-#else
-      PSH_AlignmentRec  align;
+              FT_Fixed delta_a, delta_b;
 
-      hint->cur_len = len;
+              if ( ( len / 64 ) & 1 )
+              {
+                delta_a = ( center & -64 ) + 32 - center;
+                delta_b = ( ( center + 32 ) & - 64 ) - center;
+              }
+              else
+              {
+                delta_a = ( ( center + 32 ) & - 64 ) - center;
+                delta_b = ( center & -64 ) + 32 - center;
+              }
 
-      /* check blue zones for horizontal stems */
-      align.align = PSH_BLUE_ALIGN_NONE;
-      align.align_bot = align.align_top = 0;
+              /* We choose between B) and C) above based on the amount
+               * of fractional stem width: for small amounts, choose
+               * C) always; for large amounts, B) always; inbetween,
+               * pick whichever one involves less stem movement.
+               */
+              if (frac_len < 32)
+              {
+                pos += psh3_hint_snap_stem_side_delta ( pos, len );
+              }
+              else if (frac_len < 48)
+              {
+                FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len );
 
-      if ( dimension == 1 )
-        psh_blues_snap_stem( &globals->blues,
-                             hint->org_pos + hint->org_len,
-                             hint->org_pos,
-                             &align );
-#ifdef ONLY_ALIGN_Y
-      else
-      {
-	hint->cur_pos = pos;
-	return;
-      }
-#endif
-      
-      switch ( align.align )
-      {
-      case PSH_BLUE_ALIGN_TOP:
-        /* the top of the stem is aligned against a blue zone */
-        hint->cur_pos = align.align_top - len;
-        break;
-
-      case PSH_BLUE_ALIGN_BOT:
-        /* the bottom of the stem is aligned against a blue zone */
-        hint->cur_pos = align.align_bot;
-        break;
-
-      case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:
-        /* both edges of the stem are aligned against blue zones */
-        hint->cur_pos = align.align_bot;
-        hint->cur_len = align.align_top - align.align_bot;
-        break;
-
-      default:
-        {
-          PSH3_Hint  parent = hint->parent;
-
-          if ( parent )
-          {
-            FT_Pos  par_org_center, par_cur_center;
-            FT_Pos  cur_org_center, cur_delta;
-
-
-            /* ensure that parent is already fitted */
-            if ( !psh3_hint_is_fitted( parent ) )
-              psh3_hint_align( parent, globals, dimension );
-
-            par_org_center = parent->org_pos + ( parent->org_len / 2);
-            par_cur_center = parent->cur_pos + ( parent->cur_len / 2);
-            cur_org_center = hint->org_pos   + ( hint->org_len   / 2);
-
-            cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );
-            pos = par_cur_center + cur_delta - ( len >> 1 );
+                if ( ABS( side_delta ) < ABS( delta_b ) )
+                  pos += side_delta;
+                else
+                  pos += delta_b;
+              }
+              else
+              {
+                pos += delta_b;
+              }
+            }
+            hint->cur_pos = pos;
           }
-
-          {
-	    /* Stems less than one pixel wide are easy - we want to
-	     * make them as dark as possible, so they must fall within
-	     * one pixel. If the stem is split between two pixels
-	     * then snap the edge that is nearer to the pixel boundary
-	     * to the pixel boundary
-	     */
-	    if (len <= 64)
-	    {
-	      if ( ( pos + len + 63 ) / 64  != pos / 64 + 1 )
-		pos += psh3_hint_snap_stem_side_delta ( pos, len );
-	    }
-	    /* Position stems other to minimize the amount of mid-grays.
-	     * There are, in general, two positions that do this,
-	     * illustrated as A) and B) below.
-	     *
-	     *   +                   +                   +                   +
-	     *
-	     * A)             |--------------------------------|
-	     * B)   |--------------------------------|
-	     * C)       |--------------------------------|
-	     *
-	     * Position A) (split the excess stem equally) should be better
-	     * for stems of width N + f where f < 0.5
-	     *
-	     * Position B) (split the deficiency equally) should be better
-	     * for stems of width N + f where f > 0.5
-	     *
-	     * It turns out though that minimizing the total number of lit
-	     * pixels is also important, so position C), with one edge
-	     * aligned with a pixel boundary is actually preferable
-	     * to A). There are also more possibile positions for C) than
-	     * for A) or B), so it involves less distortion of the overall
-	     * character shape.
-	     */
-	    else
-	    {
-	      FT_Fixed frac_len = len & 63;
-	      FT_Fixed center = pos + ( len >> 1 );
-
-	      FT_Fixed delta_a, delta_b;
-
-	      if ( ( len / 64 ) & 1 )
-	      {
-	        delta_a = ( center & -64 ) + 32 - center;
-	        delta_b = ( ( center + 32 ) & - 64 ) - center;
-	      }
-	      else
-	      {
-	        delta_a = ( ( center + 32 ) & - 64 ) - center;
-	        delta_b = ( center & -64 ) + 32 - center;
-	      }
-
-	      /* We choose between B) and C) above based on the amount
-	       * of fractinal stem width; for small amounts, choose
-	       * C) always, for large amounts, B) always, and inbetween,
-	       * pick whichever one involves less stem movement.
-	       */
-	      if (frac_len < 32)
-	      {
-		pos += psh3_hint_snap_stem_side_delta ( pos, len );
-	      }
-	      else if (frac_len < 48)
-	      {
-		FT_Fixed side_delta = psh3_hint_snap_stem_side_delta ( pos, len );
-		  
-		if ( ABS( side_delta ) < ABS( delta_b ) )
-		  pos += side_delta;
-		else
-		  pos += delta_b;
-	      }
-	      else
-	      {
-		pos += delta_b;
-	      }
-	    }
-	  }
-	 
-	  hint->cur_pos = pos;
-	}
+        }
       }
-#endif
-      
+
       psh3_hint_set_fitted( hint );
 
 #ifdef DEBUG_HINTER
@@ -639,7 +587,8 @@
   static void
   psh3_hint_table_align_hints( PSH3_Hint_Table  table,
                                PSH_Globals      globals,
-                               FT_Int           dimension )
+                               FT_Int           dimension,
+                               FT_UInt32        hint_flags )
   {
     PSH3_Hint      hint;
     FT_UInt        count;
@@ -667,7 +616,7 @@
     count = table->max_hints;
 
     for ( ; count > 0; count--, hint++ )
-      psh3_hint_align( hint, globals, dimension );
+      psh3_hint_align( hint, globals, dimension, hint_flags );
   }
 
 
@@ -705,231 +654,7 @@
 
 #endif
 
-#if 0
-  /* setup interpolation zones once the hints have been grid-fitted */
-  /* by the optimizer                                               */
-  static void
-  psh3_hint_table_setup_zones( PSH3_Hint_Table  table,
-                               FT_Fixed         scale,
-                               FT_Fixed         delta )
-  {
-    FT_UInt     count;
-    PSH3_Zone   zone;
-    PSH3_Hint  *sort, hint, hint2;
 
-
-    zone = table->zones;
-
-    /* special case, no hints defined */
-    if ( table->num_hints == 0 )
-    {
-      zone->scale = scale;
-      zone->delta = delta;
-      zone->min   = PSH3_ZONE_MIN;
-      zone->max   = PSH3_ZONE_MAX;
-
-      table->num_zones = 1;
-      table->zone      = zone;
-      return;
-    }
-
-    /* the first zone is before the first hint */
-    /* x' = (x-x0)*s + x0' = x*s + ( x0' - x0*s ) */
-    sort = table->sort;
-    hint = sort[0];
-
-    zone->scale = scale;
-    zone->delta = hint->cur_pos - FT_MulFix( hint->org_pos, scale );
-    zone->min   = PSH3_ZONE_MIN;
-    zone->max   = hint->org_pos;
-
-    psh3_print_zone( zone );
-
-    zone++;
-
-    for ( count = table->num_hints; count > 0; count-- )
-    {
-      FT_Fixed  scale2;
-
-
-      if ( hint->org_len > 0 )
-      {
-        /* setup a zone for inner-stem interpolation */
-        /* (x' - x0') = (x - x0)*(x1'-x0')/(x1-x0)   */
-        /* x' = x*s2 + x0' - x0*s2                   */
-
-        scale2      = FT_DivFix( hint->cur_len, hint->org_len );
-        zone->scale = scale2;
-        zone->min   = hint->org_pos;
-        zone->max   = hint->org_pos + hint->org_len;
-        zone->delta = hint->cur_pos - FT_MulFix( zone->min, scale2 );
-
-        psh3_print_zone( zone );
-
-        zone++;
-      }
-
-      if ( count == 1 )
-        break;
-
-      sort++;
-      hint2 = sort[0];
-
-      /* setup zone for inter-stem interpolation */
-      /* (x'-x1') = (x-x1)*(x2'-x1')/(x2-x1)     */
-      /* x' = x*s3 + x1' - x1*s3                 */
-
-      scale2 = FT_DivFix( hint2->cur_pos - (hint->cur_pos + hint->cur_len),
-                          hint2->org_pos - (hint->org_pos + hint->org_len) );
-      zone->scale = scale2;
-      zone->min   = hint->org_pos + hint->org_len;
-      zone->max   = hint2->org_pos;
-      zone->delta = hint->cur_pos + hint->cur_len -
-                    FT_MulFix( zone->min, scale2 );
-
-      psh3_print_zone( zone );
-
-      zone++;
-
-      hint = hint2;
-    }
-
-    /* the last zone */
-    zone->scale = scale;
-    zone->min   = hint->org_pos + hint->org_len;
-    zone->max   = PSH3_ZONE_MAX;
-    zone->delta = hint->cur_pos + hint->cur_len -
-                  FT_MulFix( zone->min, scale );
-
-    psh3_print_zone( zone );
-
-    zone++;
-
-    table->num_zones = zone - table->zones;
-    table->zone      = table->zones;
-  }
-#endif
-
-#if 0
-  /* tune a single coordinate with the current interpolation zones */
-  static FT_Pos
-  psh3_hint_table_tune_coord( PSH3_Hint_Table  table,
-                              FT_Int           coord )
-  {
-    PSH3_Zone   zone;
-
-
-    zone = table->zone;
-
-    if ( coord < zone->min )
-    {
-      do
-      {
-        if ( zone == table->zones )
-          break;
-
-        zone--;
-
-      } while ( coord < zone->min );
-      table->zone = zone;
-    }
-    else if ( coord > zone->max )
-    {
-      do
-      {
-        if ( zone == table->zones + table->num_zones - 1 )
-          break;
-
-        zone++;
-
-      } while ( coord > zone->max );
-      table->zone = zone;
-    }
-
-    return FT_MulFix( coord, zone->scale ) + zone->delta;
-  }
-#endif
-
-#if 0
- /* tune a given outline with current interpolation zones */
- /* the function only works in a single dimension..       */
-  static void
-  psh3_hint_table_tune_outline( PSH3_Hint_Table  table,
-                                FT_Outline*      outline,
-                                PSH_Globals      globals,
-                                FT_Int           dimension )
-
-  {
-    FT_UInt        count, first, last;
-    PS_Mask_Table  hint_masks = table->hint_masks;
-    PS_Mask        mask;
-    PSH_Dimension  dim        = &globals->dimension[dimension];
-    FT_Fixed       scale      = dim->scale_mult;
-    FT_Fixed       delta      = dim->scale_delta;
-
-
-    if ( hint_masks && hint_masks->num_masks > 0 )
-    {
-      first = 0;
-      mask  = hint_masks->masks;
-      count = hint_masks->num_masks;
-
-      for ( ; count > 0; count--, mask++ )
-      {
-        last = mask->end_point;
-
-        if ( last > first )
-        {
-          FT_Vector*   vec;
-          FT_Int       count2;
-
-
-          psh3_hint_table_activate_mask( table, mask );
-          psh3_hint_table_optimize( table, globals, outline, dimension );
-          psh3_hint_table_setup_zones( table, scale, delta );
-          last = mask->end_point;
-
-          vec    = outline->points + first;
-          count2 = last - first;
-
-          for ( ; count2 > 0; count2--, vec++ )
-          {
-            FT_Pos  x, *px;
-
-
-            px  = dimension ? &vec->y : &vec->x;
-            x   = *px;
-
-            *px = psh3_hint_table_tune_coord( table, (FT_Int)x );
-          }
-        }
-
-        first = last;
-      }
-    }
-    else    /* no hints in this glyph, simply scale the outline */
-    {
-      FT_Vector*  vec;
-
-
-      vec   = outline->points;
-      count = outline->n_points;
-
-      if ( dimension == 0 )
-      {
-        for ( ; count > 0; count--, vec++ )
-          vec->x = FT_MulFix( vec->x, scale ) + delta;
-      }
-      else
-      {
-        for ( ; count > 0; count--, vec++ )
-          vec->y = FT_MulFix( vec->y, scale ) + delta;
-      }
-    }
-  }
-#endif
-
-
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -1661,7 +1386,8 @@
   FT_Error
   ps3_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals )
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags )
   {
     PSH3_GlyphRec  glyphrec;
     PSH3_Glyph     glyph = &glyphrec;
@@ -1699,7 +1425,8 @@
       /* compute aligned stem/hints positions */
       psh3_hint_table_align_hints( &glyph->hint_tables[dimension],
                                    glyph->globals,
-                                   dimension );
+                                   dimension,
+                                   hint_flags );
 
       /* find strong points, align them, then interpolate others */
       psh3_glyph_find_strong_points( glyph, dimension );
--- a/src/pshinter/pshalgo3.h
+++ b/src/pshinter/pshalgo3.h
@@ -190,7 +190,8 @@
   extern FT_Error
   ps3_hints_apply( PS_Hints     ps_hints,
                    FT_Outline*  outline,
-                   PSH_Globals  globals );
+                   PSH_Globals  globals,
+                   FT_UInt32    hint_flags );
 
 
 FT_END_HEADER