[OTLayout] Add is_inplace() method to GSUB
This commit is contained in:
parent
07034f447b
commit
1b972d893a
|
@ -37,6 +37,12 @@ namespace OT {
|
||||||
|
|
||||||
struct SingleSubstFormat1
|
struct SingleSubstFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -115,6 +121,12 @@ struct SingleSubstFormat1
|
||||||
|
|
||||||
struct SingleSubstFormat2
|
struct SingleSubstFormat2
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -251,6 +263,13 @@ struct SingleSubst
|
||||||
|
|
||||||
struct Sequence
|
struct Sequence
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
/* For len==0 we don't do anything, so it's harmless. */
|
||||||
|
return TRACE_RETURN (substitute.len <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -315,6 +334,18 @@ struct Sequence
|
||||||
|
|
||||||
struct MultipleSubstFormat1
|
struct MultipleSubstFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
/* Some tools generate MultipleSubst with each substitute having length 1!
|
||||||
|
* So, check them. */
|
||||||
|
unsigned int count = sequence.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!(this+sequence[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -440,6 +471,12 @@ typedef ArrayOf<GlyphID> AlternateSet; /* Array of alternate GlyphIDs--in
|
||||||
|
|
||||||
struct AlternateSubstFormat1
|
struct AlternateSubstFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -760,6 +797,12 @@ struct LigatureSet
|
||||||
|
|
||||||
struct LigatureSubstFormat1
|
struct LigatureSubstFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -908,6 +951,12 @@ struct ExtensionSubst : Extension<ExtensionSubst>
|
||||||
|
|
||||||
struct ReverseChainSingleSubstFormat1
|
struct ReverseChainSingleSubstFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1145,6 +1194,13 @@ struct SubstLookup : Lookup
|
||||||
return lookup_type_is_reverse (type);
|
return lookup_type_is_reverse (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
c->set_recurse_func (dispatch_recurse_func<hb_is_inplace_context_t>);
|
||||||
|
return TRACE_RETURN (dispatch (c));
|
||||||
|
}
|
||||||
|
|
||||||
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
|
inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
|
|
@ -44,6 +44,55 @@ namespace OT {
|
||||||
"");
|
"");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HB_DEBUG_IS_INPLACE
|
||||||
|
#define HB_DEBUG_IS_INPLACE (HB_DEBUG+0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define TRACE_IS_INPLACE(this) \
|
||||||
|
hb_auto_trace_t<HB_DEBUG_IS_INPLACE, bool> trace \
|
||||||
|
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||||
|
"");
|
||||||
|
|
||||||
|
struct hb_is_inplace_context_t
|
||||||
|
{
|
||||||
|
inline const char *get_name (void) { return "IS_INPLACE"; }
|
||||||
|
static const unsigned int max_debug_depth = HB_DEBUG_IS_INPLACE;
|
||||||
|
typedef bool return_t;
|
||||||
|
typedef return_t (*recurse_func_t) (hb_is_inplace_context_t *c, unsigned int lookup_index);
|
||||||
|
template <typename T>
|
||||||
|
inline return_t dispatch (const T &obj) { return obj.is_inplace (this); }
|
||||||
|
static return_t default_return_value (void) { return true; }
|
||||||
|
bool stop_sublookup_iteration (return_t r) const { return !r; }
|
||||||
|
|
||||||
|
return_t recurse (unsigned int lookup_index)
|
||||||
|
{
|
||||||
|
if (unlikely (nesting_level_left == 0 || !recurse_func))
|
||||||
|
return default_return_value ();
|
||||||
|
|
||||||
|
nesting_level_left--;
|
||||||
|
bool ret = recurse_func (this, lookup_index);
|
||||||
|
nesting_level_left++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_face_t *face;
|
||||||
|
recurse_func_t recurse_func;
|
||||||
|
unsigned int nesting_level_left;
|
||||||
|
unsigned int debug_depth;
|
||||||
|
|
||||||
|
hb_is_inplace_context_t (hb_face_t *face_,
|
||||||
|
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
|
||||||
|
face (face_),
|
||||||
|
recurse_func (NULL),
|
||||||
|
nesting_level_left (nesting_level_left_),
|
||||||
|
debug_depth (0) {}
|
||||||
|
|
||||||
|
void set_recurse_func (recurse_func_t func) { recurse_func = func; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef HB_DEBUG_CLOSURE
|
#ifndef HB_DEBUG_CLOSURE
|
||||||
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -1096,6 +1145,17 @@ static inline bool context_apply_lookup (hb_apply_context_t *c,
|
||||||
|
|
||||||
struct Rule
|
struct Rule
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||||
|
unsigned int count = lookupCount;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!c->recurse (lookupRecord[i].lookupListIndex))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1155,6 +1215,16 @@ struct Rule
|
||||||
|
|
||||||
struct RuleSet
|
struct RuleSet
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int num_rules = rule.len;
|
||||||
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
|
if (!(this+rule[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1211,6 +1281,16 @@ struct RuleSet
|
||||||
|
|
||||||
struct ContextFormat1
|
struct ContextFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int count = ruleSet.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!(this+ruleSet[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1297,6 +1377,16 @@ struct ContextFormat1
|
||||||
|
|
||||||
struct ContextFormat2
|
struct ContextFormat2
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int count = ruleSet.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!(this+ruleSet[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1392,6 +1482,17 @@ struct ContextFormat2
|
||||||
|
|
||||||
struct ContextFormat3
|
struct ContextFormat3
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
|
||||||
|
unsigned int count = lookupCount;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!c->recurse (lookupRecord[i].lookupListIndex))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1633,6 +1734,19 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
|
||||||
|
|
||||||
struct ChainRule
|
struct ChainRule
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
|
||||||
|
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
|
||||||
|
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||||
|
unsigned int count = lookup.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!c->recurse (lookup.array[i].lookupListIndex))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1718,6 +1832,16 @@ struct ChainRule
|
||||||
|
|
||||||
struct ChainRuleSet
|
struct ChainRuleSet
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int num_rules = rule.len;
|
||||||
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
|
if (!(this+rule[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1771,6 +1895,16 @@ struct ChainRuleSet
|
||||||
|
|
||||||
struct ChainContextFormat1
|
struct ChainContextFormat1
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int count = ruleSet.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!(this+ruleSet[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1854,6 +1988,16 @@ struct ChainContextFormat1
|
||||||
|
|
||||||
struct ChainContextFormat2
|
struct ChainContextFormat2
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
unsigned int count = ruleSet.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!(this+ruleSet[i]).is_inplace (c))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
@ -1978,6 +2122,20 @@ struct ChainContextFormat2
|
||||||
|
|
||||||
struct ChainContextFormat3
|
struct ChainContextFormat3
|
||||||
{
|
{
|
||||||
|
inline bool is_inplace (hb_is_inplace_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_IS_INPLACE (this);
|
||||||
|
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
|
||||||
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
|
||||||
|
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
|
||||||
|
|
||||||
|
unsigned int count = lookup.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
if (!c->recurse (lookup.array[i].lookupListIndex))
|
||||||
|
return TRACE_RETURN (false);
|
||||||
|
return TRACE_RETURN (true);
|
||||||
|
}
|
||||||
|
|
||||||
inline void closure (hb_closure_context_t *c) const
|
inline void closure (hb_closure_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_CLOSURE (this);
|
TRACE_CLOSURE (this);
|
||||||
|
|
|
@ -189,6 +189,23 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUBGPOS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Always returns true for GPOS, but make writing code easier. */
|
||||||
|
HB_INTERNAL bool
|
||||||
|
hb_ot_layout_lookup_is_inplace (hb_face_t *face,
|
||||||
|
hb_tag_t table_tag,
|
||||||
|
unsigned int lookup_index);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUB
|
||||||
|
*/
|
||||||
|
|
||||||
HB_INTERNAL hb_bool_t
|
HB_INTERNAL hb_bool_t
|
||||||
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face,
|
||||||
unsigned int lookup_index,
|
unsigned int lookup_index,
|
||||||
|
@ -215,6 +232,11 @@ hb_ot_layout_substitute_finish (hb_font_t *font,
|
||||||
hb_buffer_t *buffer);
|
hb_buffer_t *buffer);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPOS
|
||||||
|
*/
|
||||||
|
|
||||||
/* Should be called before all the position_lookup's are done. Resets positions to zero. */
|
/* Should be called before all the position_lookup's are done. Resets positions to zero. */
|
||||||
HB_INTERNAL void
|
HB_INTERNAL void
|
||||||
hb_ot_layout_position_start (hb_font_t *font,
|
hb_ot_layout_position_start (hb_font_t *font,
|
||||||
|
|
|
@ -651,6 +651,33 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUBGPOS
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
hb_ot_layout_lookup_is_inplace (hb_face_t *face,
|
||||||
|
hb_tag_t table_tag,
|
||||||
|
unsigned int lookup_index)
|
||||||
|
{
|
||||||
|
OT::hb_is_inplace_context_t c (face);
|
||||||
|
|
||||||
|
switch (table_tag)
|
||||||
|
{
|
||||||
|
case HB_OT_TAG_GSUB:
|
||||||
|
{
|
||||||
|
const OT::SubstLookup& l = _get_gsub (face).get_lookup (lookup_index);
|
||||||
|
return l.is_inplace (&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
case HB_OT_TAG_GPOS:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OT::GSUB
|
* OT::GSUB
|
||||||
*/
|
*/
|
||||||
|
@ -727,6 +754,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
|
||||||
l.closure (&c);
|
l.closure (&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OT::GPOS
|
* OT::GPOS
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue