shithub: freetype+ttf2subf

Download patch

ref: 5aa6716a5eb8409f606886b5d4e63476d85a3519
parent: 69da54cacc0056a40fc7f88278c4c60fd35e7bb9
author: Werner Lemberg <[email protected]>
date: Sat Apr 22 09:27:21 EDT 2017

Add new `slight' auto-hinting mode.

This mode uses fractional advance widths and doesn't scale glyphs
horizontally, only applying vertical scaling and hinting.

At the same time, the behaviour of the `light' auto-hinter gets
restored for backwards compatibility: Both vertical and horizontal
scaling is again based on rounded metrics values (this was changed
in a commit from 2017-03-30 as a side effect).  To be more precise,
the behaviour is restored for TrueType fonts only; for other font
formats like Type 1, this is a new feature of the `light' hinting
mode.

* include/freetype/freetype.h (FT_LOAD_TARGET_SLIGHT): New macro.
(FT_RENDER_MODE_SLIGHT): New render mode.

* include/freetype/internal/ftobjs.h (FT_Size_InternalRec): Add
`autohint_mode' and `autohint_metrics' fields.

* src/autofit/afcjk.c (af_cjk_hints_init), src/autofit/aflatin.c
(af_latin_hints_init), src/autofit/aflatin2 (af_latin2_hints_init):
Updated.

* src/autofit/afloader.c (af_loader_embolden_glyph_in_slot): Use
`autohint_metrics'.
(af_loader_load_glyph): s/internal/slot_internal/.
Initialize `autohint_metrics' and `autohint_mode' depending on
current auto-hint mode.
Use `autohint_metrics'.
Updated.

* src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Updated.

* src/base/ftobjs.c (FT_Load_Glyph): Updated.
(FT_New_Size): Allocate `internal' object.

* src/pshinter/pshalgo.c (ps_hints_apply): Updated.

* src/smooth/ftsmooth.c (ft_smooth_render): Updated.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
 2017-04-22  Werner Lemberg  <[email protected]>
 
+	Add new `slight' auto-hinting mode.
+
+	This mode uses fractional advance widths and doesn't scale glyphs
+	horizontally, only applying vertical scaling and hinting.
+
+	At the same time, the behaviour of the `light' auto-hinter gets
+	restored for backwards compatibility: Both vertical and horizontal
+	scaling is again based on rounded metrics values (this was changed
+	in a commit from 2017-03-30 as a side effect).  To be more precise,
+	the behaviour is restored for TrueType fonts only; for other font
+	formats like Type 1, this is a new feature of the `light' hinting
+	mode.
+
+	* include/freetype/freetype.h (FT_LOAD_TARGET_SLIGHT): New macro.
+	(FT_RENDER_MODE_SLIGHT): New render mode.
+
+	* include/freetype/internal/ftobjs.h (FT_Size_InternalRec): Add
+	`autohint_mode' and `autohint_metrics' fields.
+
+	* src/autofit/afcjk.c (af_cjk_hints_init), src/autofit/aflatin.c
+	(af_latin_hints_init), src/autofit/aflatin2 (af_latin2_hints_init):
+	Updated.
+
+	* src/autofit/afloader.c (af_loader_embolden_glyph_in_slot): Use
+	`autohint_metrics'.
+	(af_loader_load_glyph): s/internal/slot_internal/.
+	Initialize `autohint_metrics' and `autohint_mode' depending on
+	current auto-hint mode.
+	Use `autohint_metrics'.
+	Updated.
+
+	* src/base/ftadvanc.c (LOAD_ADVANCE_FAST_CHECK): Updated.
+
+	* src/base/ftobjs.c (FT_Load_Glyph): Updated.
+	(FT_New_Size): Allocate `internal' object.
+
+	* src/pshinter/pshalgo.c (ps_hints_apply): Updated.
+
+	* src/smooth/ftsmooth.c (ft_smooth_render): Updated.
+
+2017-04-22  Werner Lemberg  <[email protected]>
+
 	Introduce `FT_Size_InternalRec' structure.
 
 	We are going to extend this later on.
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -221,6 +221,7 @@
   /*                                                                       */
   /*    FT_LOAD_TARGET_NORMAL                                              */
   /*    FT_LOAD_TARGET_LIGHT                                               */
+  /*    FT_LOAD_TARGET_SLIGHT                                              */
   /*    FT_LOAD_TARGET_MONO                                                */
   /*    FT_LOAD_TARGET_LCD                                                 */
   /*    FT_LOAD_TARGET_LCD_V                                               */
@@ -1755,7 +1756,8 @@
   /*    `slot->format' is also changed to @FT_GLYPH_FORMAT_BITMAP.         */
   /*                                                                       */
   /*    Here is a small pseudo code fragment that shows how to use         */
