shithub: freetype+ttf2subf

Download patch

ref: d1245c0dd28f3604e266b44e7b3ff0108ae0c806
parent: b08fe2dc7af972a61f4e6bcadd7bb522861faec5
author: David Turner <david@freetype.org>
date: Tue Aug 27 18:34:20 EDT 2002

updating sources to support the new FT_LOAD_TARGET_ constants
to support target-specific hinting

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/internal/autohint.h
+++ b/include/freetype/internal/autohint.h
@@ -176,7 +176,7 @@
                                   FT_GlyphSlot   slot,
                                   FT_Size        size,
                                   FT_UInt        glyph_index,
-                                  FT_ULong       load_flags );
+                                  FT_Int32       load_flags );
 
 
   /*************************************************************************/
--- a/include/freetype/internal/psaux.h
+++ b/include/freetype/internal/psaux.h
@@ -610,6 +610,7 @@
              FT_Byte**            glyph_names,
              PS_Blend             blend,
              FT_Bool              hinting,
+             FT_Render_Mode       hint_mode,
              T1_Decoder_Callback  callback );
 
     void
@@ -652,6 +653,7 @@
     PS_Blend             blend;       /* for multiple master support */
 
     FT_UInt32            hint_flags;
+    FT_Render_Mode       hint_mode;
 
     T1_Decoder_Callback  parse_callback;
     T1_Decoder_FuncsRec  funcs;
--- a/include/freetype/internal/pshints.h
+++ b/include/freetype/internal/pshints.h
@@ -280,10 +280,10 @@
   /*    which must correspond to the same font as the glyph.               */
   /*                                                                       */
   typedef FT_Error
-  (*T1_Hints_ApplyFunc)( T1_Hints     hints,
-                         FT_Outline*  outline,
-                         PSH_Globals  globals,
-                         FT_UInt32    hint_flags );
+  (*T1_Hints_ApplyFunc)( T1_Hints        hints,
+                         FT_Outline*     outline,
+                         PSH_Globals     globals,
+                         FT_Render_Mode  hint_mode );
 
 
   /*************************************************************************/
@@ -561,10 +561,10 @@
   /*    which must correspond to the same font than the glyph.             */
   /*                                                                       */
   typedef FT_Error
-  (*T2_Hints_ApplyFunc)( T2_Hints     hints,
-                         FT_Outline*  outline,
-                         PSH_Globals  globals,
-                         FT_UInt32    hint_flags );
+  (*T2_Hints_ApplyFunc)( T2_Hints        hints,
+                         FT_Outline*     outline,
+                         PSH_Globals     globals,
+                         FT_Render_Mode  hint_mode );
 
 
   /*************************************************************************/
--- a/src/autohint/ahhint.c
+++ b/src/autohint/ahhint.c
@@ -40,7 +40,6 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#if 0
   /* snap a given width in scaled coordinates to one of the */
   /* current standard widths                                */
   static FT_Pos
@@ -86,11 +85,11 @@
 
     return width;
   }
-#endif
 
+
   /* compute the snapped width of a given stem */
   static FT_Pos
