[aat] Tweak fallback positioning logic when applying morx

Such that for Indic-like scripts (eg. Khmer), we don't do any fallback mark
advance-zeroing / positioning, but we do for Latin, etc.  Reuses preferences
of our script-specific OpenType shapers for those.

Fixes regression: https://github.com/harfbuzz/harfbuzz/issues/1393
Which means, fixes again: https://github.com/harfbuzz/harfbuzz/issues/1264
While not regressing: https://github.com/harfbuzz/harfbuzz/issues/1357
This commit is contained in:
Behdad Esfahbod 2018-11-22 15:52:29 -05:00
parent fa0bd8964d
commit a201fa74cd
2 changed files with 26 additions and 15 deletions

View File

@ -76,10 +76,16 @@ hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *fac
props (*props),
map (face, props),
aat_map (face, props),
apply_morx (_hb_apply_morx (face)),
shaper (apply_morx ?
&_hb_ot_complex_shaper_default :
hb_ot_shape_complex_categorize (this)) {}
apply_morx (_hb_apply_morx (face))
{
shaper = hb_ot_shape_complex_categorize (this);
script_zero_marks = shaper->zero_width_marks != HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE;
script_fallback_mark_positioning = shaper->fallback_position;
if (apply_morx)
shaper = &_hb_ot_complex_shaper_default;
}
void
hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
@ -141,9 +147,11 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
}
bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face);
plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark;
plan.zero_marks = script_zero_marks && !plan.apply_kerx && !has_kern_mark;
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks;
plan.fallback_mark_positioning = script_fallback_mark_positioning && !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark;
plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos && !plan.apply_kerx && !has_kern_mark;
/* Currently we always apply trak. */
plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
@ -158,6 +166,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face,
hb_ot_shape_planner_t planner (face,
&key->props);
hb_ot_shape_collect_features (&planner,
key->user_features,
key->num_user_features);
@ -811,17 +820,16 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
hb_glyph_info_t *info = c->buffer->info;
hb_glyph_position_t *pos = c->buffer->pos;
/* If the font has no GPOS, AND, no fallback positioning will
* happen, AND, direction is forward, then when zeroing mark
* widths, we shift the mark with it, such that the mark
* is positioned hanging over the previous glyph. When
/* If the font has no GPOS and direction is forward, then when
* zeroing mark widths, we shift the mark with it, such that the
* mark is positioned hanging over the previous glyph. When
* direction is backward we don't shift and it will end up
* hanging over the next glyph after the final reordering.
* If fallback positinoing happens or GPOS is present, we don't
* care.
*
* Note: If fallback positinoing happens, we don't care about
* this as it will be overriden.
*/
bool adjust_offsets_when_zeroing = c->plan->fallback_mark_positioning &&
!c->plan->shaper->fallback_position &&
bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
/* We change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back. */
@ -877,7 +885,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
&pos[i].x_offset,
&pos[i].y_offset);
if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
if (c->plan->fallback_mark_positioning)
_hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
}

View File

@ -77,6 +77,7 @@ struct hb_ot_shape_plan_t
bool zero_marks : 1;
bool fallback_glyph_classes : 1;
bool fallback_mark_positioning : 1;
bool adjust_mark_positioning_when_zeroing : 1;
bool apply_gpos : 1;
bool apply_kerx : 1;
@ -113,6 +114,8 @@ struct hb_ot_shape_planner_t
hb_ot_map_builder_t map;
hb_aat_map_builder_t aat_map;
bool apply_morx : 1;
bool script_zero_marks : 1;
bool script_fallback_mark_positioning : 1;
const struct hb_ot_complex_shaper_t *shaper;
HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face,