Commit d32a7d32e4176fc63c7935d23042aeeed9b9ee93

Werner Lemberg 2013-12-27T19:26:04

[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.

diff --git a/ChangeLog b/ChangeLog
index e466396..112db7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2013-12-27  Werner Lemberg  <wl@gnu.org>
+
+	[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  <mpsuzuki@hiroshima-u.ac.jp>
 
 	[ftrfork] Fix the face order difference between POSIX and Carbon.
diff --git a/include/ftautoh.h b/include/ftautoh.h
index bf97b3f..936791e 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 1548169..fa4017d 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 43ce394..7785eea 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 d0316b3..4384f4f 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 d42c5c8..20b7b9f 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 b2731ad..61a678b 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;
 
@@ -148,6 +148,7 @@
     const hb_tag_t*  coverage_tags;
     hb_tag_t         script_tags[] = { HB_TAG_NONE,
                                        HB_TAG_NONE,
+                                       HB_TAG_NONE,
                                        HB_TAG_NONE };
 
     hb_codepoint_t  idx;
@@ -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 87a771e..fdda2ac 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 );
 
  /* */