-  ah_compute_stem_width( AH_Hinter  hinter,
+  ah_compute_stem_width( AH_Hinter   hinter,
                          int         vertical,
                          FT_Pos      width )
   {
@@ -105,85 +104,93 @@
       sign = 1;
     }
 
-#if 1
-    if ( dist < 64 )
-      dist = 64;
-
+    if ( ( vertical  && hinter->no_vert_snapping ) ||
+         ( !vertical && hinter->no_horz_snapping ) )
     {
-      FT_Pos  delta = dist - globals->stds[vertical];
-
-
-      if ( delta < 0 )
-        delta = -delta;
-
-      if ( delta < 40 )
+      /* smooth hinting process, very lightly quantize the stem width */
+      /*                                                              */
+      if ( dist < 64 )
+        dist = 64;
+  
       {
-        dist = globals->stds[vertical];
-        if ( dist < 32 )
-          dist = 32;
-      }
-
-      if ( dist < 3 * 64 )
-      {
-        delta = ( dist & 63 );
-        dist &= -64;
-
-        if ( delta < 10 )
-          dist += delta;
-
-        else if ( delta < 32 )
-          dist += 10;
-
-        else if ( delta < 54 )
-          dist += 54;
-
+        FT_Pos  delta = dist - globals->stds[vertical];
+  
+  
+        if ( delta < 0 )
+          delta = -delta;
+  
+        if ( delta < 40 )
+        {
+          dist = globals->stds[vertical];
+          if ( dist < 32 )
+            dist = 32;
+        }
+  
+        if ( dist < 3 * 64 )
+        {
+          delta = ( dist & 63 );
+          dist &= -64;
+  
+          if ( delta < 10 )
+            dist += delta;
+  
+          else if ( delta < 32 )
+            dist += 10;
+  
+          else if ( delta < 54 )
+            dist += 54;
+  
+          else
+            dist += delta;
+        }
         else
-          dist += delta;
+          dist = ( dist + 32 ) & -64;
       }
-      else
-        dist = ( dist + 32 ) & -64;
     }
-#else
-    if ( vertical )
-    {
-      dist = ah_snap_width( globals->heights, globals->num_heights, dist );
-
-      /* in the case of vertical hinting, always round */
-      /* the stem heights to integer pixels            */
-      if ( dist >= 64 )
-        dist = ( dist + 16 ) & -64;
-      else
-        dist = 64;
-    }
     else
     {
-      dist = ah_snap_width( globals->widths,  globals->num_widths, dist );
-
-      if ( hinter->flags & AH_HINTER_MONOCHROME )
+      /* strong hinting process, snap the stem width to integer pixels */
+      /*                                                               */
+      if ( vertical )
       {
-        /* monochrome horizontal hinting: snap widths to integer pixels */
-        /* with a different threshold                                   */
-        if ( dist < 64 )
-          dist = 64;
+        dist = ah_snap_width( globals->heights, globals->num_heights, dist );
+  
+        /* in the case of vertical hinting, always round */
+        /* the stem heights to integer pixels            */
+        if ( dist >= 64 )
+          dist = ( dist + 16 ) & -64;
         else
-          dist = ( dist + 32 ) & -64;
+          dist = 64;
       }
       else
       {
-        /* for horizontal anti-aliased hinting, we adopt a more subtle */
-        /* approach: we strengthen small stems, round stems whose size */
-        /* is between 1 and 2 pixels to an integer, otherwise nothing  */
-        if ( dist < 48 )
-          dist = ( dist + 64 ) >> 1;
-
-        else if ( dist < 128 )
-          dist = ( dist + 22 ) & -64;
+        dist = ah_snap_width( globals->widths,  globals->num_widths, dist );
+  
+        if ( hinter->flags & AH_HINTER_MONOCHROME )
+        {
+          /* monochrome horizontal hinting: snap widths to integer pixels */
+          /* with a different threshold                                   */
+          if ( dist < 64 )
+            dist = 64;
+          else
+            dist = ( dist + 32 ) & -64;
+        }
         else
-          /* XXX: round otherwise, prevent color fringes in LCD mode */
-          dist = ( dist + 32 ) & -64;
+        {
+          /* for horizontal anti-aliased hinting, we adopt a more subtle */
+          /* approach: we strengthen small stems, round stems whose size */
+          /* is between 1 and 2 pixels to an integer, otherwise nothing  */
+          if ( dist < 48 )
+            dist = ( dist + 64 ) >> 1;
+  
+          else if ( dist < 128 )
+            dist = ( dist + 22 ) & -64;
+          else
+            /* XXX: round otherwise, prevent color fringes in LCD mode */
+            dist = ( dist + 32 ) & -64;
+        }
       }
     }
-#endif
 
     if ( sign )
       dist = -dist;
@@ -278,10 +285,10 @@
       int       has_serifs = 0;
 
 
-      if ( ah_debug_disable_vert && !dimension )
+      if ( hinter->no_horz_hints && !dimension )
         goto Next_Dimension;
 
-      if ( ah_debug_disable_horz && dimension )
+      if ( hinter->no_vert_hints && dimension )
         goto Next_Dimension;
 
       /* we begin by aligning all stems relative to the blue zone */
@@ -467,38 +474,13 @@
 
 
   FT_LOCAL_DEF( void )
-  ah_hinter_hint_edges( AH_Hinter  hinter,
-                        FT_Bool     no_horz_edges,
-                        FT_Bool     no_vert_edges )
+  ah_hinter_hint_edges( AH_Hinter  hinter )
   {
-#if 0
-    ah_debug_disable_horz = no_horz_edges;
-    ah_debug_disable_vert = no_vert_edges;
-#else
-    FT_UNUSED( no_horz_edges );
-    FT_UNUSED( no_vert_edges );
-#endif
     /* AH_Interpolate_Blue_Edges( hinter ); -- doesn't seem to help      */
     /* reduce the problem of the disappearing eye in the `e' of Times... */
     /* also, creates some artifacts near the blue zones?                 */
     {
       ah_hint_edges_3( hinter );
-
-#if 0
-      /* outline optimizer removed temporarily */
-      if ( hinter->flags & AH_HINTER_OPTIMIZE )
-      {
-        AH_Optimizer  opt;
-
-
-        if ( !AH_Optimizer_Init( &opt, hinter->glyph, hinter->memory ) )
-        {
-          AH_Optimizer_Compute( &opt );
-          AH_Optimizer_Done( &opt );
-        }
-      }
-#endif
-
     }
   }
 
@@ -1048,7 +1030,7 @@
 
   /* create a face's autohint globals */
   FT_LOCAL_DEF( FT_Error )
-  ah_hinter_new_face_globals( AH_Hinter   hinter,
+  ah_hinter_new_face_globals( AH_Hinter    hinter,
                               FT_Face      face,
                               AH_Globals   globals )
   {
@@ -1091,9 +1073,9 @@
 
 
   static FT_Error
-  ah_hinter_load( AH_Hinter  hinter,
+  ah_hinter_load( AH_Hinter   hinter,
                   FT_UInt     glyph_index,
-                  FT_UInt     load_flags,
+                  FT_Int32    load_flags,
                   FT_UInt     depth )
   {
     FT_Face           face     = hinter->face;
@@ -1104,12 +1086,7 @@
     FT_Error          error;
     AH_Outline        outline  = hinter->glyph;
     AH_Loader         gloader  = hinter->loader;
-    FT_Bool           no_horz_hints = FT_BOOL(
-                        ( load_flags & AH_HINT_NO_HORZ_EDGES ) != 0 );
-    FT_Bool           no_vert_hints = FT_BOOL(
-                        ( load_flags & AH_HINT_NO_VERT_EDGES ) != 0 );
 
-
     /* load the glyph */
     error = FT_Load_Glyph( face, glyph_index, load_flags );
     if ( error )
@@ -1191,7 +1168,7 @@
       /* perform feature detection */
       ah_outline_detect_features( outline );
 
-      if ( !no_horz_hints )
+      if ( !hinter->no_vert_hints )
       {
         ah_outline_compute_blue_edges( outline, hinter->globals );
         ah_outline_scale_blue_edges( outline, hinter->globals );
@@ -1198,7 +1175,7 @@
       }
 
       /* perform alignment control */
-      ah_hinter_hint_edges( hinter, no_horz_hints, no_vert_hints );
+      ah_hinter_hint_edges( hinter );
       ah_hinter_align( hinter );
 
       /* now save the current outline into the loader's current table */
@@ -1421,11 +1398,11 @@
 
   /* load and hint a given glyph */
   FT_LOCAL_DEF( FT_Error )
-  ah_hinter_load_glyph( AH_Hinter    hinter,
+  ah_hinter_load_glyph( AH_Hinter     hinter,
                         FT_GlyphSlot  slot,
                         FT_Size       size,
                         FT_UInt       glyph_index,
-                        FT_Int        load_flags )
+                        FT_Int32      load_flags )
   {
     FT_Face           face         = slot->face;
     FT_Error          error;
@@ -1432,6 +1409,7 @@
     FT_Fixed          x_scale      = size->metrics.x_scale;
     FT_Fixed          y_scale      = size->metrics.y_scale;
     AH_Face_Globals   face_globals = FACE_GLOBALS( face );
+    FT_Render_Mode    hint_mode    = FT_LOAD_TARGET_MODE(load_flags);
 
 
     /* first of all, we need to check that we're using the correct face and */
@@ -1458,6 +1436,25 @@
       ah_hinter_scale_globals( hinter, x_scale, y_scale );
 
     ah_loader_rewind( hinter->loader );
+
+    /* reset hinting flags according to load flags and current render target */
+    hinter->no_horz_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
+    hinter->no_vert_hints = FT_BOOL( load_flags & FT_LOAD_NO_AUTOHINT );
+    
+#ifdef DEBUG_HINTER
+    hinter->no_horz_hints = ah_debug_disable_vert;  /* not a bug, the meaning */
+    hinter->no_vert_hints = ah_debug_disable_horz;  /* of h/v is inverted !!  */
+#endif    
+
+    /* we snap the width of vertical stems for the monochrome and horizontal */
+    /* LCD rendering targets only. Corresponds to X snapping                 */
+    hinter->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
+                                        hint_mode == FT_RENDER_MODE_LCD_V  );
+
+    /* we snap the width of horizontal stems for the monochrome and vertical */
+    /* LCD rendering targets only. Corresponds to Y snapping                 */
+    hinter->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
+                                        hint_mode == FT_RENDER_MODE_LCD    );
 
 #if 1
     load_flags  = FT_LOAD_NO_SCALE
--- a/src/autohint/ahhint.h
+++ b/src/autohint/ahhint.h
@@ -32,8 +32,8 @@
 
 #define AH_HINT_DEFAULT        0
 #define AH_HINT_NO_ALIGNMENT   1
-#define AH_HINT_NO_HORZ_EDGES  0x20000L
-#define AH_HINT_NO_VERT_EDGES  0x40000L
+#define AH_HINT_NO_HORZ_EDGES  0x200000L  /* temporary hack */
+#define AH_HINT_NO_VERT_EDGES  0x400000L  /* temporary hack */
 
 
   /* create a new empty hinter object */
@@ -47,7 +47,7 @@
                         FT_GlyphSlot  slot,
                         FT_Size       size,
                         FT_UInt       glyph_index,
-                        FT_Int        load_flags );
+                        FT_Int32      load_flags );
 
   /* finalize a hinter object */
   FT_LOCAL( void )
--- a/src/autohint/ahmodule.c
+++ b/src/autohint/ahmodule.c
@@ -69,7 +69,7 @@
                             FT_GlyphSlot   slot,
                             FT_Size        size,
                             FT_UInt        glyph_index,
-                            FT_ULong       load_flags )
+                            FT_Int32       load_flags )
   {
     return ah_hinter_load_glyph( module->hinter,
                                  slot, size, glyph_index, load_flags );
--- a/src/autohint/ahtypes.h
+++ b/src/autohint/ahtypes.h
@@ -491,6 +491,11 @@
     FT_Vector         trans_delta;
     FT_Matrix         trans_matrix;
 
+    FT_Bool           no_horz_hints;     /* disable X hinting            */
+    FT_Bool           no_vert_hints;     /* disable Y hinting            */
+    FT_Bool           no_horz_snapping;  /* disable X stem size snapping */
+    FT_Bool           no_vert_snapping;  /* disable Y stem size snapping */
+
   } AH_HinterRec, *AH_Hinter;
 
 
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -347,11 +347,12 @@
   /*    slot    :: The current glyph object.                               */
   /*                                                                       */
   FT_LOCAL_DEF( void )
