ref: 02e80da6090c21d6e59ac955b7f56e1ad4a9850b
parent: 6f2b6f8f72ffb5017ab00fca83185b21f1a9f56d
author: Alexei Podtelezhnikov <[email protected]>
date: Sun Sep 24 18:18:34 EDT 2017
Tweak per-face LCD filtering controls. Thing are simpler with a NULL-function pointer. * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): New pointer to the filter function. (FT_LibraryRec): Remove unused `lcd_filter'. (FT_Bitmap_LcdFilterFunc, ft_lcd_filter_fir): Move from here... * include/freetype/ftlcdfil.h (FT_Bitmap_LcdFilterFunc, ft_lcd_filter_fir): ... to here. * src/base/ftobjs.c (ft_open_face_internal): NULL-initialize the per-face filter. (FT_Face_Properties): Set it. * src/smooth/ftsmooth.c (ft_smooth_render_generic): Simplify. * src/base/ftlcdfil.c (ft_lcd_filter_fir, FT_Libary_SetLcdFilter): Minor.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2017-09-24 Alexei Podtelezhnikov <[email protected]>
+
+ Tweak per-face LCD filtering controls.
+
+ Thing are simpler with a NULL-function pointer.
+
+ * include/freetype/internal/ftobjs.h (FT_Face_InternalRec): New
+ pointer to the filter function.
+ (FT_LibraryRec): Remove unused `lcd_filter'.
+ (FT_Bitmap_LcdFilterFunc, ft_lcd_filter_fir): Move from here...
+ * include/freetype/ftlcdfil.h (FT_Bitmap_LcdFilterFunc,
+ ft_lcd_filter_fir): ... to here.
+
+ * src/base/ftobjs.c (ft_open_face_internal): NULL-initialize the
+ per-face filter.
+ (FT_Face_Properties): Set it.
+ * src/smooth/ftsmooth.c (ft_smooth_render_generic): Simplify.
+
+ * src/base/ftlcdfil.c (ft_lcd_filter_fir, FT_Libary_SetLcdFilter):
+ Minor.
+
2017-09-24 Jonathan Kew <[email protected]>
[sfnt] Fix `premultiply_data' (#52092).
@@ -32,7 +53,7 @@
VariationIndex subtable.
(otv_Lookup_validate): Handle MarkFilteringSet.
-2017-09-21 Alexei Podtelezhnikov <[email protected]>
+2017-09-23 Alexei Podtelezhnikov <[email protected]>
[build] Windows-style DLL versioning.
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -316,6 +316,17 @@
typedef FT_Byte FT_LcdFiveTapFilter[FT_LCD_FILTER_FIVE_TAPS];
+ typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
+ FT_Render_Mode render_mode,
+ FT_Byte* weights );
+
+
+ /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
+ FT_BASE( void )
+ ft_lcd_filter_fir( FT_Bitmap* bitmap,
+ FT_Render_Mode mode,
+ FT_LcdFiveTapFilter weights );
+
/* */
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -369,9 +369,10 @@
/* operator. Value~0 means to use the font's value. Value~-1 */
/* means to use the CFF driver's default. */
/* */
- /* lcd_weights :: */
- /* Overrides the library default with custom weights for the 5-tap */
- /* FIR filter. `{0, 0, 0, 0, 0}' means to use the library default. */
+ /* lcd_weights :: */
+ /* lcd_filter_func :: */
+ /* If subpixel rendering is activated, the LCD filtering weights */
+ /* and callback function. */
/* */
/* refcount :: */
/* A counter initialized to~1 at the time an @FT_Face structure is */
@@ -393,8 +394,10 @@
FT_Char no_stem_darkening;
FT_Int32 random_seed;
+
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- FT_LcdFiveTapFilter lcd_weights; /* preset or custom filter weights */
+ FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
+ FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
#endif
FT_Int refcount;
@@ -821,18 +824,6 @@
#define FT_DEBUG_HOOK_TRUETYPE 0
- typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap,
- FT_Render_Mode render_mode,
- FT_Byte* weights );
-
-
- /* This is the default LCD filter, an in-place, 5-tap FIR filter. */
- FT_BASE( void )
- ft_lcd_filter_fir( FT_Bitmap* bitmap,
- FT_Render_Mode mode,
- FT_LcdFiveTapFilter weights );
-
-
/*************************************************************************/
/* */
/* <Struct> */
@@ -878,9 +869,6 @@
/* interpreter. Currently, only the TrueType */
/* bytecode debugger uses this. */
/* */
- /* lcd_filter :: If subpixel rendering is activated, the */
- /* selected LCD filter mode. */
- /* */
/* lcd_weights :: If subpixel rendering is activated, the LCD */
/* filter weights, if any. */
/* */
@@ -915,7 +903,6 @@
FT_DebugHook_Func debug_hooks[4];
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- FT_LcdFilter lcd_filter;
FT_LcdFiveTapFilter lcd_weights; /* filter weights, if any */
FT_Bitmap_LcdFilterFunc lcd_filter_func; /* filtering callback */
#endif
--- a/src/base/ftlcdfil.c
+++ b/src/base/ftlcdfil.c
@@ -32,7 +32,7 @@
#define FT_SHIFTCLAMP( x ) ( x >>= 8, (FT_Byte)( x > 255 ? 255 : x ) )
/* FIR filter used by the default and light filters */
- FT_BASE( void )
+ FT_BASE_DEF( void )
ft_lcd_filter_fir( FT_Bitmap* bitmap,
FT_Render_Mode mode,
FT_LcdFiveTapFilter weights )
@@ -304,8 +304,6 @@
default:
return FT_THROW( Invalid_Argument );
}
-
- library->lcd_filter = filter;
return FT_Err_Ok;
}
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -2441,7 +2441,8 @@
internal->no_stem_darkening = -1;
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
- ft_memset( internal->lcd_weights, 0, FT_LCD_FILTER_FIVE_TAPS );
+ /* Per-face filtering can only be set up by FT_Face_Properties */
+ internal->lcd_filter_func = NULL;
#endif
}
@@ -3653,16 +3654,11 @@
{
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
if ( properties->data )
+ {
ft_memcpy( face->internal->lcd_weights,
properties->data,
FT_LCD_FILTER_FIVE_TAPS );
- else
- {
- /* Value NULL indicates `no custom weights, use library */
- /* defaults', signaled by filling the weight field with zeros. */
- ft_memset( face->internal->lcd_weights,
- 0,
- FT_LCD_FILTER_FIVE_TAPS );
+ face->internal->lcd_filter_func = ft_lcd_filter_fir;
}
#else
error = FT_THROW( Unimplemented_Feature );
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -115,57 +115,23 @@
FT_Bool have_buffer = FALSE;
#ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING
+ FT_Byte* lcd_weights;
+ FT_Bitmap_LcdFilterFunc lcd_filter_func;
- FT_LcdFiveTapFilter lcd_weights = { 0 };
- FT_Bool have_custom_weight = FALSE;
- FT_Bitmap_LcdFilterFunc lcd_filter_func = NULL;
-
- if ( slot->face )
+ /* Per-face LCD filtering takes priority if set up. */
+ if ( slot->face && slot->face->internal->lcd_filter_func )
{
- FT_Char i;
-
-
- for ( i = 0; i < FT_LCD_FILTER_FIVE_TAPS; i++ )
- if ( slot->face->internal->lcd_weights[i] != 0 )
- {
- have_custom_weight = TRUE;
- break;
- }
+ lcd_weights = slot->face->internal->lcd_weights;
+ lcd_filter_func = slot->face->internal->lcd_filter_func;
}
-
- /*
- * The LCD filter can be set library-wide and per-face. Face overrides
- * library. If the face filter weights are all zero (the default), it
- * means that the library default should be used.
- */
- if ( have_custom_weight )
- {
- /*
- * A per-font filter is set. It always uses the default 5-tap
- * in-place FIR filter.
- */
- ft_memcpy( lcd_weights,
- slot->face->internal->lcd_weights,
- FT_LCD_FILTER_FIVE_TAPS );
- lcd_filter_func = ft_lcd_filter_fir;
- }
else
{
- /*
- * The face's lcd_weights is {0, 0, 0, 0, 0}, meaning `use library
- * default'. If the library is set to use no LCD filtering
- * (lcd_filter_func == NULL), `lcd_filter_func' here is also set to
- * NULL and the tests further below pass over the filtering process.
- */
- ft_memcpy( lcd_weights,
- slot->library->lcd_weights,
- FT_LCD_FILTER_FIVE_TAPS );
+ lcd_weights = slot->library->lcd_weights;
lcd_filter_func = slot->library->lcd_filter_func;
}
+#endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-#endif /*FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
/* check glyph image format */
if ( slot->format != render->glyph_format )
{
@@ -208,7 +174,7 @@
#else /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
/* add minimal padding for LCD filter depending on specific weights */
- if ( lcd_filter_func )
+ if ( lcd_filter_func == ft_lcd_filter_fir )
{
if ( hmul )
{