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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
diff --git a/ChangeLog b/ChangeLog
index 47811d1..d42f986 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2017-09-24 Alexei Podtelezhnikov <apodtele@gmail.com>
+
+ 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 <jfkthame@gmail.com>
[sfnt] Fix `premultiply_data' (#52092).
@@ -32,7 +53,7 @@
VariationIndex subtable.
(otv_Lookup_validate): Handle MarkFilteringSet.
-2017-09-21 Alexei Podtelezhnikov <apodtele@gmail.com>
+2017-09-23 Alexei Podtelezhnikov <apodtele@gmail.com>
[build] Windows-style DLL versioning.
diff --git a/include/freetype/ftlcdfil.h b/include/freetype/ftlcdfil.h
index ea4a66e..8c75141 100644
--- a/include/freetype/ftlcdfil.h
+++ b/include/freetype/ftlcdfil.h
@@ -316,6 +316,17 @@ FT_BEGIN_HEADER
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 );
+
/* */
diff --git a/include/freetype/internal/ftobjs.h b/include/freetype/internal/ftobjs.h
index 4231be2..25c328f 100644
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -369,9 +369,10 @@ FT_BEGIN_HEADER
/* 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_BEGIN_HEADER
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 @@ FT_BEGIN_HEADER
#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 @@ FT_BEGIN_HEADER
/* 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_BEGIN_HEADER
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
diff --git a/src/base/ftlcdfil.c b/src/base/ftlcdfil.c
index 60c813f..ca781f3 100644
--- 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 )
@@ -305,8 +305,6 @@
return FT_THROW( Invalid_Argument );
}
- library->lcd_filter = filter;
-
return FT_Err_Ok;
}
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 6db8136..aedb1f3 100644
--- 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 );
diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c
index 963435d..99a9883 100644
--- a/src/smooth/ftsmooth.c
+++ b/src/smooth/ftsmooth.c
@@ -115,56 +115,22 @@
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;
- }
- }
-
- /*
- * 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;
+ lcd_weights = slot->face->internal->lcd_weights;
+ lcd_filter_func = slot->face->internal->lcd_filter_func;
}
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 )
{