[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.
This commit is contained in:
Werner Lemberg 2014-04-28 21:13:14 +02:00
parent abb3fcac85
commit ccfc4b4c4e
6 changed files with 95 additions and 32 deletions

View File

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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 );

View File

@ -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
};