[Indic] Find syllables before any features are applied
With FreeSerif, it seems that the 'ccmp' feature does ligature
substituttions. That was then causing syllable match failures. We now
find syllables before any features have been applied.
Test sequence: U+0D9A,U+0DCA,U+200D,U+0DBB,U+0DCF
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 7f6b79a..6a87c1e 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -203,6 +203,10 @@
};
static void
+setup_syllables (const hb_ot_shape_plan_t *plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer);
+static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@@ -216,6 +220,9 @@
{
hb_ot_map_builder_t *map = &plan->map;
+ /* Do this before any lookups have been applied. */
+ map->add_gsub_pause (setup_syllables);
+
map->add_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
@@ -349,6 +356,17 @@
}
+enum syllable_type_t {
+ consonant_syllable,
+ vowel_syllable,
+ standalone_cluster,
+ broken_cluster,
+ non_indic_cluster,
+};
+
+#include "hb-ot-shape-complex-indic-machine.hh"
+
+
static void
setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
@@ -365,6 +383,14 @@
set_indic_properties (buffer->info[i]);
}
+static void
+setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
+ hb_font_t *font HB_UNUSED,
+ hb_buffer_t *buffer)
+{
+ find_syllables (buffer);
+}
+
static int
compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
{
@@ -788,16 +814,6 @@
}
-enum syllable_type_t {
- consonant_syllable,
- vowel_syllable,
- standalone_cluster,
- broken_cluster,
- non_indic_cluster,
-};
-
-#include "hb-ot-shape-complex-indic-machine.hh"
-
static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
@@ -813,11 +829,23 @@
}
}
-static void
+static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
+ /* Note: This loop is extra overhead, but should not be measurable. */
+ bool has_broken_syllables = false;
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ if ((buffer->info[i].syllable() & 0x0F) == broken_cluster) {
+ has_broken_syllables = true;
+ break;
+ }
+ if (likely (!has_broken_syllables))
+ return;
+
+
hb_codepoint_t dottedcircle_glyph;
if (!font->get_glyph (0x25CC, 0, &dottedcircle_glyph))
return;
@@ -856,11 +884,7 @@
hb_buffer_t *buffer)
{
update_consonant_positions (plan, font, buffer);
-
- bool had_broken_clusters = false;
- find_syllables (plan, buffer, &had_broken_clusters);
- if (unlikely (had_broken_clusters))
- insert_dotted_circles (plan, font, buffer);
+ insert_dotted_circles (plan, font, buffer);
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;