| Index: third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| diff --git a/third_party/harfbuzz-ng/src/hb-ot-shape.cc b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| index 7811cb7f8e891834e161250ac8f21160aeebad44..ddd6662e8454be782dd282087ac59fd95204d9e0 100644
|
| --- a/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| +++ b/third_party/harfbuzz-ng/src/hb-ot-shape.cc
|
| @@ -69,6 +69,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
| {
|
| hb_ot_map_builder_t *map = &planner->map;
|
|
|
| + map->add_global_bool_feature (HB_TAG('r','v','r','n'));
|
| + map->add_gsub_pause (NULL);
|
| +
|
| switch (props->direction) {
|
| case HB_DIRECTION_LTR:
|
| map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
|
| @@ -163,7 +166,9 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
|
| hb_ot_shaper_shape_plan_data_t *
|
| _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
| const hb_feature_t *user_features,
|
| - unsigned int num_user_features)
|
| + unsigned int num_user_features,
|
| + const int *coords,
|
| + unsigned int num_coords)
|
| {
|
| hb_ot_shape_plan_t *plan = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
|
| if (unlikely (!plan))
|
| @@ -173,9 +178,10 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
|
|
|
| planner.shaper = hb_ot_shape_complex_categorize (&planner);
|
|
|
| - hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
|
| + hb_ot_shape_collect_features (&planner, &shape_plan->props,
|
| + user_features, num_user_features);
|
|
|
| - planner.compile (*plan);
|
| + planner.compile (*plan, coords, num_coords);
|
|
|
| if (plan->shaper->data_create) {
|
| plan->data = plan->shaper->data_create (plan);
|
| @@ -212,6 +218,8 @@ struct hb_ot_shape_context_t
|
| unsigned int num_user_features;
|
|
|
| /* Transient stuff */
|
| + bool fallback_positioning;
|
| + bool fallback_glyph_classes;
|
| hb_direction_t target_direction;
|
| };
|
|
|
| @@ -524,6 +532,32 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
|
| }
|
|
|
| static inline void
|
| +hb_synthesize_glyph_classes (hb_ot_shape_context_t *c)
|
| +{
|
| + unsigned int count = c->buffer->len;
|
| + hb_glyph_info_t *info = c->buffer->info;
|
| + for (unsigned int i = 0; i < count; i++)
|
| + {
|
| + hb_ot_layout_glyph_props_flags_t klass;
|
| +
|
| + /* Never mark default-ignorables as marks.
|
| + * They won't get in the way of lookups anyway,
|
| + * but having them as mark will cause them to be skipped
|
| + * over if the lookup-flag says so, but at least for the
|
| + * Mongolian variation selectors, looks like Uniscribe
|
| + * marks them as non-mark. Some Mongolian fonts without
|
| + * GDEF rely on this. Another notable character that
|
| + * this applies to is COMBINING GRAPHEME JOINER. */
|
| + klass = (_hb_glyph_info_get_general_category (&info[i]) !=
|
| + HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK ||
|
| + _hb_glyph_info_is_default_ignorable (&info[i])) ?
|
| + HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH :
|
| + HB_OT_LAYOUT_GLYPH_PROPS_MARK;
|
| + _hb_glyph_info_set_glyph_props (&info[i], klass);
|
| + }
|
| +}
|
| +
|
| +static inline void
|
| hb_ot_substitute_default (hb_ot_shape_context_t *c)
|
| {
|
| hb_buffer_t *buffer = c->buffer;
|
| @@ -539,7 +573,7 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c)
|
| hb_ot_shape_setup_masks (c);
|
|
|
| /* This is unfortunate to go here, but necessary... */
|
| - if (!hb_ot_layout_has_positioning (c->face))
|
| + if (c->fallback_positioning)
|
| _hb_ot_shape_fallback_position_recategorize_marks (c->plan, c->font, buffer);
|
|
|
| hb_ot_map_glyphs_fast (buffer);
|
| @@ -554,6 +588,9 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
|
|
|
| hb_ot_layout_substitute_start (c->font, buffer);
|
|
|
| + if (!hb_ot_layout_has_glyph_classes (c->face))
|
| + hb_synthesize_glyph_classes (c);
|
| +
|
| c->plan->substitute (c->font, buffer);
|
|
|
| return;
|
| @@ -632,14 +669,12 @@ hb_ot_position_default (hb_ot_shape_context_t *c)
|
| _hb_ot_shape_fallback_spaces (c->plan, c->font, c->buffer);
|
| }
|
|
|
| -static inline bool
|
| +static inline void
|
| hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| {
|
| hb_ot_layout_position_start (c->font, c->buffer);
|
|
|
| - bool ret = false;
|
| unsigned int count = c->buffer->len;
|
| - bool has_positioning = (bool) hb_ot_layout_has_positioning (c->face);
|
|
|
| /* If the font has no GPOS, AND, no fallback positioning will
|
| * happen, AND, direction is forward, then when zeroing mark
|
| @@ -650,8 +685,9 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| * If fallback positinoing happens or GPOS is present, we don't
|
| * care.
|
| */
|
| - bool adjust_offsets_when_zeroing = !(has_positioning || c->plan->shaper->fallback_position ||
|
| - HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction));
|
| + bool adjust_offsets_when_zeroing = c->fallback_positioning &&
|
| + !c->plan->shaper->fallback_position &&
|
| + HB_DIRECTION_IS_FORWARD (c->buffer->props.direction);
|
|
|
| switch (c->plan->shaper->zero_width_marks)
|
| {
|
| @@ -665,7 +701,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| break;
|
| }
|
|
|
| - if (has_positioning)
|
| + if (likely (!c->fallback_positioning))
|
| {
|
| hb_glyph_info_t *info = c->buffer->info;
|
| hb_glyph_position_t *pos = c->buffer->pos;
|
| @@ -688,7 +724,6 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| &pos[i].x_offset,
|
| &pos[i].y_offset);
|
|
|
| - ret = true;
|
| }
|
|
|
| switch (c->plan->shaper->zero_width_marks)
|
| @@ -707,8 +742,6 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
|
| hb_ot_layout_position_finish_advances (c->font, c->buffer);
|
| hb_ot_zero_width_default_ignorables (c);
|
| hb_ot_layout_position_finish_offsets (c->font, c->buffer);
|
| -
|
| - return ret;
|
| }
|
|
|
| static inline void
|
| @@ -718,9 +751,9 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
|
|
| hb_ot_position_default (c);
|
|
|
| - hb_bool_t fallback = !hb_ot_position_complex (c);
|
| + hb_ot_position_complex (c);
|
|
|
| - if (fallback && c->plan->shaper->fallback_position)
|
| + if (c->fallback_positioning && c->plan->shaper->fallback_position)
|
| _hb_ot_shape_fallback_position (c->plan, c->font, c->buffer);
|
|
|
| if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
|
| @@ -728,7 +761,7 @@ hb_ot_position (hb_ot_shape_context_t *c)
|
|
|
| /* Visual fallback goes here. */
|
|
|
| - if (fallback)
|
| + if (c->fallback_positioning)
|
| _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
|
|
|
| _hb_buffer_deallocate_gsubgpos_vars (c->buffer);
|
| @@ -748,6 +781,11 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
|
| (unsigned) HB_BUFFER_MAX_LEN_MIN);
|
| }
|
|
|
| + bool disable_otl = c->plan->shaper->disable_otl && c->plan->shaper->disable_otl (c->plan);
|
| + //c->fallback_substitute = disable_otl || !hb_ot_layout_has_substitution (c->face);
|
| + c->fallback_positioning = disable_otl || !hb_ot_layout_has_positioning (c->face);
|
| + c->fallback_glyph_classes = disable_otl || !hb_ot_layout_has_glyph_classes (c->face);
|
| +
|
| /* Save the original direction, we use it later. */
|
| c->target_direction = c->buffer->props.direction;
|
|
|
|
|