-  cff_decoder_init( CFF_Decoder*   decoder,
-                    TT_Face        face,
-                    CFF_Size       size,
-                    CFF_GlyphSlot  slot,
-                    FT_Bool        hinting )
+  cff_decoder_init( CFF_Decoder*    decoder,
+                    TT_Face         face,
+                    CFF_Size        size,
+                    CFF_GlyphSlot   slot,
+                    FT_Bool         hinting,
+                    FT_Render_Mode  hint_mode )
   {
     CFF_Font  cff = (CFF_Font)face->extra.data;
 
@@ -366,6 +367,8 @@
     decoder->num_globals  = cff->num_global_subrs;
     decoder->globals      = cff->global_subrs;
     decoder->globals_bias = cff_compute_bias( decoder->num_globals );
+    
+    decoder->hint_mode    = hint_mode;
   }
 
 
@@ -2203,7 +2206,7 @@
     *max_advance = 0;
 
     /* Initialize load decoder */
-    cff_decoder_init( &decoder, face, 0, 0, 0 );
+    cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
 
     decoder.builder.metrics_only = 1;
     decoder.builder.load_points  = 0;
@@ -2262,7 +2265,7 @@
   cff_slot_load( CFF_GlyphSlot  glyph,
                  CFF_Size       size,
                  FT_Int         glyph_index,
-                 FT_Int         load_flags )
+                 FT_Int32       load_flags )
   {
     FT_Error     error;
     CFF_Decoder  decoder;
@@ -2298,7 +2301,8 @@
       FT_ULong  charstring_len;
 
 
-      cff_decoder_init( &decoder, face, size, glyph, hinting );
+      cff_decoder_init( &decoder, face, size, glyph, hinting,
+                        FT_LOAD_TARGET_MODE(load_flags) );
 
       decoder.builder.no_recurse =
         (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -168,15 +168,18 @@
     FT_Byte**          glyph_names;   /* for pure CFF fonts only  */
     FT_UInt            num_glyphs;    /* number of glyphs in font */
 
+    FT_Render_Mode     hint_mode;
+
   } CFF_Decoder;
 
 
   FT_LOCAL( void )
-  cff_decoder_init( CFF_Decoder*   decoder,
-                    TT_Face        face,
-                    CFF_Size       size,
-                    CFF_GlyphSlot  slot,
-                    FT_Bool        hinting );
+  cff_decoder_init( CFF_Decoder*    decoder,
+                    TT_Face         face,
+                    CFF_Size        size,
+                    CFF_GlyphSlot   slot,
+                    FT_Bool         hinting,
+                    FT_Render_Mode  hint_mode );
 
   FT_LOCAL( void )
   cff_decoder_prepare( CFF_Decoder*  decoder,
@@ -200,7 +203,7 @@
   cff_slot_load( CFF_GlyphSlot  glyph,
                  CFF_Size       size,
                  FT_Int         glyph_index,
-                 FT_Int         load_flags );
+                 FT_Int32       load_flags );
 
 
 FT_END_HEADER
--- a/src/cid/cidgload.c
+++ b/src/cid/cidgload.c
@@ -272,7 +272,7 @@
   cid_slot_load_glyph( CID_GlyphSlot  glyph,
                        CID_Size       size,
                        FT_Int         glyph_index,
-                       FT_Int         load_flags )
+                       FT_Int32       load_flags )
   {
     FT_Error       error;
     T1_DecoderRec  decoder;
@@ -306,6 +306,7 @@
                                              0, /* glyph names -- XXX */
                                              0, /* blend == 0 */
                                              hinting,
+                                             FT_LOAD_TARGET_MODE(load_flags),
                                              cid_load_glyph );
 
       /* set up the decoder */
