diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc | 223 |
1 files changed, 121 insertions, 102 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc index fcdc79ee9bb..092633c5ddc 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout.cc @@ -42,6 +42,8 @@ #include "hb-ot-kern-table.hh" #include "hb-ot-name-table.hh" +#include "hb-aat-layout-lcar-table.hh" + /** * SECTION:hb-ot-layout @@ -53,72 +55,29 @@ **/ -static inline const OT::kern& -_get_kern (hb_face_t *face, hb_blob_t **blob = nullptr) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) - { - if (blob) - *blob = hb_blob_get_empty (); - return Null(OT::kern); - } - const OT::kern& kern = *(hb_ot_face_data (face)->kern); - if (blob) - *blob = hb_ot_face_data (face)->kern.get_blob (); - return kern; -} -const OT::GDEF& _get_gdef (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GDEF); - return *hb_ot_face_data (face)->GDEF->table; -} -static hb_blob_t * _get_gsub_blob (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty (); - return hb_ot_face_data (face)->GSUB->blob; -} -static inline const OT::GSUB& _get_gsub (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GSUB); - return *hb_ot_face_data (face)->GSUB->table; -} -const OT::GSUB& _get_gsub_relaxed (hb_face_t *face) -{ - return *hb_ot_face_data (face)->GSUB.get_relaxed ()->table; -} -static hb_blob_t * _get_gpos_blob (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return hb_blob_get_empty (); - return hb_ot_face_data (face)->GPOS->blob; -} -static inline const OT::GPOS& _get_gpos (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::GPOS); - return *hb_ot_face_data (face)->GPOS->table; -} -const OT::GPOS& _get_gpos_relaxed (hb_face_t *face) -{ - return *hb_ot_face_data (face)->GPOS.get_relaxed ()->table; -} - - /* * kern */ -hb_bool_t +bool hb_ot_layout_has_kerning (hb_face_t *face) { - return _get_kern (face).has_data (); + return face->table.kern->has_data (); +} + +bool +hb_ot_layout_has_cross_kerning (hb_face_t *face) +{ + return face->table.kern->has_cross_stream (); } void -hb_ot_layout_kern (hb_ot_shape_plan_t *plan, +hb_ot_layout_kern (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) { - hb_blob_t *blob; - const AAT::kern& kern = _get_kern (font->face, &blob); + hb_blob_t *blob = font->face->table.kern.get_blob (); + const AAT::kern& kern = *blob->as<AAT::kern> (); AAT::hb_aat_apply_context_t c (plan, font, buffer, blob); @@ -232,20 +191,18 @@ _hb_ot_blacklist_gdef (unsigned int gdef_len, return false; } -inline void +void OT::GDEF::accelerator_t::init (hb_face_t *face) { - this->blob = hb_sanitize_context_t().reference_table<GDEF> (face); + this->table = hb_sanitize_context_t().reference_table<GDEF> (face); - if (unlikely (_hb_ot_blacklist_gdef (this->blob->length, - _get_gsub_blob (face)->length, - _get_gpos_blob (face)->length))) + if (unlikely (_hb_ot_blacklist_gdef (this->table.get_length (), + face->table.GSUB->table.get_length (), + face->table.GPOS->table.get_length ()))) { - hb_blob_destroy (this->blob); - this->blob = hb_blob_get_empty (); + hb_blob_destroy (this->table.get_blob ()); + this->table = hb_blob_get_empty (); } - - table = this->blob->as<GDEF> (); } static void @@ -254,7 +211,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, { _hb_buffer_assert_gsubgpos_vars (buffer); - const OT::GDEF &gdef = _get_gdef (font->face); + const OT::GDEF &gdef = *font->face->table.GDEF->table; unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) { @@ -269,7 +226,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, hb_bool_t hb_ot_layout_has_glyph_classes (hb_face_t *face) { - return _get_gdef (face).has_glyph_classes (); + return face->table.GDEF->table->has_glyph_classes (); } /** @@ -281,7 +238,7 @@ hb_ot_layout_glyph_class_t hb_ot_layout_get_glyph_class (hb_face_t *face, hb_codepoint_t glyph) { - return (hb_ot_layout_glyph_class_t) _get_gdef (face).get_glyph_class (glyph); + return (hb_ot_layout_glyph_class_t) face->table.GDEF->table->get_glyph_class (glyph); } /** @@ -294,7 +251,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face, hb_ot_layout_glyph_class_t klass, hb_set_t *glyphs /* OUT */) { - return _get_gdef (face).get_glyphs_in_class (klass, glyphs); + return face->table.GDEF->table->get_glyphs_in_class (klass, glyphs); } unsigned int @@ -304,7 +261,10 @@ hb_ot_layout_get_attach_points (hb_face_t *face, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) { - return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array); + return face->table.GDEF->table->get_attach_points (glyph, + start_offset, + point_count, + point_array); } unsigned int @@ -315,7 +275,15 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) { - return _get_gdef (font->face).get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); + unsigned int result_caret_count = 0; + unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array); + if (result) + { + if (caret_count) *caret_count = result_caret_count; + } + else + result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array); + return result; } @@ -328,8 +296,8 @@ get_gsubgpos_table (hb_face_t *face, hb_tag_t table_tag) { switch (table_tag) { - case HB_OT_TAG_GSUB: return _get_gsub (face); - case HB_OT_TAG_GPOS: return _get_gpos (face); + case HB_OT_TAG_GSUB: return *face->table.GSUB->table; + case HB_OT_TAG_GPOS: return *face->table.GPOS->table; default: return Null(OT::GSUBGPOS); } } @@ -458,7 +426,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, return g.get_feature_tags (start_offset, feature_count, feature_tags); } -hb_bool_t +bool hb_ot_layout_table_find_feature (hb_face_t *face, hb_tag_t table_tag, hb_tag_t feature_tag, @@ -501,7 +469,12 @@ hb_ot_layout_script_find_language (hb_face_t *face, hb_tag_t language_tag, unsigned int *language_index) { - return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index); + return hb_ot_layout_script_select_language (face, + table_tag, + script_index, + 1, + &language_tag, + language_index); } /** @@ -879,8 +852,6 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, hb_set_t *glyphs_after, /* OUT. May be NULL */ hb_set_t *glyphs_output /* OUT. May be NULL */) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return; - OT::hb_collect_glyphs_context_t c (face, glyphs_before, glyphs_input, @@ -891,13 +862,13 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, { case HB_OT_TAG_GSUB: { - const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); l.collect_glyphs (&c); return; } case HB_OT_TAG_GPOS: { - const OT::PosLookup& l = hb_ot_face_data (face)->GPOS->table->get_lookup (lookup_index); + const OT::PosLookup& l = face->table.GPOS->table->get_lookup (lookup_index); l.collect_glyphs (&c); return; } @@ -944,7 +915,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face) { - return _get_gsub (face).has_data (); + return face->table.GSUB->table->has_data (); } /** @@ -959,23 +930,25 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face, unsigned int glyphs_length, hb_bool_t zero_context) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return false; - return hb_ot_layout_lookup_would_substitute_fast (face, lookup_index, glyphs, glyphs_length, zero_context); + return hb_ot_layout_lookup_would_substitute_fast (face, + lookup_index, + glyphs, glyphs_length, + zero_context); } -hb_bool_t +bool hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, unsigned int lookup_index, const hb_codepoint_t *glyphs, unsigned int glyphs_length, - hb_bool_t zero_context) + bool zero_context) { - if (unlikely (lookup_index >= hb_ot_face_data (face)->GSUB->lookup_count)) return false; + if (unlikely (lookup_index >= face->table.GSUB->lookup_count)) return false; OT::hb_would_apply_context_t c (face, glyphs, glyphs_length, (bool) zero_context); - const OT::SubstLookup& l = hb_ot_face_data (face)->GSUB->table->get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); - return l.would_apply (&c, &hb_ot_face_data (face)->GSUB->accels[lookup_index]); + return l.would_apply (&c, &face->table.GSUB->accels[lookup_index]); } void @@ -985,6 +958,56 @@ hb_ot_layout_substitute_start (hb_font_t *font, _hb_ot_layout_set_glyph_props (font, buffer); } +void +hb_ot_layout_delete_glyphs_inplace (hb_buffer_t *buffer, + bool (*filter) (const hb_glyph_info_t *info)) +{ + /* Merge clusters and delete filtered glyphs. + * NOTE! We can't use out-buffer as we have positioning data. */ + unsigned int j = 0; + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + hb_glyph_position_t *pos = buffer->pos; + for (unsigned int i = 0; i < count; i++) + { + if (filter (&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_lookup_substitute_closure: * @@ -998,7 +1021,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face, hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); - const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index); + const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index); l.closure (&c, lookup_index); } @@ -1018,7 +1041,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, { hb_map_t done_lookups; OT::hb_closure_context_t c (face, glyphs, &done_lookups); - const OT::GSUB& gsub = _get_gsub (face); + const OT::GSUB& gsub = *face->table.GSUB->table; unsigned int iteration_count = 0; unsigned int glyphs_length; @@ -1035,9 +1058,8 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, for (unsigned int i = 0; i < gsub.get_lookup_count (); i++) gsub.get_lookup (i).closure (&c, i); } - iteration_count++; - } while (iteration_count <= HB_CLOSURE_MAX_STAGES - && glyphs_length != glyphs->get_population ()); + } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && + glyphs_length != glyphs->get_population ()); } /* @@ -1047,7 +1069,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face) { - return _get_gpos (face).has_data (); + return face->table.GPOS->table->has_data (); } void @@ -1081,7 +1103,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, unsigned int *range_start, /* OUT. May be NULL */ unsigned int *range_end /* OUT. May be NULL */) { - const OT::GPOS &gpos = _get_gpos (face); + const OT::GPOS &gpos = *face->table.GPOS->table; const hb_tag_t tag = HB_TAG ('s','i','z','e'); unsigned int num_features = gpos.get_feature_count (); @@ -1254,8 +1276,8 @@ struct GSUBProxy typedef OT::SubstLookup Lookup; GSUBProxy (hb_face_t *face) : - table (*hb_ot_face_data (face)->GSUB->table), - accels (hb_ot_face_data (face)->GSUB->accels) {} + table (*face->table.GSUB->table), + accels (face->table.GSUB->accels) {} const OT::GSUB &table; const OT::hb_ot_layout_lookup_accelerator_t *accels; @@ -1268,8 +1290,8 @@ struct GPOSProxy typedef OT::PosLookup Lookup; GPOSProxy (hb_face_t *face) : - table (*hb_ot_face_data (face)->GPOS->table), - accels (hb_ot_face_data (face)->GPOS->accels) {} + table (*face->table.GPOS->table), + accels (face->table.GPOS->accels) {} const OT::GPOS &table; const OT::hb_ot_layout_lookup_accelerator_t *accels; @@ -1311,10 +1333,8 @@ apply_backward (OT::hb_ot_apply_context_t *c, if (accel.may_have (buffer->cur().codepoint) && (buffer->cur().mask & c->lookup_mask) && c->check_glyph_property (&buffer->cur(), c->lookup_props)) - { - if (accel.apply (c)) - ret = true; - } + ret |= accel.apply (c); + /* The reverse lookup doesn't "advance" cursor (for good reason). */ buffer->idx--; @@ -1427,8 +1447,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, #if 0 static const OT::BASE& _get_base (hb_face_t *face) { - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::BASE); - return *hb_ot_face_data (face)->BASE; + return *face->table.BASE; } hb_bool_t |