-  /*    `lsb_delta' and `rsb_delta':                                       */
+  /*    `lsb_delta' and `rsb_delta' to improve (integer) positioning of    */
+  /*    glyphs:                                                            */
   /*                                                                       */
   /*    {                                                                  */
   /*      FT_Pos  origin_x       = 0;                                      */
@@ -2941,6 +2943,18 @@
    *     driver, if the driver itself and the font support it, or by the
    *     auto-hinter.
    *
+   *     Use this hinting mode if you mainly need integer advance widths
+   *     and want to avoid sub-pixel rendering.
+   *
+   *   FT_LOAD_TARGET_SLIGHT ::
+   *     This is similar to @FT_LOAD_TARGET_LIGHT with a main difference:
+   *     Advance widths are not rounded to integer values; instead, the
+   *     linearly scaled values are used.  In particular this implies that
+   *     you have to apply sub-pixel rendering.
+   *
+   *     In general, this mode yields better results than
+   *     @FT_LOAD_TARGET_LIGHT.
+   *
    *   FT_LOAD_TARGET_MONO ::
    *     Strong hinting algorithm that should only be used for monochrome
    *     output.  The result is probably unpleasant if the glyph is rendered
@@ -2975,11 +2989,19 @@
    *       FT_Render_Glyph( face->glyph, FT_RENDER_MODE_LCD );
    *     }
    *
+   *   In general, you should stick with one rendering mode.  For example,
+   *   switching between @FT_LOAD_TARGET_LIGHT and @FT_LOAD_TARGET_SLIGHT
+   *   enforces a lot of recomputation, which is slow.  Another reason is
+   *   caching: Selecting a different mode usually causes changes in both
+   *   the outlines and the rasterized bitmaps; it is thus necessary to
+   *   empty the cache after a mode switch to avoid false hits.
+   *
    */
 #define FT_LOAD_TARGET_( x )   ( (FT_Int32)( (x) & 15 ) << 16 )
 
 #define FT_LOAD_TARGET_NORMAL  FT_LOAD_TARGET_( FT_RENDER_MODE_NORMAL )
 #define FT_LOAD_TARGET_LIGHT   FT_LOAD_TARGET_( FT_RENDER_MODE_LIGHT  )
+#define FT_LOAD_TARGET_SLIGHT  FT_LOAD_TARGET_( FT_RENDER_MODE_SLIGHT )
 #define FT_LOAD_TARGET_MONO    FT_LOAD_TARGET_( FT_RENDER_MODE_MONO   )
 #define FT_LOAD_TARGET_LCD     FT_LOAD_TARGET_( FT_RENDER_MODE_LCD    )
 #define FT_LOAD_TARGET_LCD_V   FT_LOAD_TARGET_( FT_RENDER_MODE_LCD_V  )
@@ -3060,6 +3082,12 @@
   /*      indirectly to define hinting algorithm selectors.  See           */
   /*      @FT_LOAD_TARGET_XXX for details.                                 */
   /*                                                                       */
+  /*    FT_RENDER_MODE_SLIGHT ::                                           */
+  /*      This is equivalent to @FT_RENDER_MODE_NORMAL.  It is only        */
+  /*      defined as a separate value because render modes are also used   */
+  /*      indirectly to define hinting algorithm selectors.  See           */
+  /*      @FT_LOAD_TARGET_XXX for details.                                 */
+  /*                                                                       */
   /*    FT_RENDER_MODE_MONO ::                                             */
   /*      This mode corresponds to 1-bit bitmaps (with 2~levels of         */
   /*      opacity).                                                        */
