summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2013-12-16 08:49:48 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-19 05:49:27 +0100
commit260fe985255c46fd2eb0aff378da8dccb5f2703f (patch)
tree11691b16243276c1b88c23d470cdb48e5f3fa1a2 /src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc
parent4b2c73b4767bcb512cbc17f65186eac5d004db07 (diff)
Update bundled HarfBuzz sources up to 0.9.25
Most important changes: - Myanmar, Indic, Javanese / Buginese shaper improvements - More aggressive shape-plan caching - Additional OpenType language tags Change-Id: I54ed62cfe936c06c18589d09ac119a0f5881a235 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape.cc156
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;