diff --git a/ChangeLog b/ChangeLog index e4663968b..112db7fb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +2013-12-27 Werner Lemberg + + [autofit] Handle `DFLT' OpenType script for coverages. + + * include/ftautoh.h: Document new `default-script' property. + + * src/autofit/hbshim.c (af_get_coverage): Use `AF_FaceGlobals' for + type of first parameter. + (script_tags): Add one more element. + (af_get_coverage): Adjust `script_tags' to handle `DFLT' script tag. + + * src/autofit/hbshim.h: Updated. + + * src/autofit/afglobal.c (af_face_globals_compute_style_coverage): + Updated. + + * src/autofit/afglobal.h (AF_SCRIPT_DEFAULT): New macro. + + * src/autofit/afmodule.h (AF_ModuleRec): New `default_script' + member. + + * src/autofit/afmodule.c (af_property_set, af_property_get): Handle + `default-script' property. + (af_autofitter_init): Updated. + 2013-12-27 suzuki toshiya [ftrfork] Fix the face order difference between POSIX and Carbon. diff --git a/include/ftautoh.h b/include/ftautoh.h index bf97b3f24..936791e72 100644 --- a/include/ftautoh.h +++ b/include/ftautoh.h @@ -287,7 +287,52 @@ FT_BEGIN_HEADER * face-specific property like @glyph-to-script-map, or by auto-hinting * any glyph from that face. In particular, if you have already created * an @FT_Face structure but not loaded any glyph (using the - * auto-hinter), a change of the fallback glyph will affect this face. + * auto-hinter), a change of the fallback script will affect this face. + * + */ + + + /************************************************************************** + * + * @property: + * default-script + * + * @description: + * *Experimental* *only* + * + * If Freetype gets compiled with FT_CONFIG_OPTION_USE_HARFBUZZ to make + * the HarfBuzz library access OpenType features for getting better + * glyph coverages, this property sets the (auto-fitter) script to be + * used for the default (OpenType) script data of a font's GSUB table. + * Features for the default script are intended for all scripts not + * explicitly handled in GSUB; an example is a `dlig' feature, + * containing the combination of the characters `T', `E', and `L' to + * form a `TEL' ligature. + * + * By default, this is @FT_AUTOHINTER_SCRIPT_LATIN. Using the + * `default-script' property, this default value can be changed. + * + * { + * FT_Library library; + * FT_UInt default_script = FT_AUTOHINTER_SCRIPT_NONE; + * + * + * FT_Init_FreeType( &library ); + * + * FT_Property_Set( library, "autofitter", + * "default-script", &default_script ); + * } + * + * @note: + * This property can be used with @FT_Property_Get also. + * + * It's important to use the right timing for changing this value: The + * creation of the glyph-to-script map that eventually uses the + * default script value gets triggered either by setting or reading a + * face-specific property like @glyph-to-script-map, or by auto-hinting + * any glyph from that face. In particular, if you have already created + * an @FT_Face structure but not loaded any glyph (using the + * auto-hinter), a change of the default script will affect this face. * */ diff --git a/src/autofit/afglobal.c b/src/autofit/afglobal.c index 1548169ad..fa4017de9 100644 --- a/src/autofit/afglobal.c +++ b/src/autofit/afglobal.c @@ -194,7 +194,7 @@ #ifdef FT_CONFIG_OPTION_USE_HARFBUZZ /* get glyphs not directly addressable by cmap */ - af_get_coverage( face, style_class, gstyles ); + af_get_coverage( globals, style_class, gstyles ); #endif } diff --git a/src/autofit/afglobal.h b/src/autofit/afglobal.h index 43ce39472..7785eead9 100644 --- a/src/autofit/afglobal.h +++ b/src/autofit/afglobal.h @@ -69,6 +69,8 @@ FT_BEGIN_HEADER #else #define AF_STYLE_FALLBACK AF_STYLE_NONE_DEFAULT #endif + /* default script for OpenType; ignored if HarfBuzz isn't used */ +#define AF_SCRIPT_DEFAULT AF_SCRIPT_LATN /* a bit mask indicating an uncovered glyph */ #define AF_STYLE_UNASSIGNED 0x7F /* if this flag is set, we have an ASCII digit */ diff --git a/src/autofit/afmodule.c b/src/autofit/afmodule.c index d0316b3f7..4384f4f95 100644 --- a/src/autofit/afmodule.c +++ b/src/autofit/afmodule.c @@ -120,6 +120,15 @@ return error; } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* default_script = (FT_UInt*)value; + + + module->default_script = *default_script; + + return error; + } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; @@ -147,6 +156,7 @@ FT_Error error = FT_Err_Ok; AF_Module module = (AF_Module)ft_module; FT_UInt fallback_style = module->fallback_style; + FT_UInt default_script = module->default_script; if ( !ft_strcmp( property_name, "glyph-to-script-map" ) ) @@ -172,6 +182,15 @@ return error; } + else if ( !ft_strcmp( property_name, "default-script" ) ) + { + FT_UInt* val = (FT_UInt*)value; + + + *val = default_script; + + return error; + } else if ( !ft_strcmp( property_name, "increase-x-height" ) ) { FT_Prop_IncreaseXHeight* prop = (FT_Prop_IncreaseXHeight*)value; @@ -232,6 +251,7 @@ module->fallback_style = AF_STYLE_FALLBACK; + module->default_script = AF_SCRIPT_DEFAULT; return af_loader_init( module ); } diff --git a/src/autofit/afmodule.h b/src/autofit/afmodule.h index d42c5c8ca..20b7b9f66 100644 --- a/src/autofit/afmodule.h +++ b/src/autofit/afmodule.h @@ -4,7 +4,7 @@ /* */ /* Auto-fitter module implementation (specification). */ /* */ -/* Copyright 2003, 2004, 2005 by */ +/* Copyright 2003-2005, 2009, 2012, 2013 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -41,6 +41,7 @@ FT_BEGIN_HEADER FT_ModuleRec root; FT_UInt fallback_style; + FT_UInt default_script; AF_LoaderRec loader[1]; diff --git a/src/autofit/hbshim.c b/src/autofit/hbshim.c index b2731ad6d..61a678b88 100644 --- a/src/autofit/hbshim.c +++ b/src/autofit/hbshim.c @@ -135,9 +135,9 @@ FT_Error - af_get_coverage( FT_Face ft_face, - AF_StyleClass style_class, - FT_Byte* gstyles ) + af_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_Byte* gstyles ) { hb_face_t* face; @@ -147,6 +147,7 @@ hb_tag_t script; const hb_tag_t* coverage_tags; hb_tag_t script_tags[] = { HB_TAG_NONE, + HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE }; @@ -156,10 +157,10 @@ #endif - if ( !ft_face || !style_class || !gstyles ) + if ( !globals || !style_class || !gstyles ) return FT_THROW( Invalid_Argument ); - face = hb_ft_face_create( ft_face, NULL ); + face = hb_ft_face_create( globals->face, NULL ); lookups = hb_set_create(); glyphs = hb_set_create(); @@ -175,10 +176,26 @@ &script_tags[1] ); /* `hb_ot_tags_from_script' usually returns HB_OT_TAG_DEFAULT_SCRIPT */ - /* as the second tag. We change that to HB_TAG_NONE since the */ - /* default script gets handled later on. */ - if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) - script_tags[1] = HB_TAG_NONE; + /* as the second tag. We change that to HB_TAG_NONE except for the */ + /* default script. */ + if ( style_class->script == globals->module->default_script && + style_class->coverage == AF_COVERAGE_DEFAULT ) + { + if ( script_tags[0] == HB_TAG_NONE ) + script_tags[0] = HB_OT_TAG_DEFAULT_SCRIPT; + else + { + if ( script_tags[1] == HB_TAG_NONE ) + script_tags[1] = HB_OT_TAG_DEFAULT_SCRIPT; + else if ( script_tags[1] != HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[2] = HB_OT_TAG_DEFAULT_SCRIPT; + } + } + else + { + if ( script_tags[1] == HB_OT_TAG_DEFAULT_SCRIPT ) + script_tags[1] = HB_TAG_NONE; + } hb_ot_layout_collect_lookups( face, HB_OT_TAG_GSUB, diff --git a/src/autofit/hbshim.h b/src/autofit/hbshim.h index 87a771e7a..fdda2ace8 100644 --- a/src/autofit/hbshim.h +++ b/src/autofit/hbshim.h @@ -30,9 +30,9 @@ FT_BEGIN_HEADER FT_Error - af_get_coverage( FT_Face face, - AF_StyleClass style_class, - FT_Byte* gstyles ); + af_get_coverage( AF_FaceGlobals globals, + AF_StyleClass style_class, + FT_Byte* gstyles ); /* */