[OT] Merge clusters when reordering marks for normalization Fixes https://bugzilla.gnome.org/show_bug.cgi?id=541608 and cluster test.
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index 9aa5e7d..7fed738 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh
@@ -201,6 +201,8 @@ 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 1709305..420da82 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc
@@ -1678,3 +1678,24 @@ } 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 dff7a74..a706461 100644 --- a/src/hb-ot-shape-normalize.cc +++ b/src/hb-ot-shape-normalize.cc
@@ -350,7 +350,7 @@ continue; } - hb_stable_sort (buffer->info + i, end - i, compare_combining_class); + buffer->sort (i, end, compare_combining_class); i = end; }