@@ -3092,6 +3120,7 @@
   {
     FT_RENDER_MODE_NORMAL = 0,
     FT_RENDER_MODE_LIGHT,
+    FT_RENDER_MODE_SLIGHT,
     FT_RENDER_MODE_MONO,
     FT_RENDER_MODE_LCD,
     FT_RENDER_MODE_LCD_V,
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -443,13 +443,20 @@
   /*    object.                                                            */
   /*                                                                       */
   /* <Fields>                                                              */
-  /*    module_data :: Data specific to a driver module.                   */
+  /*    module_data      :: Data specific to a driver module.              */
   /*                                                                       */
+  /*    autohint_mode    :: The used auto-hinting mode.                    */
+  /*                                                                       */
+  /*    autohint_metrics :: Metrics used by the auto-hinter.               */
+  /*                                                                       */
   /*************************************************************************/
 
   typedef struct  FT_Size_InternalRec_
   {
     void*  module_data;
+
+    FT_Render_Mode   autohint_mode;
+    FT_Size_Metrics  autohint_metrics;
 
   } FT_Size_InternalRec;
 
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -1398,9 +1398,12 @@
       other_flags |= AF_LATIN_HINTS_VERT_SNAP;
 
     /*
-     *  We adjust stems to full pixels unless in `light' or `lcd' mode.
+     *  We adjust stems to full pixels unless in `light', `slight',
+     *  or `lcd' mode.
      */
-    if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
+    if ( mode != FT_RENDER_MODE_LIGHT  &&
+         mode != FT_RENDER_MODE_SLIGHT &&
+         mode != FT_RENDER_MODE_LCD    )
       other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
 
     if ( mode == FT_RENDER_MODE_MONO )
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -2577,7 +2577,9 @@
     /*
      *  We adjust stems to full pixels unless in `light' or `lcd' mode.
      */
-    if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
+    if ( mode != FT_RENDER_MODE_LIGHT  &&
+         mode != FT_RENDER_MODE_SLIGHT &&
+         mode != FT_RENDER_MODE_LCD    )
       other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
 
     if ( mode == FT_RENDER_MODE_MONO )
@@ -2590,8 +2592,10 @@
      *  However, if warping is enabled (which only works in `light' hinting
      *  mode), advance widths get adjusted, too.
      */
-    if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD ||
-         ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
+    if ( mode == FT_RENDER_MODE_LIGHT                      ||
+         mode == FT_RENDER_MODE_SLIGHT                     ||
+         mode == FT_RENDER_MODE_LCD                        ||
+         ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
 
 #ifdef AF_CONFIG_OPTION_USE_WARPER
--- a/src/autofit/aflatin2.c
+++ b/src/autofit/aflatin2.c
@@ -1560,7 +1560,9 @@
     /*
      *  We adjust stems to full pixels unless in `light' or `lcd' mode.
      */
-    if ( mode != FT_RENDER_MODE_LIGHT && mode != FT_RENDER_MODE_LCD )
+    if ( mode != FT_RENDER_MODE_LIGHT  &&
+         mode != FT_RENDER_MODE_SLIGHT &&
+         mode != FT_RENDER_MODE_LCD    )
       other_flags |= AF_LATIN_HINTS_STEM_ADJUST;
 
     if ( mode == FT_RENDER_MODE_MONO )
@@ -1570,8 +1572,10 @@
      *  In `light' or `lcd' mode we disable horizontal hinting completely.
      *  We also do it if the face is italic.
      */
-    if ( mode == FT_RENDER_MODE_LIGHT || mode == FT_RENDER_MODE_LCD ||
-         ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0          )
+    if ( mode == FT_RENDER_MODE_LIGHT                      ||
+         mode == FT_RENDER_MODE_SLIGHT                     ||
+         mode == FT_RENDER_MODE_LCD                        ||
+         ( face->style_flags & FT_STYLE_FLAG_ITALIC ) != 0 )
       scaler_flags |= AF_SCALER_FLAG_NO_HORIZONTAL;
 
 #ifdef AF_CONFIG_OPTION_USE_WARPER
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -97,11 +97,13 @@
     AF_FaceGlobals         globals = loader->globals;
     AF_WritingSystemClass  writing_system_class;
 
+    FT_Size_Metrics*  size_metrics = &face->size->internal->autohint_metrics;
+
     FT_Pos  stdVW = 0;
     FT_Pos  stdHW = 0;
 
-    FT_Bool  size_changed = face->size->metrics.x_ppem
-                              != globals->stem_darkening_for_ppem;
+    FT_Bool  size_changed = size_metrics->x_ppem !=
+                              globals->stem_darkening_for_ppem;
 
     FT_Fixed  em_size  = af_intToFixed( face->units_per_EM );
     FT_Fixed  em_ratio = FT_DivFix( af_intToFixed( 1000 ), em_size );
@@ -145,11 +147,11 @@
                                                     face,
                                                     stdVW ) );
       darken_x = FT_DivFix( FT_MulFix( darken_by_font_units_x,
-                                       face->size->metrics.x_scale ),
+                                       size_metrics->x_scale ),
                             em_ratio );
 
       globals->standard_vertical_width = stdVW;
