[autofit] Introduce subscript top blue zones.

This feature is mainly for Khmer: The idea is to avoid a clash
between the top of subscript glyphs and the bottom of normal
baseline glyphs.

This only works for character clusters mapped to multiple glyphs.

* src/autofit/afblue.dat: Add subscript top blue zone for Khmer.

* src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_SUB_TOP): New
macro.

* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.

* src/autofit/aflatin.h (AF_LATIN_IS_SUB_TOP_BLUE,
AF_LATIN_BLUE_SUB_TOP): New macros.

* src/autofit/aflatin.c (af_latin_metrics_init_blues): Handle new
blue zone property.
Update tracing messages.
(af_latin_metrics_scale_dim): Handle new blue zone property.
(af_latin_hints_compute_blue_edges): Updated.
This commit is contained in:
Werner Lemberg 2015-12-09 20:04:18 +01:00
parent f02e1df7ac
commit 0164d934b6
7 changed files with 152 additions and 54 deletions

View File

@ -1,3 +1,29 @@
2015-12-09 Werner Lemberg <wl@gnu.org>
[autofit] Introduce subscript top blue zones.
This feature is mainly for Khmer: The idea is to avoid a clash
between the top of subscript glyphs and the bottom of normal
baseline glyphs.
This only works for character clusters mapped to multiple glyphs.
* src/autofit/afblue.dat: Add subscript top blue zone for Khmer.
* src/autofit/afblue.hin (AF_BLUE_PROPERTY_LATIN_SUB_TOP): New
macro.
* src/autofit/afblue.c, src/autofit/afblue.h: Regenerated.
* src/autofit/aflatin.h (AF_LATIN_IS_SUB_TOP_BLUE,
AF_LATIN_BLUE_SUB_TOP): New macros.
* src/autofit/aflatin.c (af_latin_metrics_init_blues): Handle new
blue zone property.
Update tracing messages.
(af_latin_metrics_scale_dim): Handle new blue zone property.
(af_latin_hints_compute_blue_edges): Updated.
2015-12-09 Werner Lemberg <wl@gnu.org>
[autofit] Fix tracing message.

View File

@ -66,6 +66,8 @@
'\0',
'\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x91', ' ', '\xE1', '\x9E', '\x93', ' ', '\xE1', '\x9E', '\xA7', ' ', '\xE1', '\x9E', '\xA9', ' ', '\xE1', '\x9E', '\xB6', /* ខ ទ ន ឧ ឩ ា */
'\0',
'\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x80', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x82', ' ', '\xE1', '\x9E', '\x80', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x90', /* ក្ក ក្ខ ក្គ ក្ថ */
'\0',
'\xE1', '\x9E', '\x81', ' ', '\xE1', '\x9E', '\x83', ' ', '\xE1', '\x9E', '\x85', ' ', '\xE1', '\x9E', '\x8B', ' ', '\xE1', '\x9E', '\x94', ' ', '\xE1', '\x9E', '\x98', ' ', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xB2', /* ខ ឃ ច ឋ ប ម យ ឲ */
'\0',
'\xE1', '\x9E', '\x8F', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x9A', ' ', '\xE1', '\x9E', '\x9A', '\xE1', '\x9F', '\x80', ' ', '\xE1', '\x9E', '\xB2', '\xE1', '\x9F', '\x92', '\xE1', '\x9E', '\x99', ' ', '\xE1', '\x9E', '\xA2', '\xE1', '\x9E', '\xBF', /* ត្រ រៀ ឲ្យ អឿ */
@ -217,6 +219,7 @@
{ AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT },
{ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP },
{ AF_BLUE_STRING_KHMER_BOTTOM, 0 },
{ AF_BLUE_STRING_KHMER_DESCENDER, 0 },
{ AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 },

View File

