From d682e510627086df010b0677003f8ac5e612e913 Mon Sep 17 00:00:00 2001 From: Nikolaus Waxweiler Date: Mon, 2 Nov 2015 09:06:36 +0100 Subject: [PATCH] [autofit] Add stem-darkening properties. Actual code follows in a later commit. * include/freetype/ftautoh.h: Document `no-stem-darkening' and `darkening-parameters'. * src/autofit/afmodule.h: New fields `no_stem_darkening' and `darken_params'. * src/autofit/afmodule.c (af_property_set, af_property_get): Handle them. (af_autofitter_init): Initialize them. --- ChangeLog | 16 ++++++++ include/freetype/ftautoh.h | 52 ++++++++++++++++++++++++ src/autofit/afmodule.c | 83 ++++++++++++++++++++++++++++++++++++-- src/autofit/afmodule.h | 2 + 4 files changed, 150 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index ee5e5e986..5286c876b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2015-11-02 Nikolaus Waxweiler + + [autofit] Add stem-darkening properties. + + Actual code follows in a later commit. + + * include/freetype/ftautoh.h: Document `no-stem-darkening' and + `darkening-parameters'. + + * src/autofit/afmodule.h: New fields `no_stem_darkening' and + `darken_params'. + + * src/autofit/afmodule.c (af_property_set, af_property_get): + Handle them. + (af_autofitter_init): Initialize them. + 2015-11-02 Bungeman [ftfuzzer] Add support for multiple files (patch #8779). diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h index ab39c2199..e4c1eae64 100644 --- a/include/freetype/ftautoh.h +++ b/include/freetype/ftautoh.h @@ -439,6 +439,58 @@ FT_BEGIN_HEADER */ + /************************************************************************** + * + * @property: + * no-stem-darkening + * + * @description: + * *Experimental* *only* + * + * The main purpose of emboldening glyphs or `stem darkening' is to + * enhance readability at smaller sizes. The smaller the size, the more + * emboldening is applied to keep glyphs from `thinning out'. All + * glyphs that pass through the autohinter will be emboldened unless + * this property is set to TRUE. + * + * See the description of the CFF driver for algorithmic details. Total + * consistency with the CFF driver is currently not achieved because the + * emboldening method differs and glyphs must be scaled down on the + * Y-axis to keep outline points inside their precomputed blue zones. + * The smaller the size (especially 9ppem and down), the higher the loss + * of emboldening versus the CFF driver. + * + * *ATTENTION*: This feature has been developed with linear alpha + * blending and gamma correction of glyphs in mind: A rendering library + * must apply linear alpha blending while compositing glyph bitmaps onto + * a surface and then apply gamma correction to the glyph pixels to get + * from linear space to display space (unless the display works in + * linear space). Internal testing at Adobe found that a gamma + * correction value of 1.8 gives good results across a wide range of + * displays with a sRGB gamma curve or a similar one. + * + * If this is not possible, it might be better to disable stem + * darkening. Currently, this can only be done globally. + * + */ + + + /************************************************************************** + * + * @property: + * darkening-parameters + * + * @description: + * *Experimental* *only* + * + * See the description of the CFF driver for details. This + * implementation appropriates the + * CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency. + * Note the differences described in @no-stem-darkening. + * + */ + + /* */ diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 2c759da60..6bb81934d 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -177,6 +177,46 @@ return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = (FT_Int*)value; + + FT_Int x1 = darken_params[0]; + FT_Int y1 = darken_params[1]; + FT_Int x2 = darken_params[2]; + FT_Int y2 = darken_params[3]; + FT_Int x3 = darken_params[4]; + FT_Int y3 = darken_params[5]; + FT_Int x4 = darken_params[6]; + FT_Int y4 = darken_params[7]; + + + if ( x1 < 0 || x2 < 0 || x3 < 0 || x4 < 0 || + y1 < 0 || y2 < 0 || y3 < 0 || y4 < 0 || + x1 > x2 || x2 > x3 || x3 > x4 || + y1 > 500 || y2 > 500 || y3 > 500 || y4 > 500 ) + return FT_THROW( Invalid_Argument ); + + module->darken_params[0] = x1; + module->darken_params[1] = y1; + module->darken_params[2] = x2; + module->darken_params[3] = y2; + module->darken_params[4] = x3; + module->darken_params[5] = y3; + module->darken_params[6] = x4; + module->darken_params[7] = y4; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + module->no_stem_darkening = *no_stem_darkening; + + return error; + } FT_TRACE0(( "af_property_set: missing property `%s'\n", property_name )); @@ -253,6 +293,33 @@ return error; } #endif /* AF_CONFIG_OPTION_USE_WARPER */ + else if ( !ft_strcmp( property_name, "darkening-parameters" ) ) + { + FT_Int* darken_params = module->darken_params; + FT_Int* val = (FT_Int*)value; + + + val[0] = darken_params[0]; + val[1] = darken_params[1]; + val[2] = darken_params[2]; + val[3] = darken_params[3]; + val[4] = darken_params[4]; + val[5] = darken_params[5]; + val[6] = darken_params[6]; + val[7] = darken_params[7]; + + return error; + } + else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) + { + FT_Bool no_stem_darkening = module->no_stem_darkening; + FT_Bool* val = (FT_Bool*)value; + + + *val = no_stem_darkening; + + return error; + } FT_TRACE0(( "af_property_get: missing property `%s'\n", property_name )); @@ -299,11 +366,21 @@ AF_Module module = (AF_Module)ft_module; - module->fallback_style = AF_STYLE_FALLBACK; - module->default_script = AF_SCRIPT_DEFAULT; + module->fallback_style = AF_STYLE_FALLBACK; + module->default_script = AF_SCRIPT_DEFAULT; #ifdef AF_CONFIG_OPTION_USE_WARPER - module->warping = 0; + module->warping = 0; #endif + module->no_stem_darkening = FALSE; + + module->darken_params[0] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1; + module->darken_params[1] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1; + module->darken_params[2] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2; + module->darken_params[3] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2; + module->darken_params[4] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3; + module->darken_params[5] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3; + module->darken_params[6] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4; + module->darken_params[7] = CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4; return FT_Err_Ok; } diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h index b9c2fd8a2..3c61d8956 100644 --- a/src/autofit/afmodule.h +++ b/src/autofit/afmodule.h @@ -41,6 +41,8 @@ FT_BEGIN_HEADER #ifdef AF_CONFIG_OPTION_USE_WARPER FT_Bool warping; #endif + FT_Bool no_stem_darkening; + FT_Int darken_params[8]; } AF_ModuleRec, *AF_Module;