Do Arabic fallback shaping
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index 89d6b53..991f7cf 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -58,8 +58,6 @@
static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
{
- /* TODO Macroize the magic bit operations */
-
if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
if (likely (j_type != JOINING_TYPE_X))
@@ -82,6 +80,12 @@
JOINING_TYPE_T : JOINING_TYPE_U;
}
+static hb_codepoint_t get_arabic_shape (hb_codepoint_t u, unsigned int shape)
+{
+ if (likely (hb_in_range<hb_codepoint_t> (u, SHAPING_TABLE_FIRST, SHAPING_TABLE_LAST)) && shape < 4)
+ return shaping_table[u - SHAPING_TABLE_FIRST][shape];
+ return u;
+}
static const hb_tag_t arabic_syriac_features[] =
@@ -189,6 +193,15 @@
return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS;
}
+
+static void
+arabic_fallback_shape (hb_buffer_t *buffer)
+{
+ unsigned int count = buffer->len;
+ for (unsigned int i = 0; i < count; i++)
+ buffer->info[i].codepoint = get_arabic_shape (buffer->info[i].codepoint, buffer->info[i].arabic_shaping_action());
+}
+
void
_hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer)
{
@@ -218,12 +231,27 @@
}
hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
+ hb_mask_t total_masks = 0;
unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
- for (unsigned int i = 0; i < num_masks; i++)
+ for (unsigned int i = 0; i < num_masks; i++) {
mask_array[i] = map->get_1_mask (arabic_syriac_features[i]);
+ total_masks |= mask_array[i];
+ }
- for (unsigned int i = 0; i < count; i++)
- buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
+ if (total_masks) {
+ /* Has OpenType tables */
+ for (unsigned int i = 0; i < count; i++)
+ buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
+ } else if (buffer->props.script == HB_SCRIPT_ARABIC) {
+ /* Fallback Arabic shaping to Presentation Forms */
+ /* Pitfalls:
+ * - This path fires if user force-set init/medi/fina/isol off,
+ * - If font does not declare script 'arab', well, what to do?
+ * Most probably it's safe to assume that init/medi/fina/isol
+ * still mean Arabic shaping, although they do not have to.
+ */
+ arabic_fallback_shape (buffer);
+ }
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}