--- a/src/cid/cidgload.h
+++ b/src/cid/cidgload.h
@@ -40,7 +40,7 @@
   cid_slot_load_glyph( CID_GlyphSlot  glyph,
                        CID_Size       size,
                        FT_Int         glyph_index,
-                       FT_Int         load_flags );
+                       FT_Int32       load_flags );
 
 
 FT_END_HEADER
--- a/src/psaux/t1decode.c
+++ b/src/psaux/t1decode.c
@@ -752,8 +752,8 @@
             /* apply hints to the loaded glyph outline now */
             hinter->apply( hinter->hints,
                            builder->current,
-                           (PSH_Globals)builder->hints_globals,
-                           decoder->hint_flags );
+                           (PSH_Globals) builder->hints_globals,
+                           decoder->hint_mode );
           }
 
           /* add current outline to the glyph slot */
@@ -1122,6 +1122,7 @@
                    FT_Byte**            glyph_names,
                    PS_Blend             blend,
                    FT_Bool              hinting,
+                   FT_Render_Mode       hint_mode,
                    T1_Decoder_Callback  parse_callback )
   {
     FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
@@ -1148,6 +1149,7 @@
     decoder->num_glyphs     = face->num_glyphs;
     decoder->glyph_names    = glyph_names;
     decoder->hint_flags     = face->internal->hint_flags;
+    decoder->hint_mode      = hint_mode;
     decoder->blend          = blend;
     decoder->parse_callback = parse_callback;
 
--- a/src/psaux/t1decode.h
+++ b/src/psaux/t1decode.h
@@ -50,6 +50,7 @@
                    FT_Byte**            glyph_names,
                    PS_Blend             blend,
                    FT_Bool              hinting,
+                   FT_Render_Mode       hint_mode,
                    T1_Decoder_Callback  parse_glyph );
 
   FT_LOCAL( void )
--- a/src/pshinter/pshalgo1.c
+++ b/src/pshinter/pshalgo1.c
@@ -742,10 +742,10 @@
   /*************************************************************************/
 
   FT_Error
-  ps1_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags )
+  ps1_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode )
   {
     PSH1_Hint_TableRec  hints;
     FT_Error            error = 0;
@@ -752,7 +752,7 @@
     FT_Int              dimension;
 
 
-    FT_UNUSED( hint_flags );
+    FT_UNUSED( hint_mode );
 
     for ( dimension = 1; dimension >= 0; dimension-- )
     {
--- a/src/pshinter/pshalgo1.h
+++ b/src/pshinter/pshalgo1.h
@@ -86,10 +86,10 @@
 
 
   extern FT_Error
-  ps1_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags );
+  ps1_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode );
 
 
 #ifdef DEBUG_HINTER
--- a/src/pshinter/pshalgo2.c
+++ b/src/pshinter/pshalgo2.c
@@ -1492,10 +1492,10 @@
   /*************************************************************************/
 
   FT_Error
-  ps2_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags )
+  ps2_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode )
   {
     PSH2_GlyphRec  glyphrec;
     PSH2_Glyph     glyph = &glyphrec;
@@ -1505,7 +1505,7 @@
 #endif
     FT_Int         dimension;
 
-    FT_UNUSED( hint_flags );
+    FT_UNUSED( hint_mode );
 
 #ifdef DEBUG_HINTER
     memory = globals->memory;
--- a/src/pshinter/pshalgo2.h
+++ b/src/pshinter/pshalgo2.h
@@ -188,10 +188,10 @@
 
 
   extern FT_Error
-  ps2_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags );
+  ps2_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode );
 
 
 FT_END_HEADER
--- a/src/pshinter/pshalgo3.c
+++ b/src/pshinter/pshalgo3.c
@@ -380,7 +380,7 @@
   psh3_hint_align( PSH3_Hint    hint,
                    PSH_Globals  globals,
                    FT_Int       dimension,
-                   FT_UInt32    hint_flags )
+                   PSH3_Glyph   glyph )
   {
     PSH_Dimension  dim   = &globals->dimension[dimension];
     FT_Fixed       scale = dim->scale_mult;
@@ -392,6 +392,7 @@
       FT_Pos  pos = FT_MulFix( hint->org_pos, scale ) + delta;
       FT_Pos  len = FT_MulFix( hint->org_len, scale );
 
+      FT_Int            no_snapping;
       FT_Pos            fit_center;
       FT_Pos            fit_len;
       PSH_AlignmentRec  align;
@@ -398,8 +399,8 @@
 
 
       /* 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 ) )
+      if ( ( dimension == 0 && glyph->no_horz_hints ) ||
+           ( dimension == 1 && glyph->no_vert_hints ) )
       {
         hint->cur_pos = pos;
         hint->cur_len = len;
@@ -409,7 +410,10 @@
       }
 
       /* perform stem snapping when requested */
-      if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
+      no_snapping = ( dimension == 0 && !glyph->no_horz_snapping ) ||
+                    ( dimension == 1 && !glyph->no_vert_snapping );
+                    
+      if ( !no_snapping )
       {
         /* compute fitted width/height */
         fit_len = 0;
@@ -468,7 +472,7 @@
 
             /* ensure that parent is already fitted */
             if ( !psh3_hint_is_fitted( parent ) )
-              psh3_hint_align( parent, globals, dimension, hint_flags );
+              psh3_hint_align( parent, globals, dimension, glyph );
 
             par_org_center = parent->org_pos + ( parent->org_len >> 1 );
             par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );
@@ -478,7 +482,7 @@
             pos       = par_cur_center + cur_delta - ( len >> 1 );
           }
 
