[cairo] public API for setting the lcd filter type on cairo_font_option_t
Sylvain Pasche
sylvain.pasche at gmail.com
Wed Jan 16 11:25:40 PST 2008
I'm writing this mail from a discussion about the lcd filter type on irc
with Behdad and others.
The LCD filtering patch currently available in bugzilla which was
written by David Turner and then modified by Debian maintainers uses the
following internal API:
/**
* _cairo_font_options_set_lcd_filter:
* @options: a #cairo_font_options_t
* @lcd_filter: the new lcd filterorder
*
* Sets the lcd filter for the font options object. The lcd filter
* specifies how pixels are filtered when rendered with an antialiasing
* mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
* #cairo_lcd_filter_t for full details.
**/
void
_cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
cairo_lcd_filter_t lcd_filter);
I don't think there's much to discuss for the prototype of the above
function (outside of the comment).
cairo_lcd_filter_t is then defined using constants matching the Freetype
ones:
/**
* cairo_lcd_filter_t:
* @CAIRO_LCD_FILTER_DEFAULT: Default LCD filter
* @CAIRO_LCD_FILTER_NONE: Do not perform LCD filtering
* @CAIRO_LCD_FILTER_LIGHT: Variant lighter filter
* @CAIRO_LCD_FILTER_LEGACY: Use the legacy LCD filter
*
* The LCD filter specifies the low-pass filter applied to LCD-optimized
* bitmaps generated with an antialiasing mode of
%CAIRO_ANTIALIAS_SUBPIXEL.
**/
typedef enum _cairo_lcd_filter {
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_LCD_FILTER_NONE,
CAIRO_LCD_FILTER_LIGHT,
CAIRO_LCD_FILTER_LEGACY
} cairo_lcd_filter_t;
With a mapping:
CAIRO_LCD_FILTER_DEFAULT => FT_LCD_FILTER_NONE
CAIRO_LCD_FILTER_NONE => FT_LCD_FILTER_DEFAULT
CAIRO_LCD_FILTER_LIGHT => FT_LCD_FILTER_LIGHT
CAIRO_LCD_FILTER_LEGACY => FT_LCD_FILTER_LEGACY
Two issues with this enum:
* Cairo has a convention of having a constant CAIRO_XXX_DEFAULT to use
the target device default setting. This above constant has a different
meaning than this convention so another name has to be used for mapping
to FT_LCD_FILTER_DEFAULT
* quoting Behdad: "... and LEGACY have no place in cairo as enum names"
Some information how the filtering is computed can be helpful when
choosing a name.
FT_LCD_FILTER_NONE
* Do not perform filtering. When used with subpixel rendering, this
* results in sometimes severe color fringes.
As expected this filter does nothing
FT_LCD_FILTER_DEFAULT
* The default filter reduces color fringes considerably, at the cost
* of a slight blurriness in the output.
FT_LCD_FILTER_LIGHT
* The light filter is a variant that produces less blurriness at the
* cost of slightly more color fringes than the default one. It might
* be better, depending on taste, your monitor, or your personal vision.
These two filters are using the _ft_lcd_filter_fir filter function in
http://cvs.savannah.gnu.org/viewvc/freetype/freetype2/src/base/ftlcdfil.c?view=markup
with different filter values:
static const FT_Byte light_filter[5] =
{ 0, 85, 86, 85, 0 };
/* the values here sum up to a value larger than 256, */
/* providing a cheap gamma correction */
static const FT_Byte default_filter[5] =
{ 0x10, 0x40, 0x70, 0x40, 0x10 };
The algorithm used in that filter function is FIR.
FT_LCD_FILTER_LEGACY
* This filter corresponds to the original libXft color filter. It
* provides high contrast output but can exhibit really bad color
* fringes if glyphs are not extremely well hinted to the pixel grid.
* In other words, it only works well if the TrueType bytecode
* interpreter is enabled *and* high-quality hinted fonts are used.
*
* This filter is only provided for comparison purposes, and might be
* disabled or stay unsupported in the future.
Quoting Keith: it's an intra-pixel filter, which means the three
components have different curves; green gets a three-element gaussian,
while r and b get sloping filters to left and right.
So each of these options uses a given algorithm with specific parameters
modifying how the algorithm behaves.
From quick googling, the Windows and ATSUI backends don't seem to offer
per font lcd filtering options (ClearType appears to use global registry
settings for controlling the filtering settings). So this would only be
used by Freetype for now, which uses 4 types of filtering.
Some proposals, in the cairo default, none, default, light, legacy order:
algorithm + algorithm option:
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_LCD_FILTER_NONE,
CAIRO_LCD_FILTER_FIR_NORMAL,
CAIRO_LCD_FILTER_FIR_LIGHT,
CAIRO_LCD_FILTER_INTRA_PIXEL
freetype centric, adapted (replacing default by normal):
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_LCD_FILTER_NONE,
CAIRO_LCD_FILTER_NORMAL,
CAIRO_LCD_FILTER_LIGHT,
CAIRO_LCD_FILTER_LEGACY
Code author based naming (Carl's idea ;-) ):
CAIRO_LCD_FILTER_DEFAULT,
CAIRO_LCD_FILTER_NONE,
CAIRO_LCD_FILTER_DAVID,
CAIRO_LCD_FILTER_DAVID_LIGHT,
CAIRO_LCD_FILTER_KEITH
I hope this gives enough information start the discussion.
Sylvain
More information about the cairo
mailing list