@ -127,6 +127,8 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
AF_BLUE_STRING_KHMER_TOP
"ខ ទ ន ឧ ឩ ា"
AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP
"ក្ក ក្ខ ក្គ ក្ថ"
AF_BLUE_STRING_KHMER_BOTTOM
"ខ ឃ ច ឋ ប ម យ ឲ"
AF_BLUE_STRING_KHMER_DESCENDER
@ -297,6 +299,21 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
//
// If not set, take the minimum values.
//
// Mutually exclusive with `LATIN_SUB_TOP'.
//
// LATIN_SUB_TOP
// For all glyphs of a character cluster, compute the maximum flat
// and round coordinate values of each component, then take the
// smallest of the maximum values. The idea is to get the top of
// subscript glyphs, as used in Khmer, for example. Note that
// this mechanism doesn't work for ordinary ligatures.
//
// This flags indicates a secondary blue zone: It gets removed if
// there is a non-LATIN_SUB_TOP blue zone at the same coordinate
// value (after scaling).
//
// Mutually exclusive with `LATIN_TOP'.
//
// 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
@ -401,6 +418,7 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
AF_BLUE_STRINGSET_KHMR
{ AF_BLUE_STRING_KHMER_TOP, AF_BLUE_PROPERTY_LATIN_TOP |
AF_BLUE_PROPERTY_LATIN_X_HEIGHT }
{ AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP, AF_BLUE_PROPERTY_LATIN_SUB_TOP }
{ AF_BLUE_STRING_KHMER_BOTTOM, 0 }
{ AF_BLUE_STRING_KHMER_DESCENDER, 0 }
{ AF_BLUE_STRING_KHMER_LARGE_DESCENDER, 0 }

View File