-      globals->stem_darkening_for_ppem = face->size->metrics.x_ppem;
+      globals->stem_darkening_for_ppem = size_metrics->x_ppem;
       globals->darken_x                = af_fixedToInt( darken_x );
     }
 
@@ -164,11 +166,11 @@
                                                     face,
                                                     stdHW ) );
       darken_y = FT_DivFix( FT_MulFix( darken_by_font_units_y,
-                                       face->size->metrics.y_scale ),
+                                       size_metrics->y_scale ),
                             em_ratio );
 
       globals->standard_horizontal_width = stdHW;
-      globals->stem_darkening_for_ppem   = face->size->metrics.x_ppem;
+      globals->stem_darkening_for_ppem   = size_metrics->x_ppem;
       globals->darken_y                  = af_fixedToInt( darken_y );
 
       /*
@@ -217,10 +219,11 @@
   {
     FT_Error  error;
 
-    FT_Size           size     = face->size;
-    FT_GlyphSlot      slot     = face->glyph;
-    FT_Slot_Internal  internal = slot->internal;
-    FT_GlyphLoader    gloader  = internal->loader;
+    FT_Size           size          = face->size;
+    FT_Size_Internal  size_internal = size->internal;
+    FT_GlyphSlot      slot          = face->glyph;
+    FT_Slot_Internal  slot_internal = slot->internal;
+    FT_GlyphLoader    gloader       = slot_internal->loader;
 
     AF_GlyphHints          hints         = loader->hints;
     AF_ScalerRec           scaler;
@@ -239,6 +242,44 @@
 
     FT_ZERO( &scaler );
 
+    if ( !size_internal->autohint_metrics.x_scale                          ||
+         size_internal->autohint_mode != FT_LOAD_TARGET_MODE( load_flags ) )
+    {
+      /* switching between LIGHT and SLIGHT (and vice versa) usually means */
+      /* different scaling values; this later on enforces recomputation of */
+      /* everything related to the current size                            */
+
+      size_internal->autohint_mode    = FT_LOAD_TARGET_MODE( load_flags );
+      size_internal->autohint_metrics = size->metrics;
+
+      if ( size_internal->autohint_mode != FT_RENDER_MODE_SLIGHT )
+      {
+        FT_Size_Metrics*  size_metrics = &size_internal->autohint_metrics;
+
+
+        /* set metrics to integer values and adjust scaling accordingly; */
+        /* this is the same setup as with TrueType fonts, cf. function   */
+        /* `tt_size_reset' in file `ttobjs.c'                            */
+        size_metrics->ascender  = FT_PIX_ROUND(
+                                    FT_MulFix( face->ascender,
+                                               size_metrics->y_scale ) );
+        size_metrics->descender = FT_PIX_ROUND(
+                                    FT_MulFix( face->descender,
+                                               size_metrics->y_scale ) );
+        size_metrics->height    = FT_PIX_ROUND(
+                                    FT_MulFix( face->height,
+                                               size_metrics->y_scale ) );
+
+        size_metrics->x_scale     = FT_DivFix( size_metrics->x_ppem << 6,
+                                               face->units_per_EM );
+        size_metrics->y_scale     = FT_DivFix( size_metrics->y_ppem << 6,
+                                               face->units_per_EM );
+        size_metrics->max_advance = FT_PIX_ROUND(
+                                      FT_MulFix( face->max_advance_width,
+                                                 size_metrics->x_scale ) );
+      }
+    }
+
     /*
      *  TODO: This code currently doesn't support fractional advance widths,
      *  i.e., placing hinted glyphs at anything other than integer
@@ -249,9 +290,9 @@
      *  values of the scaler would need to be adjusted.
      */
     scaler.face    = face;
