From: Behdad Esfahbod Date: Fri, 19 Jun 2015 20:31:49 +0000 (-0700) Subject: When removing default-ignorables, merge clusters X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f13bbd9d4b0970851626e2ce3cf4ecb3cfde801;p=platform%2Fupstream%2FlibHarfBuzzSharp.git When removing default-ignorables, merge clusters Fixes test-shape, and: https://code.google.com/p/chromium/issues/detail?id=497578 --- diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 6a33962..ced748f 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -192,6 +192,8 @@ struct hb_buffer_t { unsigned int end); HB_INTERNAL void merge_out_clusters (unsigned int start, unsigned int end); + /* Merge clusters for deleting current glyph, and skip it. */ + HB_INTERNAL void delete_glyph (void); /* Internal methods */ HB_INTERNAL bool enlarge (unsigned int size); diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index e13ee4a..4f953f0 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -529,7 +529,7 @@ hb_buffer_t::merge_clusters (unsigned int start, /* If we hit the start of buffer, continue in out-buffer. */ if (idx == start) - for (unsigned i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) + for (unsigned int i = out_len; i && out_info[i - 1].cluster == info[start].cluster; i--) out_info[i - 1].cluster = cluster; for (unsigned int i = start; i < end; i++) @@ -561,12 +561,44 @@ hb_buffer_t::merge_out_clusters (unsigned int start, /* If we hit the end of out-buffer, continue in buffer. */ if (end == out_len) - for (unsigned i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) + for (unsigned int i = idx; i < len && info[i].cluster == out_info[end - 1].cluster; i++) info[i].cluster = cluster; for (unsigned int i = start; i < end; i++) out_info[i].cluster = cluster; } +void +hb_buffer_t::delete_glyph () +{ + unsigned int cluster = info[idx].cluster; + if (idx + 1 < len && cluster == info[idx + 1].cluster) + { + /* Cluster survives; do nothing. */ + goto done; + } + + if (out_len) + { + /* Merge cluster backward. */ + if (cluster < out_info[out_len - 1].cluster) + { + unsigned int old_cluster = out_info[out_len - 1].cluster; + for (unsigned i = out_len; i && out_info[i - 1].cluster == old_cluster; i--) + out_info[i - 1].cluster = cluster; + } + goto done; + } + + if (idx + 1 < len) + { + /* Merge cluster forward. */ + merge_clusters (idx, idx + 2); + goto done; + } + +done: + skip_glyph (); +} void hb_buffer_t::guess_segment_properties (void) diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 5688604..a531d77 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -692,7 +692,7 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c) if (!_hb_glyph_info_ligated (&info[buffer->idx]) && _hb_glyph_info_is_default_ignorable (&info[buffer->idx])) { - buffer->skip_glyph (); + buffer->delete_glyph (); continue; } buffer->next_glyph ();