@ -97,41 +97,42 @@ FT_BEGIN_HEADER
AF_BLUE_STRING_HEBREW_BOTTOM = 350,
AF_BLUE_STRING_HEBREW_DESCENDER = 368,
AF_BLUE_STRING_KHMER_TOP = 383,
AF_BLUE_STRING_KHMER_BOTTOM = 407,
AF_BLUE_STRING_KHMER_DESCENDER = 439,
AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 473,
AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 560,
AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 568,
AF_BLUE_STRING_LAO_TOP = 576,
AF_BLUE_STRING_LAO_BOTTOM = 608,
AF_BLUE_STRING_LAO_ASCENDER = 640,
AF_BLUE_STRING_LAO_LARGE_ASCENDER = 656,
AF_BLUE_STRING_LAO_DESCENDER = 668,
AF_BLUE_STRING_LATIN_CAPITAL_TOP = 692,
AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 708,
AF_BLUE_STRING_LATIN_SMALL_F_TOP = 724,
AF_BLUE_STRING_LATIN_SMALL = 738,
AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 752,
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 762,
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 782,
AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 802,
AF_BLUE_STRING_LATIN_SUBS_SMALL = 822,
AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 858,
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 878,
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 909,
AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 938,
AF_BLUE_STRING_LATIN_SUPS_SMALL = 964,
AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 989,
AF_BLUE_STRING_TELUGU_TOP = 1000,
AF_BLUE_STRING_TELUGU_BOTTOM = 1028,
AF_BLUE_STRING_THAI_TOP = 1056,
AF_BLUE_STRING_THAI_BOTTOM = 1080,
AF_BLUE_STRING_THAI_ASCENDER = 1108,
AF_BLUE_STRING_THAI_LARGE_ASCENDER = 1120,
AF_BLUE_STRING_THAI_DESCENDER = 1132,
AF_BLUE_STRING_THAI_LARGE_DESCENDER = 1148,
AF_BLUE_STRING_THAI_DIGIT_TOP = 1156,
af_blue_1_1 = 1167,
AF_BLUE_STRING_KHMER_SUBSCRIPT_TOP = 407,
AF_BLUE_STRING_KHMER_BOTTOM = 447,
AF_BLUE_STRING_KHMER_DESCENDER = 479,
AF_BLUE_STRING_KHMER_LARGE_DESCENDER = 513,
AF_BLUE_STRING_KHMER_SYMBOLS_WAXING_TOP = 600,
AF_BLUE_STRING_KHMER_SYMBOLS_WANING_BOTTOM = 608,
AF_BLUE_STRING_LAO_TOP = 616,
AF_BLUE_STRING_LAO_BOTTOM = 648,
AF_BLUE_STRING_LAO_ASCENDER = 680,
AF_BLUE_STRING_LAO_LARGE_ASCENDER = 696,
AF_BLUE_STRING_LAO_DESCENDER = 708,
AF_BLUE_STRING_LATIN_CAPITAL_TOP = 732,
AF_BLUE_STRING_LATIN_CAPITAL_BOTTOM = 748,
AF_BLUE_STRING_LATIN_SMALL_F_TOP = 764,
AF_BLUE_STRING_LATIN_SMALL = 778,
AF_BLUE_STRING_LATIN_SMALL_DESCENDER = 792,
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_TOP = 802,
AF_BLUE_STRING_LATIN_SUBS_CAPITAL_BOTTOM = 822,
AF_BLUE_STRING_LATIN_SUBS_SMALL_F_TOP = 842,
AF_BLUE_STRING_LATIN_SUBS_SMALL = 862,
AF_BLUE_STRING_LATIN_SUBS_SMALL_DESCENDER = 898,
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_TOP = 918,
AF_BLUE_STRING_LATIN_SUPS_CAPITAL_BOTTOM = 949,
AF_BLUE_STRING_LATIN_SUPS_SMALL_F_TOP = 978,
AF_BLUE_STRING_LATIN_SUPS_SMALL = 1004,
AF_BLUE_STRING_LATIN_SUPS_SMALL_DESCENDER = 1029,
AF_BLUE_STRING_TELUGU_TOP = 1040,
AF_BLUE_STRING_TELUGU_BOTTOM = 1068,
AF_BLUE_STRING_THAI_TOP = 1096,
AF_BLUE_STRING_THAI_BOTTOM = 1120,
AF_BLUE_STRING_THAI_ASCENDER = 1148,
AF_BLUE_STRING_THAI_LARGE_ASCENDER = 1160,
AF_BLUE_STRING_THAI_DESCENDER = 1172,
AF_BLUE_STRING_THAI_LARGE_DESCENDER = 1188,
AF_BLUE_STRING_THAI_DIGIT_TOP = 1196,
af_blue_1_1 = 1207,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@ -173,9 +174,10 @@ FT_BEGIN_HEADER
/* blue string can't be used in more than a single writing system, which */
/* is a safe bet. */
#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */
#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 1 )
#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 2 )
#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 3 )
#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 )
#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 )
#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 )
#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 )
#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */
#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */
@ -195,14 +197,14 @@ FT_BEGIN_HEADER
AF_BLUE_STRINGSET_GREK = 16,
AF_BLUE_STRINGSET_HEBR = 23,
AF_BLUE_STRINGSET_KHMR = 27,
AF_BLUE_STRINGSET_KHMS = 32,
AF_BLUE_STRINGSET_LAO = 35,
AF_BLUE_STRINGSET_LATN = 41,
AF_BLUE_STRINGSET_LATB = 48,
AF_BLUE_STRINGSET_LATP = 55,
AF_BLUE_STRINGSET_TELU = 62,
AF_BLUE_STRINGSET_THAI = 65,
af_blue_2_1 = 73,
AF_BLUE_STRINGSET_KHMS = 33,
AF_BLUE_STRINGSET_LAO = 36,
AF_BLUE_STRINGSET_LATN = 42,
AF_BLUE_STRINGSET_LATB = 49,
AF_BLUE_STRINGSET_LATP = 56,
AF_BLUE_STRINGSET_TELU = 63,
AF_BLUE_STRINGSET_THAI = 66,
af_blue_2_1 = 74,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
af_blue_2_1_1 = af_blue_2_1 + 2,

View File

@ -100,9 +100,10 @@ FT_BEGIN_HEADER
/* blue string can't be used in more than a single writing system, which */
/* is a safe bet. */
#define AF_BLUE_PROPERTY_LATIN_TOP ( 1U << 0 ) /* must have value 1 */
#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 1 )
#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 2 )
#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 3 )
#define AF_BLUE_PROPERTY_LATIN_SUB_TOP ( 1U << 1 )
#define AF_BLUE_PROPERTY_LATIN_NEUTRAL ( 1U << 2 )
#define AF_BLUE_PROPERTY_LATIN_X_HEIGHT ( 1U << 3 )
#define AF_BLUE_PROPERTY_LATIN_LONG ( 1U << 4 )
#define AF_BLUE_PROPERTY_CJK_TOP ( 1U << 0 ) /* must have value 1 */
#define AF_BLUE_PROPERTY_CJK_HORIZ ( 1U << 1 ) /* must have value 2 */

View File

