From e995d33c10a4bd9404699d01bddb2b69d811e9ed Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 1 Sep 2015 16:13:32 +0100 Subject: [PATCH] [OT] Merge clusters when reordering marks for normalization Fixes https://bugzilla.gnome.org/show_bug.cgi?id=541608 and cluster test. --- src/hb-buffer-private.hh | 2 ++ src/hb-buffer.cc | 21 +++++++++++++++++++++ src/hb-ot-shape-normalize.cc | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 9aa5e7d7e..7fed7386b 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -201,6 +201,8 @@ struct hb_buffer_t { HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); inline void clear_context (unsigned int side) { context_len[side] = 0; } + + HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)); }; diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index 17093052d..420da8203 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -1678,3 +1678,24 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer) } normalize_glyphs_cluster (buffer, start, end, backward); } + +void +hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *)) +{ + assert (!have_positions); + for (unsigned int i = start + 1; i < end; i++) + { + unsigned int j = i; + while (j > start && compar (&info[j - 1], &info[i]) > 0) + j--; + if (i == j) + continue; + /* Move item i to occupy place for item j, shift what's in between. */ + merge_clusters (j, i + 1); + { + hb_glyph_info_t t = info[i]; + memmove (&info[j + 1], &info[j], (i - j) * sizeof (hb_glyph_info_t)); + info[j] = t; + } + } +} diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc index dff7a7461..a70646132 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc @@ -350,7 +350,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan, continue; } - hb_stable_sort (buffer->info + i, end - i, compare_combining_class); + buffer->sort (i, end, compare_combining_class); i = end; }