summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-06-03 21:59:11 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2020-06-03 21:59:11 +0000
commit6fdc8929296cf4197489d90fc0ad22085c6b4cbb (patch)
tree4f9a225a3c337f445480655fbf09df82624528a2 /Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
parenta5770373d74efcb24a0caf8ca58c52a92d4ca7b9 (diff)
harfbuzz 2.6.7
git-svn-id: svn://tug.org/texlive/trunk@55409 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh275
1 files changed, 228 insertions, 47 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
index c5c63edc544..2c063120647 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-layout-gsubgpos.hh
@@ -791,15 +791,15 @@ static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 &
return (data+coverage).intersects (glyphs);
}
-static inline bool intersects_array (const hb_set_t *glyphs,
- unsigned int count,
- const HBUINT16 values[],
- intersects_func_t intersects_func,
- const void *intersects_data)
+static inline bool array_is_subset_of (const hb_set_t *glyphs,
+ unsigned int count,
+ const HBUINT16 values[],
+ intersects_func_t intersects_func,
+ const void *intersects_data)
{
for (const HBUINT16 &_ : + hb_iter (values, count))
- if (intersects_func (glyphs, _, intersects_data)) return true;
- return false;
+ if (!intersects_func (glyphs, _, intersects_data)) return false;
+ return true;
}
@@ -1144,7 +1144,7 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
struct LookupRecord
{
LookupRecord* copy (hb_serialize_context_t *c,
- const hb_map_t *lookup_map)
+ const hb_map_t *lookup_map) const
{
TRACE_SERIALIZE (this);
auto *out = c->embed (*this);
@@ -1325,9 +1325,9 @@ static inline bool context_intersects (const hb_set_t *glyphs,
const HBUINT16 input[], /* Array of input values--start with second glyph */
ContextClosureLookupContext &lookup_context)
{
- return intersects_array (glyphs,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data);
+ return array_is_subset_of (glyphs,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data);
}
static inline void context_closure_lookup (hb_closure_context_t *c,
@@ -1450,6 +1450,47 @@ struct Rule
return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
}
+ bool serialize (hb_serialize_context_t *c,
+ const hb_map_t *input_mapping, /* old->new glyphid or class mapping */
+ const hb_map_t *lookup_map) const
+ {
+ TRACE_SERIALIZE (this);
+ auto *out = c->start_embed (this);
+ if (unlikely (!c->extend_min (out))) return_trace (false);
+
+ out->inputCount = inputCount;
+ out->lookupCount = lookupCount;
+
+ const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1);
+ for (const auto org : input)
+ {
+ HBUINT16 d;
+ d = input_mapping->get (org);
+ c->copy (d);
+ }
+
+ const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
+ (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
+ for (unsigned i = 0; i < (unsigned) lookupCount; i++)
+ c->copy (lookupRecord[i], lookup_map);
+
+ return_trace (true);
+ }
+
+ bool subset (hb_subset_context_t *c,
+ const hb_map_t *lookup_map,
+ const hb_map_t *klass_map = nullptr) const
+ {
+ TRACE_SUBSET (this);
+
+ const hb_array_t<const HBUINT16> input = inputZ.as_array ((inputCount ? inputCount - 1 : 0));
+ if (!input.length) return_trace (false);
+
+ const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map;
+ if (!hb_all (input, mapping)) return_trace (false);
+ return_trace (serialize (c->serializer, mapping, lookup_map));
+ }
+
public:
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -1546,6 +1587,36 @@ struct RuleSet
;
}
+ bool subset (hb_subset_context_t *c,
+ const hb_map_t *lookup_map,
+ const hb_map_t *klass_map = nullptr) const
+ {
+ TRACE_SUBSET (this);
+
+ auto snap = c->serializer->snapshot ();
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ for (const OffsetTo<Rule>& _ : rule)
+ {
+ if (!_) continue;
+ auto *o = out->rule.serialize_append (c->serializer);
+ if (unlikely (!o)) continue;
+
+ auto o_snap = c->serializer->snapshot ();
+ if (!o->serialize_subset (c, _, this, lookup_map, klass_map))
+ {
+ out->rule.pop ();
+ c->serializer->revert (o_snap);
+ }
+ }
+
+ bool ret = bool (out->rule);
+ if (!ret) c->serializer->revert (snap);
+
+ return_trace (ret);
+ }
+
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -1603,6 +1674,8 @@ struct ContextFormat1
;
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverage).collect_coverage (c->input);
@@ -1648,8 +1721,26 @@ struct ContextFormat1
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ const hb_set_t &glyphset = *c->plan->glyphset ();
+ const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+ hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ + hb_zip (this+coverage, ruleSet)
+ | hb_filter (glyphset, hb_first)
+ | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second)
+ | hb_map (hb_first)
+ | hb_map (glyph_map)
+ | hb_sink (new_coverage)
+ ;
+
+ out->coverage.serialize (c->serializer, out)
+ .serialize (c->serializer, new_coverage.iter ());
+ return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1725,6 +1816,8 @@ struct ContextFormat2
;
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverage).collect_coverage (c->input);
@@ -1774,8 +1867,45 @@ struct ContextFormat2
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ auto *out = c->serializer->start_embed (*this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ out->format = format;
+ if (unlikely (!out->coverage.serialize_subset (c, coverage, this)))
+ return_trace (false);
+
+ hb_map_t klass_map;
+ out->classDef.serialize_subset (c, classDef, this, &klass_map);
+
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+ bool ret = true;
+ unsigned non_zero_index = 0, index = 0;
+ for (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _ : + hb_enumerate (ruleSet)
+ | hb_filter (klass_map, hb_first))
+ {
+ auto *o = out->ruleSet.serialize_append (c->serializer);
+ if (unlikely (!o))
+ {
+ ret = false;
+ break;
+ }
+
+ if (o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
+ non_zero_index = index;
+
+ index++;
+ }
+
+ if (!ret) return_trace (ret);
+
+ //prune empty trailing ruleSets
+ --index;
+ while (index > non_zero_index)
+ {
+ out->ruleSet.pop ();
+ index--;
+ }
+
+ return_trace (bool (out->ruleSet));
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1838,6 +1968,8 @@ struct ContextFormat3
recurse_lookups (c, lookupCount, lookupRecord);
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverageZ[0]).collect_coverage (c->input);
@@ -1886,8 +2018,28 @@ struct ContextFormat3
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- // TODO(subset)
- return_trace (false);
+ auto *out = c->serializer->start_embed (this);
+ if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+ out->format = format;
+ out->glyphCount = glyphCount;
+ out->lookupCount = lookupCount;
+
+ const hb_array_t<const OffsetTo<Coverage>> coverages = coverageZ.as_array (glyphCount);
+
+ for (const OffsetTo<Coverage>& offset : coverages)
+ {
+ auto *o = c->serializer->allocate_size<OffsetTo<Coverage>> (OffsetTo<Coverage>::static_size);
+ if (unlikely (!o)) return_trace (false);
+ if (!o->serialize_subset (c, offset, this)) return_trace (false);
+ }
+
+ const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+ for (unsigned i = 0; i < (unsigned) lookupCount; i++)
+ c->serializer->copy (lookupRecord[i], lookup_map);
+
+ return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -1972,15 +2124,15 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs,
const HBUINT16 lookahead[],
ChainContextClosureLookupContext &lookup_context)
{
- return intersects_array (glyphs,
- backtrackCount, backtrack,
- lookup_context.funcs.intersects, lookup_context.intersects_data[0])
- && intersects_array (glyphs,
- inputCount ? inputCount - 1 : 0, input,
- lookup_context.funcs.intersects, lookup_context.intersects_data[1])
- && intersects_array (glyphs,
- lookaheadCount, lookahead,
- lookup_context.funcs.intersects, lookup_context.intersects_data[2]);
+ return array_is_subset_of (glyphs,
+ backtrackCount, backtrack,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ && array_is_subset_of (glyphs,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ && array_is_subset_of (glyphs,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[2]);
}
static inline void chain_context_closure_lookup (hb_closure_context_t *c,
@@ -2171,6 +2323,7 @@ struct ChainRule
}
ChainRule* copy (hb_serialize_context_t *c,
+ const hb_map_t *lookup_map,
const hb_map_t *backtrack_map,
const hb_map_t *input_map = nullptr,
const hb_map_t *lookahead_map = nullptr) const
@@ -2193,13 +2346,19 @@ struct ChainRule
serialize_array (c, lookahead.len, + lookahead.iter ()
| hb_map (mapping));
- const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
- c->copy (lookup);
+ const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+ HBUINT16 lookupCount;
+ lookupCount = lookupRecord.len;
+ if (!c->copy (lookupCount)) return_trace (nullptr);
+
+ for (unsigned i = 0; i < (unsigned) lookupCount; i++)
+ if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr);
return_trace (out);
}
bool subset (hb_subset_context_t *c,
+ const hb_map_t *lookup_map,
const hb_map_t *backtrack_map = nullptr,
const hb_map_t *input_map = nullptr,
const hb_map_t *lookahead_map = nullptr) const
@@ -2217,7 +2376,7 @@ struct ChainRule
!hb_all (lookahead, glyphset))
return_trace (false);
- copy (c->serializer, c->plan->glyph_map);
+ copy (c->serializer, lookup_map, c->plan->glyph_map);
}
else
{
@@ -2226,7 +2385,7 @@ struct ChainRule
!hb_all (lookahead, lookahead_map))
return_trace (false);
- copy (c->serializer, backtrack_map, input_map, lookahead_map);
+ copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
}
return_trace (true);
@@ -2327,6 +2486,7 @@ struct ChainRuleSet
}
bool subset (hb_subset_context_t *c,
+ const hb_map_t *lookup_map,
const hb_map_t *backtrack_klass_map = nullptr,
const hb_map_t *input_klass_map = nullptr,
const hb_map_t *lookahead_klass_map = nullptr) const
@@ -2345,6 +2505,7 @@ struct ChainRuleSet
auto o_snap = c->serializer->snapshot ();
if (!o->serialize_subset (c, _, this,
+ lookup_map,
backtrack_klass_map,
input_klass_map,
lookahead_klass_map))
@@ -2416,6 +2577,8 @@ struct ChainContextFormat1
;
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverage).collect_coverage (c->input);
@@ -2467,10 +2630,11 @@ struct ChainContextFormat1
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ruleSet)
| hb_filter (glyphset, hb_first)
- | hb_filter (subset_offset_array (c, out->ruleSet, this), hb_second)
+ | hb_filter (subset_offset_array (c, out->ruleSet, this, lookup_map), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
@@ -2560,6 +2724,8 @@ struct ChainContextFormat2
;
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
(this+coverage).collect_coverage (c->input);
@@ -2639,8 +2805,9 @@ struct ChainContextFormat2
hb_map_t lookahead_klass_map;
out->lookaheadClassDef.serialize_subset (c, lookaheadClassDef, this, &lookahead_klass_map);
- hb_vector_t<unsigned> rulesets;
+ unsigned non_zero_index = 0, index = 0;
bool ret = true;
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
for (const OffsetTo<ChainRuleSet>& _ : + hb_enumerate (ruleSet)
| hb_filter (input_klass_map, hb_first)
| hb_map (hb_second))
@@ -2651,24 +2818,24 @@ struct ChainContextFormat2
ret = false;
break;
}
- if (!o->serialize_subset (c, _, this,
- &backtrack_klass_map,
- &input_klass_map,
- &lookahead_klass_map))
- {
- rulesets.push (0);
- }
- else rulesets.push (1);
+ if (o->serialize_subset (c, _, this,
+ lookup_map,
+ &backtrack_klass_map,
+ &input_klass_map,
+ &lookahead_klass_map))
+ non_zero_index = index;
+
+ index++;
}
if (!ret) return_trace (ret);
//prune empty trailing ruleSets
- unsigned count = rulesets.length;
- while (count > 0 && rulesets[count-1] == 0)
+ --index;
+ while (index > non_zero_index)
{
out->ruleSet.pop ();
- count--;
+ index--;
}
return_trace (bool (out->ruleSet));
@@ -2758,6 +2925,8 @@ struct ChainContextFormat3
recurse_lookups (c, lookup.len, lookup.arrayZ);
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const {}
+
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
@@ -2856,8 +3025,16 @@ struct ChainContextFormat3
if (!serialize_coverage_offsets (c, lookahead.iter (), this))
return_trace (false);
- const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
- return_trace (c->serializer->copy (lookup));
+ const ArrayOf<LookupRecord> &lookupRecord = StructAfter<ArrayOf<LookupRecord>> (lookahead);
+ HBUINT16 lookupCount;
+ lookupCount = lookupRecord.len;
+ if (!c->serializer->copy (lookupCount)) return_trace (false);
+
+ const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
+ for (unsigned i = 0; i < (unsigned) lookupCount; i++)
+ if (!c->serializer->copy (lookupRecord[i], lookup_map)) return_trace (false);
+
+ return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const
@@ -2936,6 +3113,9 @@ struct ExtensionFormat1
return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...));
}
+ void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+ { dispatch (c); }
+
/* This is called from may_dispatch() above with hb_sanitize_context_t. */
bool sanitize (hb_sanitize_context_t *c) const
{
@@ -3142,8 +3322,9 @@ struct GSUBGPOS
unsigned int feature_count = hb_min (get_feature_count (), (unsigned) HB_MAX_FEATURES);
for (unsigned i = 0; i < feature_count; i++)
{
- if (get_feature (i).intersects_lookup_indexes (lookup_indexes))
- feature_indexes->add (i);
+ const Feature& f = get_feature (i);
+ if ((!f.featureParams.is_null ()) || f.intersects_lookup_indexes (lookup_indexes))
+ feature_indexes->add (i);
}
#ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u)