#ifndef HB_OT_LAYOUT_GDEF_PRIVATE_H
#define HB_OT_LAYOUT_GDEF_PRIVATE_H
-#include "hb-ot-layout-private.h"
-
#include "hb-ot-layout-open-private.h"
#ifndef HB_OT_LAYOUT_GSUB_PRIVATE_H
#define HB_OT_LAYOUT_GSUB_PRIVATE_H
-#include "hb-ot-layout-private.h"
-
-#include "hb-ot-layout-open-private.h"
-#include "hb-ot-layout-gdef-private.h"
-
-#include "harfbuzz-buffer-private.h" /* XXX */
-
-#define LOOKUP_ARGS_DEF \
- hb_ot_layout_t *layout, \
- hb_buffer_t *buffer, \
- unsigned int context_length HB_GNUC_UNUSED, \
- unsigned int nesting_level_left HB_GNUC_UNUSED, \
- unsigned int lookup_flag
-#define LOOKUP_ARGS \
- layout, \
- buffer, \
- context_length, \
- nesting_level_left, \
- lookup_flag
+#include "hb-ot-layout-gsubgpos-private.h"
struct SingleSubstFormat1 {
DEFINE_NULL (LigatureSubst, 2);
-typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, char *data);
-typedef bool (*apply_lookup_func_t) (LOOKUP_ARGS_DEF, unsigned int lookup_index);
-struct ContextLookupContext {
- inline bool match (hb_codepoint_t glyph_id, const USHORT &value) const {
- return match_func (glyph_id, value, match_data);
- }
- inline bool apply (LOOKUP_ARGS_DEF, unsigned int lookup_index) const {
- return apply_func (LOOKUP_ARGS, lookup_index);
- }
-
- match_func_t match_func;
- char *match_data;
- apply_lookup_func_t apply_func;
-};
-
-struct LookupRecord {
-
- inline bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
- return context.apply (LOOKUP_ARGS, lookupListIndex);
- }
-
- USHORT sequenceIndex; /* Index into current glyph
- * sequence--first glyph = 0 */
- USHORT lookupListIndex; /* Lookup to apply to that
- * position--zero--based */
-};
-ASSERT_SIZE (LookupRecord, 4);
-
-static inline bool context_lookup (LOOKUP_ARGS_DEF,
- USHORT glyphCount, /* Including the first glyph (not matched) */
- USHORT recordCount,
- const USHORT value[], /* Array of match values--start with second glyph */
- const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
- ContextLookupContext &context) {
-
- 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 (context.match (IN_GLYPH(j), value[i - 1])))
- return false;
- }
-
- /* XXX right? or j - buffer_inpos? */
- context_length = count;
-
- unsigned int record_count = recordCount;
- const LookupRecord *record = lookupRecord;
- for (i = 0; i < count;)
- {
- if ( record_count && i == record->sequenceIndex )
- {
- unsigned int old_pos = buffer->in_pos;
-
- /* Apply a lookup */
- bool done = record->apply (LOOKUP_ARGS, context);
-
- record++;
- record_count--;
- i += buffer->in_pos - old_pos;
+static inline bool substitute_lookup (LOOKUP_ARGS_DEF, unsigned int lookup_index);
- if (!done)
- goto not_applied;
- }
- else
- {
- not_applied:
- /* No lookup applied for this index */
- _hb_buffer_next_glyph (buffer);
- i++;
- }
- }
-
- return true;
-}
-struct Rule {
-
- friend struct RuleSet;
-
- private:
- DEFINE_ARRAY_TYPE (USHORT, value, (glyphCount ? glyphCount - 1 : 0));
-
- bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
- const LookupRecord *record = (const LookupRecord *) ((const char *) value + sizeof (value[0]) * (glyphCount - 1));
- return context_lookup (LOOKUP_ARGS,
- glyphCount,
- recordCount,
- value,
- record,
- context);
- }
+struct ContextSubst : Context {
- private:
- USHORT glyphCount; /* Total number of glyphs in input
- * glyph sequence--includes the first
- * glyph */
- USHORT recordCount; /* Number of LookupRecords */
- USHORT value[]; /* Array of match values--start with
- * second glyph */
- LookupRecord lookupRecord[]; /* Array of LookupRecords--in
- * design order */
-};
-ASSERT_SIZE (Rule, 4);
-
-struct RuleSet {
-
- bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
-
- unsigned int num_rules = rule.len;
- for (unsigned int i = 0; i < num_rules; i++) {
- if ((this+rule[i]).apply (LOOKUP_ARGS, context))
- return true;
- }
-
- return false;
- }
-
- private:
- OffsetArrayOf<Rule>
- rule; /* Array SubRule tables
- * ordered by preference */
-};
-
-static inline bool substitute_one_lookup (LOOKUP_ARGS_DEF, unsigned int lookup_index);
-
-static inline bool glyph_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
- return glyph_id == value;
-}
-
-struct SubRuleSet : RuleSet {
inline bool substitute (LOOKUP_ARGS_DEF) const {
- struct ContextLookupContext context = {
- glyph_match, NULL,
- substitute_one_lookup
- };
- return apply (LOOKUP_ARGS, context);
+ return this->apply (LOOKUP_ARGS, substitute_lookup);
}
};
-ASSERT_SIZE (SubRuleSet, 2);
-
-struct ContextSubstFormat1 {
-
- friend struct ContextSubst;
-
- private:
-
- inline bool substitute (LOOKUP_ARGS_DEF) const {
-
- unsigned int property;
- if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
- return false;
-
- unsigned int index = (this+coverage) (IN_CURGLYPH ());
- const SubRuleSet &rule_set = this+subRuleSet[index];
- return rule_set.substitute (LOOKUP_ARGS);
- }
-
- private:
- USHORT substFormat; /* Format identifier--format = 1 */
- OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- OffsetArrayOf<SubRuleSet>
- subRuleSet; /* Array of SubRuleSet tables
- * ordered by Coverage Index */
-};
-ASSERT_SIZE (ContextSubstFormat1, 6);
-
-static inline bool class_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
- const ClassDef &class_def = * (const ClassDef *) data;
- return class_def.get_class (glyph_id) == value;
-}
-
-struct SubClassSet : RuleSet {
- inline bool substitute_class (LOOKUP_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.
- */
- struct ContextLookupContext context = {
- class_match, (char *) &class_def,
- substitute_one_lookup
- };
- return apply (LOOKUP_ARGS, context);
- }
-};
-ASSERT_SIZE (SubClassSet, 2);
-
-
-struct ContextSubstFormat2 {
-
- friend struct ContextSubst;
-
- private:
-
- inline bool substitute (LOOKUP_ARGS_DEF) const {
-
- unsigned int property;
- if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
- return false;
-
- unsigned int index = (this+coverage) (IN_CURGLYPH ());
- const SubClassSet &class_set = this+subClassSet[index];
- return class_set.substitute_class (LOOKUP_ARGS, this+classDef);
- }
-
- private:
- USHORT substFormat; /* Format identifier--format = 2 */
- OffsetTo<Coverage>
- coverage; /* Offset to Coverage table--from
- * beginning of Substitution table */
- OffsetTo<ClassDef>
- classDef; /* Offset to glyph ClassDef table--from
- * beginning of Substitution table */
- OffsetArrayOf<SubClassSet>
- subClassSet; /* Array of SubClassSet tables
- * ordered by class */
-};
-ASSERT_SIZE (ContextSubstFormat2, 8);
-
-static inline bool coverage_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
- const OffsetTo<Coverage> &coverage = * (const OffsetTo<Coverage> *) &value;
- return (data+coverage) (glyph_id) != NOT_COVERED;
-}
-
-struct ContextSubstFormat3 {
-
- friend struct ContextSubst;
-
- private:
-
- /* Coverage tables, in glyph sequence order */
- DEFINE_OFFSET_ARRAY_TYPE (Coverage, coverage, glyphCount);
-
- inline bool substitute_coverage (LOOKUP_ARGS_DEF) const {
- struct ContextLookupContext context = {
- coverage_match, (char *) this,
- substitute_one_lookup
- };
- const LookupRecord *record = (const LookupRecord *) ((const char *) coverage + sizeof (coverage[0]) * glyphCount);
- return context_lookup (LOOKUP_ARGS,
- glyphCount,
- recordCount,
- (const USHORT *) (coverage + 1),
- record,
- context);
- }
-
- inline bool substitute (LOOKUP_ARGS_DEF) const {
-
- unsigned int property;
- if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
- return false;
-
- if ((*this)[0].get_coverage (IN_CURGLYPH () == NOT_COVERED))
- return false;
-
- return substitute_coverage (LOOKUP_ARGS);
- }
-
- private:
- USHORT substFormat; /* Format identifier--format = 3 */
- USHORT glyphCount; /* Number of glyphs in the input glyph
- * sequence */
- USHORT recordCount; /* Number of LookupRecords */
- Offset coverage[]; /* Array of offsets to Coverage
- * table--from beginning of
- * Substitution table--in glyph
- * sequence order */
- LookupRecord lookupRecord[]; /* Array of LookupRecords--in
- * design order */
-};
-ASSERT_SIZE (ContextSubstFormat3, 6);
-
-struct ContextSubst {
-
- friend struct SubstLookupSubTable;
-
- private:
-
- inline bool substitute (LOOKUP_ARGS_DEF) const {
- switch (u.substFormat) {
- case 1: return u.format1.substitute (LOOKUP_ARGS);
- case 2: return u.format2.substitute (LOOKUP_ARGS);
- case 3: return u.format3.substitute (LOOKUP_ARGS);
- default:return false;
- }
- }
-
- private:
- union {
- USHORT substFormat; /* Format identifier */
- ContextSubstFormat1 format1;
- ContextSubstFormat2 format2;
- ContextSubstFormat3 format3;
- } u;
-};
DEFINE_NULL (ContextSubst, 2);
get_type ());
}
-static inline bool substitute_one_lookup (LOOKUP_ARGS_DEF, unsigned int lookup_index) {
+static inline bool substitute_lookup (LOOKUP_ARGS_DEF, unsigned int lookup_index) {
const GSUB &gsub = *(layout->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
}
-
#endif /* HB_OT_LAYOUT_GSUB_PRIVATE_H */
--- /dev/null
+/*
+ * Copyright (C) 2007,2008,2009 Red Hat, Inc.
+ *
+ * This is part of HarfBuzz, an OpenType Layout engine 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_H
+#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_H
+
+#include "hb-ot-layout-gdef-private.h"
+#include "harfbuzz-buffer-private.h" /* XXX */
+
+#define LOOKUP_ARGS_DEF \
+ hb_ot_layout_t *layout, \
+ hb_buffer_t *buffer, \
+ unsigned int context_length HB_GNUC_UNUSED, \
+ unsigned int nesting_level_left HB_GNUC_UNUSED, \
+ unsigned int lookup_flag
+#define LOOKUP_ARGS \
+ layout, \
+ buffer, \
+ context_length, \
+ nesting_level_left, \
+ lookup_flag
+
+
+/* Context lookups */
+
+typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const USHORT &value, char *data);
+typedef bool (*apply_lookup_func_t) (LOOKUP_ARGS_DEF, unsigned int lookup_index);
+
+struct ContextLookupContext {
+ inline bool match (hb_codepoint_t glyph_id, const USHORT &value) const {
+ return match_func (glyph_id, value, match_data);
+ }
+ inline bool apply (LOOKUP_ARGS_DEF, unsigned int lookup_index) const {
+ return apply_func (LOOKUP_ARGS, lookup_index);
+ }
+
+ match_func_t match_func;
+ char *match_data;
+ apply_lookup_func_t apply_func;
+};
+
+struct LookupRecord {
+
+ inline bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
+ return context.apply (LOOKUP_ARGS, lookupListIndex);
+ }
+
+ USHORT sequenceIndex; /* Index into current glyph
+ * sequence--first glyph = 0 */
+ USHORT lookupListIndex; /* Lookup to apply to that
+ * position--zero--based */
+};
+ASSERT_SIZE (LookupRecord, 4);
+
+static inline bool context_lookup (LOOKUP_ARGS_DEF,
+ USHORT glyphCount, /* Including the first glyph (not matched) */
+ USHORT recordCount,
+ const USHORT value[], /* Array of match values--start with second glyph */
+ const LookupRecord lookupRecord[], /* Array of LookupRecords--in design order */
+ ContextLookupContext &context) {
+
+ 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 (context.match (IN_GLYPH(j), value[i - 1])))
+ return false;
+ }
+
+ /* XXX right? or j - buffer_inpos? */
+ context_length = count;
+
+ /* XXX We have to jump non-matching glyphs when applying too, right? */
+ unsigned int record_count = recordCount;
+ const LookupRecord *record = lookupRecord;
+ for (i = 0; i < count;)
+ {
+ if ( record_count && i == record->sequenceIndex )
+ {
+ unsigned int old_pos = buffer->in_pos;
+
+ /* Apply a lookup */
+ bool done = record->apply (LOOKUP_ARGS, context);
+
+ record++;
+ record_count--;
+ i += buffer->in_pos - old_pos;
+
+ if (!done)
+ goto not_applied;
+ }
+ else
+ {
+ not_applied:
+ /* No lookup applied for this index */
+ _hb_buffer_next_glyph (buffer);
+ i++;
+ }
+ }
+
+ return true;
+}
+struct Rule {
+
+ friend struct RuleSet;
+
+ private:
+ DEFINE_ARRAY_TYPE (USHORT, value, (glyphCount ? glyphCount - 1 : 0));
+
+ inline bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
+ const LookupRecord *record = (const LookupRecord *) ((const char *) value + sizeof (value[0]) * (glyphCount - 1));
+ return context_lookup (LOOKUP_ARGS,
+ glyphCount,
+ recordCount,
+ value,
+ record,
+ context);
+ }
+
+ private:
+ USHORT glyphCount; /* Total number of glyphs in input
+ * glyph sequence--includes the first
+ * glyph */
+ USHORT recordCount; /* Number of LookupRecords */
+ USHORT value[]; /* Array of match values--start with
+ * second glyph */
+ LookupRecord lookupRecord[]; /* Array of LookupRecords--in
+ * design order */
+};
+ASSERT_SIZE (Rule, 4);
+
+struct RuleSet {
+
+ inline bool apply (LOOKUP_ARGS_DEF, ContextLookupContext &context) const {
+
+ unsigned int num_rules = rule.len;
+ for (unsigned int i = 0; i < num_rules; i++) {
+ if ((this+rule[i]).apply (LOOKUP_ARGS, context))
+ return true;
+ }
+
+ return false;
+ }
+
+ private:
+ OffsetArrayOf<Rule>
+ rule; /* Array SubRule tables
+ * ordered by preference */
+};
+
+
+static inline bool glyph_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
+ return glyph_id == value;
+}
+
+struct ContextFormat1 {
+
+ friend struct Context;
+
+ private:
+
+ inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+
+ unsigned int property;
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ unsigned int index = (this+coverage) (IN_CURGLYPH ());
+ const RuleSet &rule_set = this+ruleSet[index];
+ struct ContextLookupContext context = {
+ glyph_match, NULL,
+ apply_func
+ };
+ return rule_set.apply (LOOKUP_ARGS, context);
+ }
+
+ private:
+ USHORT format; /* Format identifier--format = 1 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by Coverage Index */
+};
+ASSERT_SIZE (ContextFormat1, 6);
+
+
+static inline bool class_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
+ const ClassDef &class_def = * (const ClassDef *) data;
+ return class_def.get_class (glyph_id) == value;
+}
+
+struct ContextFormat2 {
+
+ friend struct Context;
+
+ private:
+
+ inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+
+ unsigned int property;
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ unsigned int index = (this+coverage) (IN_CURGLYPH ());
+ const RuleSet &rule_set = this+ruleSet[index];
+ /* LONGTERMTODO: Old code fetches glyph classes at most once and caches
+ * them across subrule lookups. Not sure it's worth it.
+ */
+ struct ContextLookupContext context = {
+ class_match, (char *) &(this+classDef),
+ apply_func
+ };
+ return rule_set.apply (LOOKUP_ARGS, context);
+ }
+
+ private:
+ USHORT format; /* Format identifier--format = 2 */
+ OffsetTo<Coverage>
+ coverage; /* Offset to Coverage table--from
+ * beginning of table */
+ OffsetTo<ClassDef>
+ classDef; /* Offset to glyph ClassDef table--from
+ * beginning of table */
+ OffsetArrayOf<RuleSet>
+ ruleSet; /* Array of RuleSet tables
+ * ordered by class */
+};
+ASSERT_SIZE (ContextFormat2, 8);
+
+
+static inline bool coverage_match (hb_codepoint_t glyph_id, const USHORT &value, char *data) {
+ const OffsetTo<Coverage> &coverage = * (const OffsetTo<Coverage> *) &value;
+ return (data+coverage) (glyph_id) != NOT_COVERED;
+}
+
+struct ContextFormat3 {
+
+ friend struct Context;
+
+ private:
+
+ /* Coverage tables, in glyph sequence order */
+ DEFINE_OFFSET_ARRAY_TYPE (Coverage, coverage, glyphCount);
+
+ inline bool apply_coverage (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+ const LookupRecord *record = (const LookupRecord *) ((const char *) coverage + sizeof (coverage[0]) * glyphCount);
+ struct ContextLookupContext context = {
+ coverage_match, (char *) this,
+ apply_func
+ };
+ return context_lookup (LOOKUP_ARGS,
+ glyphCount,
+ recordCount,
+ (const USHORT *) (coverage + 1),
+ record,
+ context);
+ }
+
+ inline bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+
+ unsigned int property;
+ if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
+ return false;
+
+ if ((*this)[0].get_coverage (IN_CURGLYPH () == NOT_COVERED))
+ return false;
+
+ return apply_coverage (LOOKUP_ARGS, apply_func);
+ }
+
+ private:
+ USHORT format; /* Format identifier--format = 3 */
+ USHORT glyphCount; /* Number of glyphs in the input glyph
+ * sequence */
+ USHORT recordCount; /* Number of LookupRecords */
+ Offset coverage[]; /* Array of offsets to Coverage
+ * table--from beginning of
+ * table--in glyph
+ * sequence order */
+ LookupRecord lookupRecord[]; /* Array of LookupRecords--in
+ * design order */
+};
+ASSERT_SIZE (ContextFormat3, 6);
+
+struct Context {
+
+ protected:
+ bool apply (LOOKUP_ARGS_DEF, apply_lookup_func_t apply_func) const {
+ switch (u.format) {
+ case 1: return u.format1.apply (LOOKUP_ARGS, apply_func);
+ case 2: return u.format2.apply (LOOKUP_ARGS, apply_func);
+ case 3: return u.format3.apply (LOOKUP_ARGS, apply_func);
+ default:return false;
+ }
+ }
+
+ private:
+ union {
+ USHORT format; /* Format identifier */
+ ContextFormat1 format1;
+ ContextFormat2 format2;
+ ContextFormat3 format3;
+ } u;
+};
+DEFINE_NULL (Context, 2);
+
+
+#endif /* HB_OT_LAYOUT_GSUBGPOS_PRIVATE_H */