diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc | 156 |
1 files changed, 95 insertions, 61 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc index c23240c80c..63c36f936f 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc +++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc @@ -290,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; } } @@ -307,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++) { @@ -320,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); } } } @@ -338,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; } @@ -408,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; @@ -418,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) { @@ -452,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; @@ -500,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); @@ -533,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; } @@ -562,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 (); @@ -578,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; |