summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc307
1 files changed, 137 insertions, 170 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
index 8c5e38e06dd..ccee8d34300 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-shape.cc
@@ -26,8 +26,6 @@
* Google Author(s): Behdad Esfahbod
*/
-#define HB_SHAPER ot
-#define hb_ot_shape_plan_data_t hb_ot_shape_plan_t
#include "hb-shaper-impl.hh"
#include "hb-ot-shape.hh"
@@ -52,6 +50,11 @@
**/
+static void
+hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features);
+
static bool
_hb_apply_morx (hb_face_t *face)
{
@@ -59,37 +62,41 @@ _hb_apply_morx (hb_face_t *face)
hb_aat_layout_has_substitution (face))
return true;
- return !hb_ot_layout_has_substitution (face) &&
+ /* Ignore empty GSUB tables. */
+ return (!hb_ot_layout_has_substitution (face) ||
+ !hb_ot_layout_table_get_script_tags (face,
+ HB_OT_TAG_GSUB,
+ 0, nullptr, nullptr)) &&
hb_aat_layout_has_substitution (face);
}
-hb_ot_shape_planner_t::hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
- face (master_plan->face_unsafe),
- props (master_plan->props),
- map (face, &props),
- aat_map (face, &props),
+hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face,
+ const hb_segment_properties_t *props) :
+ face (face),
+ props (*props),
+ map (face, props),
+ aat_map (face, props),
apply_morx (_hb_apply_morx (face)),
shaper (apply_morx ?
&_hb_ot_complex_shaper_default :
hb_ot_shape_complex_categorize (this)) {}
void
-hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
- const int *coords,
- unsigned int num_coords)
+hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
+ const hb_ot_shape_plan_key_t &key)
{
plan.props = props;
plan.shaper = shaper;
- map.compile (plan.map, coords, num_coords);
+ map.compile (plan.map, key);
if (apply_morx)
- aat_map.compile (plan.aat_map, coords, num_coords);
+ aat_map.compile (plan.aat_map);
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
- hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (plan.props.direction) ?
+ hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
plan.kern_mask = plan.map.get_mask (kern_tag);
plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
@@ -119,30 +126,91 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
if (hb_options ().aat && hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
- else if (!disable_gpos && hb_ot_layout_has_positioning (face))
+ else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
plan.apply_gpos = true;
else if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
- if (plan.requested_kerning && !plan.apply_kerx && !has_gpos_kern)
+ if (!plan.apply_kerx && !has_gpos_kern)
{
/* Apparently Apple applies kerx if GPOS kern was not applied. */
if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
- if (hb_ot_layout_has_kerning (face))
+ else if (hb_ot_layout_has_kerning (face))
plan.apply_kern = true;
- else
- plan.fallback_kerning = true;
}
+ bool has_kern_mark = plan.apply_kern && hb_ot_layout_has_cross_kerning (face);
+ plan.zero_marks = !plan.apply_morx && !plan.apply_kerx && !has_kern_mark;
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
- if (!plan.apply_gpos && !plan.apply_kerx)
- plan.fallback_mark_positioning = true;
+ plan.fallback_mark_positioning = !plan.apply_gpos && plan.zero_marks;
/* Currently we always apply trak. */
plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
}
+bool
+hb_ot_shape_plan_t::init0 (hb_face_t *face,
+ const hb_shape_plan_key_t *key)
+{
+ map.init ();
+ aat_map.init ();
+
+ hb_ot_shape_planner_t planner (face,
+ &key->props);
+ hb_ot_shape_collect_features (&planner,
+ key->user_features,
+ key->num_user_features);
+
+ planner.compile (*this, key->ot);
+
+ if (shaper->data_create)
+ {
+ data = shaper->data_create (this);
+ if (unlikely (!data))
+ return false;
+ }
+
+ return true;
+}
+
+void
+hb_ot_shape_plan_t::fini (void)
+{
+ if (shaper->data_destroy)
+ shaper->data_destroy (const_cast<void *> (data));
+
+ map.fini ();
+ aat_map.fini ();
+}
+
+void
+hb_ot_shape_plan_t::substitute (hb_font_t *font,
+ hb_buffer_t *buffer) const
+{
+ if (unlikely (apply_morx))
+ hb_aat_layout_substitute (this, font, buffer);
+ else
+ map.substitute (this, font, buffer);
+}
+
+void
+hb_ot_shape_plan_t::position (hb_font_t *font,
+ hb_buffer_t *buffer) const
+{
+ if (this->apply_gpos)
+ map.position (this, font, buffer);
+ else if (this->apply_kerx)
+ hb_aat_layout_position (this, font, buffer);
+ else if (this->apply_kern)
+ hb_ot_layout_kern (this, font, buffer);
+ else
+ _hb_ot_shape_fallback_kern (this, font, buffer);
+
+ if (this->apply_trak)
+ hb_aat_layout_track (this, font, buffer);
+}
+
static const hb_ot_map_feature_t
common_features[] =
@@ -168,7 +236,6 @@ horizontal_features[] =
static void
hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
- const hb_segment_properties_t *props,
const hb_feature_t *user_features,
unsigned int num_user_features)
{
@@ -177,7 +244,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
map->enable_feature (HB_TAG('r','v','r','n'));
map->add_gsub_pause (nullptr);
- switch (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'));
@@ -216,7 +283,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
map->add_feature (common_features[i]);
- if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
+ if (HB_DIRECTION_IS_HORIZONTAL (planner->props.direction))
for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
map->add_feature (horizontal_features[i]);
else
@@ -256,18 +323,17 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
* shaper face data
*/
-HB_SHAPER_DATA_ENSURE_DEFINE(ot, face)
+struct hb_ot_face_data_t {};
hb_ot_face_data_t *
_hb_ot_shaper_face_data_create (hb_face_t *face)
{
- return _hb_ot_face_data_create (face);
+ return (hb_ot_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
}
void
_hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
{
- _hb_ot_face_data_destroy (data);
}
@@ -275,8 +341,6 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
* shaper font data
*/
-HB_SHAPER_DATA_ENSURE_DEFINE(ot, font)
-
struct hb_ot_font_data_t {};
hb_ot_font_data_t *
@@ -292,54 +356,6 @@ _hb_ot_shaper_font_data_destroy (hb_ot_font_data_t *data HB_UNUSED)
/*
- * shaper shape_plan data
- */
-
-hb_ot_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,
- 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))
- return nullptr;
-
- plan->init ();
-
- hb_ot_shape_planner_t planner (shape_plan);
-
- hb_ot_shape_collect_features (&planner, &shape_plan->props,
- user_features, num_user_features);
-
- planner.compile (*plan, coords, num_coords);
-
- if (plan->shaper->data_create) {
- plan->data = plan->shaper->data_create (plan);
- if (unlikely (!plan->data))
- {
- free (plan);
- return nullptr;
- }
- }
-
- return plan;
-}
-
-void
-_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shape_plan_data_t *plan)
-{
- if (plan->shaper->data_destroy)
- plan->shaper->data_destroy (const_cast<void *> (plan->data));
-
- plan->fini ();
-
- free (plan);
-}
-
-
-/*
* shaper
*/
@@ -476,7 +492,9 @@ hb_ensure_native_direction (hb_buffer_t *buffer)
}
-/* Substitute */
+/*
+ * Substitute
+ */
static inline void
hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
@@ -582,10 +600,8 @@ hb_ot_shape_setup_masks (const hb_ot_shape_context_t *c)
}
static void
-hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
+hb_ot_zero_width_default_ignorables (const hb_buffer_t *buffer)
{
- hb_buffer_t *buffer = c->buffer;
-
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES))
@@ -601,21 +617,19 @@ hb_ot_zero_width_default_ignorables (const hb_ot_shape_context_t *c)
}
static void
-hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (hb_buffer_t *buffer,
+ hb_font_t *font)
{
- hb_buffer_t *buffer = c->buffer;
-
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
return;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
- hb_glyph_position_t *pos = buffer->pos;
- hb_codepoint_t invisible = c->buffer->invisible;
+ hb_codepoint_t invisible = buffer->invisible;
if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
- (invisible || c->font->get_nominal_glyph (' ', &invisible)))
+ (invisible || font->get_nominal_glyph (' ', &invisible)))
{
/* Replace default-ignorables with a zero-advance invisible glyph. */
for (unsigned int i = 0; i < count; i++)
@@ -625,49 +639,7 @@ hb_ot_hide_default_ignorables (const hb_ot_shape_context_t *c)
}
}
else
- {
- /* Merge clusters and delete default-ignorables.
- * NOTE! We can't use out-buffer as we have positioning data. */
- unsigned int j = 0;
- for (unsigned int i = 0; i < count; i++)
- {
- if (_hb_glyph_info_is_default_ignorable (&info[i]))
- {
- /* Merge clusters.
- * Same logic as buffer->delete_glyph(), but for in-place removal. */
-
- unsigned int cluster = info[i].cluster;
- if (i + 1 < count && cluster == info[i + 1].cluster)
- continue; /* Cluster survives; do nothing. */
-
- if (j)
- {
- /* Merge cluster backward. */
- if (cluster < info[j - 1].cluster)
- {
- unsigned int mask = info[i].mask;
- unsigned int old_cluster = info[j - 1].cluster;
- for (unsigned k = j; k && info[k - 1].cluster == old_cluster; k--)
- buffer->set_cluster (info[k - 1], cluster, mask);
- }
- continue;
- }
-
- if (i + 1 < count)
- buffer->merge_clusters (i, i + 2); /* Merge cluster forward. */
-
- continue;
- }
-
- if (j != i)
- {
- info[j] = info[i];
- pos[j] = pos[i];
- }
- j++;
- }
- buffer->len = j;
- }
+ hb_ot_layout_delete_glyphs_inplace (buffer, _hb_glyph_info_is_default_ignorable);
}
@@ -684,10 +656,10 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
}
static inline void
-hb_synthesize_glyph_classes (const hb_ot_shape_context_t *c)
+hb_synthesize_glyph_classes (hb_buffer_t *buffer)
{
- unsigned int count = c->buffer->len;
- hb_glyph_info_t *info = c->buffer->info;
+ unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
{
hb_ot_layout_glyph_props_flags_t klass;
@@ -739,16 +711,13 @@ hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
hb_ot_layout_substitute_start (c->font, buffer);
if (c->plan->fallback_glyph_classes)
- hb_synthesize_glyph_classes (c);
+ hb_synthesize_glyph_classes (c->buffer);
- if (unlikely (c->plan->apply_morx))
- hb_aat_layout_substitute (c->plan, c->font, c->buffer);
- else
- c->plan->substitute (c->font, buffer);
+ c->plan->substitute (c->font, buffer);
}
static inline void
-hb_ot_substitute (const hb_ot_shape_context_t *c)
+hb_ot_substitute_pre (const hb_ot_shape_context_t *c)
{
hb_ot_substitute_default (c);
@@ -757,7 +726,21 @@ hb_ot_substitute (const hb_ot_shape_context_t *c)
hb_ot_substitute_complex (c);
}
-/* Position */
+static inline void
+hb_ot_substitute_post (const hb_ot_shape_context_t *c)
+{
+ hb_ot_hide_default_ignorables (c->buffer, c->font);
+ if (c->plan->apply_morx)
+ hb_aat_layout_remove_deleted_glyphs (c->buffer);
+
+ if (c->plan->shaper->postprocess_glyphs)
+ c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
+}
+
+
+/*
+ * Position
+ */
static inline void
adjust_mark_offsets (hb_glyph_position_t *pos)
@@ -852,7 +835,7 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
hb_ot_layout_position_start (c->font, c->buffer);
- if (!c->plan->apply_kerx)
+ if (c->plan->zero_marks)
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY:
@@ -865,15 +848,9 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
break;
}
- if (c->plan->apply_gpos)
- c->plan->position (c->font, c->buffer);
- else if (c->plan->apply_kerx)
- hb_aat_layout_position (c->plan, c->font, c->buffer);
-
- if (c->plan->apply_trak)
- hb_aat_layout_track (c->plan, c->font, c->buffer);
+ c->plan->position (c->font, c->buffer);
- if (!c->plan->apply_kerx)
+ if (c->plan->zero_marks)
switch (c->plan->shaper->zero_width_marks)
{
case HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE:
@@ -886,9 +863,11 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
break;
}
- /* Finishing off GPOS has to follow a certain order. */
+ /* Finish off. Has to follow a certain order. */
hb_ot_layout_position_finish_advances (c->font, c->buffer);
- hb_ot_zero_width_default_ignorables (c);
+ hb_ot_zero_width_default_ignorables (c->buffer);
+ if (c->plan->apply_morx)
+ hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
hb_ot_layout_position_finish_offsets (c->font, c->buffer);
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
@@ -897,6 +876,9 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
c->font->subtract_glyph_h_origin (info[i].codepoint,
&pos[i].x_offset,
&pos[i].y_offset);
+
+ if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
+ _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
}
static inline void
@@ -908,19 +890,9 @@ hb_ot_position (const hb_ot_shape_context_t *c)
hb_ot_position_complex (c);
- if (c->plan->fallback_mark_positioning && c->plan->shaper->fallback_position)
- _hb_ot_shape_fallback_mark_position (c->plan, c->font, c->buffer);
-
if (HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction))
hb_buffer_reverse (c->buffer);
- /* Visual fallback goes here. */
-
- if (c->plan->apply_kern)
- hb_ot_layout_kern (c->plan, c->font, c->buffer);
- else if (c->plan->fallback_kerning)
- _hb_ot_shape_fallback_kern (c->plan, c->font, c->buffer);
-
_hb_buffer_deallocate_gsubgpos_vars (c->buffer);
}
@@ -986,13 +958,9 @@ hb_ot_shape_internal (hb_ot_shape_context_t *c)
if (c->plan->shaper->preprocess_text)
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
- hb_ot_substitute (c);
+ hb_ot_substitute_pre (c);
hb_ot_position (c);
-
- hb_ot_hide_default_ignorables (c);
-
- if (c->plan->shaper->postprocess_glyphs)
- c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
+ hb_ot_substitute_post (c);
hb_propagate_flags (c->buffer);
@@ -1013,7 +981,7 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
+ hb_ot_shape_context_t c = {&shape_plan->ot, font, font->face, buffer, features, num_features};
hb_ot_shape_internal (&c);
return true;
@@ -1030,8 +998,7 @@ hb_ot_shape_plan_collect_lookups (hb_shape_plan_t *shape_plan,
hb_tag_t table_tag,
hb_set_t *lookup_indexes /* OUT */)
{
- /* XXX Does the first part always succeed? */
- HB_SHAPER_DATA_GET (shape_plan)->collect_lookups (table_tag, lookup_indexes);
+ shape_plan->ot.collect_lookups (table_tag, lookup_indexes);
}