-    scaler.x_scale = size->metrics.x_scale;
+    scaler.x_scale = size_internal->autohint_metrics.x_scale;
     scaler.x_delta = 0;
-    scaler.y_scale = size->metrics.y_scale;
+    scaler.y_scale = size_internal->autohint_metrics.y_scale;
     scaler.y_delta = 0;
 
     scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
@@ -339,21 +380,22 @@
      *
      */
 
-    /* stem darkening only works well in `light' mode */
-    if ( scaler.render_mode == FT_RENDER_MODE_LIGHT    &&
+    /* stem darkening only works well in `light' and `slight' modes */
+    if ( ( scaler.render_mode == FT_RENDER_MODE_LIGHT  ||
+           scaler.render_mode == FT_RENDER_MODE_SLIGHT ) &&
          ( !face->internal->no_stem_darkening        ||
            ( face->internal->no_stem_darkening < 0 &&
-             !module->no_stem_darkening            ) ) )
+             !module->no_stem_darkening            ) )   )
       af_loader_embolden_glyph_in_slot( loader, face, style_metrics );
 
-    loader->transformed = internal->glyph_transformed;
+    loader->transformed = slot_internal->glyph_transformed;
     if ( loader->transformed )
     {
       FT_Matrix  inverse;
 
 
-      loader->trans_matrix = internal->glyph_matrix;
-      loader->trans_delta  = internal->glyph_delta;
+      loader->trans_matrix = slot_internal->glyph_matrix;
+      loader->trans_delta  = slot_internal->glyph_delta;
 
       inverse = loader->trans_matrix;
       if ( !FT_Matrix_Invert( &inverse ) )
@@ -391,7 +433,8 @@
 
       /* we now need to adjust the metrics according to the change in */
       /* width/positioning that occurred during the hinting process   */
-      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT )
+      if ( scaler.render_mode != FT_RENDER_MODE_LIGHT  &&
+           scaler.render_mode != FT_RENDER_MODE_SLIGHT )
       {
         FT_Pos  old_rsb, old_lsb, new_lsb;
         FT_Pos  pp1x_uh, pp2x_uh;
@@ -448,7 +491,10 @@
           slot->rsb_delta = loader->pp2.x - pp2x;
         }
       }
-      else
+      /* `light' mode uses integer advance widths */
+      /* (but sets `lsb_delta' and `rsb_delta'),  */
+      /* `slight' mode uses fractional values     */
+      else if ( scaler.render_mode == FT_RENDER_MODE_LIGHT )
       {
         FT_Pos  pp1x = loader->pp1.x;
         FT_Pos  pp2x = loader->pp2.x;
@@ -460,6 +506,11 @@
         slot->lsb_delta = loader->pp1.x - pp1x;
         slot->rsb_delta = loader->pp2.x - pp2x;
       }
+      else
+      {
+        slot->lsb_delta = 0;
+        slot->rsb_delta = 0;
+      }
 
       break;
 
