diff --git a/ChangeLog b/ChangeLog index 830840e3e..1a1b4a588 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2016-07-11 Werner Lemberg + + Handle properties in `FREETYPE_PROPERTIES' environment variable. + + This commit covers the most important one. + + * src/autofit/afmodule.c (af_property_set): Handle `warping', + `darkening-parameters', and `no-stem-darkening'. + + * src/cff/cffdrivr.c (cff_property_set): Handle + `darkening-parameters', `hinting-engine', and `no-stem-darkening'. + + * src/truetype/ttdriver.c (tt_property_set): Handle + `interpreter-version'. + 2016-07-11 Werner Lemberg Replace calls to `atol' with `strtol'. diff --git a/include/freetype/ftautoh.h b/include/freetype/ftautoh.h index 40c8003c4..48ff1aa26 100644 --- a/include/freetype/ftautoh.h +++ b/include/freetype/ftautoh.h @@ -428,6 +428,9 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * * The warping code can also change advance widths. Have a look at the * `lsb_delta' and `rsb_delta' fields in the @FT_GlyphSlotRec structure * for details on improving inter-glyph distances while rendering. @@ -473,6 +476,9 @@ FT_BEGIN_HEADER * The smaller the size (especially 9ppem and down), the higher the loss * of emboldening versus the CFF driver. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable similar to the CFF driver. + * */ @@ -489,6 +495,8 @@ FT_BEGIN_HEADER * CFF_CONFIG_OPTION_DARKENING_PARAMETER_* #defines for consistency. * Note the differences described in @no-stem-darkening[autofit]. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable similar to the CFF driver. */ diff --git a/include/freetype/ftcffdrv.h b/include/freetype/ftcffdrv.h index ad34541fd..8f88cc48f 100644 --- a/include/freetype/ftcffdrv.h +++ b/include/freetype/ftcffdrv.h @@ -148,6 +148,8 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `adobe' or `freetype'). */ @@ -199,6 +201,9 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values 1 and 0 for `on' and `off', respectively). + * */ @@ -248,6 +253,14 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable, using eight comma-separated integers without spaces. Here + * the above example, using `\' to break the line for readability. + * + * { + * FREETYPE_PROPERTIES=\ + * cff:darkening-parameters=500,300,1000,200,1500,100,2000,0 + * } */ /* */ diff --git a/include/freetype/ftttdrv.h b/include/freetype/ftttdrv.h index 0d868bc25..22186ee4a 100644 --- a/include/freetype/ftttdrv.h +++ b/include/freetype/ftttdrv.h @@ -181,6 +181,8 @@ FT_BEGIN_HEADER * @note: * This property can be used with @FT_Property_Get also. * + * This property can be set via the `FREETYPE_PROPERTIES' environment + * variable (using values `35', `38', or `40'). */ diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index 03680beac..4a6b04914 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -184,15 +184,26 @@ #ifdef AF_CONFIG_OPTION_USE_WARPER else if ( !ft_strcmp( property_name, "warping" ) ) { - FT_Bool* warping; - - if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; + long w = ft_strtol( s, NULL, 10 ); - warping = (FT_Bool*)value; - module->warping = *warping; + if ( w == 0 ) + module->warping = 0; + else if ( w == 1 ) + module->warping = 1; + else + return FT_THROW( Invalid_Argument ); + } + else + { + FT_Bool* warping = (FT_Bool*)value; + + + module->warping = *warping; + } return error; } @@ -201,12 +212,34 @@ { FT_Int* darken_params; FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + FT_Int dp[8]; if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; + char* ep; + int i; - darken_params = (FT_Int*)value; + + /* eight comma-separated numbers */ + for ( i = 0; i < 7; i++ ) + { + dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( *ep != ',' || s == ep ) + return FT_THROW( Invalid_Argument ); + + s = ep + 1; + } + + dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) + return FT_THROW( Invalid_Argument ); + + darken_params = dp; + } + else + darken_params = (FT_Int*)value; x1 = darken_params[0]; y1 = darken_params[1]; @@ -236,15 +269,26 @@ } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { - FT_Bool* no_stem_darkening; - - if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; + long nsd = ft_strtol( s, NULL, 10 ); - no_stem_darkening = (FT_Bool*)value; - module->no_stem_darkening = *no_stem_darkening; + if ( nsd == 0 ) + module->no_stem_darkening = 0; + else if ( nsd == 1 ) + module->no_stem_darkening = 1; + else + return FT_THROW( Invalid_Argument ); + } + else + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + module->no_stem_darkening = *no_stem_darkening; + } return error; } diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 88bb7e6fc..2e2a43776 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -670,12 +670,34 @@ { FT_Int* darken_params; FT_Int x1, y1, x2, y2, x3, y3, x4, y4; + FT_Int dp[8]; if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; + char* ep; + int i; - darken_params = (FT_Int*)value; + + /* eight comma-separated numbers */ + for ( i = 0; i < 7; i++ ) + { + dp[i] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( *ep != ',' || s == ep ) + return FT_THROW( Invalid_Argument ); + + s = ep + 1; + } + + dp[7] = (FT_Int)ft_strtol( s, &ep, 10 ); + if ( !( *ep == '\0' || *ep == ' ' ) || s == ep ) + return FT_THROW( Invalid_Argument ); + + darken_params = dp; + } + else + darken_params = (FT_Int*)value; x1 = darken_params[0]; y1 = darken_params[1]; @@ -705,36 +727,58 @@ } else if ( !ft_strcmp( property_name, "hinting-engine" ) ) { - FT_UInt* hinting_engine; - - if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; - hinting_engine = (FT_UInt*)value; - if ( *hinting_engine == FT_CFF_HINTING_ADOBE + if ( !ft_strcmp( s, "adobe" ) ) + driver->hinting_engine = FT_CFF_HINTING_ADOBE; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE - || *hinting_engine == FT_CFF_HINTING_FREETYPE + else if ( !ft_strcmp( s, "freetype" ) ) + driver->hinting_engine = FT_CFF_HINTING_FREETYPE; #endif - ) - driver->hinting_engine = *hinting_engine; + else + return FT_THROW( Invalid_Argument ); + } else - error = FT_ERR( Unimplemented_Feature ); + { + FT_UInt* hinting_engine = (FT_UInt*)value; - return error; + if ( *hinting_engine == FT_CFF_HINTING_ADOBE +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + || *hinting_engine == FT_CFF_HINTING_FREETYPE +#endif + ) + driver->hinting_engine = *hinting_engine; + else + error = FT_ERR( Unimplemented_Feature ); + + return error; + } } else if ( !ft_strcmp( property_name, "no-stem-darkening" ) ) { - FT_Bool* no_stem_darkening; - - if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; + long nsd = ft_strtol( s, NULL, 10 ); - no_stem_darkening = (FT_Bool*)value; - driver->no_stem_darkening = *no_stem_darkening; + if ( nsd == 0 ) + driver->no_stem_darkening = 0; + else if ( nsd == 1 ) + driver->no_stem_darkening = 1; + else + return FT_THROW( Invalid_Argument ); + } + else + { + FT_Bool* no_stem_darkening = (FT_Bool*)value; + + + driver->no_stem_darkening = *no_stem_darkening; + } return error; } diff --git a/src/truetype/ttdriver.c b/src/truetype/ttdriver.c index 83a804290..3debf7868 100644 --- a/src/truetype/ttdriver.c +++ b/src/truetype/ttdriver.c @@ -70,23 +70,33 @@ if ( !ft_strcmp( property_name, "interpreter-version" ) ) { - FT_UInt* interpreter_version; + FT_UInt interpreter_version; if ( value_is_string ) - return FT_THROW( Invalid_Argument ); + { + const char* s = (const char*)value; - interpreter_version = (FT_UInt*)value; - if ( *interpreter_version == TT_INTERPRETER_VERSION_35 + interpreter_version = (FT_UInt)ft_strtol( s, NULL, 10 ); + } + else + { + FT_UInt* iv = (FT_UInt*)value; + + + interpreter_version = *iv; + } + + if ( interpreter_version == TT_INTERPRETER_VERSION_35 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY - || *interpreter_version == TT_INTERPRETER_VERSION_38 + || interpreter_version == TT_INTERPRETER_VERSION_38 #endif #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL - || *interpreter_version == TT_INTERPRETER_VERSION_40 + || interpreter_version == TT_INTERPRETER_VERSION_40 #endif ) - driver->interpreter_version = *interpreter_version; + driver->interpreter_version = interpreter_version; else error = FT_ERR( Unimplemented_Feature );