From 5aa6716a5eb8409f606886b5d4e63476d85a3519 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Sat, 22 Apr 2017 13:27:21 +0200 Subject: [PATCH] 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. --- ChangeLog | 42 +++++++++++++ include/freetype/freetype.h | 31 +++++++++- include/freetype/internal/ftobjs.h | 9 ++- src/autofit/afcjk.c | 7 ++- src/autofit/aflatin.c | 10 +++- src/autofit/aflatin2.c | 10 +++- src/autofit/afloader.c | 95 +++++++++++++++++++++++------- src/base/ftadvanc.c | 9 +-- src/base/ftobjs.c | 9 +-- src/pshinter/pshalgo.c | 3 +- src/smooth/ftsmooth.c | 3 +- 11 files changed, 187 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00ba418be..05db1d150 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,45 @@ +2017-04-22 Werner Lemberg + + 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 Introduce `FT_Size_InternalRec' structure. diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 4ed86b981..e579056d0 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -221,6 +221,7 @@ FT_BEGIN_HEADER /* */ /* 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 @@ FT_BEGIN_HEADER /* `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 @@ FT_BEGIN_HEADER * 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_BEGIN_HEADER * 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 @@ FT_BEGIN_HEADER /* 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_BEGIN_HEADER { 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, diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h index c8526e6fd..558409166 100644 --- a/include/freetype/internal/ftobjs.h +++ b/include/freetype/internal/ftobjs.h @@ -443,7 +443,11 @@ FT_BEGIN_HEADER /* object. */ /* */ /* */ - /* 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. */ /* */ /*************************************************************************/ @@ -451,6 +455,9 @@ FT_BEGIN_HEADER { void* module_data; + FT_Render_Mode autohint_mode; + FT_Size_Metrics autohint_metrics; + } FT_Size_InternalRec; diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c index 61e29cded..86b8b4067 100644 --- 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 ) diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c index 11fa523c8..e03fdf01f 100644 --- 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 diff --git a/src/autofit/aflatin2.c b/src/autofit/aflatin2.c index 0607278b1..87ab91d8e 100644 --- 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 diff --git a/src/autofit/afloader.c b/src/autofit/afloader.c index fb8ea3ce1..d90c217fb 100644 --- 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; diff --git a/src/base/ftadvanc.c b/src/base/ftadvanc.c index 1557607fc..5f2e0b167 100644 --- 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 */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 83d51c09e..7a9169b32 100644 --- 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 && diff --git a/src/pshinter/pshalgo.c b/src/pshinter/pshalgo.c index 9ad1a3a02..27cb229eb 100644 --- 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++ ) { diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 435854e67..52e61e559 100644 --- 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,