@@ -510,6 +561,7 @@
       /* to keep the original rounded advance width; ditto for     */
       /* digits if all have the same advance width                 */
       if ( scaler.render_mode != FT_RENDER_MODE_LIGHT                       &&
+           scaler.render_mode != FT_RENDER_MODE_SLIGHT                      &&
            ( FT_IS_FIXED_WIDTH( slot->face )                              ||
              ( af_face_globals_is_digit( loader->globals, glyph_index ) &&
                style_metrics->digits_have_same_width                    ) ) )
@@ -533,7 +585,8 @@
       slot->metrics.vertAdvance = FT_MulFix( slot->metrics.vertAdvance,
                                              style_metrics->scaler.y_scale );
 
-      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
+      if ( scaler.render_mode != FT_RENDER_MODE_SLIGHT )
+        slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
       slot->metrics.vertAdvance = FT_PIX_ROUND( slot->metrics.vertAdvance );
 
       slot->format  = FT_GLYPH_FORMAT_OUTLINE;
--- a/src/base/ftadvanc.c
+++ b/src/base/ftadvanc.c
@@ -59,14 +59,15 @@
    /*                                                              */
    /*  - unscaled load                                             */
    /*  - unhinted load                                             */
-   /*  - light-hinted load                                         */
+   /*  - light-hinted and slight-hinted load                       */
    /*  - if a variations font, it must have an `HVAR' or `VVAR'    */
    /*    table (thus the old MM or GX fonts don't qualify; this    */
    /*    gets checked by the driver-specific functions)            */
 
-#define LOAD_ADVANCE_FAST_CHECK( face, flags )                      \
-          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )    || \
-            FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT )
+#define LOAD_ADVANCE_FAST_CHECK( face, flags )                           \
+          ( flags & ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING )         || \
+            ( FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_LIGHT  ||   \
+              FT_LOAD_TARGET_MODE( flags ) == FT_RENDER_MODE_SLIGHT ) )
 
 
   /* documentation is in ftadvanc.h */
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -668,8 +668,8 @@
      * - Then, auto-hint if FT_LOAD_FORCE_AUTOHINT is set or if we don't
      *   have a native font hinter.
      *
-     * - Otherwise, auto-hint for LIGHT hinting mode or if there isn't
-     *   any hinting bytecode in the TrueType/OpenType font.
+     * - Otherwise, auto-hint for LIGHT or SLIGHT hinting mode or if there
+     *   isn't any hinting bytecode in the TrueType/OpenType font.
      *
      * - Exception: The font is `tricky' and requires the native hinter to
      *   load properly.
@@ -702,8 +702,9 @@
         /* check the size of the `fpgm' and `prep' tables, too --    */
         /* the assumption is that there don't exist real TTFs where  */
         /* both `fpgm' and `prep' tables are missing                 */
-        if ( ( mode == FT_RENDER_MODE_LIGHT                   &&
-               !FT_DRIVER_HINTS_LIGHTLY( driver ) )             ||
+        if ( ( ( mode == FT_RENDER_MODE_LIGHT  ||
+                 mode == FT_RENDER_MODE_SLIGHT )              &&
+               !FT_DRIVER_HINTS_LIGHTLY( driver )             ) ||
              ( FT_IS_SFNT( face )                             &&
                ttface->num_locations                          &&
                ttface->max_profile.maxSizeOfInstructions == 0 &&
--- a/src/pshinter/pshalgo.c
+++ b/src/pshinter/pshalgo.c
@@ -2149,7 +2149,8 @@
       glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO  ||
                                          hint_mode == FT_RENDER_MODE_LCD_V );
 
-      glyph->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );
+      glyph->do_stem_adjust = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT  &&
+                                       hint_mode != FT_RENDER_MODE_SLIGHT );
 
       for ( dimension = 0; dimension < 2; dimension++ )
       {
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -433,7 +433,8 @@
                     FT_Render_Mode    mode,
                     const FT_Vector*  origin )
   {
-    if ( mode == FT_RENDER_MODE_LIGHT )
+    if ( mode == FT_RENDER_MODE_LIGHT  ||
+         mode == FT_RENDER_MODE_SLIGHT )
       mode = FT_RENDER_MODE_NORMAL;
 
     return ft_smooth_render_generic( render, slot, mode, origin,