diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 56b3a4f61..a9933d14b 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -1429,6 +1429,12 @@ struct PosLookup : Lookup inline const PosLookupSubTable& get_subtable (unsigned int i) const { return this+CastR > (subTable)[i]; } + inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 3b6635bf9..fc37cd93d 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -37,6 +37,12 @@ namespace OT { 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 { TRACE_CLOSURE (this); @@ -115,6 +121,12 @@ struct SingleSubstFormat1 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 { TRACE_CLOSURE (this); @@ -251,6 +263,13 @@ struct SingleSubst 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 { TRACE_CLOSURE (this); @@ -315,6 +334,18 @@ struct Sequence 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 { TRACE_CLOSURE (this); @@ -440,6 +471,12 @@ typedef ArrayOf AlternateSet; /* Array of alternate GlyphIDs--in 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 { TRACE_CLOSURE (this); @@ -760,6 +797,12 @@ struct LigatureSet 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 { TRACE_CLOSURE (this); @@ -908,6 +951,12 @@ struct ExtensionSubst : Extension 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 { TRACE_CLOSURE (this); @@ -1145,6 +1194,13 @@ struct SubstLookup : Lookup 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); + return TRACE_RETURN (dispatch (c)); + } + inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 5169e7877..9fc638b75 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -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 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 + 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 #define HB_DEBUG_CLOSURE (HB_DEBUG+0) #endif @@ -1102,6 +1151,17 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, struct Rule { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const LookupRecord *lookupRecord = &StructAtOffset (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 { TRACE_CLOSURE (this); @@ -1161,6 +1221,16 @@ struct Rule 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 { TRACE_CLOSURE (this); @@ -1217,6 +1287,16 @@ struct RuleSet 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 { TRACE_CLOSURE (this); @@ -1303,6 +1383,16 @@ struct ContextFormat1 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 { TRACE_CLOSURE (this); @@ -1398,6 +1488,17 @@ struct ContextFormat2 struct ContextFormat3 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const LookupRecord *lookupRecord = &StructAtOffset (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 { TRACE_CLOSURE (this); @@ -1639,6 +1740,19 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, struct ChainRule { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const HeadlessArrayOf &input = StructAfter > (backtrack); + const ArrayOf &lookahead = StructAfter > (input); + const ArrayOf &lookup = StructAfter > (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 { TRACE_CLOSURE (this); @@ -1724,6 +1838,16 @@ struct ChainRule 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 { TRACE_CLOSURE (this); @@ -1777,6 +1901,16 @@ struct ChainRuleSet 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 { TRACE_CLOSURE (this); @@ -1860,6 +1994,16 @@ struct ChainContextFormat1 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 { TRACE_CLOSURE (this); @@ -1984,6 +2128,20 @@ struct ChainContextFormat2 struct ChainContextFormat3 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &lookahead = StructAfter > (input); + const ArrayOf &lookup = StructAfter > (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 { TRACE_CLOSURE (this);