@ -330,6 +330,11 @@
FT_TRACE5(( "top" ));
have_flag = 1;
}
else if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) )
{
FT_TRACE5(( "sub top" ));
have_flag = 1;
}
if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
{
@ -462,7 +467,8 @@
if ( last <= first )
continue;
if ( AF_LATIN_IS_TOP_BLUE( bs ) )
if ( AF_LATIN_IS_TOP_BLUE( bs ) ||
AF_LATIN_IS_SUB_TOP_BLUE( bs ) )
{
for ( pp = first; pp <= last; pp++ )
{
@ -871,7 +877,8 @@
FT_Bool over_ref = FT_BOOL( shoot > ref );
if ( AF_LATIN_IS_TOP_BLUE( bs ) ^ over_ref )
if ( ( AF_LATIN_IS_TOP_BLUE( bs ) ||
AF_LATIN_IS_SUB_TOP_BLUE( bs) ) ^ over_ref )
{
*blue_ref =
*blue_shoot = ( shoot + ref ) / 2;
@ -887,6 +894,8 @@
blue->flags = 0;
if ( AF_LATIN_IS_TOP_BLUE( bs ) )
blue->flags |= AF_LATIN_BLUE_TOP;
if ( AF_LATIN_IS_SUB_TOP_BLUE( bs ) )
blue->flags |= AF_LATIN_BLUE_SUB_TOP;
if ( AF_LATIN_IS_NEUTRAL_BLUE( bs ) )
blue->flags |= AF_LATIN_BLUE_NEUTRAL;
@ -1259,6 +1268,40 @@
}
}
/* use sub-top blue zone only if it doesn't overlap with */
/* another (non-sup-top) blue zone; otherwise, the */
/* effect would be similar to a neutral blue zone, which */
/* is not desired here */
for ( nn = 0; nn < axis->blue_count; nn++ )
{
AF_LatinBlue blue = &axis->blues[nn];
FT_UInt i;
if ( !( blue->flags & AF_LATIN_BLUE_SUB_TOP ) )
continue;
if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )
continue;
for ( i = 0; i < axis->blue_count; i++ )
{
AF_LatinBlue b = &axis->blues[i];
if ( b->flags & AF_LATIN_BLUE_SUB_TOP )
continue;
if ( !( b->flags & AF_LATIN_BLUE_ACTIVE ) )
continue;
if ( b->ref.fit <= blue->shoot.fit &&
b->shoot.fit >= blue->ref.fit )
{
blue->flags &= ~AF_LATIN_BLUE_ACTIVE;
break;
}
}
}
#ifdef FT_DEBUG_LEVEL_TRACE
for ( nn = 0; nn < axis->blue_count; nn++ )
{
@ -2071,7 +2114,8 @@
/* 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 );
(FT_Byte)( ( blue->flags & ( AF_LATIN_BLUE_TOP |
AF_LATIN_BLUE_SUB_TOP ) ) != 0 );
is_neutral_blue =
(FT_Byte)( ( blue->flags & AF_LATIN_BLUE_NEUTRAL ) != 0);
is_major_dir =

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_SUB_TOP_BLUE( b ) \
( (b)->properties & AF_BLUE_PROPERTY_LATIN_SUB_TOP )
#define AF_LATIN_IS_NEUTRAL_BLUE( b ) \
( (b)->properties & AF_BLUE_PROPERTY_LATIN_NEUTRAL )
#define AF_LATIN_IS_X_HEIGHT_BLUE( b ) \
@ -65,8 +67,10 @@ FT_BEGIN_HEADER
#define AF_LATIN_BLUE_ACTIVE ( 1U << 0 ) /* zone height is <= 3/4px */
#define AF_LATIN_BLUE_TOP ( 1U << 1 ) /* we have a top blue zone */
#define AF_LATIN_BLUE_NEUTRAL ( 1U << 2 ) /* we have neutral blue zone */
#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 3 ) /* used for scale adjustment */
#define AF_LATIN_BLUE_SUB_TOP ( 1U << 2 ) /* we have a subscript top */
/* blue zone */
#define AF_LATIN_BLUE_NEUTRAL ( 1U << 3 ) /* we have neutral blue zone */
#define AF_LATIN_BLUE_ADJUSTMENT ( 1U << 4 ) /* used for scale adjustment */
/* optimization */