[PairPos] Split GPOS kerning to both sides (#3235)

This commit is contained in:
Behdad Esfahbod 2022-01-20 13:18:19 -08:00 committed by GitHub
parent ae9fc7f533
commit 84aa1a836c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 7 deletions

View File

@ -1566,11 +1566,73 @@ struct PairPosFormat2
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
bool applied_first = false, applied_second = false;
/* Isolate simple kerning and apply it half to each side.
* Results in better cursor positinoing / underline drawing. */
{
if (!len2)
{
const hb_direction_t dir = buffer->props.direction;
const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
if (backward)
mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
/* Add Devices. */
mask |= mask << 4;
if (valueFormat1 & !mask)
goto bail;
/* Is simple kern. Apply value on an empty position slot,
* then split it between sides. */
hb_glyph_position_t pos{};
if (valueFormat1.apply_value (c, this, v, pos))
{
hb_position_t *src = &pos.x_advance;
hb_position_t *dst1 = &buffer->cur_pos().x_advance;
hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
unsigned i = horizontal ? 0 : 1;
hb_position_t kern = src[i];
hb_position_t kern1 = kern >> 1;
hb_position_t kern2 = kern - kern1;
if (!backward)
{
dst1[i] += kern1;
dst2[i] += kern2;
dst2[i + 2] += kern2;
}
else
{
dst1[i] += kern1;
dst1[i + 2] += src[i + 2] - kern2;
dst2[i] += kern2;
}
applied_first = applied_second = kern != 0;
goto success;
}
goto boring;
}
}
bail:
applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
success:
if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
boring:
buffer->idx = skippy_iter.idx;
if (len2)
buffer->idx++;

View File

@ -128,6 +128,3 @@ TESTS = \
tests/lookupflag_ignore_ligatures.tests \
tests/lookupflag_ignore_marks.tests \
$(NULL)
DISABLED_TESTS = \
$(NULL)

View File

@ -2,4 +2,4 @@
../fonts/gpos2_2_font2.otf;--features="test" --single-par --no-clusters --no-glyph-names --ned;U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011;[17|19@1300,0|20@3000,-100|17@4500,0|19@5800,0|18@7500,0|20@9000,-100|17@10500,0]
../fonts/gpos2_2_font3.otf;--features="test" --single-par --no-clusters --no-glyph-names --ned;U+0011,U+0013,U+0014,U+0011,U+0013,U+0012,U+0014,U+0011;[17|19@1500,0|20@2800,-100|17@4300,0|19@5800,0|18@7100,0|20@8600,-100|17@10100,0]
../fonts/gpos2_2_font4.otf;--features="test" --single-par --no-clusters --no-glyph-names --ned;U+0012,U+0012,U+0012,U+0012;[18@-100,0|18@1500,-100|18@2900,0|18@4500,-100]
../fonts/gpos2_2_font5.otf;--features="test" --single-par --no-clusters --no-glyph-names --ned;U+0012,U+0012,U+0012,U+0012;[18@-100,0|18@1400,0|18@2900,0|18@4500,0]
#../fonts/gpos2_2_font5.otf;--features="test" --single-par --no-clusters --no-glyph-names --ned;U+0012,U+0012,U+0012,U+0012;[18@-100,0|18@1400,0|18@2900,0|18@4500,0]

View File

@ -1,3 +1,3 @@
../fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf;;U+0041,U+0056;[A=0+625|V=1+675]
../fonts/53a91c20e33a596f2be17fb68b382d6b7eb85d5c.ttf;;U+0041,U+0056;[A=0+665|V=1@-40,0+635]
../fonts/f79eb71df4e4c9c273b67b89a06e5ff9e3c1f834.ttf;;U+006D,U+0315;[m=0+945|uni0315=0@32,-178+0]
../fonts/ea3f63620511b2097200d23774ffef197e829e69.ttf;;U+0079,U+0325;[y=0+565|uni0325=0@-422,-240+0]