[OTLayout] Port would_apply() and get_coverage() to process() templates

This commit is contained in:
Behdad Esfahbod 2012-11-22 14:38:10 -05:00
parent 44fc237b53
commit 2005fa5340
3 changed files with 156 additions and 293 deletions

View File

@ -212,9 +212,6 @@ struct ValueFormat : USHORT
struct AnchorFormat1
{
friend struct Anchor;
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
@ -237,9 +234,6 @@ struct AnchorFormat1
struct AnchorFormat2
{
friend struct Anchor;
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
hb_position_t *x, hb_position_t *y) const
{
@ -270,9 +264,6 @@ struct AnchorFormat2
struct AnchorFormat3
{
friend struct Anchor;
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
@ -428,10 +419,6 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
struct SinglePosFormat1
{
friend struct SinglePos;
private:
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@ -471,10 +458,6 @@ struct SinglePosFormat1
struct SinglePosFormat2
{
friend struct SinglePos;
private:
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@ -517,16 +500,13 @@ struct SinglePosFormat2
struct SinglePos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
case 2: return u.format2.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
case 2: return c->process (u.format2);
default:return c->default_return_value ();
}
}
@ -635,10 +615,6 @@ struct PairSet
struct PairPosFormat1
{
friend struct PairPos;
private:
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@ -693,10 +669,6 @@ struct PairPosFormat1
struct PairPosFormat2
{
friend struct PairPos;
private:
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@ -783,16 +755,13 @@ struct PairPosFormat2
struct PairPos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
case 2: return u.format2.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
case 2: return c->process (u.format2);
default:return c->default_return_value ();
}
}
@ -849,10 +818,6 @@ struct EntryExitRecord
struct CursivePosFormat1
{
friend struct CursivePos;
private:
inline const Coverage &get_coverage (void) const
{
return this+coverage;
@ -959,15 +924,12 @@ struct CursivePosFormat1
struct CursivePos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
default:return c->default_return_value ();
}
}
@ -1004,10 +966,6 @@ typedef AnchorMatrix BaseArray; /* base-major--
struct MarkBasePosFormat1
{
friend struct MarkBasePos;
private:
inline const Coverage &get_coverage (void) const
{
return this+markCoverage;
@ -1065,15 +1023,12 @@ struct MarkBasePosFormat1
struct MarkBasePos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
default:return c->default_return_value ();
}
}
@ -1115,10 +1070,6 @@ typedef OffsetListOf<LigatureAttach> LigatureArray;
struct MarkLigPosFormat1
{
friend struct MarkLigPos;
private:
inline const Coverage &get_coverage (void) const
{
return this+markCoverage;
@ -1193,15 +1144,12 @@ struct MarkLigPosFormat1
struct MarkLigPos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
default:return c->default_return_value ();
}
}
@ -1238,10 +1186,6 @@ typedef AnchorMatrix Mark2Array; /* mark2-major--
struct MarkMarkPosFormat1
{
friend struct MarkMarkPos;
private:
inline const Coverage &get_coverage (void) const
{
return this+mark1Coverage;
@ -1319,15 +1263,12 @@ struct MarkMarkPosFormat1
struct MarkMarkPos
{
friend struct PosLookupSubTable;
private:
inline const Coverage &get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
case 1: return c->process (u.format1);
default:return c->default_return_value ();
}
}
@ -1361,9 +1302,6 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
struct ContextPos : Context
{
friend struct PosLookupSubTable;
private:
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -1373,9 +1311,6 @@ struct ContextPos : Context
struct ChainContextPos : ChainContext
{
friend struct PosLookupSubTable;
private:
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -1386,9 +1321,6 @@ struct ChainContextPos : ChainContext
struct ExtensionPos : Extension
{
friend struct PosLookupSubTable;
private:
inline const struct PosLookupSubTable& get_subtable (void) const
{
unsigned int offset = get_offset ();
@ -1396,7 +1328,8 @@ struct ExtensionPos : Extension
return StructAtOffset<PosLookupSubTable> (this, offset);
}
inline const Coverage &get_coverage (void) const;
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const;
inline bool apply (hb_apply_context_t *c) const;
@ -1426,19 +1359,20 @@ struct PosLookupSubTable
Extension = 9
};
inline const Coverage &get_coverage (unsigned int lookup_type) const
template <typename context_t>
inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const
{
switch (lookup_type) {
case Single: return u.single.get_coverage ();
case Pair: return u.pair.get_coverage ();
case Cursive: return u.cursive.get_coverage ();
case MarkBase: return u.markBase.get_coverage ();
case MarkLig: return u.markLig.get_coverage ();
case MarkMark: return u.markMark.get_coverage ();
case Context: return u.context.get_coverage ();
case ChainContext: return u.chainContext.get_coverage ();
case Extension: return u.extension.get_coverage ();
default: return Null(Coverage);
case Single: return u.single.process (c);
case Pair: return u.pair.process (c);
case Cursive: return u.cursive.process (c);
case MarkBase: return u.markBase.process (c);
case MarkLig: return u.markLig.process (c);
case MarkMark: return u.markMark.process (c);
case Context: return u.context.process (c);
case ChainContext: return u.chainContext.process (c);
case Extension: return u.extension.process (c);
default: return c->default_return_value ();
}
}
@ -1480,7 +1414,7 @@ struct PosLookupSubTable
protected:
union {
struct {
USHORT sub_format;
USHORT sub_format;
} header;
SinglePos single;
PairPos pair;
@ -1502,16 +1436,30 @@ struct PosLookup : Lookup
inline const PosLookupSubTable& get_subtable (unsigned int i) const
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const
{
unsigned int lookup_type = get_type ();
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
typename context_t::return_t r = get_subtable (i).process (c, lookup_type);
if (c->stop_sublookup_iteration (r))
return r;
}
return c->default_return_value ();
}
template <typename set_t>
inline void add_coverage (set_t *glyphs) const
{
hb_get_coverage_context_t c;
const Coverage *last = NULL;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
const Coverage *c = &get_subtable (i).get_coverage (get_type ());
if (c != last) {
c->add_coverage (glyphs);
last = c;
const Coverage *coverage = &get_subtable (i).process (&c, get_type ());
if (coverage != last) {
coverage->add_coverage (glyphs);
last = coverage;
}
}
}
@ -1673,9 +1621,10 @@ GPOS::position_finish (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer, hb_bool_t
/* Out-of-class implementation for methods recursing */
inline const Coverage & ExtensionPos::get_coverage (void) const
template <typename context_t>
inline typename context_t::return_t ExtensionPos::process (context_t *c) const
{
return get_subtable ().get_coverage (get_type ());
return get_subtable ().process (c, get_type ());
}
inline bool ExtensionPos::apply (hb_apply_context_t *c) const

View File

@ -63,6 +63,12 @@ struct SingleSubstFormat1
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
return TRACE_RETURN (c->len == 1 && (this+coverage) (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -132,6 +138,12 @@ struct SingleSubstFormat2
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
return TRACE_RETURN (c->len == 1 && (this+coverage) (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -184,16 +196,7 @@ struct SingleSubst
switch (u.format) {
case 1: return c->process (u.format1);
case 2: return c->process (u.format2);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
case 2: return u.format2.get_coverage ();
default:return Null(Coverage);
default:return c->default_return_value ();
}
}
@ -333,6 +336,12 @@ struct MultipleSubstFormat1
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
return TRACE_RETURN (c->len == 1 && (this+coverage) (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -385,15 +394,7 @@ struct MultipleSubst
{
switch (u.format) {
case 1: return c->process (u.format1);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
default:return c->default_return_value ();
}
}
@ -475,6 +476,12 @@ struct AlternateSubstFormat1
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
return TRACE_RETURN (c->len == 1 && (this+coverage) (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -545,15 +552,7 @@ struct AlternateSubst
{
switch (u.format) {
case 1: return c->process (u.format1);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
default:return c->default_return_value ();
}
}
@ -621,14 +620,15 @@ struct Ligature
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
if (c->len != component.len)
return false;
return TRACE_RETURN (false);
for (unsigned int i = 1; i < c->len; i++)
if (likely (c->glyphs[i] != component[i]))
return false;
return TRACE_RETURN (false);
return true;
return TRACE_RETURN (true);
}
inline bool apply (hb_apply_context_t *c) const
@ -712,14 +712,15 @@ struct LigatureSet
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
unsigned int num_ligs = ligature.len;
for (unsigned int i = 0; i < num_ligs; i++)
{
const Ligature &lig = this+ligature[i];
if (lig.would_apply (c))
return true;
return TRACE_RETURN (true);
}
return false;
return TRACE_RETURN (false);
}
inline bool apply (hb_apply_context_t *c) const
@ -795,7 +796,12 @@ struct LigatureSubstFormat1
inline bool would_apply (hb_would_apply_context_t *c) const
{
return (this+ligatureSet[(this+coverage) (c->glyphs[0])]).would_apply (c);
TRACE_WOULD_APPLY ();
unsigned int index = (this+coverage) (c->glyphs[0]);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
const LigatureSet &lig_set = this+ligatureSet[index];
return TRACE_RETURN (lig_set.would_apply (c));
}
inline bool apply (hb_apply_context_t *c) const
@ -856,23 +862,7 @@ struct LigatureSubst
{
switch (u.format) {
case 1: return c->process (u.format1);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
}
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
switch (u.format) {
case 1: return u.format1.would_apply (c);
default:return false;
default:return c->default_return_value ();
}
}
@ -966,10 +956,6 @@ struct ExtensionSubst : Extension
template <typename context_t>
inline typename context_t::return_t process (context_t *c) const;
inline const Coverage &get_coverage (void) const;
inline bool would_apply (hb_would_apply_context_t *c) const;
inline bool apply (hb_apply_context_t *c) const;
inline bool sanitize (hb_sanitize_context_t *c);
@ -1032,6 +1018,12 @@ struct ReverseChainSingleSubstFormat1
return this+coverage;
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
TRACE_WOULD_APPLY ();
return TRACE_RETURN (c->len == 1 && (this+coverage) (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@ -1098,15 +1090,7 @@ struct ReverseChainSingleSubst
{
switch (u.format) {
case 1: return c->process (u.format1);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
default:return Null(Coverage);
default:return c->default_return_value ();
}
}
@ -1168,48 +1152,7 @@ struct SubstLookupSubTable
case ChainContext: return u.chainContext.process (c);
case Extension: return u.extension.process (c);
case ReverseChainSingle: return u.reverseChainContextSingle.process (c);
default: return c->default_return_value;
}
}
inline const Coverage &get_coverage (unsigned int lookup_type) const
{
switch (lookup_type) {
case Single: return u.single.get_coverage ();
case Multiple: return u.multiple.get_coverage ();
case Alternate: return u.alternate.get_coverage ();
case Ligature: return u.ligature.get_coverage ();
case Context: return u.context.get_coverage ();
case ChainContext: return u.chainContext.get_coverage ();
case Extension: return u.extension.get_coverage ();
case ReverseChainSingle: return u.reverseChainContextSingle.get_coverage ();
default: return Null(Coverage);
}
}
inline bool would_apply (hb_would_apply_context_t *c,
unsigned int lookup_type) const
{
TRACE_WOULD_APPLY ();
if (get_coverage (lookup_type).get_coverage (c->glyphs[0]) == NOT_COVERED) return false;
if (c->len == 1) {
switch (lookup_type) {
case Single:
case Multiple:
case Alternate:
case ReverseChainSingle:
return true;
}
}
/* Only need to look further for lookups that support substitutions
* of input longer than 1. */
switch (lookup_type) {
case Ligature: return u.ligature.would_apply (c);
case Context: return u.context.would_apply (c);
case ChainContext: return u.chainContext.would_apply (c);
case Extension: return u.extension.would_apply (c);
default: return false;
default: return c->default_return_value ();
}
}
@ -1286,36 +1229,35 @@ struct SubstLookup : Lookup
{
unsigned int lookup_type = get_type ();
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++)
if (c->stop_sublookup_iteration (get_subtable (i).process (c, lookup_type)))
return c->default_return_value;
return c->default_return_value;
for (unsigned int i = 0; i < count; i++) {
typename context_t::return_t r = get_subtable (i).process (c, lookup_type);
if (c->stop_sublookup_iteration (r))
return r;
}
return c->default_return_value ();
}
template <typename set_t>
inline void add_coverage (set_t *glyphs) const
{
hb_get_coverage_context_t c;
const Coverage *last = NULL;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
const Coverage *c = &get_subtable (i).get_coverage (get_type ());
if (c != last) {
c->add_coverage (glyphs);
last = c;
const Coverage *coverage = &get_subtable (i).process (&c, get_type ());
if (coverage != last) {
coverage->add_coverage (glyphs);
last = coverage;
}
}
}
inline bool would_apply (hb_would_apply_context_t *c, const hb_set_digest_t *digest) const
{
if (unlikely (!c->len)) return false;
if (!digest->may_have (c->glyphs[0])) return false;
unsigned int lookup_type = get_type ();
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++)
if (get_subtable (i).would_apply (c, lookup_type))
return true;
return false;
TRACE_WOULD_APPLY ();
if (unlikely (!c->len)) return TRACE_RETURN (false);
if (!digest->may_have (c->glyphs[0])) return TRACE_RETURN (false);
return TRACE_RETURN (process (c));
}
inline bool apply_once (hb_apply_context_t *c) const
@ -1491,7 +1433,7 @@ struct GSUB : GSUBGPOS
hb_set_t *glyphs,
unsigned int lookup_index) const
{
OT::hb_closure_context_t c (face, glyphs, closure_recurse_func);
hb_closure_context_t c (face, glyphs, closure_recurse_func);
return get_lookup (lookup_index).process (&c);
}
@ -1541,16 +1483,6 @@ inline typename context_t::return_t ExtensionSubst::process (context_t *c) const
return get_subtable ().process (c, get_type ());
}
inline const Coverage & ExtensionSubst::get_coverage (void) const
{
return get_subtable ().get_coverage (get_type ());
}
inline bool ExtensionSubst::would_apply (hb_would_apply_context_t *c) const
{
return get_subtable ().would_apply (c, get_type ());
}
inline bool ExtensionSubst::apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();

View File

@ -53,17 +53,17 @@ struct hb_closure_context_t
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
template <typename T>
inline return_t process (const T &obj) { obj.closure (this); return void_t (); }
static const return_t default_return_value;
static const return_t default_return_value (void) { return return_t (); }
bool stop_sublookup_iteration (const return_t r) const { return false; }
return_t recurse (unsigned int lookup_index)
{
if (unlikely (nesting_level_left == 0))
return default_return_value;
return default_return_value ();
nesting_level_left--;
recurse_func (this, lookup_index);
nesting_level_left++;
return default_return_value;
return default_return_value ();
}
hb_face_t *face;
@ -111,6 +111,13 @@ struct hb_would_apply_context_t
len (len_),
zero_context (zero_context_),
debug_depth (0) {};
typedef bool return_t;
template <typename T>
inline return_t process (const T &obj) { return obj.would_apply (this); }
static return_t default_return_value (void) { return false; }
bool stop_sublookup_iteration (const return_t r) const { return r; }
return_t recurse (unsigned int lookup_index) { return true; }
};
@ -148,19 +155,34 @@ struct hb_collect_glyphs_context_t
typedef void_t return_t;
template <typename T>
inline return_t process (const T &obj) { obj.collect_glyphs (this); return void_t (); }
static const return_t default_return_value;
static const return_t default_return_value (void) { return return_t (); }
bool stop_iteration (const return_t r) const { return false; }
return_t recurse (unsigned int lookup_index)
{
#if 0
/* XXX */
#endif
return default_return_value;
return default_return_value ();
}
};
struct hb_get_coverage_context_t
{
hb_get_coverage_context_t (void) {}
typedef const Coverage &return_t;
template <typename T>
inline return_t process (const T &obj) { return obj.get_coverage (); }
static return_t default_return_value (void) { return Null(Coverage); }
bool stop_sublookup_iteration (const return_t r) const { return true; /* Unused */ }
return_t recurse (unsigned int lookup_index)
{ return default_return_value (); }
};
#ifndef HB_DEBUG_APPLY
#define HB_DEBUG_APPLY (HB_DEBUG+0)
#endif
@ -1162,27 +1184,7 @@ struct Context
case 1: return c->process (u.format1);
case 2: return c->process (u.format2);
case 3: return c->process (u.format3);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
case 2: return u.format2.get_coverage ();
case 3: return u.format3.get_coverage ();
default:return Null(Coverage);
}
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
switch (u.format) {
case 1: return u.format1.would_apply (c);
case 2: return u.format2.would_apply (c);
case 3: return u.format3.would_apply (c);
default:return false;
default:return c->default_return_value ();
}
}
@ -1695,27 +1697,7 @@ struct ChainContext
case 1: return c->process (u.format1);
case 2: return c->process (u.format2);
case 3: return c->process (u.format3);
default:return c->default_return_value;
}
}
inline const Coverage &get_coverage (void) const
{
switch (u.format) {
case 1: return u.format1.get_coverage ();
case 2: return u.format2.get_coverage ();
case 3: return u.format3.get_coverage ();
default:return Null(Coverage);
}
}
inline bool would_apply (hb_would_apply_context_t *c) const
{
switch (u.format) {
case 1: return u.format1.would_apply (c);
case 2: return u.format2.would_apply (c);
case 3: return u.format3.would_apply (c);
default:return false;
default:return c->default_return_value ();
}
}