diff options
Diffstat (limited to 'thirdparty/harfbuzz/src/hb-ot-shape.cc')
-rw-r--r-- | thirdparty/harfbuzz/src/hb-ot-shape.cc | 92 |
1 files changed, 74 insertions, 18 deletions
diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 7d90558458..0e215c24f7 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -149,13 +149,17 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, * Decide who does positioning. GPOS, kerx, kern, or fallback. */ - if (0) +#ifndef HB_NO_AAT_SHAPE + bool has_gsub = hb_ot_layout_has_substitution (face); +#endif + bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); + if (false) ; #ifndef HB_NO_AAT_SHAPE - else if (hb_aat_layout_has_positioning (face)) + else if (hb_aat_layout_has_positioning (face) && !(has_gsub && has_gpos)) plan.apply_kerx = true; #endif - else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face)) + else if (!apply_morx && has_gpos) plan.apply_gpos = true; if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) @@ -172,6 +176,8 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, #endif } + plan.apply_fallback_kern = !(plan.apply_gpos || plan.apply_kerx || plan.apply_kern); + plan.zero_marks = script_zero_marks && !plan.apply_kerx && (!plan.apply_kern @@ -193,6 +199,12 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan, script_fallback_mark_positioning; #ifndef HB_NO_AAT_SHAPE + /* If we're using morx shaping, we cancel mark position adjustment because + Apple Color Emoji assumes this will NOT be done when forming emoji sequences; + https://github.com/harfbuzz/harfbuzz/issues/2967. */ + if (plan.apply_morx) + plan.adjust_mark_positioning_when_zeroing = false; + /* Currently we always apply trak. */ plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face); #endif @@ -266,11 +278,12 @@ hb_ot_shape_plan_t::position (hb_font_t *font, else if (this->apply_kerx) hb_aat_layout_position (this, font, buffer); #endif + #ifndef HB_NO_OT_KERN - else if (this->apply_kern) + if (this->apply_kern) hb_ot_layout_kern (this, font, buffer); #endif - else + else if (this->apply_fallback_kern) _hb_ot_shape_fallback_kern (this, font, buffer); #ifndef HB_NO_AAT_SHAPE @@ -306,16 +319,17 @@ horizontal_features[] = }; static void -hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, - const hb_feature_t *user_features, - unsigned int num_user_features) +hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, + const hb_feature_t *user_features, + unsigned int num_user_features) { hb_ot_map_builder_t *map = &planner->map; map->enable_feature (HB_TAG('r','v','r','n')); map->add_gsub_pause (nullptr); - switch (planner->props.direction) { + switch (planner->props.direction) + { case HB_DIRECTION_LTR: map->enable_feature (HB_TAG ('l','t','r','a')); map->enable_feature (HB_TAG ('l','t','r','m')); @@ -348,12 +362,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK); #endif - map->enable_feature (HB_TAG ('H','A','R','F')); + map->enable_feature (HB_TAG ('H','a','r','f')); /* Considered required. */ + map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */ if (planner->shaper->collect_features) planner->shaper->collect_features (planner); - map->enable_feature (HB_TAG ('B','U','Z','Z')); + map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */ + map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */ for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++) map->add_feature (common_features[i]); @@ -363,6 +379,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, map->add_feature (horizontal_features[i]); else { + /* We only apply `vert` feature. See: + * https://github.com/harfbuzz/harfbuzz/commit/d71c0df2d17f4590d5611239577a6cb532c26528 + * https://lists.freedesktop.org/archives/harfbuzz/2013-August/003490.html */ + /* We really want to find a 'vert' feature if there's any in the font, no * matter which script/langsys it is listed (or not) under. * See various bugs referenced from: @@ -478,6 +498,14 @@ hb_set_unicode_props (hb_buffer_t *buffer) if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL && hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu))) { + _hb_glyph_info_set_continuation (&info[i]); + } + /* Regional_Indicators are hairy as hell... + * https://github.com/harfbuzz/harfbuzz/issues/2265 */ + else if (unlikely (i && hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F1E6u, 0x1F1FFu))) + { + if (hb_in_range<hb_codepoint_t> (info[i - 1].codepoint, 0x1F1E6u, 0x1F1FFu) && + !_hb_glyph_info_is_continuation (&info[i - 1])) _hb_glyph_info_set_continuation (&info[i]); } #ifndef HB_NO_EMOJI_SEQUENCES @@ -534,9 +562,8 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font) hb_glyph_info_t info = dottedcircle; info.cluster = buffer->cur().cluster; info.mask = buffer->cur().mask; - buffer->output_info (info); - while (buffer->idx < buffer->len && buffer->successful) - buffer->next_glyph (); + (void) buffer->output_info (info); + buffer->swap_buffers (); } @@ -560,6 +587,36 @@ hb_ensure_native_direction (hb_buffer_t *buffer) hb_direction_t direction = buffer->props.direction; hb_direction_t horiz_dir = hb_script_get_horizontal_direction (buffer->props.script); + /* Numeric runs in natively-RTL scripts are actually native-LTR, so we reset + * the horiz_dir if the run contains at least one decimal-number char, and no + * letter chars (ideally we should be checking for chars with strong + * directionality but hb-unicode currently lacks bidi categories). + * + * This allows digit sequences in Arabic etc to be shaped in "native" + * direction, so that features like ligatures will work as intended. + * + * https://github.com/harfbuzz/harfbuzz/issues/501 + */ + if (unlikely (horiz_dir == HB_DIRECTION_RTL && direction == HB_DIRECTION_LTR)) + { + bool found_number = false, found_letter = false; + const auto* info = buffer->info; + const auto count = buffer->len; + for (unsigned i = 0; i < count; i++) + { + auto gc = _hb_glyph_info_get_general_category (&info[i]); + if (gc == HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + found_number = true; + else if (HB_UNICODE_GENERAL_CATEGORY_IS_LETTER (gc)) + { + found_letter = true; + break; + } + } + if (found_number && !found_letter) + horiz_dir = HB_DIRECTION_LTR; + } + /* TODO vertical: * The only BTT vertical script is Ogham, but it's not clear to me whether OpenType * Ogham fonts are supposed to be implemented BTT or not. Need to research that @@ -1113,8 +1170,6 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) _hb_buffer_allocate_unicode_vars (c->buffer); - c->buffer->clear_output (); - hb_ot_shape_initialize_masks (c); hb_set_unicode_props (c->buffer); hb_insert_dotted_circle (c->buffer, c->font); @@ -1124,7 +1179,8 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c) hb_ensure_native_direction (c->buffer); if (c->plan->shaper->preprocess_text && - c->buffer->message(c->font, "start preprocess-text")) { + c->buffer->message(c->font, "start preprocess-text")) + { c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); (void) c->buffer->message(c->font, "end preprocess-text"); } @@ -1166,7 +1222,7 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan, * @lookup_indexes: (out): The #hb_set_t set of lookups returned * * Computes the complete set of GSUB or GPOS lookups that are applicable - * under a given @shape_plan. + * under a given @shape_plan. * * Since: 0.9.7 **/ |