| Index: third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| index 3080a1d03dbfc9f75589a5bc4b28686535af101f..a9de431cbdd16d1c1293699002dbcd6d830d0c34 100644
|
| --- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| +++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| @@ -29,15 +29,18 @@
|
| #define HB_SHAPER ot
|
| #define hb_ot_shaper_face_data_t hb_ot_layout_t
|
| #define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
|
| -#include "hb-shaper-impl-private.hh"
|
| +
|
| +#include "hb-ot-layout-private.hh"
|
|
|
| #include "hb-ot-shape-private.hh"
|
| #include "hb-ot-shape-complex-private.hh"
|
| #include "hb-ot-shape-fallback-private.hh"
|
| #include "hb-ot-shape-normalize-private.hh"
|
|
|
| -#include "hb-ot-layout-private.hh"
|
| #include "hb-set-private.hh"
|
| +#include "hb-shaper-impl-private.hh"
|
| +
|
| +#include "hb-unicode-private.hh"
|
|
|
|
|
| static hb_tag_t common_features[] = {
|
| @@ -226,8 +229,9 @@ static void
|
| hb_set_unicode_props (hb_buffer_t *buffer)
|
| {
|
| unsigned int count = buffer->len;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| - _hb_glyph_info_set_unicode_props (&buffer->info[i], buffer->unicode);
|
| + _hb_glyph_info_set_unicode_props (&info[i], buffer->unicode);
|
| }
|
|
|
| static void
|
| @@ -238,11 +242,11 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
|
| HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
| return;
|
|
|
| - if (!font->has_glyph (0x25CC))
|
| + if (!font->has_glyph (0x25CCu))
|
| return;
|
|
|
| hb_glyph_info_t dottedcircle;
|
| - dottedcircle.codepoint = 0x25CC;
|
| + dottedcircle.codepoint = 0x25CCu;
|
| _hb_glyph_info_set_unicode_props (&dottedcircle, buffer->unicode);
|
|
|
| buffer->clear_output ();
|
| @@ -262,8 +266,9 @@ static void
|
| hb_form_clusters (hb_buffer_t *buffer)
|
| {
|
| unsigned int count = buffer->len;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 1; i < count; i++)
|
| - if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[i])))
|
| + if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&info[i])))
|
| buffer->merge_clusters (i - 1, i + 1);
|
| }
|
|
|
| @@ -321,7 +326,7 @@ hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c)
|
| hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| {
|
| - if (info[i].codepoint == 0x2044) /* FRACTION SLASH */
|
| + if (info[i].codepoint == 0x2044u) /* FRACTION SLASH */
|
| {
|
| unsigned int start = i, end = i + 1;
|
| while (start &&
|
| @@ -381,8 +386,9 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
|
| {
|
| /* Normalization process sets up glyph_index(), we just copy it. */
|
| unsigned int count = buffer->len;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| - buffer->info[i].codepoint = buffer->info[i].glyph_index();
|
| + info[i].codepoint = info[i].glyph_index();
|
| }
|
|
|
| static inline void
|
| @@ -391,11 +397,24 @@ hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
|
| unsigned int count = c->buffer->len;
|
| hb_glyph_info_t *info = c->buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| - _hb_glyph_info_set_glyph_props (&info[i],
|
| - _hb_glyph_info_get_general_category (&info[i])
|
| - == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
|
| - HB_OT_LAYOUT_GLYPH_PROPS_MARK :
|
| - HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
|
| + {
|
| + hb_ot_layout_glyph_class_mask_t klass;
|
| +
|
| + /* Never mark default-ignorables as marks.
|
| + * They won't get in the way of lookups anyway,
|
| + * but having them as mark will cause them to be skipped
|
| + * over if the lookup-flag says so, but at least for the
|
| + * Mongolian variation selectors, looks like Uniscribe
|
| + * marks them as non-mark. Some Mongolian fonts without
|
| + * GDEF rely on this. Another notable character that
|
| + * this applies to is COMBINING GRAPHEME JOINER. */
|
| + klass = (_hb_glyph_info_get_general_category (&info[i]) !=
|
| + HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
|
| + _hb_glyph_info_is_default_ignorable (&info[i])) ?
|
| + HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
|
| + HB_OT_LAYOUT_GLYPH_PROPS_MARK;
|
| + _hb_glyph_info_set_glyph_props (&info[i], klass);
|
| + }
|
| }
|
|
|
| static inline void
|
| @@ -452,26 +471,44 @@ hb_ot_substitute (hb_ot_shape_context_t *c)
|
| /* Position */
|
|
|
| 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;
|
| + hb_glyph_info_t *info = buffer->info;
|
| 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 (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
|
| {
|
| - buffer->pos[i].x_advance = 0;
|
| - buffer->pos[i].y_advance = 0;
|
| + if (adjust_offsets)
|
| + adjust_mark_offsets (&buffer->pos[i]);
|
| + zero_mark_width (&buffer->pos[i]);
|
| }
|
| }
|
|
|
| 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;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| - if (_hb_glyph_info_is_mark (&buffer->info[i]))
|
| + if (_hb_glyph_info_is_mark (&info[i]))
|
| {
|
| - buffer->pos[i].x_advance = 0;
|
| - buffer->pos[i].y_advance = 0;
|
| + if (adjust_offsets)
|
| + adjust_mark_offsets (&buffer->pos[i]);
|
| + zero_mark_width (&buffer->pos[i]);
|
| }
|
| }
|
|
|
| @@ -501,16 +538,28 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| {
|
| bool ret = false;
|
| 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)
|
| {
|
| 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;
|
|
|
| /* Not currently used for any shaper:
|
| 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;
|
| */
|
|
|
| @@ -521,7 +570,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| break;
|
| }
|
|
|
| - if (hb_ot_layout_has_positioning (c->face))
|
| + if (has_positioning)
|
| {
|
| hb_glyph_info_t *info = c->buffer->info;
|
| hb_glyph_position_t *pos = c->buffer->pos;
|
| @@ -550,11 +599,11 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| switch (c->plan->shaper->zero_width_marks)
|
| {
|
| 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;
|
|
|
| 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;
|
|
|
| default:
|
| @@ -731,8 +780,9 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
|
| bool mirror = hb_script_get_horizontal_direction (buffer->props.script) == HB_DIRECTION_RTL;
|
|
|
| unsigned int count = buffer->len;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++)
|
| - add_char (font, buffer->unicode, mirror, buffer->info[i].codepoint, glyphs);
|
| + add_char (font, buffer->unicode, mirror, info[i].codepoint, glyphs);
|
|
|
| hb_set_t lookups;
|
| lookups.init ();
|
|
|