[subset] optimize glyph closure method: step 4
optimize recurse_lookups in Context/ChainContext glyph closure, only the glyphs that the parent lookup can apply the recursion to can participate in recursing the lookup.
This commit is contained in:
parent
62423504ee
commit
b8a58a0c0b
|
@ -52,18 +52,9 @@ struct SingleSubstFormat1
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
unsigned d = deltaGlyphID;
|
unsigned d = deltaGlyphID;
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hb_iter (this+coverage)
|
+ hb_iter (this+coverage)
|
||||||
| hb_filter (active_parent_glyphs)
|
| hb_filter (c->parent_active_glyphs ())
|
||||||
| hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
|
| hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
|
||||||
| hb_sink (c->output)
|
| hb_sink (c->output)
|
||||||
;
|
;
|
||||||
|
@ -166,18 +157,8 @@ struct SingleSubstFormat2
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (active_parent_glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_sink (c->output)
|
| hb_sink (c->output)
|
||||||
;
|
;
|
||||||
|
@ -421,18 +402,8 @@ struct MultipleSubstFormat1
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hb_zip (this+coverage, sequence)
|
+ hb_zip (this+coverage, sequence)
|
||||||
| hb_filter (active_parent_glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const Sequence &_) { _.closure (c); })
|
| hb_apply ([c] (const Sequence &_) { _.closure (c); })
|
||||||
|
@ -662,18 +633,8 @@ struct AlternateSubstFormat1
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hb_zip (this+coverage, alternateSet)
|
+ hb_zip (this+coverage, alternateSet)
|
||||||
| hb_filter (active_parent_glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
|
| hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
|
||||||
|
@ -1047,18 +1008,8 @@ struct LigatureSubstFormat1
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hb_zip (this+coverage, ligatureSet)
|
+ hb_zip (this+coverage, ligatureSet)
|
||||||
| hb_filter (active_parent_glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
|
| hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
|
||||||
|
@ -1251,20 +1202,11 @@ struct ReverseChainSingleSubstFormat1
|
||||||
{
|
{
|
||||||
if (!intersects (c->glyphs)) return;
|
if (!intersects (c->glyphs)) return;
|
||||||
|
|
||||||
hb_set_t *active_parent_glyphs;
|
|
||||||
if (c->active_glyphs_stack.length >= 1)
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->parent_active_glyphs ();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
active_parent_glyphs = c->glyphs;
|
|
||||||
}
|
|
||||||
|
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
||||||
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||||
|
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (active_parent_glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_sink (c->output)
|
| hb_sink (c->output)
|
||||||
;
|
;
|
||||||
|
@ -1610,12 +1552,14 @@ struct SubstLookup : Lookup
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
|
static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
|
||||||
|
|
||||||
static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
|
static inline typename hb_closure_context_t::return_t closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *chaos, unsigned seq_index, unsigned end_index);
|
||||||
|
|
||||||
|
static inline hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *chaos, unsigned seq_index, unsigned end_index)
|
||||||
{
|
{
|
||||||
if (!c->should_visit_lookup (lookup_index))
|
if (!c->should_visit_lookup (lookup_index))
|
||||||
return hb_empty_t ();
|
return hb_empty_t ();
|
||||||
|
|
||||||
hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);
|
hb_closure_context_t::return_t ret = closure_glyphs_recurse_func (c, lookup_index, chaos, seq_index, end_index);
|
||||||
|
|
||||||
/* While in theory we should flush here, it will cause timeouts because a recursive
|
/* While in theory we should flush here, it will cause timeouts because a recursive
|
||||||
* lookup can keep growing the glyph set. Skip, and outer loop will retry up to
|
* lookup can keep growing the glyph set. Skip, and outer loop will retry up to
|
||||||
|
@ -1688,6 +1632,14 @@ template <typename context_t>
|
||||||
return l.dispatch (c);
|
return l.dispatch (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ typename hb_closure_context_t::return_t SubstLookup::closure_glyphs_recurse_func (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *chaos, unsigned seq_index, unsigned end_index)
|
||||||
|
{
|
||||||
|
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (lookup_index);
|
||||||
|
if (l.may_have_non_1to1 ())
|
||||||
|
hb_set_add_range (chaos, seq_index, end_index);
|
||||||
|
return l.dispatch (c);
|
||||||
|
}
|
||||||
|
|
||||||
/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
|
/*static*/ inline hb_closure_lookups_context_t::return_t SubstLookup::dispatch_closure_lookups_recurse_func (hb_closure_lookups_context_t *c, unsigned this_index)
|
||||||
{
|
{
|
||||||
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index);
|
const SubstLookup &l = c->face->table.GSUB.get_relaxed ()->table->get_lookup (this_index);
|
||||||
|
|
|
@ -67,17 +67,17 @@ struct hb_have_non_1to1_context_t :
|
||||||
struct hb_closure_context_t :
|
struct hb_closure_context_t :
|
||||||
hb_dispatch_context_t<hb_closure_context_t>
|
hb_dispatch_context_t<hb_closure_context_t>
|
||||||
{
|
{
|
||||||
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
|
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned lookup_index, hb_set_t *chaos, unsigned seq_index, unsigned end_index);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
|
return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
|
||||||
static return_t default_return_value () { return hb_empty_t (); }
|
static return_t default_return_value () { return hb_empty_t (); }
|
||||||
void recurse (unsigned int lookup_index)
|
void recurse (unsigned lookup_index, hb_set_t *chaos, unsigned seq_index, unsigned end_index)
|
||||||
{
|
{
|
||||||
if (unlikely (nesting_level_left == 0 || !recurse_func))
|
if (unlikely (nesting_level_left == 0 || !recurse_func))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nesting_level_left--;
|
nesting_level_left--;
|
||||||
recurse_func (this, lookup_index);
|
recurse_func (this, lookup_index, chaos, seq_index, end_index);
|
||||||
nesting_level_left++;
|
nesting_level_left++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +107,9 @@ struct hb_closure_context_t :
|
||||||
|
|
||||||
hb_set_t* parent_active_glyphs ()
|
hb_set_t* parent_active_glyphs ()
|
||||||
{
|
{
|
||||||
|
if (active_glyphs_stack.length < 1)
|
||||||
|
return glyphs;
|
||||||
|
|
||||||
return active_glyphs_stack.tail ();
|
return active_glyphs_stack.tail ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,12 +773,14 @@ struct hb_get_subtables_context_t :
|
||||||
|
|
||||||
|
|
||||||
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
||||||
|
typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs);
|
||||||
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
|
||||||
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
|
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
|
||||||
|
|
||||||
struct ContextClosureFuncs
|
struct ContextClosureFuncs
|
||||||
{
|
{
|
||||||
intersects_func_t intersects;
|
intersects_func_t intersects;
|
||||||
|
intersected_glyphs_func_t intersected_glyphs;
|
||||||
};
|
};
|
||||||
struct ContextCollectGlyphsFuncs
|
struct ContextCollectGlyphsFuncs
|
||||||
{
|
{
|
||||||
|
@ -802,6 +807,25 @@ static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 &
|
||||||
return (data+coverage).intersects (glyphs);
|
return (data+coverage).intersects (glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void intersected_glyph (const hb_set_t *glyphs HB_UNUSED, const void *data, unsigned value, hb_set_t *intersected_glyphs)
|
||||||
|
{
|
||||||
|
unsigned g = reinterpret_cast<const HBUINT16 *>(data)[value];
|
||||||
|
intersected_glyphs->add (g);
|
||||||
|
}
|
||||||
|
static inline void intersected_class_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
|
||||||
|
{
|
||||||
|
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
|
||||||
|
class_def.intersected_class_glyphs (glyphs, value, intersected_glyphs);
|
||||||
|
}
|
||||||
|
static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs)
|
||||||
|
{
|
||||||
|
OffsetTo<Coverage> coverage;
|
||||||
|
coverage = value;
|
||||||
|
(data+coverage).intersected_coverage_glyphs (glyphs, intersected_glyphs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool array_is_subset_of (const hb_set_t *glyphs,
|
static inline bool array_is_subset_of (const hb_set_t *glyphs,
|
||||||
unsigned int count,
|
unsigned int count,
|
||||||
const HBUINT16 values[],
|
const HBUINT16 values[],
|
||||||
|
@ -1179,16 +1203,80 @@ struct LookupRecord
|
||||||
DEFINE_SIZE_STATIC (4);
|
DEFINE_SIZE_STATIC (4);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 };
|
||||||
|
|
||||||
|
static void context_closure_recurse_lookups (hb_closure_context_t *c,
|
||||||
|
unsigned inputCount, const HBUINT16 input[],
|
||||||
|
unsigned lookupCount,
|
||||||
|
const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */,
|
||||||
|
unsigned value,
|
||||||
|
ContextFormat context_format,
|
||||||
|
const void *data,
|
||||||
|
intersected_glyphs_func_t intersected_glyphs_func)
|
||||||
|
{
|
||||||
|
printf ("qxliu_1\n");
|
||||||
|
hb_set_t *chaos = hb_set_create ();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < lookupCount; i++)
|
||||||
|
{
|
||||||
|
unsigned seqIndex = lookupRecord[i].sequenceIndex;
|
||||||
|
if (seqIndex > inputCount) continue;
|
||||||
|
|
||||||
|
hb_set_t *pos_glyphs = hb_set_create ();
|
||||||
|
|
||||||
|
if (hb_set_is_empty (chaos) || !hb_set_has (chaos, seqIndex))
|
||||||
|
{
|
||||||
|
if (seqIndex == 0)
|
||||||
|
{
|
||||||
|
switch (context_format) {
|
||||||
|
case ContextFormat::SimpleContext:
|
||||||
|
pos_glyphs->add (value);
|
||||||
|
break;
|
||||||
|
case ContextFormat::ClassBasedContext:
|
||||||
|
intersected_glyphs_func (c->parent_active_glyphs (), data, value, pos_glyphs);
|
||||||
|
break;
|
||||||
|
case ContextFormat::CoverageBasedContext:
|
||||||
|
hb_set_set (pos_glyphs, c->parent_active_glyphs ());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const void *input_data = input;
|
||||||
|
unsigned input_value = seqIndex - 1;
|
||||||
|
if (context_format == ContextFormat::ClassBasedContext)
|
||||||
|
{
|
||||||
|
input_data = data;
|
||||||
|
input_value = input[seqIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
intersected_glyphs_func (c->parent_active_glyphs (), input_data, input_value, pos_glyphs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_set_add (chaos, seqIndex);
|
||||||
|
c->push_cur_active_glyphs (pos_glyphs);
|
||||||
|
|
||||||
|
unsigned endIndex = inputCount;
|
||||||
|
if (context_format == ContextFormat::CoverageBasedContext)
|
||||||
|
endIndex += 1;
|
||||||
|
|
||||||
|
c->recurse (lookupRecord[i].lookupListIndex, chaos, seqIndex, endIndex);
|
||||||
|
|
||||||
|
c->pop_cur_done_glyphs ();
|
||||||
|
hb_set_destroy (pos_glyphs);
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_set_destroy (chaos);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename context_t>
|
template <typename context_t>
|
||||||
static inline void recurse_lookups (context_t *c,
|
static inline void recurse_lookups (context_t *c,
|
||||||
unsigned int lookupCount,
|
unsigned int lookupCount,
|
||||||
const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
|
const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */)
|
||||||
{
|
{
|
||||||
hb_set_t *chaos = hb_set_create ();
|
|
||||||
for (unsigned int i = 0; i < lookupCount; i++)
|
for (unsigned int i = 0; i < lookupCount; i++)
|
||||||
c->recurse (lookupRecord[i].lookupListIndex);
|
c->recurse (lookupRecord[i].lookupListIndex);
|
||||||
|
|
||||||
hb_set_destroy (chaos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||||
|
@ -1320,6 +1408,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||||
struct ContextClosureLookupContext
|
struct ContextClosureLookupContext
|
||||||
{
|
{
|
||||||
ContextClosureFuncs funcs;
|
ContextClosureFuncs funcs;
|
||||||
|
ContextFormat context_format;
|
||||||
const void *intersects_data;
|
const void *intersects_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1350,13 +1439,19 @@ static inline void context_closure_lookup (hb_closure_context_t *c,
|
||||||
const HBUINT16 input[], /* Array of input values--start with second glyph */
|
const HBUINT16 input[], /* Array of input values--start with second glyph */
|
||||||
unsigned int lookupCount,
|
unsigned int lookupCount,
|
||||||
const LookupRecord lookupRecord[],
|
const LookupRecord lookupRecord[],
|
||||||
|
unsigned value, /* Index of first glyph in Coverage or Class value in ClassDef table */
|
||||||
ContextClosureLookupContext &lookup_context)
|
ContextClosureLookupContext &lookup_context)
|
||||||
{
|
{
|
||||||
if (context_intersects (c->glyphs,
|
if (context_intersects (c->glyphs,
|
||||||
inputCount, input,
|
inputCount, input,
|
||||||
lookup_context))
|
lookup_context))
|
||||||
recurse_lookups (c,
|
context_closure_recurse_lookups (c,
|
||||||
lookupCount, lookupRecord);
|
inputCount, input,
|
||||||
|
lookupCount, lookupRecord,
|
||||||
|
value,
|
||||||
|
lookup_context.context_format,
|
||||||
|
lookup_context.intersects_data,
|
||||||
|
lookup_context.funcs.intersected_glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
||||||
|
@ -1413,7 +1508,7 @@ struct Rule
|
||||||
lookup_context);
|
lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
void closure (hb_closure_context_t *c, unsigned value, ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
|
||||||
|
@ -1422,7 +1517,7 @@ struct Rule
|
||||||
context_closure_lookup (c,
|
context_closure_lookup (c,
|
||||||
inputCount, inputZ.arrayZ,
|
inputCount, inputZ.arrayZ,
|
||||||
lookupCount, lookupRecord.arrayZ,
|
lookupCount, lookupRecord.arrayZ,
|
||||||
lookup_context);
|
value, lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c,
|
void closure_lookups (hb_closure_lookups_context_t *c,
|
||||||
|
@ -1547,7 +1642,7 @@ struct RuleSet
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c,
|
void closure (hb_closure_context_t *c, unsigned value,
|
||||||
ContextClosureLookupContext &lookup_context) const
|
ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
@ -1555,7 +1650,7 @@ struct RuleSet
|
||||||
return
|
return
|
||||||
+ hb_iter (rule)
|
+ hb_iter (rule)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([&] (const Rule &_) { _.closure (c, lookup_context); })
|
| hb_apply ([&] (const Rule &_) { _.closure (c, value, lookup_context); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1653,7 +1748,8 @@ struct ContextFormat1
|
||||||
bool intersects (const hb_set_t *glyphs) const
|
bool intersects (const hb_set_t *glyphs) const
|
||||||
{
|
{
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_glyph},
|
{intersects_glyph, intersected_glyph},
|
||||||
|
ContextFormat::SimpleContext,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1673,15 +1769,15 @@ struct ContextFormat1
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_glyph},
|
{intersects_glyph, intersected_glyph},
|
||||||
|
ContextFormat::SimpleContext,
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
+ hb_zip (this+coverage, ruleSet)
|
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
|
||||||
| hb_filter (*c->glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const RuleSet&> (_.first, this+ruleSet[_.second]); })
|
||||||
| hb_map (hb_add (this))
|
| hb_apply ([&] (const hb_pair_t<unsigned, const RuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
|
||||||
| hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1798,7 +1894,8 @@ struct ContextFormat2
|
||||||
const ClassDef &class_def = this+classDef;
|
const ClassDef &class_def = this+classDef;
|
||||||
|
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_class},
|
{intersects_class, intersected_class_glyphs},
|
||||||
|
ContextFormat::ClassBasedContext,
|
||||||
&class_def
|
&class_def
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1824,18 +1921,21 @@ struct ContextFormat2
|
||||||
const ClassDef &class_def = this+classDef;
|
const ClassDef &class_def = this+classDef;
|
||||||
|
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_class},
|
{intersects_class, intersected_class_glyphs},
|
||||||
|
ContextFormat::ClassBasedContext,
|
||||||
&class_def
|
&class_def
|
||||||
};
|
};
|
||||||
|
|
||||||
return
|
return
|
||||||
+ hb_enumerate (ruleSet)
|
+ hb_enumerate (ruleSet)
|
||||||
| hb_filter ([&] (unsigned _)
|
| hb_filter ([&] (unsigned _)
|
||||||
{ return class_def.intersects_class (c->glyphs, _); },
|
{ return class_def.intersects_class (c->parent_active_glyphs (), _); },
|
||||||
hb_first)
|
hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_apply ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet>&> _)
|
||||||
| hb_map (hb_add (this))
|
{
|
||||||
| hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
|
const RuleSet& rule_set = this+_.second;
|
||||||
|
rule_set.closure (c, _.first, lookup_context);
|
||||||
|
})
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1983,7 +2083,8 @@ struct ContextFormat3
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_coverage},
|
{intersects_coverage, intersected_coverage_glyphs},
|
||||||
|
ContextFormat::CoverageBasedContext,
|
||||||
this
|
this
|
||||||
};
|
};
|
||||||
return context_intersects (glyphs,
|
return context_intersects (glyphs,
|
||||||
|
@ -2001,13 +2102,14 @@ struct ContextFormat3
|
||||||
|
|
||||||
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
|
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
|
||||||
struct ContextClosureLookupContext lookup_context = {
|
struct ContextClosureLookupContext lookup_context = {
|
||||||
{intersects_coverage},
|
{intersects_coverage, intersected_coverage_glyphs},
|
||||||
|
ContextFormat::CoverageBasedContext,
|
||||||
this
|
this
|
||||||
};
|
};
|
||||||
context_closure_lookup (c,
|
context_closure_lookup (c,
|
||||||
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
||||||
lookupCount, lookupRecord,
|
lookupCount, lookupRecord,
|
||||||
lookup_context);
|
0, lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||||
|
@ -2151,6 +2253,7 @@ struct Context
|
||||||
struct ChainContextClosureLookupContext
|
struct ChainContextClosureLookupContext
|
||||||
{
|
{
|
||||||
ContextClosureFuncs funcs;
|
ContextClosureFuncs funcs;
|
||||||
|
ContextFormat context_format;
|
||||||
const void *intersects_data[3];
|
const void *intersects_data[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2195,6 +2298,7 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
|
||||||
const HBUINT16 lookahead[],
|
const HBUINT16 lookahead[],
|
||||||
unsigned int lookupCount,
|
unsigned int lookupCount,
|
||||||
const LookupRecord lookupRecord[],
|
const LookupRecord lookupRecord[],
|
||||||
|
unsigned value,
|
||||||
ChainContextClosureLookupContext &lookup_context)
|
ChainContextClosureLookupContext &lookup_context)
|
||||||
{
|
{
|
||||||
if (chain_context_intersects (c->glyphs,
|
if (chain_context_intersects (c->glyphs,
|
||||||
|
@ -2202,8 +2306,13 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
|
||||||
inputCount, input,
|
inputCount, input,
|
||||||
lookaheadCount, lookahead,
|
lookaheadCount, lookahead,
|
||||||
lookup_context))
|
lookup_context))
|
||||||
recurse_lookups (c,
|
context_closure_recurse_lookups (c,
|
||||||
lookupCount, lookupRecord);
|
inputCount, input,
|
||||||
|
lookupCount, lookupRecord,
|
||||||
|
value,
|
||||||
|
lookup_context.context_format,
|
||||||
|
lookup_context.intersects_data[1],
|
||||||
|
lookup_context.funcs.intersected_glyphs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
||||||
|
@ -2292,7 +2401,7 @@ struct ChainRule
|
||||||
lookup_context);
|
lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure (hb_closure_context_t *c,
|
void closure (hb_closure_context_t *c, unsigned value,
|
||||||
ChainContextClosureLookupContext &lookup_context) const
|
ChainContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
@ -2305,6 +2414,7 @@ struct ChainRule
|
||||||
input.lenP1, input.arrayZ,
|
input.lenP1, input.arrayZ,
|
||||||
lookahead.len, lookahead.arrayZ,
|
lookahead.len, lookahead.arrayZ,
|
||||||
lookup.len, lookup.arrayZ,
|
lookup.len, lookup.arrayZ,
|
||||||
|
value,
|
||||||
lookup_context);
|
lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2488,14 +2598,14 @@ struct ChainRuleSet
|
||||||
| hb_any
|
| hb_any
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
void closure (hb_closure_context_t *c, unsigned value, ChainContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
if (unlikely (c->lookup_limit_exceeded ())) return;
|
if (unlikely (c->lookup_limit_exceeded ())) return;
|
||||||
|
|
||||||
return
|
return
|
||||||
+ hb_iter (rule)
|
+ hb_iter (rule)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([&] (const ChainRule &_) { _.closure (c, lookup_context); })
|
| hb_apply ([&] (const ChainRule &_) { _.closure (c, value, lookup_context); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2596,7 +2706,8 @@ struct ChainContextFormat1
|
||||||
bool intersects (const hb_set_t *glyphs) const
|
bool intersects (const hb_set_t *glyphs) const
|
||||||
{
|
{
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_glyph},
|
{intersects_glyph, intersected_glyph},
|
||||||
|
ContextFormat::SimpleContext,
|
||||||
{nullptr, nullptr, nullptr}
|
{nullptr, nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2616,15 +2727,15 @@ struct ChainContextFormat1
|
||||||
void closure (hb_closure_context_t *c) const
|
void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_glyph},
|
{intersects_glyph, intersected_glyph},
|
||||||
|
ContextFormat::SimpleContext,
|
||||||
{nullptr, nullptr, nullptr}
|
{nullptr, nullptr, nullptr}
|
||||||
};
|
};
|
||||||
|
|
||||||
+ hb_zip (this+coverage, ruleSet)
|
+ hb_zip (this+coverage, hb_range ((unsigned) ruleSet.len))
|
||||||
| hb_filter (*c->glyphs, hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map ([&](const hb_pair_t<hb_codepoint_t, unsigned> _) { return hb_pair_t<unsigned, const ChainRuleSet&> (_.first, this+ruleSet[_.second]); })
|
||||||
| hb_map (hb_add (this))
|
| hb_apply ([&] (const hb_pair_t<unsigned, const ChainRuleSet&>& _) { _.second.closure (c, _.first, lookup_context); })
|
||||||
| hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2741,7 +2852,8 @@ struct ChainContextFormat2
|
||||||
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
|
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
|
||||||
|
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_class},
|
{intersects_class, intersected_class_glyphs},
|
||||||
|
ContextFormat::ClassBasedContext,
|
||||||
{&backtrack_class_def,
|
{&backtrack_class_def,
|
||||||
&input_class_def,
|
&input_class_def,
|
||||||
&lookahead_class_def}
|
&lookahead_class_def}
|
||||||
|
@ -2771,7 +2883,8 @@ struct ChainContextFormat2
|
||||||
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
|
const ClassDef &lookahead_class_def = this+lookaheadClassDef;
|
||||||
|
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_class},
|
{intersects_class, intersected_class_glyphs},
|
||||||
|
ContextFormat::ClassBasedContext,
|
||||||
{&backtrack_class_def,
|
{&backtrack_class_def,
|
||||||
&input_class_def,
|
&input_class_def,
|
||||||
&lookahead_class_def}
|
&lookahead_class_def}
|
||||||
|
@ -2780,11 +2893,13 @@ struct ChainContextFormat2
|
||||||
return
|
return
|
||||||
+ hb_enumerate (ruleSet)
|
+ hb_enumerate (ruleSet)
|
||||||
| hb_filter ([&] (unsigned _)
|
| hb_filter ([&] (unsigned _)
|
||||||
{ return input_class_def.intersects_class (c->glyphs, _); },
|
{ return input_class_def.intersects_class (c->parent_active_glyphs (), _); },
|
||||||
hb_first)
|
hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_apply ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet>&> _)
|
||||||
| hb_map (hb_add (this))
|
{
|
||||||
| hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
|
const ChainRuleSet& chainrule_set = this+_.second;
|
||||||
|
chainrule_set.closure (c, _.first, lookup_context);
|
||||||
|
})
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2983,7 +3098,8 @@ struct ChainContextFormat3
|
||||||
|
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_coverage},
|
{intersects_coverage, intersected_coverage_glyphs},
|
||||||
|
ContextFormat::CoverageBasedContext,
|
||||||
{this, this, this}
|
{this, this, this}
|
||||||
};
|
};
|
||||||
return chain_context_intersects (glyphs,
|
return chain_context_intersects (glyphs,
|
||||||
|
@ -3006,7 +3122,8 @@ struct ChainContextFormat3
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (input);
|
||||||
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
|
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord>> (lookahead);
|
||||||
struct ChainContextClosureLookupContext lookup_context = {
|
struct ChainContextClosureLookupContext lookup_context = {
|
||||||
{intersects_coverage},
|
{intersects_coverage, intersected_coverage_glyphs},
|
||||||
|
ContextFormat::CoverageBasedContext,
|
||||||
{this, this, this}
|
{this, this, this}
|
||||||
};
|
};
|
||||||
chain_context_closure_lookup (c,
|
chain_context_closure_lookup (c,
|
||||||
|
@ -3014,7 +3131,7 @@ struct ChainContextFormat3
|
||||||
input.len, (const HBUINT16 *) input.arrayZ + 1,
|
input.len, (const HBUINT16 *) input.arrayZ + 1,
|
||||||
lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
|
lookahead.len, (const HBUINT16 *) lookahead.arrayZ,
|
||||||
lookup.len, lookup.arrayZ,
|
lookup.len, lookup.arrayZ,
|
||||||
lookup_context);
|
0, lookup_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_lookups (hb_closure_lookups_context_t *c) const
|
void closure_lookups (hb_closure_lookups_context_t *c) const
|
||||||
|
|
Loading…
Reference in New Issue