shithub: freetype+ttf2subf

Download patch

ref: ccfc4b4c4e2c4fc51f20ce5c9bf107739e86e5ad
parent: abb3fcac8578c4161606973e751beb7d3f05b2c2
author: Werner Lemberg <[email protected]>
date: Mon Apr 28 17:13:14 EDT 2014

[autofit] Introduce neutral blue zones to the latin module.

Such blue zones match either the top or the bottom of a contour.  We
need them for scripts where accent-like elements directly touch the
base character (for example, some vowel signs in Devanagari, cf.
U+0913 or U+0914).

* src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_NEUTRAL): New
property.

* src/autofit/afblue.h: Regenerated.

* src/autofit/aflatin.h (AF_LATIN_IS_NEUTRAL_BLUE): New macro.
(AF_LATIN_BLUE_NEUTRAL): New enumeration value.

* src/autofit/aflatin.c (af_latin_metrics_init_blues,
af_latin_hints_compute_blue_edges): Handle neutral blue zones.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2014-04-28  Werner Lemberg  <[email protected]>
+
+	[autofit] Introduce neutral blue zones to the latin module.
+
+	Such blue zones match either the top or the bottom of a contour.  We
+	need them for scripts where accent-like elements directly touch the
+	base character (for example, some vowel signs in Devanagari, cf.
+	U+0913 or U+0914).
+
+	* src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_NEUTRAL): New
+	property.
+
+	* src/autofit/afblue.h: Regenerated.
+
+	* src/autofit/aflatin.h (AF_LATIN_IS_NEUTRAL_BLUE): New macro.
+	(AF_LATIN_BLUE_NEUTRAL): New enumeration value.
+
+	* src/autofit/aflatin.c (af_latin_metrics_init_blues,
+	af_latin_hints_compute_blue_edges): Handle neutral blue zones.
+
 2014-04-25  Werner Lemberg  <[email protected]>
 
 	* src/autofit/hbshim.c: Partially revert commit from 2014-04-17.
@@ -47,7 +67,7 @@
 
 	* src/autofit/afblue.hin (AF_BLUE_PROPERTY_CJK_FILL): Removed, no
 	longer used.
-	(AF_BLUE_PROPERTY_CJK_TOP, AF_BLUE_PROPERTY_CJK_HORIZ): Fix values. 
+	(AF_BLUE_PROPERTY_CJK_TOP, AF_BLUE_PROPERTY_CJK_HORIZ): Fix values.
 	This is error #3.
 
 	* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
@@ -57,7 +77,7 @@
 	values.
 	Improve tracing messages, synchronizing them with the latin
 	auto-hinter.
-	(af_cjk_hints_compute_blue_edges): Fix value of `is_top_right_blue'. 
+	(af_cjk_hints_compute_blue_edges): Fix value of `is_top_right_blue'.
 	This is error #2.
 	(af_cjk_align_linked_edge): Add tracing message.
 
--- a/src/autofit/afblue.dat
+++ b/src/autofit/afblue.dat
@@ -34,11 +34,11 @@
 //   using C syntax.  There can be only one string per line, thus the
 //   starting and ending double quote must be the first and last character
 //   in the line, respectively, ignoring whitespace before and after the
-//   string.  If there are multiple strings (in multiple lines), they are
-//   concatenated to a single string.  In the output, a string gets
-//   represented as a series of singles bytes, followed by a zero byte.  The
-//   enumeration values simply hold byte offsets to the start of the
-//   corresponding strings.
+//   string.  Space characters within the string are ignored too.  If there
+//   are multiple strings (in multiple lines), they are concatenated to a
+//   single string.  In the output, a string gets represented as a series of
+//   singles bytes, followed by a zero byte.  The enumeration values simply
+//   hold byte offsets to the start of the corresponding strings.
 //
 // - Data blocks enclosed in balanced braces, which get copied verbatim and
 //   which can span multiple lines.  The opening brace of a block must be
@@ -163,7 +163,11 @@
 // wider than 0.75 pixels (otherwise the blue zone gets ignored).  All
 // entries must have `AF_BLUE_STRING_MAX' as the final line.
 //
+// During the glyph analysis, edges are sorted from bottom to top, and then
+// sequentially checked, edge by edge, against the blue zones in the order
+// given below.
 //
+//
 // latin auto-hinter
 // -----------------
 //
@@ -178,7 +182,22 @@
 //
 //   LATIN_TOP
 //     Take the maximum flat and round coordinate values of the blue string
-//     characters.  If not set, take the minimum values.
+//     characters for computing the blue zone's reference and overshoot
+//     values.
+//
+//     If not set, take the minimum values.
+//
+//   LATIN_NEUTRAL
+//     Ignore round extrema and define the blue zone with flat values only.
+//     Both top and bottom of contours can match.  This is useful for
+//     scripts like Devanagari where vowel signs attach to the base
+//     character and are implemented as components of composite glyphs.
+//
+//     If not set, both round and flat extrema are taken into account.
+//     Additionally, only the top or the bottom of a contour can match,
+//     depending on the LATIN_TOP flag.
+//
+//     Neutral blue zones should always follow non-neutral blue zones.
 //
 //   LATIN_X_HEIGHT
 //     Scale all glyphs vertically from the corresponding script to make the
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -132,12 +132,13 @@
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -96,12 +96,13 @@
   /* Properties are specific to a writing system.  We assume that a given  */
   /* blue string can't be used in more than a single writing system, which */
   /* is a safe bet.                                                        */
