[HarfBuzz] harfbuzz-ng: Branch 'master' - 12 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Mon Apr 23 13:57:52 PDT 2012
TODO | 3
src/Makefile.am | 7
src/hb-ot-layout-common-private.hh | 150 ++++++++++
src/hb-ot-layout-gpos-table.hh | 27 -
src/hb-ot-layout-gsub-table.hh | 422 ++++++++++++++++++++++++++++-
src/hb-ot-layout-gsubgpos-private.hh | 438 ++++++++++++++++++++++++++-----
src/hb-ot-layout-private.hh | 47 +++
src/hb-ot-layout.cc | 14
src/hb-ot-layout.h | 8
src/hb-ot-shape-complex-indic-private.hh | 264 ++++++++++++++++++
src/hb-ot-shape-complex-indic.cc | 227 ----------------
src/hb-private.hh | 4
src/hb-shape.cc | 2
src/indic.cc | 46 +++
14 files changed, 1326 insertions(+), 333 deletions(-)
New commits:
commit 31081f7390e5130df72f89acc609ccab5dc77a48
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 16:54:58 2012 -0400
Implement closure() for Context and ChainContext lookups
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 410c933..cec339b 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -131,6 +131,10 @@ struct RangeRecord
return c->check_struct (this);
}
+ inline bool intersects (const hb_glyph_map_t *glyphs) const {
+ return glyphs->intersects (start, end);
+ }
+
GlyphID start; /* First GlyphID in the range */
GlyphID end; /* Last GlyphID in the range */
USHORT value; /* Value */
@@ -354,6 +358,10 @@ struct CoverageFormat1
return glyphArray.sanitize (c);
}
+ inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ return glyphs->has (glyphArray[index]);
+ }
+
struct Iter {
inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
inline bool more (void) { return i < c->glyphArray.len; }
@@ -394,6 +402,21 @@ struct CoverageFormat2
return rangeRecord.sanitize (c);
}
+ inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ unsigned int i;
+ unsigned int count = rangeRecord.len;
+ for (i = 0; i < count; i++) {
+ const RangeRecord &range = rangeRecord[i];
+ if (range.value <= index &&
+ index < range.value + (range.end - range.start) &&
+ range.intersects (glyphs))
+ return true;
+ else if (index < range.value)
+ return false;
+ }
+ return false;
+ }
+
struct Iter {
inline void init (const CoverageFormat2 &c_) {
c = &c_;
@@ -461,7 +484,14 @@ struct Coverage
return true;
}
return false;
+ }
+ inline bool intersects_coverage (const hb_glyph_map_t *glyphs, unsigned int index) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_coverage (glyphs, index);
+ case 2: return u.format2.intersects_coverage (glyphs, index);
+ default:return false;
+ }
}
struct Iter {
@@ -544,6 +574,14 @@ struct ClassDefFormat1
&& classValue.sanitize (c);
}
+ inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ unsigned int count = classValue.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (classValue[i] == klass && glyphs->has (startGlyph + i))
+ return true;
+ return false;
+ }
+
USHORT classFormat; /* Format identifier--format = 1 */
GlyphID startGlyph; /* First GlyphID of the classValueArray */
ArrayOf<USHORT>
@@ -570,6 +608,14 @@ struct ClassDefFormat2
return rangeRecord.sanitize (c);
}
+ inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ unsigned int count = rangeRecord.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
+ return true;
+ return false;
+ }
+
USHORT classFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
rangeRecord; /* Array of glyph ranges--ordered by
@@ -601,6 +647,14 @@ struct ClassDef
}
}
+ inline bool intersects_class (const hb_glyph_map_t *glyphs, unsigned int klass) const {
+ switch (u.format) {
+ case 1: return u.format1.intersects_class (glyphs, klass);
+ case 2: return u.format2.intersects_class (glyphs, klass);
+ default:return false;
+ }
+ }
+
private:
union {
USHORT format; /* Format identifier */
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 46e322b..10cfd34 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -71,8 +71,6 @@ struct hb_closure_context_t
debug_depth (0) {}
};
-typedef bool (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
-
#ifndef HB_DEBUG_APPLY
@@ -229,31 +227,63 @@ struct hb_apply_context_t
+typedef bool (*intersects_func_t) (hb_glyph_map_t *glyphs, const USHORT &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, const void *data);
+typedef bool (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
typedef bool (*apply_lookup_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
-struct ContextFuncs
+struct ContextClosureFuncs
+{
+ intersects_func_t intersects;
+ closure_lookup_func_t closure;
+};
+struct ContextApplyFuncs
{
match_func_t match;
apply_lookup_func_t apply;
};
+static inline bool intersects_glyph (hb_glyph_map_t *glyphs, const USHORT &value, const void *data HB_UNUSED)
+{
+ return glyphs->has (value);
+}
+static inline bool intersects_class (hb_glyph_map_t *glyphs, const USHORT &value, const void *data)
+{
+ const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+ return class_def.intersects_class (glyphs, value);
+}
+static inline bool intersects_coverage (hb_glyph_map_t *glyphs, const USHORT &value, const void *data)
+{
+ const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
+ return (data+coverage).intersects (glyphs);
+}
+
+static inline bool intersects_array (hb_closure_context_t *c,
+ unsigned int count,
+ const USHORT values[],
+ intersects_func_t intersects_func,
+ const void *intersects_data)
+{
+ for (unsigned int i = 0; i < count; i++)
+ if (likely (!intersects_func (c->glyphs, values[i], intersects_data)))
+ return false;
+ return true;
+}
+
static inline bool match_glyph (hb_codepoint_t glyph_id, const USHORT &value, const void *data HB_UNUSED)
{
return glyph_id == value;
}
-
static inline bool match_class (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.get_class (glyph_id) == value;
}
-
static inline bool match_coverage (hb_codepoint_t glyph_id, const USHORT &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
- return (data+coverage) (glyph_id) != NOT_COVERED;
+ return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
}
@@ -345,6 +375,16 @@ struct LookupRecord
};
+static inline bool closure_lookup (hb_closure_context_t *c,
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+ closure_lookup_func_t closure_func)
+{
+ bool ret = false;
+ for (unsigned int i = 0; i < lookupCount; i++)
+ ret = closure_func (c, lookupRecord->lookupListIndex) || ret;
+ return ret;
+}
static inline bool apply_lookup (hb_apply_context_t *c,
unsigned int count, /* Including the first glyph */
@@ -408,18 +448,40 @@ static inline bool apply_lookup (hb_apply_context_t *c,
/* Contextual lookups */
-struct ContextLookupContext
+struct ContextClosureLookupContext
+{
+ ContextClosureFuncs funcs;
+ const void *intersects_data;
+};
+
+struct ContextApplyLookupContext
{
- ContextFuncs funcs;
+ ContextApplyFuncs funcs;
const void *match_data;
};
-static inline bool context_lookup (hb_apply_context_t *c,
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- ContextLookupContext &lookup_context)
+static inline bool context_closure_lookup (hb_closure_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextClosureLookupContext &lookup_context)
+{
+ return intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data)
+ && closure_lookup (c,
+ lookupCount, lookupRecord,
+ lookup_context.funcs.closure);
+}
+
+
+static inline bool context_apply_lookup (hb_apply_context_t *c,
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ContextApplyLookupContext &lookup_context)
{
hb_apply_context_t new_context = *c;
return match_input (c,
@@ -437,14 +499,25 @@ struct Rule
friend struct RuleSet;
private:
- inline bool apply (hb_apply_context_t *c, ContextLookupContext &lookup_context) const
+
+ inline bool closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE ();
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
+ return context_closure_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY ();
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (input, input[0].static_size * (inputCount ? inputCount - 1 : 0));
- return context_lookup (c,
- inputCount, input,
- lookupCount, lookupRecord,
- lookup_context);
+ return context_apply_lookup (c,
+ inputCount, input,
+ lookupCount, lookupRecord,
+ lookup_context);
}
public:
@@ -459,7 +532,7 @@ struct Rule
private:
USHORT inputCount; /* Total number of glyphs in input
- * glyph sequence--includes the first
+ * glyph sequence--includes the first
* glyph */
USHORT lookupCount; /* Number of LookupRecords */
USHORT input[VAR]; /* Array of match inputs--start with
@@ -472,7 +545,17 @@ struct Rule
struct RuleSet
{
- inline bool apply (hb_apply_context_t *c, ContextLookupContext &lookup_context) const
+ inline bool closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE ();
+ bool ret = false;
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ ret = (this+rule[i]).closure (c, lookup_context) || ret;
+ return ret;
+ }
+
+ inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY ();
unsigned int num_rules = rule.len;
@@ -481,7 +564,6 @@ struct RuleSet
if ((this+rule[i]).apply (c, lookup_context))
return true;
}
-
return false;
}
@@ -508,8 +590,22 @@ struct ContextFormat1
inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+
+ const Coverage &cov = (this+coverage);
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_glyph, closure_func},
+ NULL
+ };
+
+ bool ret = false;
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ ret = rule_set.closure (c, lookup_context) || ret;
+ }
+ return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -520,7 +616,7 @@ struct ContextFormat1
return false;
const RuleSet &rule_set = this+ruleSet[index];
- struct ContextLookupContext lookup_context = {
+ struct ContextApplyLookupContext lookup_context = {
{match_glyph, apply_func},
NULL
};
@@ -555,8 +651,24 @@ struct ContextFormat2
inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ if (!(this+coverage).intersects (c->glyphs))
+ return false;
+
+ const ClassDef &class_def = this+classDef;
+
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_class, closure_func},
+ NULL
+ };
+
+ bool ret = false;
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (class_def.intersects_class (c->glyphs, i)) {
+ const RuleSet &rule_set = this+ruleSet[i];
+ ret = rule_set.closure (c, lookup_context) || ret;
+ }
+ return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -569,7 +681,7 @@ struct ContextFormat2
const ClassDef &class_def = this+classDef;
index = class_def (c->buffer->info[c->buffer->idx].codepoint);
const RuleSet &rule_set = this+ruleSet[index];
- struct ContextLookupContext lookup_context = {
+ struct ContextApplyLookupContext lookup_context = {
{match_class, apply_func},
&class_def
};
@@ -608,8 +720,18 @@ struct ContextFormat3
inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ if (!(this+coverage[0]).intersects (c->glyphs))
+ return false;
+
+ const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
+ struct ContextClosureLookupContext lookup_context = {
+ {intersects_coverage, closure_func},
+ this
+ };
+ return context_closure_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -620,14 +742,14 @@ struct ContextFormat3
return false;
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverage, coverage[0].static_size * glyphCount);
- struct ContextLookupContext lookup_context = {
+ struct ContextApplyLookupContext lookup_context = {
{match_coverage, apply_func},
this
};
- return context_lookup (c,
- glyphCount, (const USHORT *) (coverage + 1),
- lookupCount, lookupRecord,
- lookup_context);
+ return context_apply_lookup (c,
+ glyphCount, (const USHORT *) (coverage + 1),
+ lookupCount, lookupRecord,
+ lookup_context);
}
inline bool sanitize (hb_sanitize_context_t *c) {
@@ -704,22 +826,53 @@ struct Context
/* Chaining Contextual lookups */
-struct ChainContextLookupContext
+struct ChainContextClosureLookupContext
{
- ContextFuncs funcs;
+ ContextClosureFuncs funcs;
+ const void *intersects_data[3];
+};
+
+struct ChainContextApplyLookupContext
+{
+ ContextApplyFuncs funcs;
const void *match_data[3];
};
-static inline bool chain_context_lookup (hb_apply_context_t *c,
- unsigned int backtrackCount,
- const USHORT backtrack[],
- unsigned int inputCount, /* Including the first glyph (not matched) */
- const USHORT input[], /* Array of input values--start with second glyph */
- unsigned int lookaheadCount,
- const USHORT lookahead[],
- unsigned int lookupCount,
- const LookupRecord lookupRecord[],
- ChainContextLookupContext &lookup_context)
+static inline bool chain_context_closure_lookup (hb_closure_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextClosureLookupContext &lookup_context)
+{
+ return intersects_array (c,
+ backtrackCount, backtrack,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[0])
+ && intersects_array (c,
+ inputCount ? inputCount - 1 : 0, input,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[1])
+ && intersects_array (c,
+ lookaheadCount, lookahead,
+ lookup_context.funcs.intersects, lookup_context.intersects_data[2])
+ && closure_lookup (c,
+ lookupCount, lookupRecord,
+ lookup_context.funcs.closure);
+}
+
+static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
+ unsigned int backtrackCount,
+ const USHORT backtrack[],
+ unsigned int inputCount, /* Including the first glyph (not matched) */
+ const USHORT input[], /* Array of input values--start with second glyph */
+ unsigned int lookaheadCount,
+ const USHORT lookahead[],
+ unsigned int lookupCount,
+ const LookupRecord lookupRecord[],
+ ChainContextApplyLookupContext &lookup_context)
{
/* First guess */
if (unlikely (c->buffer->backtrack_len () < backtrackCount ||
@@ -750,18 +903,33 @@ struct ChainRule
friend struct ChainRuleSet;
private:
- inline bool apply (hb_apply_context_t *c, ChainContextLookupContext &lookup_context) const
+
+ inline bool closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE ();
+ const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
+ const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
+ const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
+ return chain_context_closure_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY ();
const HeadlessArrayOf<USHORT> &input = StructAfter<HeadlessArrayOf<USHORT> > (backtrack);
const ArrayOf<USHORT> &lookahead = StructAfter<ArrayOf<USHORT> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
- return chain_context_lookup (c,
- backtrack.len, backtrack.array,
- input.len, input.array,
- lookahead.len, lookahead.array,
- lookup.len, lookup.array,
- lookup_context);
+ return chain_context_apply_lookup (c,
+ backtrack.len, backtrack.array,
+ input.len, input.array,
+ lookahead.len, lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
}
public:
@@ -796,7 +964,17 @@ struct ChainRule
struct ChainRuleSet
{
- inline bool apply (hb_apply_context_t *c, ChainContextLookupContext &lookup_context) const
+ inline bool closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
+ {
+ TRACE_CLOSURE ();
+ bool ret = false;
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++)
+ ret = (this+rule[i]).closure (c, lookup_context) || ret;
+ return ret;
+ }
+
+ inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY ();
unsigned int num_rules = rule.len;
@@ -831,8 +1009,21 @@ struct ChainContextFormat1
inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ const Coverage &cov = (this+coverage);
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_glyph, closure_func},
+ {NULL, NULL, NULL}
+ };
+
+ bool ret = false;
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (cov.intersects_coverage (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ ret = rule_set.closure (c, lookup_context) || ret;
+ }
+ return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -843,7 +1034,7 @@ struct ChainContextFormat1
return false;
const ChainRuleSet &rule_set = this+ruleSet[index];
- struct ChainContextLookupContext lookup_context = {
+ struct ChainContextApplyLookupContext lookup_context = {
{match_glyph, apply_func},
{NULL, NULL, NULL}
};
@@ -877,8 +1068,28 @@ struct ChainContextFormat2
inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ if (!(this+coverage).intersects (c->glyphs))
+ return false;
+
+ const ClassDef &backtrack_class_def = this+backtrackClassDef;
+ const ClassDef &input_class_def = this+inputClassDef;
+ const ClassDef &lookahead_class_def = this+lookaheadClassDef;
+
+ struct ChainContextClosureLookupContext lookup_context = {
+ {intersects_class, closure_func},
+ {&backtrack_class_def,
+ &input_class_def,
+ &lookahead_class_def}
+ };
+
+ bool ret = false;
+ unsigned int count = ruleSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (input_class_def.intersects_class (c->glyphs, i)) {
+ const ChainRuleSet &rule_set = this+ruleSet[i];
+ ret = rule_set.closure (c, lookup_context) || ret;
+ }
+ return ret;
}
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
@@ -894,7 +1105,7 @@ struct ChainContextFormat2
index = input_class_def (c->buffer->info[c->buffer->idx].codepoint);
const ChainRuleSet &rule_set = this+ruleSet[index];
- struct ChainContextLookupContext lookup_context = {
+ struct ChainContextApplyLookupContext lookup_context = {
{match_class, apply_func},
{&backtrack_class_def,
&input_class_def,
@@ -960,16 +1171,16 @@ struct ChainContextFormat3
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
- struct ChainContextLookupContext lookup_context = {
+ struct ChainContextApplyLookupContext lookup_context = {
{match_coverage, apply_func},
{this, this, this}
};
- return chain_context_lookup (c,
- backtrack.len, (const USHORT *) backtrack.array,
- input.len, (const USHORT *) input.array + 1,
- lookahead.len, (const USHORT *) lookahead.array,
- lookup.len, lookup.array,
- lookup_context);
+ return chain_context_apply_lookup (c,
+ backtrack.len, (const USHORT *) backtrack.array,
+ input.len, (const USHORT *) input.array + 1,
+ lookahead.len, (const USHORT *) lookahead.array,
+ lookup.len, lookup.array,
+ lookup_context);
}
inline bool sanitize (hb_sanitize_context_t *c) {
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index acc1d18..92f3c26 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -100,11 +100,8 @@ struct _hb_glyph_map_t
void clear (void) {
memset (elts, 0, sizeof elts);
}
- bool has (hb_codepoint_t g) const {
- if (unlikely (g > MAX_G)) return false;
- return !!(elt (g) & mask (g));
- }
- bool add (hb_codepoint_t g) {
+ bool add (hb_codepoint_t g)
+ {
if (unlikely (g > MAX_G)) return false;
elt_t &e = elt (g);
elt_t m = mask (g);
@@ -112,6 +109,22 @@ struct _hb_glyph_map_t
e |= m;
return ret;
}
+ bool has (hb_codepoint_t g) const
+ {
+ if (unlikely (g > MAX_G)) return false;
+ return !!(elt (g) & mask (g));
+ }
+ bool intersects (hb_codepoint_t first,
+ hb_codepoint_t last) const
+ {
+ if (unlikely (first > MAX_G)) return false;
+ if (unlikely (last > MAX_G)) last = MAX_G;
+ unsigned int end = last + 1;
+ for (hb_codepoint_t i = first; i < end; i++)
+ if (has (i))
+ return true;
+ return false;
+ }
private:
typedef uint32_t elt_t;
commit c64ddab3c34897cd520d4d73a054866e649e8793
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 15:28:35 2012 -0400
Flesh out closure() for GSUB
The GSUBGPOS part still missing.
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index c41010a..410c933 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -355,10 +355,11 @@ struct CoverageFormat1
}
struct Iter {
- void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
- bool more (void) { return i < c->glyphArray.len; }
- void next (void) { i++; }
- uint16_t get (void) { return c->glyphArray[i]; }
+ inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
+ inline bool more (void) { return i < c->glyphArray.len; }
+ inline void next (void) { i++; }
+ inline uint16_t get_glyph (void) { return c->glyphArray[i]; }
+ inline uint16_t get_coverage (void) { return i; }
private:
const struct CoverageFormat1 *c;
@@ -394,9 +395,15 @@ struct CoverageFormat2
}
struct Iter {
- void init (const CoverageFormat2 &c_) { c = &c_; i = 0; j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; }
- bool more (void) { return i < c->rangeRecord.len; }
- void next (void) {
+ inline void init (const CoverageFormat2 &c_) {
+ c = &c_;
+ coverage = 0;
+ i = 0;
+ j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0;
+ }
+ inline bool more (void) { return i < c->rangeRecord.len; }
+ inline void next (void) {
+ coverage++;
if (j == c->rangeRecord[i].end) {
i++;
if (more ())
@@ -405,13 +412,12 @@ struct CoverageFormat2
}
j++;
}
- uint16_t get (void) {
- return j;
- }
+ inline uint16_t get_glyph (void) { return j; }
+ inline uint16_t get_coverage (void) { return coverage; }
private:
const struct CoverageFormat2 *c;
- unsigned int i, j;
+ unsigned int i, j, coverage;
};
private:
@@ -447,8 +453,20 @@ struct Coverage
}
}
+ inline bool intersects (const hb_glyph_map_t *glyphs) const {
+ /* TODO speed this up */
+ Coverage::Iter iter;
+ for (iter.init (*this); iter.more (); iter.next ()) {
+ if (glyphs->has (iter.get_glyph ()))
+ return true;
+ }
+ return false;
+
+ }
+
struct Iter {
- void init (const Coverage &c_) {
+ Iter (void) : format (0) {};
+ inline void init (const Coverage &c_) {
format = c_.u.format;
switch (format) {
case 1: return u.format1.init (c_.u.format1);
@@ -456,30 +474,37 @@ struct Coverage
default:return;
}
}
- bool more (void) {
+ inline bool more (void) {
switch (format) {
case 1: return u.format1.more ();
case 2: return u.format2.more ();
default:return true;
}
}
- void next (void) {
+ inline void next (void) {
switch (format) {
case 1: u.format1.next (); break;
case 2: u.format2.next (); break;
default: break;
}
}
- uint16_t get (void) {
+ inline uint16_t get_glyph (void) {
+ switch (format) {
+ case 1: return u.format1.get_glyph ();
+ case 2: return u.format2.get_glyph ();
+ default:return true;
+ }
+ }
+ inline uint16_t get_coverage (void) {
switch (format) {
- case 1: return u.format1.get ();
- case 2: return u.format2.get ();
+ case 1: return u.format1.get_coverage ();
+ case 2: return u.format2.get_coverage ();
default:return true;
}
}
private:
- USHORT format;
+ unsigned int format;
union {
CoverageFormat1::Iter format1;
CoverageFormat2::Iter format2;
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index f0db228..1feb3c8 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -42,8 +42,14 @@ struct SingleSubstFormat1
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ hb_codepoint_t glyph_id = iter.get_glyph ();
+ if (c->glyphs->has (glyph_id))
+ ret = c->glyphs->add ((glyph_id + deltaGlyphID) & 0xFFFF) || ret;
+ }
+ return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -93,8 +99,13 @@ struct SingleSubstFormat2
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ ret = c->glyphs->add (substitute[iter.get_coverage ()]) || ret;
+ }
+ return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -200,8 +211,11 @@ struct Sequence
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ unsigned int count = substitute.len;
+ bool ret = false;
+ for (unsigned int i = 0; i < count; i++)
+ ret = c->glyphs->add (substitute[i]) || ret;
+ return ret;
}
inline bool apply (hb_apply_context_t *c) const
@@ -239,8 +253,13 @@ struct MultipleSubstFormat1
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ ret = (this+sequence[iter.get_coverage ()]).closure (c) || ret;
+ }
+ return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -338,8 +357,17 @@ struct AlternateSubstFormat1
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ())) {
+ const AlternateSet &alt_set = this+alternateSet[iter.get_coverage ()];
+ unsigned int count = alt_set.len;
+ for (unsigned int i = 0; i < count; i++)
+ ret = c->glyphs->add (alt_set[i]) || ret;
+ }
+ }
+ return ret;
}
inline bool would_apply (hb_codepoint_t glyph_id) const
@@ -454,8 +482,11 @@ struct Ligature
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ unsigned int count = component.len;
+ for (unsigned int i = 1; i < count; i++)
+ if (!c->glyphs->has (component[i]))
+ return false;
+ return c->glyphs->add (ligGlyph);
}
inline bool would_apply (hb_codepoint_t second) const
@@ -556,8 +587,14 @@ struct LigatureSet
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
+ bool ret = false;
+ unsigned int num_ligs = ligature.len;
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const Ligature &lig = this+ligature[i];
+ ret = lig.closure (c) || ret;
+ }
+ return ret;
}
inline bool would_apply (hb_codepoint_t second) const
@@ -609,7 +646,13 @@ struct LigatureSubstFormat1
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ ret = (this+ligatureSet[iter.get_coverage ()]).closure (c) || ret;
+ }
+ return ret;
return false;
}
@@ -755,13 +798,7 @@ struct ExtensionSubst : Extension
return StructAtOffset<SubstLookupSubTable> (this, offset);
}
- inline bool closure (hb_closure_context_t *c) const
- {
- TRACE_CLOSURE ();
- /* TODO FILLME */
- return false;
- }
-
+ inline bool closure (hb_closure_context_t *c) const;
inline bool would_apply (hb_codepoint_t glyph_id) const;
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const;
@@ -782,7 +819,27 @@ struct ReverseChainSingleSubstFormat1
inline bool closure (hb_closure_context_t *c) const
{
TRACE_CLOSURE ();
- /* TODO FILLME */
+ const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
+
+ unsigned int count;
+
+ count = backtrack.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+backtrack[i]).intersects (c->glyphs))
+ return false;
+
+ count = lookahead.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (!(this+lookahead[i]).intersects (c->glyphs))
+ return false;
+
+ const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID> > (lookahead);
+ bool ret = false;
+ Coverage::Iter iter;
+ for (iter.init (this+coverage); iter.more (); iter.next ()) {
+ if (c->glyphs->has (iter.get_glyph ()))
+ ret = c->glyphs->add (substitute[iter.get_coverage ()]) || ret;
+ }
return false;
}
@@ -1014,8 +1071,8 @@ struct SubstLookup : Lookup
inline bool closure (hb_closure_context_t *c) const
{
unsigned int lookup_type = get_type ();
- unsigned int count = get_subtable_count ();
bool ret = false;
+ unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++)
ret = get_subtable (i).closure (c, lookup_type) || ret;
return ret;
@@ -1054,8 +1111,8 @@ struct SubstLookup : Lookup
*
* This is rather slow to do this here for every glyph,
* but it's easiest, and who uses extension lookups anyway?!*/
- unsigned int count = get_subtable_count ();
unsigned int type = get_subtable(0).u.extension.get_type ();
+ unsigned int count = get_subtable_count ();
for (unsigned int i = 1; i < count; i++)
if (get_subtable(i).u.extension.get_type () != type)
return false;
@@ -1174,6 +1231,11 @@ GSUB::substitute_finish (hb_buffer_t *buffer)
/* Out-of-class implementation for methods recursing */
+inline bool ExtensionSubst::closure (hb_closure_context_t *c) const
+{
+ return get_subtable ().closure (c, get_type ());
+}
+
inline bool ExtensionSubst::would_apply (hb_codepoint_t glyph_id) const
{
return get_subtable ().would_apply (glyph_id, get_type ());
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index bf7e43b..acc1d18 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -95,4 +95,38 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout);
+struct _hb_glyph_map_t
+{
+ void clear (void) {
+ memset (elts, 0, sizeof elts);
+ }
+ bool has (hb_codepoint_t g) const {
+ if (unlikely (g > MAX_G)) return false;
+ return !!(elt (g) & mask (g));
+ }
+ bool add (hb_codepoint_t g) {
+ if (unlikely (g > MAX_G)) return false;
+ elt_t &e = elt (g);
+ elt_t m = mask (g);
+ bool ret = !!(e & m);
+ e |= m;
+ return ret;
+ }
+
+ private:
+ typedef uint32_t elt_t;
+ static const unsigned int MAX_G = 65536 - 1;
+ static const unsigned int SHIFT = 5;
+ static const unsigned int BITS = (1 << SHIFT);
+ static const unsigned int MASK = BITS - 1;
+
+ elt_t &elt (hb_codepoint_t g) { return elts[g >> SHIFT]; }
+ elt_t elt (hb_codepoint_t g) const { return elts[g >> SHIFT]; }
+ elt_t mask (hb_codepoint_t g) const { return elt_t (1) << (g & MASK); }
+
+ elt_t elts[(MAX_G + 1 + (BITS - 1)) / BITS]; /* 8kb */
+ ASSERT_STATIC (sizeof (elt_t) * 8 == BITS);
+ ASSERT_STATIC (sizeof (elts) * 8 > MAX_G);
+};
+
#endif /* HB_OT_LAYOUT_PRIVATE_HH */
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 16addc6..a9db04f 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -183,7 +183,7 @@ void
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
-typedef uint32_t hb_glyph_map_t[65536 / 32]; /* 8kb */
+typedef struct _hb_glyph_map_t hb_glyph_map_t;
hb_bool_t
hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
commit 0da132bde4d576a03095d6738507954f7f85103d
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 14:21:33 2012 -0400
Fix Coverage iters
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 48840f2..c41010a 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -357,7 +357,8 @@ struct CoverageFormat1
struct Iter {
void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
bool more (void) { return i < c->glyphArray.len; }
- uint16_t next (void) { return c->glyphArray[i++]; }
+ void next (void) { i++; }
+ uint16_t get (void) { return c->glyphArray[i]; }
private:
const struct CoverageFormat1 *c;
@@ -394,14 +395,18 @@ struct CoverageFormat2
struct Iter {
void init (const CoverageFormat2 &c_) { c = &c_; i = 0; j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; }
- bool more (void) { return i < c->rangeRecord.len ||
- (i == c->rangeRecord.len && j < c->rangeRecord[i].end); }
- uint16_t next (void) {
+ bool more (void) { return i < c->rangeRecord.len; }
+ void next (void) {
if (j == c->rangeRecord[i].end) {
i++;
- j = c->rangeRecord[i].start;
+ if (more ())
+ j = c->rangeRecord[i].start;
+ return;
}
- return j++;
+ j++;
+ }
+ uint16_t get (void) {
+ return j;
}
private:
@@ -458,10 +463,17 @@ struct Coverage
default:return true;
}
}
- uint16_t next (void) {
+ void next (void) {
+ switch (format) {
+ case 1: u.format1.next (); break;
+ case 2: u.format2.next (); break;
+ default: break;
+ }
+ }
+ uint16_t get (void) {
switch (format) {
- case 1: return u.format1.next ();
- case 2: return u.format2.next ();
+ case 1: return u.format1.get ();
+ case 2: return u.format2.get ();
default:return true;
}
}
commit 3e32cd9570fd8b09901fb790b80365ae425f681a
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 13:20:52 2012 -0400
Minor
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 810a495..46e322b 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -31,7 +31,6 @@
#include "hb-buffer-private.hh"
#include "hb-ot-layout-gdef-table.hh"
-#include "hb-ot-layout-closure.h"
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index b018661..4441a7e 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -471,9 +471,9 @@ hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
}
hb_bool_t
-hb_ot_layout_closure_lookup (hb_face_t *face,
- hb_glyph_map_t *glyphs,
- unsigned int lookup_index)
+hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+ hb_glyph_map_t *glyphs,
+ unsigned int lookup_index)
{
hb_closure_context_t c (face, glyphs);
return _get_gsub (face).closure_lookup (&c, lookup_index);
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 430e54c..16addc6 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -182,6 +182,14 @@ hb_ot_layout_substitute_lookup (hb_face_t *face,
void
hb_ot_layout_substitute_finish (hb_buffer_t *buffer);
+
+typedef uint32_t hb_glyph_map_t[65536 / 32]; /* 8kb */
+
+hb_bool_t
+hb_ot_layout_substitute_closure_lookup (hb_face_t *face,
+ hb_glyph_map_t *glyphs,
+ unsigned int lookup_index);
+
/*
* GPOS
*/
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 64cb3c8..4f211a1 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -34,9 +34,11 @@
#endif
#include "hb.h"
-#include "hb-ot.h"
#define HB_H_IN
+#ifdef HAVE_OT
+#include "hb-ot.h"
#define HB_OT_H_IN
+#endif
#include <stdlib.h>
#include <stddef.h>
commit 650ac00da3d2f988197393f34d40f0ba1a0fa093
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 13:17:09 2012 -0400
Minor refactoring
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 7a3c117..6e5b85e 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1417,24 +1417,22 @@ struct PosLookup : Lookup
return false;
}
- inline bool apply_string (hb_font_t *font,
- hb_buffer_t *buffer,
- hb_mask_t mask) const
+ inline bool apply_string (hb_apply_context_t *c) const
{
bool ret = false;
- if (unlikely (!buffer->len))
+ if (unlikely (!c->buffer->len))
return false;
- hb_apply_context_t c (font, font->face, buffer, mask, *this);
+ c->set_lookup (*this);
- buffer->idx = 0;
- while (buffer->idx < buffer->len)
+ c->buffer->idx = 0;
+ while (c->buffer->idx < c->buffer->len)
{
- if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
+ if ((c->buffer->info[c->buffer->idx].mask & c->lookup_mask) && apply_once (c))
ret = true;
else
- buffer->idx++;
+ c->buffer->idx++;
}
return ret;
@@ -1461,11 +1459,8 @@ struct GPOS : GSUBGPOS
inline const PosLookup& get_lookup (unsigned int i) const
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
- inline bool position_lookup (hb_font_t *font,
- hb_buffer_t *buffer,
- unsigned int lookup_index,
- hb_mask_t mask) const
- { return get_lookup (lookup_index).apply_string (font, buffer, mask); }
+ inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
+ { return get_lookup (lookup_index).apply_string (c); }
static inline void position_start (hb_buffer_t *buffer);
static inline void position_finish (hb_buffer_t *buffer);
@@ -1584,7 +1579,9 @@ static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_i
if (unlikely (c->context_length < 1))
return false;
- hb_apply_context_t new_c (*c, l);
+ hb_apply_context_t new_c (*c);
+ new_c.nesting_level_left--;
+ new_c.set_lookup (l);
return l.apply_once (&new_c);
}
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 54d81e5..f0db228 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1069,46 +1069,44 @@ struct SubstLookup : Lookup
return false;
}
- inline bool apply_string (hb_face_t *face,
- hb_buffer_t *buffer,
- hb_mask_t mask) const
+ inline bool apply_string (hb_apply_context_t *c) const
{
bool ret = false;
- if (unlikely (!buffer->len))
+ if (unlikely (!c->buffer->len))
return false;
- hb_apply_context_t c (NULL, face, buffer, mask, *this);
+ c->set_lookup (*this);
if (likely (!is_reverse ()))
{
/* in/out forward substitution */
- buffer->clear_output ();
- buffer->idx = 0;
- while (buffer->idx < buffer->len)
+ c->buffer->clear_output ();
+ c->buffer->idx = 0;
+ while (c->buffer->idx < c->buffer->len)
{
- if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
+ if ((c->buffer->info[c->buffer->idx].mask & c->lookup_mask) && apply_once (c))
ret = true;
else
- buffer->next_glyph ();
+ c->buffer->next_glyph ();
}
if (ret)
- buffer->swap_buffers ();
+ c->buffer->swap_buffers ();
}
else
{
/* in-place backward substitution */
- buffer->idx = buffer->len - 1;
+ c->buffer->idx = c->buffer->len - 1;
do
{
- if ((buffer->info[buffer->idx].mask & mask) && apply_once (&c))
+ if ((c->buffer->info[c->buffer->idx].mask & c->lookup_mask) && apply_once (c))
ret = true;
else
- buffer->idx--;
+ c->buffer->idx--;
}
- while ((int) buffer->idx >= 0);
+ while ((int) c->buffer->idx >= 0);
}
return ret;
@@ -1135,11 +1133,8 @@ struct GSUB : GSUBGPOS
inline const SubstLookup& get_lookup (unsigned int i) const
{ return CastR<SubstLookup> (GSUBGPOS::get_lookup (i)); }
- inline bool substitute_lookup (hb_face_t *face,
- hb_buffer_t *buffer,
- unsigned int lookup_index,
- hb_mask_t mask) const
- { return get_lookup (lookup_index).apply_string (face, buffer, mask); }
+ inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index) const
+ { return get_lookup (lookup_index).apply_string (c); }
static inline void substitute_start (hb_buffer_t *buffer);
static inline void substitute_finish (hb_buffer_t *buffer);
@@ -1238,7 +1233,9 @@ static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup
if (unlikely (c->context_length < 1))
return false;
- hb_apply_context_t new_c (*c, l);
+ hb_apply_context_t new_c (*c);
+ new_c.nesting_level_left--;
+ new_c.set_lookup (l);
return l.apply_once (&new_c);
}
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index d5bc377..810a495 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -103,7 +103,6 @@ struct hb_apply_context_t
hb_face_t *face_,
hb_buffer_t *buffer_,
hb_mask_t lookup_mask_,
- const Lookup &l,
unsigned int context_length_ = NO_CONTEXT,
unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
font (font_), face (face_), buffer (buffer_),
@@ -111,12 +110,9 @@ struct hb_apply_context_t
lookup_mask (lookup_mask_),
context_length (context_length_),
nesting_level_left (nesting_level_left_),
- lookup_props (l.get_props ()),
- property (0), debug_depth (0) {}
+ lookup_props (0), property (0), debug_depth (0) {}
- hb_apply_context_t (const hb_apply_context_t &c, const Lookup &l) {
- *this = c;
- nesting_level_left--;
+ void set_lookup (const Lookup &l) {
lookup_props = l.get_props ();
}
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index e515890..b018661 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -460,7 +460,8 @@ hb_ot_layout_substitute_lookup (hb_face_t *face,
unsigned int lookup_index,
hb_mask_t mask)
{
- return _get_gsub (face).substitute_lookup (face, buffer, lookup_index, mask);
+ hb_apply_context_t c (NULL, face, buffer, mask);
+ return _get_gsub (face).substitute_lookup (&c, lookup_index);
}
void
@@ -500,7 +501,8 @@ hb_ot_layout_position_lookup (hb_font_t *font,
unsigned int lookup_index,
hb_mask_t mask)
{
- return _get_gpos (font->face).position_lookup (font, buffer, lookup_index, mask);
+ hb_apply_context_t c (font, font->face, buffer, mask);
+ return _get_gpos (font->face).position_lookup (&c, lookup_index);
}
void
commit f94b0aa64609654497ced9c00312c9643eb69053
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 13:04:38 2012 -0400
Add "closure" operation stubs to GSUB
Filling in.
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index f2210a0..54d81e5 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -39,6 +39,13 @@ struct SingleSubstFormat1
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
return (this+coverage) (glyph_id) != NOT_COVERED;
@@ -83,6 +90,13 @@ struct SingleSubstFormat2
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
return (this+coverage) (glyph_id) != NOT_COVERED;
@@ -129,6 +143,16 @@ struct SingleSubst
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c);
+ case 2: return u.format2.closure (c);
+ default:return false;
+ }
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
switch (u.format) {
@@ -172,6 +196,14 @@ struct Sequence
friend struct MultipleSubstFormat1;
private:
+
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -204,6 +236,13 @@ struct MultipleSubstFormat1
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
return (this+coverage) (glyph_id) != NOT_COVERED;
@@ -244,6 +283,15 @@ struct MultipleSubst
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c);
+ default:return false;
+ }
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
switch (u.format) {
@@ -287,6 +335,13 @@ struct AlternateSubstFormat1
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
return (this+coverage) (glyph_id) != NOT_COVERED;
@@ -347,6 +402,15 @@ struct AlternateSubst
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c);
+ default:return false;
+ }
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const
{
switch (u.format) {
@@ -387,6 +451,13 @@ struct Ligature
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t second) const
{
return component.len == 2 && component[1] == second;
@@ -482,6 +553,13 @@ struct LigatureSet
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t second) const
{
unsigned int num_ligs = ligature.len;
@@ -528,6 +606,13 @@ struct LigatureSubstFormat1
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
{
unsigned int index;
@@ -572,6 +657,15 @@ struct LigatureSubst
private:
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c);
+ default:return false;
+ }
+ }
+
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
{
switch (u.format) {
@@ -607,12 +701,20 @@ struct LigatureSubst
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index);
+static inline bool closure_lookup (hb_closure_context_t *c, unsigned int lookup_index);
struct ContextSubst : Context
{
friend struct SubstLookupSubTable;
private:
+
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ return Context::closure (c, closure_lookup);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -625,6 +727,13 @@ struct ChainContextSubst : ChainContext
friend struct SubstLookupSubTable;
private:
+
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ return ChainContext::closure (c, closure_lookup);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -646,6 +755,13 @@ struct ExtensionSubst : Extension
return StructAtOffset<SubstLookupSubTable> (this, offset);
}
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id) const;
inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const;
@@ -662,6 +778,14 @@ struct ReverseChainSingleSubstFormat1
friend struct ReverseChainSingleSubst;
private:
+
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -728,6 +852,16 @@ struct ReverseChainSingleSubst
friend struct SubstLookupSubTable;
private:
+
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -774,6 +908,23 @@ struct SubstLookupSubTable
ReverseChainSingle = 8
};
+ inline bool closure (hb_closure_context_t *c,
+ unsigned int lookup_type) const
+ {
+ TRACE_CLOSURE ();
+ switch (lookup_type) {
+ case Single: return u.single.closure (c);
+ case Multiple: return u.multiple.closure (c);
+ case Alternate: return u.alternate.closure (c);
+ case Ligature: return u.ligature.closure (c);
+ case Context: return u.c.closure (c);
+ case ChainContext: return u.chainContext.closure (c);
+ case Extension: return u.extension.closure (c);
+ case ReverseChainSingle: return u.reverseChainContextSingle.closure (c);
+ default:return false;
+ }
+ }
+
inline bool would_apply (hb_codepoint_t glyph_id,
unsigned int lookup_type) const
{
@@ -860,6 +1011,15 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
+ inline bool closure (hb_closure_context_t *c) const
+ {
+ unsigned int lookup_type = get_type ();
+ unsigned int count = get_subtable_count ();
+ bool ret = false;
+ for (unsigned int i = 0; i < count; i++)
+ ret = get_subtable (i).closure (c, lookup_type) || ret;
+ return ret;
+ }
inline bool would_apply (hb_codepoint_t glyph_id) const
{
@@ -984,6 +1144,10 @@ struct GSUB : GSUBGPOS
static inline void substitute_start (hb_buffer_t *buffer);
static inline void substitute_finish (hb_buffer_t *buffer);
+ inline bool closure_lookup (hb_closure_context_t *c,
+ unsigned int lookup_index) const
+ { return get_lookup (lookup_index).closure (c); }
+
inline bool sanitize (hb_sanitize_context_t *c) {
TRACE_SANITIZE ();
if (unlikely (!GSUBGPOS::sanitize (c))) return false;
@@ -1048,6 +1212,21 @@ inline bool ExtensionSubst::is_reverse (void) const
return SubstLookup::lookup_type_is_reverse (type);
}
+static inline bool closure_lookup (hb_closure_context_t *c, unsigned int lookup_index)
+{
+ const GSUB &gsub = *(c->face->ot_layout->gsub);
+ const SubstLookup &l = gsub.get_lookup (lookup_index);
+
+ if (unlikely (c->nesting_level_left == 0))
+ return false;
+
+ c->nesting_level_left--;
+ bool ret = l.closure (c);
+ c->nesting_level_left++;
+
+ return ret;
+}
+
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
{
const GSUB &gsub = *(c->face->ot_layout->gsub);
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 62ac29e..d5bc377 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -31,6 +31,8 @@
#include "hb-buffer-private.hh"
#include "hb-ot-layout-gdef-table.hh"
+#include "hb-ot-layout-closure.h"
+
/* buffer var allocations */
@@ -45,6 +47,35 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
+#ifndef HB_DEBUG_CLOSURE
+#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
+#endif
+
+#define TRACE_CLOSURE() \
+ hb_auto_trace_t<HB_DEBUG_CLOSURE> trace (&c->debug_depth, "CLOSURE", this, NULL, HB_FUNC);
+
+
+
+struct hb_closure_context_t
+{
+ hb_face_t *face;
+ hb_glyph_map_t *glyphs;
+ unsigned int nesting_level_left;
+ unsigned int debug_depth;
+
+
+ hb_closure_context_t (hb_face_t *face_,
+ hb_glyph_map_t *glyphs_,
+ unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) :
+ face (face_), glyphs (glyphs_),
+ nesting_level_left (nesting_level_left_),
+ debug_depth (0) {}
+};
+
+typedef bool (*closure_lookup_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
+
+
+
#ifndef HB_DEBUG_APPLY
#define HB_DEBUG_APPLY (HB_DEBUG+0)
#endif
@@ -56,7 +87,6 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) {
struct hb_apply_context_t
{
- unsigned int debug_depth;
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
@@ -66,6 +96,7 @@ struct hb_apply_context_t
unsigned int nesting_level_left;
unsigned int lookup_props;
unsigned int property; /* propety of first glyph */
+ unsigned int debug_depth;
hb_apply_context_t (hb_font_t *font_,
@@ -81,7 +112,7 @@ struct hb_apply_context_t
context_length (context_length_),
nesting_level_left (nesting_level_left_),
lookup_props (l.get_props ()),
- property (0) {}
+ property (0), debug_depth (0) {}
hb_apply_context_t (const hb_apply_context_t &c, const Lookup &l) {
*this = c;
@@ -427,8 +458,8 @@ struct Rule
return inputCount.sanitize (c)
&& lookupCount.sanitize (c)
&& c->check_range (input,
- input[0].static_size * inputCount
- + lookupRecordX[0].static_size * lookupCount);
+ input[0].static_size * inputCount
+ + lookupRecordX[0].static_size * lookupCount);
}
private:
@@ -478,6 +509,14 @@ struct ContextFormat1
friend struct Context;
private:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -517,6 +556,14 @@ struct ContextFormat2
friend struct Context;
private:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -562,6 +609,14 @@ struct ContextFormat3
friend struct Context;
private:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -608,6 +663,18 @@ struct ContextFormat3
struct Context
{
protected:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c, closure_func);
+ case 2: return u.format2.closure (c, closure_func);
+ case 3: return u.format3.closure (c, closure_func);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -765,6 +832,14 @@ struct ChainContextFormat1
friend struct ChainContext;
private:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -803,6 +878,14 @@ struct ChainContextFormat2
friend struct ChainContext;
private:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -864,6 +947,13 @@ struct ChainContextFormat3
private:
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ /* TODO FILLME */
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
@@ -922,6 +1012,18 @@ struct ChainContextFormat3
struct ChainContext
{
protected:
+
+ inline bool closure (hb_closure_context_t *c, closure_lookup_func_t closure_func) const
+ {
+ TRACE_CLOSURE ();
+ switch (u.format) {
+ case 1: return u.format1.closure (c, closure_func);
+ case 2: return u.format2.closure (c, closure_func);
+ case 3: return u.format3.closure (c, closure_func);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c, apply_lookup_func_t apply_func) const
{
TRACE_APPLY ();
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index f3e0713..e515890 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -469,6 +469,14 @@ hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED)
GSUB::substitute_finish (buffer);
}
+hb_bool_t
+hb_ot_layout_closure_lookup (hb_face_t *face,
+ hb_glyph_map_t *glyphs,
+ unsigned int lookup_index)
+{
+ hb_closure_context_t c (face, glyphs);
+ return _get_gsub (face).closure_lookup (&c, lookup_index);
+}
/*
* GPOS
commit 7d50d502635d7c95e6bd091e7d4cc993f0853f76
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Mon Apr 23 13:02:14 2012 -0400
Add Coverage iterators
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index ff967ea..48840f2 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -354,6 +354,16 @@ struct CoverageFormat1
return glyphArray.sanitize (c);
}
+ struct Iter {
+ void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; };
+ bool more (void) { return i < c->glyphArray.len; }
+ uint16_t next (void) { return c->glyphArray[i++]; }
+
+ private:
+ const struct CoverageFormat1 *c;
+ unsigned int i;
+ };
+
private:
USHORT coverageFormat; /* Format identifier--format = 1 */
SortedArrayOf<GlyphID>
@@ -382,6 +392,23 @@ struct CoverageFormat2
return rangeRecord.sanitize (c);
}
+ struct Iter {
+ void init (const CoverageFormat2 &c_) { c = &c_; i = 0; j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; }
+ bool more (void) { return i < c->rangeRecord.len ||
+ (i == c->rangeRecord.len && j < c->rangeRecord[i].end); }
+ uint16_t next (void) {
+ if (j == c->rangeRecord[i].end) {
+ i++;
+ j = c->rangeRecord[i].start;
+ }
+ return j++;
+ }
+
+ private:
+ const struct CoverageFormat2 *c;
+ unsigned int i, j;
+ };
+
private:
USHORT coverageFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
@@ -415,6 +442,38 @@ struct Coverage
}
}
+ struct Iter {
+ void init (const Coverage &c_) {
+ format = c_.u.format;
+ switch (format) {
+ case 1: return u.format1.init (c_.u.format1);
+ case 2: return u.format2.init (c_.u.format2);
+ default:return;
+ }
+ }
+ bool more (void) {
+ switch (format) {
+ case 1: return u.format1.more ();
+ case 2: return u.format2.more ();
+ default:return true;
+ }
+ }
+ uint16_t next (void) {
+ switch (format) {
+ case 1: return u.format1.next ();
+ case 2: return u.format2.next ();
+ default:return true;
+ }
+ }
+
+ private:
+ USHORT format;
+ union {
+ CoverageFormat1::Iter format1;
+ CoverageFormat2::Iter format2;
+ } u;
+ };
+
private:
union {
USHORT format; /* Format identifier */
commit 3ed4634ec349fa9e943ad23718c04be4dd4bba62
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 19 22:34:06 2012 -0400
Add Indic inspection tool
diff --git a/src/Makefile.am b/src/Makefile.am
index 9311ab7..f53505e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -67,6 +67,7 @@ HBSOURCES += \
hb-ot-shape-complex-arabic-table.hh \
hb-ot-shape-complex-indic.cc \
hb-ot-shape-complex-indic-machine.hh \
+ hb-ot-shape-complex-indic-private.hh \
hb-ot-shape-complex-indic-table.hh \
hb-ot-shape-complex-misc.cc \
hb-ot-shape-complex-private.hh \
@@ -169,13 +170,17 @@ hb-ot-shape-complex-indic-machine.hh: hb-ot-shape-complex-indic-machine.rl
$(AM_V_GEN)$(top_srcdir)/missing --run ragel -e -F1 -o "$@.tmp" "$<" && \
mv "$@.tmp" "$@" || ( $(RM) "$@.tmp" && false )
-noinst_PROGRAMS = main
+noinst_PROGRAMS = main indic
bin_PROGRAMS =
main_SOURCES = main.cc
main_CPPFLAGS = $(HBCFLAGS)
main_LDADD = libharfbuzz.la $(HBLIBS)
+indic_SOURCES = indic.cc
+indic_CPPFLAGS = $(HBCFLAGS)
+indic_LDADD = libharfbuzz.la $(HBLIBS)
+
dist_check_SCRIPTS = \
check-c-linkage-decls.sh \
check-header-guards.sh \
diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh
new file mode 100644
index 0000000..b7bce17
--- /dev/null
+++ b/src/hb-ot-shape-complex-indic-private.hh
@@ -0,0 +1,264 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+#define HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH
+
+#include "hb-private.hh"
+
+
+#include "hb-ot-shape-complex-private.hh"
+
+
+/* buffer var allocations */
+#define indic_category() complex_var_persistent_u8_0() /* indic_category_t */
+#define indic_position() complex_var_persistent_u8_1() /* indic_matra_category_t */
+
+#define INDIC_TABLE_ELEMENT_TYPE uint8_t
+
+/* Cateories used in the OpenType spec:
+ * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
+ */
+/* Note: This enum is duplicated in the -machine.rl source file.
+ * Not sure how to avoid duplication. */
+enum indic_category_t {
+ OT_X = 0,
+ OT_C,
+ OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
+ OT_V,
+ OT_N,
+ OT_H,
+ OT_ZWNJ,
+ OT_ZWJ,
+ OT_M,
+ OT_SM,
+ OT_VD,
+ OT_A,
+ OT_NBSP
+};
+
+/* Visual positions in a syllable from left to right. */
+enum indic_position_t {
+ POS_PRE = 1,
+ POS_BASE = 2,
+ POS_ABOVE = 3,
+ POS_BELOW = 4,
+ POS_POST = 5
+};
+
+/* Categories used in IndicSyllabicCategory.txt from UCD */
+/* The assignments are guesswork */
+enum indic_syllabic_category_t {
+ INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
+
+ INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
+ INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
+ INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_C,
+ INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
+ INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
+ INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_X,
+ INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
+ INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
+ INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
+ INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
+};
+
+/* Categories used in IndicSMatraCategory.txt from UCD */
+enum indic_matra_category_t {
+ INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_BASE,
+
+ INDIC_MATRA_CATEGORY_LEFT = POS_PRE - 1, /* Move *before* existing "pre" chars */
+ INDIC_MATRA_CATEGORY_TOP = POS_ABOVE,
+ INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW,
+ INDIC_MATRA_CATEGORY_RIGHT = POS_POST,
+
+ /* We don't really care much about these since we decompose them
+ * in the generic pre-shaping layer. They will only be used if
+ * the font does not cover the decomposition. In which case, we
+ * define these as aliases to the place we want the split-matra
+ * glyph to show up. Quite arbitrary.
+ *
+ * TODO: There are some split matras without Unicode decompositions.
+ * We have to figure out what to do with them.
+ */
+ INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_RIGHT,
+
+ INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
+ INDIC_MATRA_CATEGORY_OVERSTRUCK = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
+ INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = INDIC_MATRA_CATEGORY_NOT_APPLICABLE
+};
+
+/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
+ * because gcc fails to optimize the latter and fills the table in at runtime. */
+#define INDIC_COMBINE_CATEGORIES(S,M) \
+ (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
+ ASSERT_STATIC_EXPR_ZERO (S < 16 && M < 16) + \
+ ((M << 4) | S))
+
+
+#include "hb-ot-shape-complex-indic-table.hh"
+
+/* XXX
+ * This is a hack for now. We should:
+ * 1. Move this data into the main Indic table,
+ * and/or
+ * 2. Probe font lookups to determine consonant positions.
+ */
+static const struct consonant_position_t {
+ hb_codepoint_t u;
+ indic_position_t position;
+} consonant_positions[] = {
+ {0x0930, POS_BELOW},
+ {0x09AC, POS_BELOW},
+ {0x09AF, POS_POST},
+ {0x09B0, POS_BELOW},
+ {0x09F0, POS_BELOW},
+ {0x0A2F, POS_POST},
+ {0x0A30, POS_BELOW},
+ {0x0A35, POS_BELOW},
+ {0x0A39, POS_BELOW},
+ {0x0AB0, POS_BELOW},
+ {0x0B24, POS_BELOW},
+ {0x0B28, POS_BELOW},
+ {0x0B2C, POS_BELOW},
+ {0x0B2D, POS_BELOW},
+ {0x0B2E, POS_BELOW},
+ {0x0B2F, POS_POST},
+ {0x0B30, POS_BELOW},
+ {0x0B32, POS_BELOW},
+ {0x0B33, POS_BELOW},
+ {0x0B5F, POS_POST},
+ {0x0B71, POS_BELOW},
+ {0x0C15, POS_BELOW},
+ {0x0C16, POS_BELOW},
+ {0x0C17, POS_BELOW},
+ {0x0C18, POS_BELOW},
+ {0x0C19, POS_BELOW},
+ {0x0C1A, POS_BELOW},
+ {0x0C1B, POS_BELOW},
+ {0x0C1C, POS_BELOW},
+ {0x0C1D, POS_BELOW},
+ {0x0C1E, POS_BELOW},
+ {0x0C1F, POS_BELOW},
+ {0x0C20, POS_BELOW},
+ {0x0C21, POS_BELOW},
+ {0x0C22, POS_BELOW},
+ {0x0C23, POS_BELOW},
+ {0x0C24, POS_BELOW},
+ {0x0C25, POS_BELOW},
+ {0x0C26, POS_BELOW},
+ {0x0C27, POS_BELOW},
+ {0x0C28, POS_BELOW},
+ {0x0C2A, POS_BELOW},
+ {0x0C2B, POS_BELOW},
+ {0x0C2C, POS_BELOW},
+ {0x0C2D, POS_BELOW},
+ {0x0C2E, POS_BELOW},
+ {0x0C2F, POS_BELOW},
+ {0x0C30, POS_BELOW},
+ {0x0C32, POS_BELOW},
+ {0x0C33, POS_BELOW},
+ {0x0C35, POS_BELOW},
+ {0x0C36, POS_BELOW},
+ {0x0C37, POS_BELOW},
+ {0x0C38, POS_BELOW},
+ {0x0C39, POS_BELOW},
+ {0x0C95, POS_BELOW},
+ {0x0C96, POS_BELOW},
+ {0x0C97, POS_BELOW},
+ {0x0C98, POS_BELOW},
+ {0x0C99, POS_BELOW},
+ {0x0C9A, POS_BELOW},
+ {0x0C9B, POS_BELOW},
+ {0x0C9C, POS_BELOW},
+ {0x0C9D, POS_BELOW},
+ {0x0C9E, POS_BELOW},
+ {0x0C9F, POS_BELOW},
+ {0x0CA0, POS_BELOW},
+ {0x0CA1, POS_BELOW},
+ {0x0CA2, POS_BELOW},
+ {0x0CA3, POS_BELOW},
+ {0x0CA4, POS_BELOW},
+ {0x0CA5, POS_BELOW},
+ {0x0CA6, POS_BELOW},
+ {0x0CA7, POS_BELOW},
+ {0x0CA8, POS_BELOW},
+ {0x0CAA, POS_BELOW},
+ {0x0CAB, POS_BELOW},
+ {0x0CAC, POS_BELOW},
+ {0x0CAD, POS_BELOW},
+ {0x0CAE, POS_BELOW},
+ {0x0CAF, POS_BELOW},
+ {0x0CB0, POS_BELOW},
+ {0x0CB2, POS_BELOW},
+ {0x0CB3, POS_BELOW},
+ {0x0CB5, POS_BELOW},
+ {0x0CB6, POS_BELOW},
+ {0x0CB7, POS_BELOW},
+ {0x0CB8, POS_BELOW},
+ {0x0CB9, POS_BELOW},
+ {0x0CDE, POS_BELOW},
+ {0x0D2F, POS_POST},
+ {0x0D30, POS_POST},
+ {0x0D32, POS_BELOW},
+ {0x0D35, POS_POST},
+};
+
+/* XXX
+ * This is a hack for now. We should move this data into the main Indic table.
+ */
+static const hb_codepoint_t ra_chars[] = {
+ 0x0930, /* Devanagari */
+ 0x09B0, /* Bengali */
+ 0x09F0, /* Bengali */
+//0x09F1, /* Bengali */
+//0x0A30, /* Gurmukhi */
+ 0x0AB0, /* Gujarati */
+ 0x0B30, /* Oriya */
+//0x0BB0, /* Tamil */
+//0x0C30, /* Telugu */
+ 0x0CB0, /* Kannada */
+//0x0D30, /* Malayalam */
+};
+
+
+#endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 06b8d48..09222f7 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -24,235 +24,8 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-ot-shape-complex-private.hh"
-
-
-/* buffer var allocations */
-#define indic_category() complex_var_persistent_u8_0() /* indic_category_t */
-#define indic_position() complex_var_persistent_u8_1() /* indic_matra_category_t */
-
-#define INDIC_TABLE_ELEMENT_TYPE uint8_t
-
-/* Cateories used in the OpenType spec:
- * https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx
- */
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-enum indic_category_t {
- OT_X = 0,
- OT_C,
- OT_Ra, /* Not explicitly listed in the OT spec, but used in the grammar. */
- OT_V,
- OT_N,
- OT_H,
- OT_ZWNJ,
- OT_ZWJ,
- OT_M,
- OT_SM,
- OT_VD,
- OT_A,
- OT_NBSP
-};
-
-/* Visual positions in a syllable from left to right. */
-enum indic_position_t {
- POS_PRE = 1,
- POS_BASE = 2,
- POS_ABOVE = 3,
- POS_BELOW = 4,
- POS_POST = 5
-};
-
-/* Categories used in IndicSyllabicCategory.txt from UCD */
-/* The assignments are guesswork */
-enum indic_syllabic_category_t {
- INDIC_SYLLABIC_CATEGORY_OTHER = OT_X,
-
- INDIC_SYLLABIC_CATEGORY_AVAGRAHA = OT_X,
- INDIC_SYLLABIC_CATEGORY_BINDU = OT_SM,
- INDIC_SYLLABIC_CATEGORY_CONSONANT = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER = OT_NBSP,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED = OT_C,
- INDIC_SYLLABIC_CATEGORY_CONSONANT_REPHA = OT_C,
- INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_NUKTA = OT_N,
- INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_TONE_LETTER = OT_X,
- INDIC_SYLLABIC_CATEGORY_TONE_MARK = OT_X,
- INDIC_SYLLABIC_CATEGORY_VIRAMA = OT_H,
- INDIC_SYLLABIC_CATEGORY_VISARGA = OT_SM,
- INDIC_SYLLABIC_CATEGORY_VOWEL = OT_V,
- INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT = OT_M,
- INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT = OT_V
-};
-
-/* Categories used in IndicSMatraCategory.txt from UCD */
-enum indic_matra_category_t {
- INDIC_MATRA_CATEGORY_NOT_APPLICABLE = POS_BASE,
-
- INDIC_MATRA_CATEGORY_LEFT = POS_PRE - 1, /* Move *before* existing "pre" chars */
- INDIC_MATRA_CATEGORY_TOP = POS_ABOVE,
- INDIC_MATRA_CATEGORY_BOTTOM = POS_BELOW,
- INDIC_MATRA_CATEGORY_RIGHT = POS_POST,
-
- /* We don't really care much about these since we decompose them
- * in the generic pre-shaping layer. They will only be used if
- * the font does not cover the decomposition. In which case, we
- * define these as aliases to the place we want the split-matra
- * glyph to show up. Quite arbitrary.
- *
- * TODO: There are some split matras without Unicode decompositions.
- * We have to figure out what to do with them.
- */
- INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT = 8 | INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_RIGHT,
-
- INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
- INDIC_MATRA_CATEGORY_OVERSTRUCK = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
- INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT = INDIC_MATRA_CATEGORY_NOT_APPLICABLE
-};
-
-/* Note: We use ASSERT_STATIC_EXPR_ZERO() instead of ASSERT_STATIC_EXPR() and the comma operation
- * because gcc fails to optimize the latter and fills the table in at runtime. */
-#define INDIC_COMBINE_CATEGORIES(S,M) \
- (ASSERT_STATIC_EXPR_ZERO (M == INDIC_MATRA_CATEGORY_NOT_APPLICABLE || (S == INDIC_SYLLABIC_CATEGORY_VIRAMA || S == INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT)) + \
- ASSERT_STATIC_EXPR_ZERO (S < 16 && M < 16) + \
- ((M << 4) | S))
-
-#include "hb-ot-shape-complex-indic-table.hh"
-
-/* XXX
- * This is a hack for now. We should:
- * 1. Move this data into the main Indic table,
- * and/or
- * 2. Probe font lookups to determine consonant positions.
- */
-static const struct consonant_position_t {
- hb_codepoint_t u;
- indic_position_t position;
-} consonant_positions[] = {
- {0x0930, POS_BELOW},
- {0x09AC, POS_BELOW},
- {0x09AF, POS_POST},
- {0x09B0, POS_BELOW},
- {0x09F0, POS_BELOW},
- {0x0A2F, POS_POST},
- {0x0A30, POS_BELOW},
- {0x0A35, POS_BELOW},
- {0x0A39, POS_BELOW},
- {0x0AB0, POS_BELOW},
- {0x0B24, POS_BELOW},
- {0x0B28, POS_BELOW},
- {0x0B2C, POS_BELOW},
- {0x0B2D, POS_BELOW},
- {0x0B2E, POS_BELOW},
- {0x0B2F, POS_POST},
- {0x0B30, POS_BELOW},
- {0x0B32, POS_BELOW},
- {0x0B33, POS_BELOW},
- {0x0B5F, POS_POST},
- {0x0B71, POS_BELOW},
- {0x0C15, POS_BELOW},
- {0x0C16, POS_BELOW},
- {0x0C17, POS_BELOW},
- {0x0C18, POS_BELOW},
- {0x0C19, POS_BELOW},
- {0x0C1A, POS_BELOW},
- {0x0C1B, POS_BELOW},
- {0x0C1C, POS_BELOW},
- {0x0C1D, POS_BELOW},
- {0x0C1E, POS_BELOW},
- {0x0C1F, POS_BELOW},
- {0x0C20, POS_BELOW},
- {0x0C21, POS_BELOW},
- {0x0C22, POS_BELOW},
- {0x0C23, POS_BELOW},
- {0x0C24, POS_BELOW},
- {0x0C25, POS_BELOW},
- {0x0C26, POS_BELOW},
- {0x0C27, POS_BELOW},
- {0x0C28, POS_BELOW},
- {0x0C2A, POS_BELOW},
- {0x0C2B, POS_BELOW},
- {0x0C2C, POS_BELOW},
- {0x0C2D, POS_BELOW},
- {0x0C2E, POS_BELOW},
- {0x0C2F, POS_BELOW},
- {0x0C30, POS_BELOW},
- {0x0C32, POS_BELOW},
- {0x0C33, POS_BELOW},
- {0x0C35, POS_BELOW},
- {0x0C36, POS_BELOW},
- {0x0C37, POS_BELOW},
- {0x0C38, POS_BELOW},
- {0x0C39, POS_BELOW},
- {0x0C95, POS_BELOW},
- {0x0C96, POS_BELOW},
- {0x0C97, POS_BELOW},
- {0x0C98, POS_BELOW},
- {0x0C99, POS_BELOW},
- {0x0C9A, POS_BELOW},
- {0x0C9B, POS_BELOW},
- {0x0C9C, POS_BELOW},
- {0x0C9D, POS_BELOW},
- {0x0C9E, POS_BELOW},
- {0x0C9F, POS_BELOW},
- {0x0CA0, POS_BELOW},
- {0x0CA1, POS_BELOW},
- {0x0CA2, POS_BELOW},
- {0x0CA3, POS_BELOW},
- {0x0CA4, POS_BELOW},
- {0x0CA5, POS_BELOW},
- {0x0CA6, POS_BELOW},
- {0x0CA7, POS_BELOW},
- {0x0CA8, POS_BELOW},
- {0x0CAA, POS_BELOW},
- {0x0CAB, POS_BELOW},
- {0x0CAC, POS_BELOW},
- {0x0CAD, POS_BELOW},
- {0x0CAE, POS_BELOW},
- {0x0CAF, POS_BELOW},
- {0x0CB0, POS_BELOW},
- {0x0CB2, POS_BELOW},
- {0x0CB3, POS_BELOW},
- {0x0CB5, POS_BELOW},
- {0x0CB6, POS_BELOW},
- {0x0CB7, POS_BELOW},
- {0x0CB8, POS_BELOW},
- {0x0CB9, POS_BELOW},
- {0x0CDE, POS_BELOW},
- {0x0D2F, POS_POST},
- {0x0D30, POS_POST},
- {0x0D32, POS_BELOW},
- {0x0D35, POS_POST},
-};
-
-/* XXX
- * This is a hack for now. We should move this data into the main Indic table.
- */
-static const hb_codepoint_t ra_chars[] = {
- 0x0930, /* Devanagari */
- 0x09B0, /* Bengali */
- 0x09F0, /* Bengali */
-//0x09F1, /* Bengali */
-//0x0A30, /* Gurmukhi */
- 0x0AB0, /* Gujarati */
- 0x0B30, /* Oriya */
-//0x0BB0, /* Tamil */
-//0x0C30, /* Telugu */
- 0x0CB0, /* Kannada */
-//0x0D30, /* Malayalam */
-};
+#include "hb-ot-shape-complex-indic-private.hh"
static int
compare_codepoint (const void *pa, const void *pb)
diff --git a/src/indic.cc b/src/indic.cc
new file mode 100644
index 0000000..6c6e05a
--- /dev/null
+++ b/src/indic.cc
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-ot-shape-complex-indic-private.hh"
+
+int
+main (void)
+{
+ hb_unicode_funcs_t *funcs = hb_unicode_funcs_get_default ();
+
+ printf ("There are split matras without a Unicode decomposition:\n");
+ for (hb_codepoint_t u = 0; u < 0x110000; u++)
+ {
+ unsigned int type = get_indic_categories (u);
+
+ unsigned int category = type & 0x0F;
+ unsigned int position = type >> 4;
+
+ hb_codepoint_t a, b;
+ if ((position & 8) && !hb_unicode_decompose (funcs, u, &a, &b))
+ printf ("U+%04X\n", u);
+ }
+}
commit a06411ecf93c7e5256e363eef3ef69554896dd55
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 19 22:28:25 2012 -0400
Minor matra renumbering
Should have no visible effect.
diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc
index 3a57bb8..06b8d48 100644
--- a/src/hb-ot-shape-complex-indic.cc
+++ b/src/hb-ot-shape-complex-indic.cc
@@ -58,10 +58,10 @@ enum indic_category_t {
/* Visual positions in a syllable from left to right. */
enum indic_position_t {
POS_PRE = 1,
- POS_BASE = 3,
- POS_ABOVE = 5,
- POS_BELOW = 7,
- POS_POST = 9
+ POS_BASE = 2,
+ POS_ABOVE = 3,
+ POS_BELOW = 4,
+ POS_POST = 5
};
/* Categories used in IndicSyllabicCategory.txt from UCD */
@@ -104,14 +104,18 @@ enum indic_matra_category_t {
* in the generic pre-shaping layer. They will only be used if
* the font does not cover the decomposition. In which case, we
* define these as aliases to the place we want the split-matra
- * glyph to show up. Quite arbitrary. */
- INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = INDIC_MATRA_CATEGORY_BOTTOM,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT = INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = INDIC_MATRA_CATEGORY_LEFT,
- INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = INDIC_MATRA_CATEGORY_RIGHT,
+ * glyph to show up. Quite arbitrary.
+ *
+ * TODO: There are some split matras without Unicode decompositions.
+ * We have to figure out what to do with them.
+ */
+ INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_BOTTOM,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_LEFT,
+ INDIC_MATRA_CATEGORY_TOP_AND_RIGHT = 8 | INDIC_MATRA_CATEGORY_RIGHT,
INDIC_MATRA_CATEGORY_INVISIBLE = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
INDIC_MATRA_CATEGORY_OVERSTRUCK = INDIC_MATRA_CATEGORY_NOT_APPLICABLE,
@@ -392,7 +396,7 @@ _hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map, hb_buffer_t *buffer, h
unsigned int type = get_indic_categories (buffer->info[i].codepoint);
buffer->info[i].indic_category() = type & 0x0F;
- buffer->info[i].indic_position() = type >> 4;
+ buffer->info[i].indic_position() = (type >> 4) & 7;
if (buffer->info[i].indic_category() == OT_C) {
buffer->info[i].indic_position() = consonant_position (buffer->info[i].codepoint);
commit 36608941f3cc530fea57282fa175e4cc3b4c66c6
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Apr 19 22:21:38 2012 -0400
Add GSUB "would_apply" API
To be used in the Indic shaper later. Unused for now.
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 8f01e13..f2210a0 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -39,6 +39,11 @@ struct SingleSubstFormat1
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ return (this+coverage) (glyph_id) != NOT_COVERED;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -78,6 +83,11 @@ struct SingleSubstFormat2
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ return (this+coverage) (glyph_id) != NOT_COVERED;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -119,6 +129,15 @@ struct SingleSubst
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.would_apply (glyph_id);
+ case 2: return u.format2.would_apply (glyph_id);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -185,6 +204,11 @@ struct MultipleSubstFormat1
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ return (this+coverage) (glyph_id) != NOT_COVERED;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -220,6 +244,14 @@ struct MultipleSubst
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.would_apply (glyph_id);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -255,12 +287,15 @@ struct AlternateSubstFormat1
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ return (this+coverage) (glyph_id) != NOT_COVERED;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
hb_codepoint_t glyph_id = c->buffer->info[c->buffer->idx].codepoint;
- hb_mask_t glyph_mask = c->buffer->info[c->buffer->idx].mask;
- hb_mask_t lookup_mask = c->lookup_mask;
unsigned int index = (this+coverage) (glyph_id);
if (likely (index == NOT_COVERED))
@@ -271,6 +306,9 @@ struct AlternateSubstFormat1
if (unlikely (!alt_set.len))
return false;
+ hb_mask_t glyph_mask = c->buffer->info[c->buffer->idx].mask;
+ hb_mask_t lookup_mask = c->lookup_mask;
+
/* Note: This breaks badly if two features enabled this lookup together. */
unsigned int shift = _hb_ctz (lookup_mask);
unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
@@ -309,6 +347,14 @@ struct AlternateSubst
private:
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.would_apply (glyph_id);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -340,6 +386,12 @@ struct Ligature
friend struct LigatureSet;
private:
+
+ inline bool would_apply (hb_codepoint_t second) const
+ {
+ return component.len == 2 && component[1] == second;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -429,6 +481,19 @@ struct LigatureSet
friend struct LigatureSubstFormat1;
private:
+
+ inline bool would_apply (hb_codepoint_t second) const
+ {
+ 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 (second))
+ return true;
+ }
+ return false;
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -462,6 +527,14 @@ struct LigatureSubstFormat1
friend struct LigatureSubst;
private:
+
+ inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
+ {
+ unsigned int index;
+ return (index = (this+coverage) (first)) != NOT_COVERED &&
+ (this+ligatureSet[index]).would_apply (second);
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -498,6 +571,15 @@ struct LigatureSubst
friend struct SubstLookupSubTable;
private:
+
+ inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
+ {
+ switch (u.format) {
+ case 1: return u.format1.would_apply (first, second);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
@@ -564,6 +646,9 @@ struct ExtensionSubst : Extension
return StructAtOffset<SubstLookupSubTable> (this, offset);
}
+ inline bool would_apply (hb_codepoint_t glyph_id) const;
+ inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const;
+
inline bool apply (hb_apply_context_t *c) const;
inline bool sanitize (hb_sanitize_context_t *c);
@@ -689,6 +774,28 @@ struct SubstLookupSubTable
ReverseChainSingle = 8
};
+ inline bool would_apply (hb_codepoint_t glyph_id,
+ unsigned int lookup_type) const
+ {
+ switch (lookup_type) {
+ case Single: return u.single.would_apply (glyph_id);
+ case Multiple: return u.multiple.would_apply (glyph_id);
+ case Alternate: return u.alternate.would_apply (glyph_id);
+ case Extension: return u.extension.would_apply (glyph_id);
+ default:return false;
+ }
+ }
+ inline bool would_apply (hb_codepoint_t first,
+ hb_codepoint_t second,
+ unsigned int lookup_type) const
+ {
+ switch (lookup_type) {
+ case Ligature: return u.ligature.would_apply (first, second);
+ case Extension: return u.extension.would_apply (first, second);
+ default:return false;
+ }
+ }
+
inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
{
TRACE_APPLY ();
@@ -754,6 +861,25 @@ struct SubstLookup : Lookup
}
+ inline bool would_apply (hb_codepoint_t glyph_id) const
+ {
+ 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 (glyph_id, lookup_type))
+ return true;
+ return false;
+ }
+ inline bool would_apply (hb_codepoint_t first, hb_codepoint_t second) const
+ {
+ 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 (first, second, lookup_type))
+ return true;
+ return false;
+ }
+
inline bool apply_once (hb_apply_context_t *c) const
{
unsigned int lookup_type = get_type ();
@@ -889,6 +1015,16 @@ GSUB::substitute_finish (hb_buffer_t *buffer)
/* Out-of-class implementation for methods recursing */
+inline bool ExtensionSubst::would_apply (hb_codepoint_t glyph_id) const
+{
+ return get_subtable ().would_apply (glyph_id, get_type ());
+}
+
+inline bool ExtensionSubst::would_apply (hb_codepoint_t first, hb_codepoint_t second) const
+{
+ return get_subtable ().would_apply (first, second, get_type ());
+}
+
inline bool ExtensionSubst::apply (hb_apply_context_t *c) const
{
TRACE_APPLY ();
commit a0d4caeb91fa5e5f2090db4efc35c64ff9a64789
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Apr 17 13:42:30 2012 -0400
Minor
diff --git a/TODO b/TODO
index b0eac7a..d763c30 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,9 @@
General fixes:
=============
+- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode funcs
+ found / set.
+
- In hb_shape(), assert if direction is INVALID.
- Fix TT 'kern' on/off and GPOS interaction (move kerning before GPOS).
commit a5e40542ab9508f0ba6f822f1262d93fccb71f45
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Apr 17 12:37:19 2012 -0400
Make font immutable in hb_shape()
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 3d5f56c..d97028e 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -121,6 +121,8 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
+ hb_font_make_immutable (font); /* So we can safely cache stuff on it */
+
if (likely (!shaper_list)) {
for (unsigned int i = 0; i < ARRAY_LENGTH (shapers); i++)
if (likely (shapers[i].func (font, buffer, features, num_features)))
More information about the HarfBuzz
mailing list