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; |