-#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )
-#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 1 )
-#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_TOP       ( 1 << 0 )   /* must have value 1 */
+#define AF_BLUE_PROPERTY_LATIN_NEUTRAL   ( 1 << 1 )
+#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT  ( 1 << 2 )
+#define AF_BLUE_PROPERTY_LATIN_LONG      ( 1 << 3 )
 
-#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )
-#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )
+#define AF_BLUE_PROPERTY_CJK_TOP    ( 1 << 0 )        /* must have value 1 */
+#define AF_BLUE_PROPERTY_CJK_HORIZ  ( 1 << 1 )        /* must have value 2 */
 #define AF_BLUE_PROPERTY_CJK_RIGHT  AF_BLUE_PROPERTY_CJK_TOP
 
 
--- a/src/autofit/aflatin.c
+++ b/src/autofit/aflatin.c
@@ -306,6 +306,14 @@
             have_flag = 1;
           }
 
+          if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+          {
+            if ( have_flag )
+              FT_TRACE5(( ", " ));
+            FT_TRACE5(( "neutral" ));
+            have_flag = 1;
+          }
+
           if ( AF_LATIN_IS_X_HEIGHT_BLUE( bs ) )
           {
             if ( have_flag )
@@ -697,6 +705,13 @@
                       FT_CURVE_TAG( outline.tags[best_segment_last]  ) !=
                         FT_CURVE_TAG_ON                                   );
 
+          if ( round && AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+          {
+            /* only use flat segments for a neutral blue zone */
+            FT_TRACE5(( " (round, skipped)\n" ));
+            continue;
+          }
+
           FT_TRACE5(( " (%s)\n", round ? "round" : "flat" ));
         }
 
@@ -767,6 +782,8 @@
       blue->flags = 0;
       if ( AF_LATIN_IS_TOP_BLUE( bs ) )
         blue->flags |= AF_LATIN_BLUE_TOP;
+      if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
+        blue->flags |= AF_LATIN_BLUE_NEUTRAL;
 
       /*
        * The following flag is used later to adjust the y and x scales
@@ -1846,17 +1863,16 @@
         if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
           continue;
 
-        /* if it is a top zone, check for right edges -- if it is a bottom */
-        /* zone, check for left edges                                      */
-        /*                                                                 */
-        /* of course, that's for TrueType                                  */
+        /* if it is a top zone, check for right edges (against the major */
+        /* direction); if it is a bottom zone, check for left edges (in  */
+        /* the major direction) -- this assumes the TrueType convention  */
+        /* for the orientation of contours                               */
         is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );
         is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
 
-        /* if it is a top zone, the edge must be against the major    */
-        /* direction; if it is a bottom zone, it must be in the major */
-        /* direction                                                  */
-        if ( is_top_blue ^ is_major_dir )
+        /* neutral blue zones are handled for both directions */
+        if ( is_top_blue ^ is_major_dir          ||
+             blue->flags & AF_LATIN_BLUE_NEUTRAL )
         {
           FT_Pos  dist;
 
@@ -1876,8 +1892,11 @@
           /* now compare it to the overshoot position and check whether */
           /* the edge is rounded, and whether the edge is over the      */
           /* reference position of a top zone, or under the reference   */
-          /* position of a bottom zone                                  */
-          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )
+          /* position of a bottom zone (provided we don't have a        */
+          /* neutral blue zone)                                         */
+          if ( edge->flags & AF_EDGE_ROUND              &&
+               dist != 0                                &&
+               !( blue->flags & AF_LATIN_BLUE_NEUTRAL ) )
           {
             FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );
 
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -53,6 +53,8 @@
 
 #define AF_LATIN_IS_TOP_BLUE( b ) \
           ( (b)->properties & AF_BLUE_PROPERTY_LATIN_TOP )
+#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \
+          ( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )
 #define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \
           ( (b)->properties & AF_BLUE_PROPERTY_LATIN_X_HEIGHT )
 #define AF_LATIN_IS_LONG_BLUE( b ) \
@@ -63,10 +65,11 @@
 
   enum
   {
-    AF_LATIN_BLUE_ACTIVE     = 1 << 0,  /* set if zone height is <= 3/4px */
-    AF_LATIN_BLUE_TOP        = 1 << 1,  /* result of AF_LATIN_IS_TOP_BLUE */
-    AF_LATIN_BLUE_ADJUSTMENT = 1 << 2,  /* used for scale adjustment      */
-                                        /* optimization                   */
+    AF_LATIN_BLUE_ACTIVE     = 1 << 0, /* set if zone height is <= 3/4px   */
+    AF_LATIN_BLUE_TOP        = 1 << 1, /* set if we have a top blue zone   */
+    AF_LATIN_BLUE_NEUTRAL    = 1 << 2, /* set if we have neutral blue zone */
+    AF_LATIN_BLUE_ADJUSTMENT = 1 << 3, /* used for scale adjustment        */
+                                       /* optimization                     */
     AF_LATIN_BLUE_FLAG_MAX
   };