summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2015-09-01 15:07:52 +0100
committerBehdad Esfahbod <behdad@behdad.org>2015-09-01 15:07:52 +0100
commit85846b3de7491b6a07fed6a2c0c6c1b09943b249 (patch)
treefe57cf783794c19c5cdbe9832a310bd07a5a2cde
parentfad2674874591b4a1df822603144c8864f5364c1 (diff)
downloadharfbuzz-85846b3de7491b6a07fed6a2c0c6c1b09943b249.tar.gz
Use insertion-sort instead of bubble-sort
Needed for upcoming merge-clusters fix.
-rw-r--r--src/hb-buffer.cc4
-rw-r--r--src/hb-ot-shape-complex-arabic-fallback.hh6
-rw-r--r--src/hb-ot-shape-complex-indic.cc2
-rw-r--r--src/hb-ot-shape-complex-myanmar.cc2
-rw-r--r--src/hb-ot-shape-normalize.cc6
-rw-r--r--src/hb-private.hh56
6 files changed, 34 insertions, 42 deletions
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 03fe8e13..17093052 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -1636,7 +1636,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
pos[end - 1].x_advance = total_x_advance;
pos[end - 1].y_advance = total_y_advance;
- hb_bubble_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
+ hb_stable_sort (buffer->info + start, end - start - 1, compare_info_codepoint, buffer->pos + start);
} else {
/* Transfer all cluster advance to the first glyph. */
pos[start].x_advance += total_x_advance;
@@ -1645,7 +1645,7 @@ normalize_glyphs_cluster (hb_buffer_t *buffer,
pos[i].x_offset -= total_x_advance;
pos[i].y_offset -= total_y_advance;
}
- hb_bubble_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
+ hb_stable_sort (buffer->info + start + 1, end - start - 1, compare_info_codepoint, buffer->pos + start + 1);
}
}
diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh
index a77f24ec..d97d2852 100644
--- a/src/hb-ot-shape-complex-arabic-fallback.hh
+++ b/src/hb-ot-shape-complex-arabic-fallback.hh
@@ -75,9 +75,9 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
if (!num_glyphs)
return NULL;
- /* Bubble-sort!
+ /* Bubble-sort or something equally good!
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
- hb_bubble_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
+ hb_stable_sort (&glyphs[0], num_glyphs, OT::GlyphID::cmp, &substitutes[0]);
OT::Supplier<OT::GlyphID> glyphs_supplier (glyphs, num_glyphs);
OT::Supplier<OT::GlyphID> substitutes_supplier (substitutes, num_glyphs);
@@ -126,7 +126,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
first_glyphs_indirection[num_first_glyphs] = first_glyph_idx;
num_first_glyphs++;
}
- hb_bubble_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
+ hb_stable_sort (&first_glyphs[0], num_first_glyphs, OT::GlyphID::cmp, &first_glyphs_indirection[0]);
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
for (unsigned int i = 0; i < num_first_glyphs; i++)
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index b7f3d5c6..8b55484a 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -1012,7 +1012,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
info[i].syllable() = i - start;
/* Sit tight, rock 'n roll! */
- hb_bubble_sort (info + start, end - start, compare_indic_order);
+ hb_stable_sort (info + start, end - start, compare_indic_order);
/* Find base again */
base = end;
for (unsigned int i = start; i < end; i++)
diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc
index 7e3ab01d..9afcbf84 100644
--- a/src/hb-ot-shape-complex-myanmar.cc
+++ b/src/hb-ot-shape-complex-myanmar.cc
@@ -393,7 +393,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
buffer->merge_clusters (start, end);
/* Sit tight, rock 'n roll! */
- hb_bubble_sort (info + start, end - start, compare_myanmar_order);
+ hb_stable_sort (info + start, end - start, compare_myanmar_order);
}
static void
diff --git a/src/hb-ot-shape-normalize.cc b/src/hb-ot-shape-normalize.cc
index 111b5908..dff7a746 100644
--- a/src/hb-ot-shape-normalize.cc
+++ b/src/hb-ot-shape-normalize.cc
@@ -344,15 +344,13 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
- /* We are going to do a bubble-sort. Only do this if the
- * sequence is short. Doing it on long sequences can result
- * in an O(n^2) DoS. */
+ /* We are going to do a O(n^2). Only do this if the sequence is short. */
if (end - i > 10) {
i = end;
continue;
}
- hb_bubble_sort (buffer->info + i, end - i, compare_combining_class);
+ hb_stable_sort (buffer->info + i, end - i, compare_combining_class);
i = end;
}
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 81129343..ce92b727 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -855,42 +855,36 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
template <typename T, typename T2> static inline void
-hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *), T2 *array2)
{
- if (unlikely (!len))
- return;
-
- unsigned int k = len - 1;
- do {
- unsigned int new_k = 0;
-
- for (unsigned int j = 0; j < k; j++)
- if (compar (&array[j], &array[j+1]) > 0)
- {
- {
- T t;
- t = array[j];
- array[j] = array[j + 1];
- array[j + 1] = t;
- }
- if (array2)
- {
- T2 t;
- t = array2[j];
- array2[j] = array2[j + 1];
- array2[j + 1] = t;
- }
-
- new_k = j;
- }
- k = new_k;
- } while (k);
+ for (unsigned int i = 1; i < len; i++)
+ {
+ unsigned int j = i;
+ while (j && compar (&array[j - 1], &array[i]) > 0)
+ j--;
+ if (i == j)
+ continue;
+ /* Move item i to occupy place for item j, shift what's in between. */
+ {
+ T t;
+ t = array[i];
+ memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
+ array[j] = t;
+ }
+ if (array2)
+ {
+ T2 t;
+ t = array2[i];
+ memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T2));
+ array2[j] = t;
+ }
+ }
}
template <typename T> static inline void
-hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
{
- hb_bubble_sort (array, len, compar, (int *) NULL);
+ hb_stable_sort (array, len, compar, (int *) NULL);
}
static inline hb_bool_t