summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Lemberg <wl@gnu.org>2014-04-28 21:13:14 +0200
committerWerner Lemberg <wl@gnu.org>2014-04-28 21:13:14 +0200
commitccfc4b4c4e2c4fc51f20ce5c9bf107739e86e5ad (patch)
tree0dcc2ccd5b4187eced3b0afa1c2ea18ff88b73ad
parentabb3fcac8578c4161606973e751beb7d3f05b2c2 (diff)
downloadfreetype2-ccfc4b4c4e2c4fc51f20ce5c9bf107739e86e5ad.tar.gz
[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.
-rw-r--r--ChangeLog24
-rw-r--r--src/autofit/afblue.dat31
-rw-r--r--src/autofit/afblue.h11
-rw-r--r--src/autofit/afblue.hin11
-rw-r--r--src/autofit/aflatin.c39
-rw-r--r--src/autofit/aflatin.h11
6 files changed, 95 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index c9f93b207..ddc68cee2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2014-04-28 Werner Lemberg <wl@gnu.org>
+
+ [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 <wl@gnu.org>
* 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.
diff --git a/src/autofit/afblue.dat b/src/autofit/afblue.dat
index ad3aeff76..4923f9ce5 100644
--- 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,6 +163,10 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
// 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 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
//
// 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
diff --git a/src/autofit/afblue.h b/src/autofit/afblue.h
index a16849fed..a656c28db 100644
--- a/src/autofit/afblue.h
+++ b/src/autofit/afblue.h
@@ -132,12 +132,13 @@ FT_BEGIN_HEADER
/* 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
diff --git a/src/autofit/afblue.hin b/src/autofit/afblue.hin
index c4f2526b1..0b4b48d7f 100644
--- a/src/autofit/afblue.hin
+++ b/src/autofit/afblue.hin
@@ -96,12 +96,13 @@ FT_BEGIN_HEADER
/* 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
diff --git a/src/autofit/aflatin.c b/src/autofit/aflatin.c
index 32dd577ce..825c3612e 100644
--- 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 );
diff --git a/src/autofit/aflatin.h b/src/autofit/aflatin.h
index 0f62186ce..2c0bfca18 100644
--- a/src/autofit/aflatin.h
+++ b/src/autofit/aflatin.h
@@ -53,6 +53,8 @@ FT_BEGIN_HEADER
#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 @@ FT_BEGIN_HEADER
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
};