-          if ( ( hint_flags & FT_HINT_NO_INTEGER_STEM ) == 0 )
+          if ( !no_snapping )
           {
             /* normal processing */
             if ( fit_len & 64 )
@@ -537,7 +541,7 @@
               FT_Fixed delta_a, delta_b;
 
 
-              if ( ( len / 64 ) & 1 )
+              if ( len & 64 )           
               {
                 delta_a = ( center & -64 ) + 32 - center;
                 delta_b = ( ( center + 32 ) & - 64 ) - center;
@@ -587,7 +591,7 @@
   psh3_hint_table_align_hints( PSH3_Hint_Table  table,
                                PSH_Globals      globals,
                                FT_Int           dimension,
-                               FT_UInt32        hint_flags )
+                               PSH3_Glyph       glyph )
   {
     PSH3_Hint      hint;
     FT_UInt        count;
@@ -617,7 +621,7 @@
     count = table->max_hints;
 
     for ( ; count > 0; count--, hint++ )
-      psh3_hint_align( hint, globals, dimension, hint_flags );
+      psh3_hint_align( hint, globals, dimension, glyph );
   }
 
 
@@ -1675,10 +1679,10 @@
   /*************************************************************************/
 
   FT_Error
-  ps3_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags )
+  ps3_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode )
   {
     PSH3_GlyphRec  glyphrec;
     PSH3_Glyph     glyph = &glyphrec;
@@ -1706,6 +1710,15 @@
 
 #endif /* DEBUG_HINTER */
 
+    glyph->no_horz_hints = 0;
+    glyph->no_vert_hints = 0;
+    
+    glyph->no_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
+                                       hint_mode == FT_RENDER_MODE_LCD_V  );
+
+    glyph->no_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_NORMAL ||
+                                       hint_mode == FT_RENDER_MODE_LCD    );
+
     error = psh3_glyph_init( glyph, outline, ps_hints, globals );
     if ( error )
       goto Exit;
@@ -1722,7 +1735,7 @@
       psh3_hint_table_align_hints( &glyph->hint_tables[dimension],
                                    glyph->globals,
                                    dimension,
-                                   hint_flags );
+                                   glyph );
 
       /* 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
@@ -217,6 +217,11 @@
     FT_Int              major_dir;
     FT_Int              minor_dir;
 
+    FT_Bool             no_horz_hints;
+    FT_Bool             no_vert_hints;
+    FT_Bool             no_horz_snapping;
+    FT_Bool             no_vert_snapping;
+
   } PSH3_GlyphRec, *PSH3_Glyph;
 
 
@@ -234,10 +239,10 @@
 
 
   extern FT_Error
-  ps3_hints_apply( PS_Hints     ps_hints,
-                   FT_Outline*  outline,
-                   PSH_Globals  globals,
-                   FT_UInt32    hint_flags );
+  ps3_hints_apply( PS_Hints        ps_hints,
+                   FT_Outline*     outline,
+                   PSH_Globals     globals,
+                   FT_Render_Mode  hint_mode );
 
 
 FT_END_HEADER
--- a/src/type1/t1gload.c
+++ b/src/type1/t1gload.c
@@ -164,6 +164,7 @@
                                            (FT_Byte**)type1->glyph_names,
                                            face->blend,
                                            0,
+                                           0,
                                            T1_Parse_Glyph );
     if ( error )
       return error;
@@ -214,7 +215,7 @@
   T1_Load_Glyph( T1_GlyphSlot  glyph,
                  T1_Size       size,
                  FT_UInt       glyph_index,
-                 FT_Int        load_flags )
+                 FT_Int32      load_flags )
   {
     FT_Error                error;
     T1_DecoderRec           decoder;
@@ -251,6 +252,7 @@
                                  (FT_Byte**)type1->glyph_names,
                                  face->blend,
                                  FT_BOOL( hinting ),
+                                 FT_LOAD_TARGET_MODE(load_flags),
                                  T1_Parse_Glyph );
     if ( error )
       goto Exit;
--- a/src/type1/t1gload.h
+++ b/src/type1/t1gload.h
@@ -35,7 +35,7 @@
   T1_Load_Glyph( T1_GlyphSlot  glyph,
                  T1_Size       size,
                  FT_UInt       glyph_index,
-                 FT_Int        load_flags );
+                 FT_Int32      load_flags );
 
 
 FT_END_HEADER