提交 798e4185 编写于 作者: J Jonathan Kew 提交者: Behdad Esfahbod

When zeroing mark widths for LTR, also adjust offset...

...so that they overstrike preceding glyph.

https://github.com/behdad/harfbuzz/pull/43
上级 80f7405a
...@@ -452,26 +452,42 @@ hb_ot_substitute (hb_ot_shape_context_t *c) ...@@ -452,26 +452,42 @@ hb_ot_substitute (hb_ot_shape_context_t *c)
/* Position */ /* Position */
static inline void static inline void
zero_mark_widths_by_unicode (hb_buffer_t *buffer) adjust_mark_offsets (hb_glyph_position_t *pos)
{
pos->x_offset -= pos->x_advance;
pos->y_offset -= pos->y_advance;
}
static inline void
zero_mark_width (hb_glyph_position_t *pos)
{
pos->x_advance = 0;
pos->y_advance = 0;
}
static inline void
zero_mark_widths_by_unicode (hb_buffer_t *buffer, bool adjust_offsets)
{ {
unsigned int count = buffer->len; unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) if (_hb_glyph_info_get_general_category (&buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
{ {
buffer->pos[i].x_advance = 0; if (adjust_offsets)
buffer->pos[i].y_advance = 0; adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
} }
} }
static inline void static inline void
zero_mark_widths_by_gdef (hb_buffer_t *buffer) zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
{ {
unsigned int count = buffer->len; unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (_hb_glyph_info_is_mark (&buffer->info[i])) if (_hb_glyph_info_is_mark (&buffer->info[i]))
{ {
buffer->pos[i].x_advance = 0; if (adjust_offsets)
buffer->pos[i].y_advance = 0; adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
} }
} }
...@@ -501,16 +517,28 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) ...@@ -501,16 +517,28 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
{ {
bool ret = false; bool ret = false;
unsigned int count = c->buffer->len; unsigned int count = c->buffer->len;
bool has_positioning = hb_ot_layout_has_positioning (c->face);
/* 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
* 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.
*/
bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
switch (c->plan->shaper->zero_width_marks) switch (c->plan->shaper->zero_width_marks)
{ {
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
zero_mark_widths_by_gdef (c->buffer); zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
break; break;
/* Not currently used for any shaper: /* Not currently used for any shaper:
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_EARLY:
zero_mark_widths_by_unicode (c->buffer); zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
break; break;
*/ */
...@@ -521,7 +549,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) ...@@ -521,7 +549,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
break; break;
} }
if (hb_ot_layout_has_positioning (c->face)) if (has_positioning)
{ {
hb_glyph_info_t *info = c->buffer->info; hb_glyph_info_t *info = c->buffer->info;
hb_glyph_position_t *pos = c->buffer->pos; hb_glyph_position_t *pos = c->buffer->pos;
...@@ -550,11 +578,11 @@ hb_ot_position_complex (hb_ot_shape_context_t *c) ...@@ -550,11 +578,11 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
switch (c->plan->shaper->zero_width_marks) switch (c->plan->shaper->zero_width_marks)
{ {
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE_LATE:
zero_mark_widths_by_unicode (c->buffer); zero_mark_widths_by_unicode (c->buffer, adjust_offsets_when_zeroing);
break; break;
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE: case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
zero_mark_widths_by_gdef (c->buffer); zero_mark_widths_by_gdef (c->buffer, adjust_offsets_when_zeroing);
break; break;
default: default:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册