Number of failing shape-complex tests goes from 125 down to 94.
Next: Add Ra handling and it's fair to say we kinda support Indic :).
POS_ABOVE,
POS_BELOW,
POS_POST,
-
- POS_INHERIT /* For Halant, Nukta, ZWJ, ZWNJ */
};
/* Categories used in IndicSyllabicCategory.txt from UCD */
}
}
+static int
+compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ int a = pa->indic_position();
+ int b = pb->indic_position();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
static void
found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
*/
+ /* Reorder characters */
+
+ for (i = start; i < base; i++)
+ buffer->info[i].indic_position() = POS_PRE;
+ buffer->info[base].indic_position() = POS_BASE;
+
+ /* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
+ for (i = start + 1; i < end; i++)
+ if ((FLAG (buffer->info[i].indic_category()) &
+ (FLAG (OT_ZWNJ) | FLAG (OT_ZWJ) | FLAG (OT_N) | FLAG (OT_H))))
+ buffer->info[i].indic_position() = buffer->info[i - 1].indic_position();
+
+ /* We do bubble-sort, skip malicious clusters attempts */
+ if (end - start > 20)
+ return;
+
+ /* Sit tight, rock 'n roll! */
+ hb_bubble_sort (buffer->info + start, end - start, compare_indic_order);
+
/* Setup masks now */
/* Pre-base */
decompose_current_glyph (c, FALSE);
}
+static int
+compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
+{
+ unsigned int a = pa->combining_class();
+ unsigned int b = pb->combining_class();
+
+ return a < b ? -1 : a == b ? 0 : +1;
+}
+
void
_hb_ot_shape_normalize (hb_ot_shape_context_t *c)
{
continue;
}
- unsigned int k = end - i - 1;
- do {
- hb_glyph_info_t *pinfo = buffer->info + i;
- unsigned int new_k = 0;
-
- for (unsigned int j = 0; j < k; j++)
- if (pinfo[j].combining_class() > pinfo[j+1].combining_class()) {
- hb_glyph_info_t t;
- t = pinfo[j];
- pinfo[j] = pinfo[j + 1];
- pinfo[j + 1] = t;
-
- new_k = j;
- }
- k = new_k;
- } while (k);
+ hb_bubble_sort (buffer->info + i, end - i, compare_combining_class);
i = end;
}
const char *message) {}
};
-HB_BEGIN_DECLS
-
/* Misc */
-HB_END_DECLS
/* Pre-mature optimization:
* Checks for lo <= u <= hi but with an optimization if lo and hi
return lo <= u && u <= hi;
}
-HB_BEGIN_DECLS
-
-/* Useful for set-operations on small enums */
+/* Useful for set-operations on small enums.
+ * For example, for testing "x ∈ {x1, x2, x3}" use:
+ * (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
+ */
#define FLAG(x) (1<<(x))
+template <typename T> inline void
+hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
+{
+ 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;
+
+ new_k = j;
+ }
+ k = new_k;
+ } while (k);
+}
+
+
+HB_BEGIN_DECLS
+
HB_END_DECLS
#endif /* HB_PRIVATE_HH */