[pango/harfbuzz-ng] [GSUB] Implement ContextSubstFormat2
- From: Behdad Esfahbod <behdad src gnome org>
- To: svn-commits-list gnome org
- Subject: [pango/harfbuzz-ng] [GSUB] Implement ContextSubstFormat2
- Date: Sun, 17 May 2009 19:48:40 -0400 (EDT)
commit e9622c8c8c1dd88f63e1ba01df5295fc59eafde8
Author: Behdad Esfahbod <behdad behdad org>
Date: Fri May 15 20:25:37 2009 -0400
[GSUB] Implement ContextSubstFormat2
---
pango/opentype/hb-ot-layout-gsub-private.h | 105 +++++++++++++++++++++++++--
1 files changed, 97 insertions(+), 8 deletions(-)
diff --git a/pango/opentype/hb-ot-layout-gsub-private.h b/pango/opentype/hb-ot-layout-gsub-private.h
index 3980c6c..dcc7958 100644
--- a/pango/opentype/hb-ot-layout-gsub-private.h
+++ b/pango/opentype/hb-ot-layout-gsub-private.h
@@ -540,12 +540,8 @@ DEFINE_NULL (LigatureSubst, 2);
struct SubstLookupRecord {
- friend struct SubRule;
-
- private:
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const;
- private:
USHORT sequenceIndex; /* Index into current glyph
* sequence--first glyph = 0 */
USHORT lookupListIndex; /* Lookup to apply to that
@@ -615,7 +611,6 @@ struct SubRule {
}
}
-
private:
USHORT glyphCount; /* Total number of glyphs in input
* glyph sequence--includes the first
@@ -694,7 +689,66 @@ ASSERT_SIZE (ContextSubstFormat1, 6);
struct SubClassRule {
- /* TODO */
+
+ friend struct SubClassSet;
+
+ private:
+ DEFINE_ARRAY_TYPE (USHORT, klass, (glyphCount ? glyphCount - 1 : 0));
+
+ inline bool substitute_class (SUBTABLE_SUBSTITUTE_ARGS_DEF, const ClassDef &class_def) const {
+
+ unsigned int i, j;
+ unsigned int property;
+ unsigned int count = glyphCount;
+
+ if (HB_UNLIKELY (buffer->in_pos + count > buffer->in_length ||
+ context_length < count))
+ return false; /* Not enough glyphs in input or context */
+
+ /* XXX context_length should also be checked when skipping glyphs, right?
+ * What does context_length really mean, anyway? */
+
+ for (i = 1, j = buffer->in_pos + 1; i < count; i++, j++) {
+ while (!_hb_ot_layout_check_glyph_property (layout, IN_ITEM (j), lookup_flag, &property)) {
+ if (HB_UNLIKELY (j + count - i == buffer->in_length))
+ return false;
+ j++;
+ }
+
+ if (HB_LIKELY (class_def.get_class (IN_GLYPH(j)) != (*this)[i - 1]))
+ return false;
+ }
+
+ /* XXX right? or j - buffer_inpos? */
+ context_length = count;
+
+ unsigned int subst_count = substCount;
+ const SubstLookupRecord *subst = (const SubstLookupRecord *) ((const char *) klass + sizeof (klass[0]) * glyphCount);
+ for (i = 0; i < count;)
+ {
+ if ( subst_count && i == subst->sequenceIndex )
+ {
+ unsigned int old_pos = buffer->in_pos;
+
+ /* Do a substitution */
+ bool done = subst->substitute (SUBTABLE_SUBSTITUTE_ARGS);
+
+ subst++;
+ subst_count--;
+ i += buffer->in_pos - old_pos;
+
+ if (!done)
+ goto no_subst;
+ }
+ else
+ {
+ no_subst:
+ /* No substitution for this index */
+ _hb_buffer_copy_output_glyph (buffer);
+ i++;
+ }
+ }
+ }
private:
USHORT glyphCount; /* Total number of classes
@@ -710,7 +764,27 @@ struct SubClassRule {
DEFINE_NULL_ASSERT_SIZE (SubClassRule, 4);
struct SubClassSet {
- /* TODO */
+
+ friend struct ContextSubstFormat2;
+
+ private:
+ DEFINE_OFFSET_ARRAY_TYPE (SubClassRule, subClassRule, subClassRuleCnt);
+
+ inline bool substitute_class (SUBTABLE_SUBSTITUTE_ARGS_DEF, const ClassDef &class_def) const {
+
+ /* LONGTERMTODO: Old code fetches glyph classes at most once and caches
+ * them across subrule lookups. Not sure it's worth it.
+ */
+
+ unsigned int num_rules = get_len ();
+ for (unsigned int i = 0; i < num_rules; i++) {
+ const SubClassRule &rule = (*this)[i];
+ if (rule.substitute_class (SUBTABLE_SUBSTITUTE_ARGS, class_def))
+ return true;
+ }
+
+ return false;
+ }
private:
USHORT subClassRuleCnt; /* Number of SubClassRule tables */
@@ -725,9 +799,24 @@ struct ContextSubstFormat2 {
friend struct ContextSubst;
private:
+ /* SubClassSet tables, in Coverage Index order */
+ DEFINE_OFFSET_ARRAY_TYPE (SubClassSet, subClassSet, subClassSetCnt);
+ DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
+ DEFINE_GET_ACCESSOR (ClassDef, class_def, classDef);
+ DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
inline bool substitute (SUBTABLE_SUBSTITUTE_ARGS_DEF) const {
- return false;
+
+ unsigned int property;
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ hb_codepoint_t glyph_id = IN_CURGLYPH ();
+
+ unsigned int index = get_glyph_coverage (glyph_id);
+
+ const SubClassSet &class_set = (*this)[index];
+ return class_set.substitute_class (SUBTABLE_SUBSTITUTE_ARGS, get_class_def ());
}
private:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]