From: Behdad Esfahbod Date: Wed, 22 Jul 2015 16:36:23 +0000 (+0100) Subject: [ot] Hide default-ignorables before finishing off positioning X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f0010dfd01ef4a927b0bdc175dd4e343a8637174;p=platform%2Fupstream%2FlibHarfBuzzSharp.git [ot] Hide default-ignorables before finishing off positioning For example, fixes the following sequence with Arial XP: 628 25cc 651 25cc 64e 3a 20 628 651 34f 64e 628 25cc 64e 25cc 651 3a 20 628 64e 34f 651 Discovered as part of: https://bugs.freedesktop.org/show_bug.cgi?id=85873 --- diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index d290cad..59c58fd 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -411,6 +411,65 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) } } + +static void +hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + + if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) + return; + + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + unsigned int i = 0; + for (i = 0; i < count; i++) + { + if (unlikely (!_hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_is_default_ignorable (&info[i]))) + break; + } + + /* No default-ignorables found; return. */ + if (i == count) + return; + + hb_codepoint_t space; + if (c->font->get_glyph (' ', 0, &space)) + { + /* Replace default-ignorables with a zero-advance space glyph. */ + for (/*continue*/; i < count; i++) + { + if (!_hb_glyph_info_ligated (&info[i]) && + _hb_glyph_info_is_default_ignorable (&info[i])) + { + info[i].codepoint = space; + pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; + } + } + } + else + { + /* Merge clusters and delete default-ignorables. */ + buffer->clear_output (); + buffer->idx = 0; + buffer->next_glyphs (i); + while (buffer->idx < buffer->len) + { + if (!_hb_glyph_info_ligated (&info[buffer->idx]) && + _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) + { + buffer->delete_glyph (); + continue; + } + buffer->next_glyph (); + } + buffer->swap_buffers (); + } +} + + static inline void hb_ot_map_glyphs_fast (hb_buffer_t *buffer) { @@ -656,6 +715,10 @@ hb_ot_position (hb_ot_shape_context_t *c) hb_bool_t fallback = !hb_ot_position_complex (c); + /* Need to do this here, since position_finish and fallback positioning + * might be affected by width of default_ignorables. */ + hb_ot_hide_default_ignorables (c); + hb_ot_layout_position_finish (c->font, c->buffer); if (fallback && c->plan->shaper->fallback_position) @@ -673,66 +736,6 @@ hb_ot_position (hb_ot_shape_context_t *c) } -/* Post-process */ - -static void -hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) -{ - hb_buffer_t *buffer = c->buffer; - - if (buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) - return; - - unsigned int count = buffer->len; - hb_glyph_info_t *info = buffer->info; - hb_glyph_position_t *pos = buffer->pos; - unsigned int i = 0; - for (i = 0; i < count; i++) - { - if (unlikely (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i]))) - break; - } - - /* No default-ignorables found; return. */ - if (i == count) - return; - - hb_codepoint_t space; - if (c->font->get_glyph (' ', 0, &space)) - { - /* Replace default-ignorables with a zero-advance space glyph. */ - for (/*continue*/; i < count; i++) - { - if (!_hb_glyph_info_ligated (&info[i]) && - _hb_glyph_info_is_default_ignorable (&info[i])) - { - info[i].codepoint = space; - pos[i].x_advance = pos[i].y_advance = pos[i].x_offset = pos[i].y_offset = 0; - } - } - } - else - { - /* Merge clusters and delete default-ignorables. */ - buffer->clear_output (); - buffer->idx = 0; - buffer->next_glyphs (i); - while (buffer->idx < buffer->len) - { - if (!_hb_glyph_info_ligated (&info[buffer->idx]) && - _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) - { - buffer->delete_glyph (); - continue; - } - buffer->next_glyph (); - } - buffer->swap_buffers (); - } -} - - /* Pull it all together! */ static void @@ -756,8 +759,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ot_substitute (c); hb_ot_position (c); - hb_ot_hide_default_ignorables (c); - _hb_buffer_deallocate_unicode_vars (c->buffer); c->buffer->props.direction = c->target_direction;