| 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 6a0c7866b3f826c71fc59f73bfc1181311236179..63c36f936fbf67e2b47d959f9d05d2beb2c07ca7 100644
|
| --- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| +++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| @@ -58,17 +58,8 @@ static hb_tag_t horizontal_features[] = {
|
| HB_TAG('r','c','l','t'),
|
| };
|
|
|
| -/* Note:
|
| - * Technically speaking, vrt2 and vert are mutually exclusive.
|
| - * According to the spec, valt and vpal are also mutually exclusive.
|
| - * But we apply them all for now.
|
| - */
|
| static hb_tag_t vertical_features[] = {
|
| - HB_TAG('v','a','l','t'),
|
| HB_TAG('v','e','r','t'),
|
| - HB_TAG('v','k','r','n'),
|
| - HB_TAG('v','p','a','l'),
|
| - HB_TAG('v','r','t','2'),
|
| };
|
|
|
|
|
| @@ -299,16 +290,18 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c)
|
| if (HB_DIRECTION_IS_FORWARD (c->target_direction))
|
| return;
|
|
|
| - hb_unicode_funcs_t *unicode = c->buffer->unicode;
|
| + hb_buffer_t *buffer = c->buffer;
|
| + hb_unicode_funcs_t *unicode = buffer->unicode;
|
| hb_mask_t rtlm_mask = c->plan->map.get_1_mask (HB_TAG ('r','t','l','m'));
|
|
|
| - unsigned int count = c->buffer->len;
|
| + unsigned int count = buffer->len;
|
| + hb_glyph_info_t *info = buffer->info;
|
| for (unsigned int i = 0; i < count; i++) {
|
| - hb_codepoint_t codepoint = unicode->mirroring (c->buffer->info[i].codepoint);
|
| - if (likely (codepoint == c->buffer->info[i].codepoint))
|
| - c->buffer->info[i].mask |= rtlm_mask;
|
| + hb_codepoint_t codepoint = unicode->mirroring (info[i].codepoint);
|
| + if (likely (codepoint == info[i].codepoint))
|
| + info[i].mask |= rtlm_mask;
|
| else
|
| - c->buffer->info[i].codepoint = codepoint;
|
| + info[i].codepoint = codepoint;
|
| }
|
| }
|
|
|
| @@ -316,12 +309,13 @@ static inline void
|
| hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
|
| {
|
| hb_ot_map_t *map = &c->plan->map;
|
| + hb_buffer_t *buffer = c->buffer;
|
|
|
| hb_mask_t global_mask = map->get_global_mask ();
|
| - c->buffer->reset_masks (global_mask);
|
| + buffer->reset_masks (global_mask);
|
|
|
| if (c->plan->shaper->setup_masks)
|
| - c->plan->shaper->setup_masks (c->plan, c->buffer, c->font);
|
| + c->plan->shaper->setup_masks (c->plan, buffer, c->font);
|
|
|
| for (unsigned int i = 0; i < c->num_user_features; i++)
|
| {
|
| @@ -329,7 +323,7 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c)
|
| if (!(feature->start == 0 && feature->end == (unsigned int)-1)) {
|
| unsigned int shift;
|
| hb_mask_t mask = map->get_mask (feature->tag, &shift);
|
| - c->buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
|
| + buffer->set_masks (feature->value << shift, mask, feature->start, feature->end);
|
| }
|
| }
|
| }
|
| @@ -347,46 +341,53 @@ static inline void
|
| 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++)
|
| - c->buffer->info[i].glyph_props() = _hb_glyph_info_get_general_category (&c->buffer->info[i]) == HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ?
|
| - HB_OT_LAYOUT_GLYPH_PROPS_MARK :
|
| - HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
|
| + _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);
|
| }
|
|
|
| static inline void
|
| hb_ot_substitute_default (hb_ot_shape_context_t *c)
|
| {
|
| + hb_buffer_t *buffer = c->buffer;
|
| +
|
| if (c->plan->shaper->preprocess_text)
|
| - c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
|
| + c->plan->shaper->preprocess_text (c->plan, buffer, c->font);
|
|
|
| hb_ot_mirror_chars (c);
|
|
|
| - HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);
|
| + HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index);
|
|
|
| - _hb_ot_shape_normalize (c->plan, c->buffer, c->font);
|
| + _hb_ot_shape_normalize (c->plan, buffer, c->font);
|
|
|
| hb_ot_shape_setup_masks (c);
|
|
|
| /* This is unfortunate to go here, but necessary... */
|
| if (!hb_ot_layout_has_positioning (c->face))
|
| - _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, c->buffer);
|
| + _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
|
|
|
| - hb_ot_map_glyphs_fast (c->buffer);
|
| + hb_ot_map_glyphs_fast (buffer);
|
|
|
| - HB_BUFFER_DEALLOCATE_VAR (c->buffer, glyph_index);
|
| + HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_index);
|
| }
|
|
|
| static inline void
|
| hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
| {
|
| - hb_ot_layout_substitute_start (c->font, c->buffer);
|
| + hb_buffer_t *buffer = c->buffer;
|
| +
|
| + hb_ot_layout_substitute_start (c->font, buffer);
|
|
|
| if (!hb_ot_layout_has_glyph_classes (c->face))
|
| hb_synthesize_glyph_classes (c);
|
|
|
| - c->plan->substitute (c->font, c->buffer);
|
| + c->plan->substitute (c->font, buffer);
|
|
|
| - hb_ot_layout_substitute_finish (c->font, c->buffer);
|
| + hb_ot_layout_substitute_finish (c->font, buffer);
|
|
|
| return;
|
| }
|
| @@ -417,7 +418,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
|
| {
|
| unsigned int count = buffer->len;
|
| for (unsigned int i = 0; i < count; i++)
|
| - if ((buffer->info[i].glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
|
| + if (_hb_glyph_info_is_mark (&buffer->info[i]))
|
| {
|
| buffer->pos[i].x_advance = 0;
|
| buffer->pos[i].y_advance = 0;
|
| @@ -427,21 +428,29 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer)
|
| static inline void
|
| hb_ot_position_default (hb_ot_shape_context_t *c)
|
| {
|
| - hb_ot_layout_position_start (c->font, c->buffer);
|
| -
|
| + hb_direction_t direction = c->buffer->props.direction;
|
| unsigned int count = c->buffer->len;
|
| + hb_glyph_info_t *info = c->buffer->info;
|
| + hb_glyph_position_t *pos = c->buffer->pos;
|
| for (unsigned int i = 0; i < count; i++)
|
| {
|
| - c->font->get_glyph_advance_for_direction (c->buffer->info[i].codepoint,
|
| - c->buffer->props.direction,
|
| - &c->buffer->pos[i].x_advance,
|
| - &c->buffer->pos[i].y_advance);
|
| - c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
| - c->buffer->props.direction,
|
| - &c->buffer->pos[i].x_offset,
|
| - &c->buffer->pos[i].y_offset);
|
| + c->font->get_glyph_advance_for_direction (info[i].codepoint,
|
| + direction,
|
| + &pos[i].x_advance,
|
| + &pos[i].y_advance);
|
| + c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
|
| + direction,
|
| + &pos[i].x_offset,
|
| + &pos[i].y_offset);
|
|
|
| }
|
| +}
|
| +
|
| +static inline bool
|
| +hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| +{
|
| + bool ret = false;
|
| + unsigned int count = c->buffer->len;
|
|
|
| switch (c->plan->shaper->zero_width_marks)
|
| {
|
| @@ -461,32 +470,28 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
|
| case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
|
| break;
|
| }
|
| -}
|
| -
|
| -static inline bool
|
| -hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| -{
|
| - bool ret = false;
|
| - unsigned int count = c->buffer->len;
|
|
|
| if (hb_ot_layout_has_positioning (c->face))
|
| {
|
| + hb_glyph_info_t *info = c->buffer->info;
|
| + hb_glyph_position_t *pos = c->buffer->pos;
|
| +
|
| /* Change glyph origin to what GPOS expects, apply GPOS, change it back. */
|
|
|
| for (unsigned int i = 0; i < count; i++) {
|
| - c->font->add_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
| + c->font->add_glyph_origin_for_direction (info[i].codepoint,
|
| HB_DIRECTION_LTR,
|
| - &c->buffer->pos[i].x_offset,
|
| - &c->buffer->pos[i].y_offset);
|
| + &pos[i].x_offset,
|
| + &pos[i].y_offset);
|
| }
|
|
|
| c->plan->position (c->font, c->buffer);
|
|
|
| for (unsigned int i = 0; i < count; i++) {
|
| - c->font->subtract_glyph_origin_for_direction (c->buffer->info[i].codepoint,
|
| + c->font->subtract_glyph_origin_for_direction (info[i].codepoint,
|
| HB_DIRECTION_LTR,
|
| - &c->buffer->pos[i].x_offset,
|
| - &c->buffer->pos[i].y_offset);
|
| + &pos[i].x_offset,
|
| + &pos[i].y_offset);
|
| }
|
|
|
| ret = true;
|
| @@ -509,18 +514,20 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| break;
|
| }
|
|
|
| - hb_ot_layout_position_finish (c->font, c->buffer);
|
| -
|
| return ret;
|
| }
|
|
|
| static inline void
|
| hb_ot_position (hb_ot_shape_context_t *c)
|
| {
|
| + hb_ot_layout_position_start (c->font, c->buffer);
|
| +
|
| hb_ot_position_default (c);
|
|
|
| hb_bool_t fallback = !hb_ot_position_complex (c);
|
|
|
| + hb_ot_layout_position_finish (c->font, c->buffer);
|
| +
|
| if (fallback && c->plan->shaper->fallback_position)
|
| _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
|
|
|
| @@ -542,22 +549,42 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
|
| if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
|
| return;
|
|
|
| - hb_codepoint_t space = 0;
|
| + hb_codepoint_t space;
|
| + enum {
|
| + SPACE_DONT_KNOW,
|
| + SPACE_AVAILABLE,
|
| + SPACE_UNAVAILABLE
|
| + } space_status = SPACE_DONT_KNOW;
|
|
|
| unsigned int count = c->buffer->len;
|
| + hb_glyph_info_t *info = c->buffer->info;
|
| + hb_glyph_position_t *pos = c->buffer->pos;
|
| + unsigned int j = 0;
|
| for (unsigned int i = 0; i < count; i++)
|
| - if (unlikely (!is_a_ligature (c->buffer->info[i]) &&
|
| - _hb_glyph_info_is_default_ignorable (&c->buffer->info[i])))
|
| + {
|
| + if (unlikely (!_hb_glyph_info_ligated (&info[i]) &&
|
| + _hb_glyph_info_is_default_ignorable (&info[i])))
|
| {
|
| - if (!space) {
|
| - /* We assume that the space glyph is not gid0. */
|
| - if (unlikely (!c->font->get_glyph (' ', 0, &space)) || !space)
|
| - return; /* No point! */
|
| + if (space_status == SPACE_DONT_KNOW)
|
| + space_status = c->font->get_glyph (' ', 0, &space) ? SPACE_AVAILABLE : SPACE_UNAVAILABLE;
|
| +
|
| + if (space_status == SPACE_AVAILABLE)
|
| + {
|
| + info[i].codepoint = space;
|
| + pos[i].x_advance = 0;
|
| + pos[i].y_advance = 0;
|
| }
|
| - c->buffer->info[i].codepoint = space;
|
| - c->buffer->pos[i].x_advance = 0;
|
| - c->buffer->pos[i].y_advance = 0;
|
| + else
|
| + continue; /* Delete it. */
|
| + }
|
| + if (j != i)
|
| + {
|
| + info[j] = info[i];
|
| + pos[j] = pos[i];
|
| }
|
| + j++;
|
| + }
|
| + c->buffer->len = j;
|
| }
|
|
|
|
|
| @@ -571,8 +598,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
| /* Save the original direction, we use it later. */
|
| c->target_direction = c->buffer->props.direction;
|
|
|
| - HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props0);
|
| - HB_BUFFER_ALLOCATE_VAR (c->buffer, unicode_props1);
|
| + _hb_buffer_allocate_unicode_vars (c->buffer);
|
|
|
| c->buffer->clear_output ();
|
|
|
| @@ -587,8 +613,7 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
|
|
| hb_ot_hide_default_ignorables (c);
|
|
|
| - HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
|
| - HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);
|
| + _hb_buffer_deallocate_unicode_vars (c->buffer);
|
|
|
| c->buffer->props.direction = c->target_direction;
|
|
|
|
|