You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-20 14:45:44 +00:00
HarfBuzz: Update to version 3.0.0
This commit is contained in:
186
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
186
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
@@ -131,7 +131,9 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
|
||||
|
||||
AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
|
||||
|
||||
if (!buffer->message (font, "start table kern")) return;
|
||||
kern.apply (&c);
|
||||
(void) buffer->message (font, "end table kern");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -144,7 +146,7 @@ bool
|
||||
OT::GDEF::is_blocklisted (hb_blob_t *blob,
|
||||
hb_face_t *face) const
|
||||
{
|
||||
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
|
||||
#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
|
||||
return false;
|
||||
#endif
|
||||
/* The ugly business of blocklisting individual fonts' tables happen here!
|
||||
@@ -331,6 +333,8 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
|
||||
*
|
||||
* Useful if the client program wishes to cache the list.
|
||||
*
|
||||
* Return value: Total number of attachment points for @glyph.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
@@ -357,6 +361,8 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
|
||||
* Fetches a list of the caret positions defined for a ligature glyph in the GDEF
|
||||
* table of the font. The list returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of ligature caret positions for @glyph.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_get_ligature_carets (hb_font_t *font,
|
||||
@@ -379,7 +385,7 @@ bool
|
||||
OT::GSUB::is_blocklisted (hb_blob_t *blob HB_UNUSED,
|
||||
hb_face_t *face) const
|
||||
{
|
||||
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
|
||||
#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
@@ -389,7 +395,7 @@ bool
|
||||
OT::GPOS::is_blocklisted (hb_blob_t *blob HB_UNUSED,
|
||||
hb_face_t *face HB_UNUSED) const
|
||||
{
|
||||
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
|
||||
#ifdef HB_NO_OT_LAYOUT_BLOCKLIST
|
||||
return false;
|
||||
#endif
|
||||
return false;
|
||||
@@ -419,6 +425,8 @@ get_gsubgpos_table (hb_face_t *face,
|
||||
* Fetches a list of all scripts enumerated in the specified face's GSUB table
|
||||
* or GPOS table. The list returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of script tags.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_script_tags (hb_face_t *face,
|
||||
@@ -585,6 +593,8 @@ hb_ot_layout_table_select_script (hb_face_t *face,
|
||||
*
|
||||
* Fetches a list of all feature tags in the given face's GSUB or GPOS table.
|
||||
*
|
||||
* Return value: Total number of feature tags.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
|
||||
@@ -647,6 +657,8 @@ hb_ot_layout_table_find_feature (hb_face_t *face,
|
||||
* Fetches a list of language tags in the given face's GSUB or GPOS table, underneath
|
||||
* the specified script index. The list returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of language tags.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_script_get_language_tags (hb_face_t *face,
|
||||
@@ -818,6 +830,8 @@ hb_ot_layout_language_get_required_feature (hb_face_t *face,
|
||||
* Fetches a list of all features in the specified face's GSUB table
|
||||
* or GPOS table, underneath the specified script and language. The list
|
||||
* returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of features.
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
@@ -850,6 +864,7 @@ hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
|
||||
* or GPOS table, underneath the specified script and language. The list
|
||||
* returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of feature tags.
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
|
||||
@@ -932,6 +947,8 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
|
||||
* the specified face's GSUB table or GPOS table. The list returned will
|
||||
* begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of lookups.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
unsigned int
|
||||
@@ -960,6 +977,8 @@ hb_ot_layout_feature_get_lookups (hb_face_t *face,
|
||||
* Fetches the total number of lookups enumerated in the specified
|
||||
* face's GSUB table or GPOS table.
|
||||
*
|
||||
* Return value: Total number of lookups.
|
||||
*
|
||||
* Since: 0.9.22
|
||||
**/
|
||||
unsigned int
|
||||
@@ -974,10 +993,46 @@ struct hb_collect_features_context_t
|
||||
{
|
||||
hb_collect_features_context_t (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
hb_set_t *feature_indexes_)
|
||||
hb_set_t *feature_indices_,
|
||||
const hb_tag_t *features)
|
||||
|
||||
: g (get_gsubgpos_table (face, table_tag)),
|
||||
feature_indexes (feature_indexes_),
|
||||
script_count (0),langsys_count (0), feature_index_count (0) {}
|
||||
feature_indices (feature_indices_),
|
||||
has_feature_filter (false),
|
||||
script_count (0),langsys_count (0), feature_index_count (0)
|
||||
{
|
||||
compute_feature_filter (features);
|
||||
}
|
||||
|
||||
void compute_feature_filter (const hb_tag_t *features)
|
||||
{
|
||||
if (features == nullptr)
|
||||
{
|
||||
has_feature_filter = false;
|
||||
return;
|
||||
}
|
||||
|
||||
has_feature_filter = true;
|
||||
for (; *features; features++)
|
||||
{
|
||||
hb_tag_t tag = *features;
|
||||
unsigned index;
|
||||
g.find_feature_index (tag, &index);
|
||||
if (index == OT::Index::NOT_FOUND_INDEX) continue;
|
||||
|
||||
feature_indices_filter.add(index);
|
||||
for (int i = (int) index - 1; i >= 0; i--)
|
||||
{
|
||||
if (g.get_feature_tag (i) != tag) break;
|
||||
feature_indices_filter.add(i);
|
||||
}
|
||||
for (unsigned i = index + 1; i < g.get_feature_count (); i++)
|
||||
{
|
||||
if (g.get_feature_tag (i) != tag) break;
|
||||
feature_indices_filter.add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool visited (const OT::Script &s)
|
||||
{
|
||||
@@ -1026,7 +1081,9 @@ struct hb_collect_features_context_t
|
||||
|
||||
public:
|
||||
const OT::GSUBGPOS &g;
|
||||
hb_set_t *feature_indexes;
|
||||
hb_set_t *feature_indices;
|
||||
hb_set_t feature_indices_filter;
|
||||
bool has_feature_filter;
|
||||
|
||||
private:
|
||||
hb_set_t visited_script;
|
||||
@@ -1038,37 +1095,31 @@ struct hb_collect_features_context_t
|
||||
|
||||
static void
|
||||
langsys_collect_features (hb_collect_features_context_t *c,
|
||||
const OT::LangSys &l,
|
||||
const hb_tag_t *features)
|
||||
const OT::LangSys &l)
|
||||
{
|
||||
if (c->visited (l)) return;
|
||||
|
||||
if (!features)
|
||||
if (!c->has_feature_filter)
|
||||
{
|
||||
/* All features. */
|
||||
if (l.has_required_feature () && !c->visited_feature_indices (1))
|
||||
c->feature_indexes->add (l.get_required_feature_index ());
|
||||
c->feature_indices->add (l.get_required_feature_index ());
|
||||
|
||||
// TODO(garretrieger): filter out indices >= feature count?
|
||||
if (!c->visited_feature_indices (l.featureIndex.len))
|
||||
l.add_feature_indexes_to (c->feature_indexes);
|
||||
l.add_feature_indexes_to (c->feature_indices);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ugh. Any faster way? */
|
||||
for (; *features; features++)
|
||||
if (c->feature_indices_filter.is_empty()) return;
|
||||
unsigned int num_features = l.get_feature_count ();
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
hb_tag_t feature_tag = *features;
|
||||
unsigned int num_features = l.get_feature_count ();
|
||||
for (unsigned int i = 0; i < num_features; i++)
|
||||
{
|
||||
unsigned int feature_index = l.get_feature_index (i);
|
||||
unsigned int feature_index = l.get_feature_index (i);
|
||||
if (!c->feature_indices_filter.has (feature_index)) continue;
|
||||
|
||||
if (feature_tag == c->g.get_feature_tag (feature_index))
|
||||
{
|
||||
c->feature_indexes->add (feature_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
c->feature_indices->add (feature_index);
|
||||
c->feature_indices_filter.del (feature_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1076,8 +1127,7 @@ langsys_collect_features (hb_collect_features_context_t *c,
|
||||
static void
|
||||
script_collect_features (hb_collect_features_context_t *c,
|
||||
const OT::Script &s,
|
||||
const hb_tag_t *languages,
|
||||
const hb_tag_t *features)
|
||||
const hb_tag_t *languages)
|
||||
{
|
||||
if (c->visited (s)) return;
|
||||
|
||||
@@ -1086,14 +1136,13 @@ script_collect_features (hb_collect_features_context_t *c,
|
||||
/* All languages. */
|
||||
if (s.has_default_lang_sys ())
|
||||
langsys_collect_features (c,
|
||||
s.get_default_lang_sys (),
|
||||
features);
|
||||
s.get_default_lang_sys ());
|
||||
|
||||
|
||||
unsigned int count = s.get_lang_sys_count ();
|
||||
for (unsigned int language_index = 0; language_index < count; language_index++)
|
||||
langsys_collect_features (c,
|
||||
s.get_lang_sys (language_index),
|
||||
features);
|
||||
s.get_lang_sys (language_index));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1102,8 +1151,8 @@ script_collect_features (hb_collect_features_context_t *c,
|
||||
unsigned int language_index;
|
||||
if (s.find_lang_sys_index (*languages, &language_index))
|
||||
langsys_collect_features (c,
|
||||
s.get_lang_sys (language_index),
|
||||
features);
|
||||
s.get_lang_sys (language_index));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1134,7 +1183,7 @@ hb_ot_layout_collect_features (hb_face_t *face,
|
||||
const hb_tag_t *features,
|
||||
hb_set_t *feature_indexes /* OUT */)
|
||||
{
|
||||
hb_collect_features_context_t c (face, table_tag, feature_indexes);
|
||||
hb_collect_features_context_t c (face, table_tag, feature_indexes, features);
|
||||
if (!scripts)
|
||||
{
|
||||
/* All scripts. */
|
||||
@@ -1142,8 +1191,7 @@ hb_ot_layout_collect_features (hb_face_t *face,
|
||||
for (unsigned int script_index = 0; script_index < count; script_index++)
|
||||
script_collect_features (&c,
|
||||
c.g.get_script (script_index),
|
||||
languages,
|
||||
features);
|
||||
languages);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1153,8 +1201,7 @@ hb_ot_layout_collect_features (hb_face_t *face,
|
||||
if (c.g.find_script_index (*scripts, &script_index))
|
||||
script_collect_features (&c,
|
||||
c.g.get_script (script_index),
|
||||
languages,
|
||||
features);
|
||||
languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1262,6 +1309,8 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
||||
* Fetches a list of feature variations in the specified face's GSUB table
|
||||
* or GPOS table, at the specified variation coordinates.
|
||||
*
|
||||
* Return value: %true if feature variations were found, %false otherwise.
|
||||
*
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_find_feature_variations (hb_face_t *face,
|
||||
@@ -1291,6 +1340,8 @@ hb_ot_layout_table_find_feature_variations (hb_face_t *face,
|
||||
* the specified face's GSUB table or GPOS table, enabled at the specified
|
||||
* variations index. The list returned will begin at the offset provided.
|
||||
*
|
||||
* Return value: Total number of lookups.
|
||||
*
|
||||
**/
|
||||
unsigned int
|
||||
hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face,
|
||||
@@ -1337,7 +1388,8 @@ hb_ot_layout_has_substitution (hb_face_t *face)
|
||||
* @lookup_index: The index of the lookup to query
|
||||
* @glyphs: The sequence of glyphs to query for substitution
|
||||
* @glyphs_length: The length of the glyph sequence
|
||||
* @zero_context: #hb_bool_t indicating whether substitutions should be context-free
|
||||
* @zero_context: #hb_bool_t indicating whether pre-/post-context are disallowed
|
||||
* in substitutions
|
||||
*
|
||||
* Tests whether a specified lookup in the specified face would
|
||||
* trigger a substitution on the given glyph sequence.
|
||||
@@ -1443,12 +1495,17 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||
unsigned int lookup_index,
|
||||
hb_set_t *glyphs /* OUT */)
|
||||
{
|
||||
hb_map_t done_lookups;
|
||||
OT::hb_closure_context_t c (face, glyphs, &done_lookups);
|
||||
hb_set_t cur_intersected_glyphs;
|
||||
hb_map_t done_lookups_glyph_count;
|
||||
hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
|
||||
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
|
||||
const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
|
||||
|
||||
l.closure (&c, lookup_index);
|
||||
|
||||
for (auto _ : done_lookups_glyph_set.iter ())
|
||||
hb_set_destroy (_.second);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1467,8 +1524,10 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
|
||||
const hb_set_t *lookups,
|
||||
hb_set_t *glyphs /* OUT */)
|
||||
{
|
||||
hb_map_t done_lookups;
|
||||
OT::hb_closure_context_t c (face, glyphs, &done_lookups);
|
||||
hb_set_t cur_intersected_glyphs;
|
||||
hb_map_t done_lookups_glyph_count;
|
||||
hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
|
||||
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
|
||||
const OT::GSUB& gsub = *face->table.GSUB->table;
|
||||
|
||||
unsigned int iteration_count = 0;
|
||||
@@ -1488,6 +1547,9 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
|
||||
}
|
||||
} while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
|
||||
glyphs_length != glyphs->get_population ());
|
||||
|
||||
for (auto _ : done_lookups_glyph_set.iter ())
|
||||
hb_set_destroy (_.second);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1824,27 +1886,20 @@ apply_string (OT::hb_ot_apply_context_t *c,
|
||||
if (likely (!lookup.is_reverse ()))
|
||||
{
|
||||
/* in/out forward substitution/positioning */
|
||||
if (Proxy::table_index == 0u)
|
||||
if (!Proxy::inplace)
|
||||
buffer->clear_output ();
|
||||
buffer->idx = 0;
|
||||
|
||||
bool ret;
|
||||
ret = apply_forward (c, accel);
|
||||
if (ret)
|
||||
{
|
||||
if (!Proxy::inplace)
|
||||
buffer->swap_buffers ();
|
||||
else
|
||||
assert (!buffer->has_separate_output ());
|
||||
}
|
||||
buffer->idx = 0;
|
||||
apply_forward (c, accel);
|
||||
|
||||
if (!Proxy::inplace)
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* in-place backward substitution/positioning */
|
||||
if (Proxy::table_index == 0u)
|
||||
buffer->remove_output ();
|
||||
assert (!buffer->have_output);
|
||||
buffer->idx = buffer->len - 1;
|
||||
|
||||
apply_backward (c, accel);
|
||||
}
|
||||
}
|
||||
@@ -1860,7 +1915,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
|
||||
OT::hb_ot_apply_context_t c (table_index, font, buffer);
|
||||
c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
|
||||
|
||||
for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++) {
|
||||
for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
|
||||
{
|
||||
const stage_map_t *stage = &stages[table_index][stage_index];
|
||||
for (; i < stage->last_lookup; i++)
|
||||
{
|
||||
@@ -1870,11 +1926,8 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
|
||||
c.set_lookup_mask (lookups[table_index][i].mask);
|
||||
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
|
||||
c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
|
||||
if (lookups[table_index][i].random)
|
||||
{
|
||||
c.set_random (true);
|
||||
buffer->unsafe_to_break_all ();
|
||||
}
|
||||
c.set_random (lookups[table_index][i].random);
|
||||
|
||||
apply_string<Proxy> (&c,
|
||||
proxy.table.get_lookup (lookup_index),
|
||||
proxy.accels[lookup_index]);
|
||||
@@ -1882,10 +1935,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
|
||||
}
|
||||
|
||||
if (stage->pause_func)
|
||||
{
|
||||
buffer->clear_output ();
|
||||
stage->pause_func (plan, font, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1925,7 +1975,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||
*
|
||||
* Fetches a baseline value from the face.
|
||||
*
|
||||
* Return value: if found baseline value in the font.
|
||||
* Return value: %true if found baseline value in the font.
|
||||
*
|
||||
* Since: 2.6.0
|
||||
**/
|
||||
@@ -1984,7 +2034,7 @@ struct hb_get_glyph_alternates_dispatch_t :
|
||||
*
|
||||
* Fetches alternates of a glyph from a given GSUB lookup index.
|
||||
*
|
||||
* Return value: total number of alternates found in the specific lookup index for the given glyph id.
|
||||
* Return value: Total number of alternates found in the specific lookup index for the given glyph id.
|
||||
*
|
||||
* Since: 2.6.8
|
||||
**/
|
||||
|
||||
Reference in New Issue
Block a user