--- old/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc 2019-02-28 12:04:06.982502828 -0800 +++ new/src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-shape-complex-use.cc 2019-02-28 12:04:06.882502830 -0800 @@ -26,8 +26,9 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-use-private.hh" -#include "hb-ot-shape-complex-arabic-private.hh" +#include "hb-ot-shape-complex-use.hh" +#include "hb-ot-shape-complex-arabic.hh" +#include "hb-ot-shape-complex-vowel-constraints.hh" /* buffer var allocations */ #define use_category() complex_var_u8_0() @@ -79,14 +80,22 @@ { /* * Other features. - * These features are applied all at once, after reordering. + * These features are applied all at once, after reordering and + * clearing syllables. */ HB_TAG('a','b','v','s'), HB_TAG('b','l','w','s'), HB_TAG('h','a','l','n'), HB_TAG('p','r','e','s'), HB_TAG('p','s','t','s'), - /* Positioning features, though we don't care about the types. */ +}; +static const hb_tag_t +positioning_features[] = +{ + /* + * Positioning features. + * We don't care about the types. + */ HB_TAG('d','i','s','t'), HB_TAG('a','b','v','m'), HB_TAG('b','l','w','m'), @@ -112,6 +121,10 @@ reorder (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); +static void +clear_syllables (const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer); static void collect_features_use (hb_ot_shape_planner_t *plan) @@ -122,39 +135,42 @@ map->add_gsub_pause (setup_syllables); /* "Default glyph pre-processing group" */ - map->add_global_bool_feature (HB_TAG('l','o','c','l')); - map->add_global_bool_feature (HB_TAG('c','c','m','p')); - map->add_global_bool_feature (HB_TAG('n','u','k','t')); - map->add_global_bool_feature (HB_TAG('a','k','h','n')); + map->enable_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p')); + map->enable_feature (HB_TAG('n','u','k','t')); + map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ); /* "Reordering group" */ map->add_gsub_pause (clear_substitution_flags); - map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ); + map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ); map->add_gsub_pause (record_rphf); map->add_gsub_pause (clear_substitution_flags); - map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ); map->add_gsub_pause (record_pref); /* "Orthographic unit shaping group" */ for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++) - map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (basic_features[i], F_MANUAL_ZWJ); map->add_gsub_pause (reorder); + map->add_gsub_pause (clear_syllables); /* "Topographical features" */ for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++) - map->add_feature (arabic_features[i], 1, F_NONE); + map->add_feature (arabic_features[i]); map->add_gsub_pause (nullptr); - /* "Standard typographic presentation" and "Positional feature application" */ + /* "Standard typographic presentation" */ for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++) - map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ); + map->enable_feature (other_features[i], F_MANUAL_ZWJ); + + /* "Positional feature application" */ + for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++) + map->enable_feature (positioning_features[i]); } struct use_shape_plan_t { - ASSERT_POD (); - hb_mask_t rphf_mask; arabic_shape_plan_t *arabic_plan; @@ -361,7 +377,7 @@ } static void -clear_substitution_flags (const hb_ot_shape_plan_t *plan, +clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { @@ -373,7 +389,7 @@ static void record_rphf (const hb_ot_shape_plan_t *plan, - hb_font_t *font, + hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data; @@ -395,8 +411,8 @@ } static void -record_pref (const hb_ot_shape_plan_t *plan, - hb_font_t *font, +record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, hb_buffer_t *buffer) { hb_glyph_info_t *info = buffer->info; @@ -416,7 +432,8 @@ static inline bool is_halant (const hb_glyph_info_t &info) { - return info.use_category() == USE_H && !_hb_glyph_info_ligated (&info); + return (info.use_category() == USE_H || info.use_category() == USE_HVM) && + !_hb_glyph_info_ligated (&info); } static void @@ -433,19 +450,38 @@ hb_glyph_info_t *info = buffer->info; -#define BASE_FLAGS (FLAG (USE_B) | FLAG (USE_GB)) +#define POST_BASE_FLAGS64 (FLAG64 (USE_FM) | \ + FLAG64 (USE_FAbv) | \ + FLAG64 (USE_FBlw) | \ + FLAG64 (USE_FPst) | \ + FLAG64 (USE_MAbv) | \ + FLAG64 (USE_MBlw) | \ + FLAG64 (USE_MPst) | \ + FLAG64 (USE_MPre) | \ + FLAG64 (USE_VAbv) | \ + FLAG64 (USE_VBlw) | \ + FLAG64 (USE_VPst) | \ + FLAG64 (USE_VPre) | \ + FLAG64 (USE_VMAbv) | \ + FLAG64 (USE_VMBlw) | \ + FLAG64 (USE_VMPst) | \ + FLAG64 (USE_VMPre)) /* Move things forward. */ if (info[start].use_category() == USE_R && end - start > 1) { - /* Got a repha. Reorder it to after first base, before first halant. */ + /* Got a repha. Reorder it towards the end, but before the first post-base + * glyph. */ for (unsigned int i = start + 1; i < end; i++) - if ((FLAG_UNSAFE (info[i].use_category()) & (BASE_FLAGS)) || is_halant (info[i])) + { + bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) || + is_halant (info[i]); + if (is_post_base_glyph || i == end - 1) { - /* If we hit a halant, move before it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ + /* If we hit a post-base glyph, move before it; otherwise move to the + * end. Shift things in between backward. */ - if (is_halant (info[i])) + if (is_post_base_glyph) i--; buffer->merge_clusters (start, i + 1); @@ -455,21 +491,19 @@ break; } + } } /* Move things back. */ - unsigned int j = end; + unsigned int j = start; for (unsigned int i = start; i < end; i++) { uint32_t flag = FLAG_UNSAFE (info[i].use_category()); - if ((flag & (BASE_FLAGS)) || is_halant (info[i])) + if (is_halant (info[i])) { - /* If we hit a halant, move after it; otherwise it's a base: move to it's - * place, and shift things in between backward. */ - if (is_halant (info[i])) - j = i + 1; - else - j = i; + /* If we hit a halant, move after it; otherwise move to the beginning, and + * shift things in between forward. */ + j = i + 1; } else if (((flag) & (FLAG (USE_VPre) | FLAG (USE_VMPre))) && /* Only move the first component of a MultipleSubst. */ @@ -536,7 +570,6 @@ else buffer->next_glyph (); } - buffer->swap_buffers (); } @@ -547,36 +580,30 @@ { insert_dotted_circles (plan, font, buffer); - hb_glyph_info_t *info = buffer->info; - foreach_syllable (buffer, start, end) reorder_syllable (buffer, start, end); - /* Zero syllables now... */ + HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); +} + +static void +clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_font_t *font HB_UNUSED, + hb_buffer_t *buffer) +{ + hb_glyph_info_t *info = buffer->info; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) info[i].syllable() = 0; - - HB_BUFFER_DEALLOCATE_VAR (buffer, use_category); } -static bool -decompose_use (const hb_ot_shape_normalize_context_t *c, - hb_codepoint_t ab, - hb_codepoint_t *a, - hb_codepoint_t *b) -{ - switch (ab) - { - /* Chakma: - * Special case where the Unicode decomp gives matras in the wrong order - * for cluster validation. - */ - case 0x1112Eu : *a = 0x11127u; *b= 0x11131u; return true; - case 0x1112Fu : *a = 0x11127u; *b= 0x11132u; return true; - } - return (bool) c->unicode->decompose (ab, a, b); +static void +preprocess_text_use (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + _hb_preprocess_text_vowel_constraints (plan, buffer, font); } static bool @@ -599,13 +626,13 @@ nullptr, /* override_features */ data_create_use, data_destroy_use, - nullptr, /* preprocess_text */ + preprocess_text_use, nullptr, /* postprocess_glyphs */ HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, - decompose_use, + nullptr, /* decompose */ compose_use, setup_masks_use, - nullptr, /* disable_otl */ + HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */