#include "hb-ot-layout-gsubgpos-private.hh"
+namespace OT {
+
/* buffer **position** var allocations */
#define attach_lookback() var.u16[0] /* number of glyphs to go back to attach this glyph to its base */
}
inline bool sanitize_value (hb_sanitize_context_t *c, void *base, Value *values) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
}
inline bool sanitize_values (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
unsigned int len = get_len ();
if (!c->check_array (values, get_size (), count)) return TRACE_RETURN (false);
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */
inline bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, void *base, Value *values, unsigned int count, unsigned int stride) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!has_device ()) return TRACE_RETURN (true);
struct AnchorFormat1
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
struct AnchorFormat2
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
hb_position_t *x, hb_position_t *y) const
{
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this));
}
struct AnchorFormat3
{
- friend struct Anchor;
-
- private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
struct AnchorMatrix
{
- inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols) const {
+ inline const Anchor& get_anchor (unsigned int row, unsigned int col, unsigned int cols, bool *found) const {
+ *found = false;
if (unlikely (row >= rows || col >= cols)) return Null(Anchor);
+ *found = !matrix[row * cols + col].is_null ();
return this+matrix[row * cols + col];
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int cols) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!c->check_struct (this)) return TRACE_RETURN (false);
if (unlikely (rows > 0 && cols >= ((unsigned int) -1) / rows)) return TRACE_RETURN (false);
unsigned int count = rows * cols;
friend struct MarkArray;
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markAnchor.sanitize (c, base));
}
const AnchorMatrix &anchors, unsigned int class_count,
unsigned int glyph_pos) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
const MarkRecord &record = ArrayOf<MarkRecord>::operator[](mark_index);
unsigned int mark_class = record.klass;
const Anchor& mark_anchor = this + record.markAnchor;
- const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count);
+ bool found;
+ const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+ /* If this subtable doesn't have an anchor for this base and this class,
+ * return false such that the subsequent subtables have a chance at it. */
+ if (unlikely (!found)) return TRACE_RETURN (false);
hb_position_t mark_x, mark_y, base_x, base_y;
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (ArrayOf<MarkRecord>::sanitize (c, this));
}
};
struct SinglePosFormat1
{
- friend struct SinglePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
valueFormat.apply_value (c->font, c->direction, this,
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_value (c, this, values));
}
struct SinglePosFormat2
{
- friend struct SinglePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (likely (index >= valueCount)) return TRACE_RETURN (false);
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && coverage.sanitize (c, this) && valueFormat.sanitize_values (c, this, values, valueCount));
}
struct SinglePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- case 2: return u.format2.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- case 2: return TRACE_RETURN (u.format2.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
{
friend struct PairPosFormat1;
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c,
+ const ValueFormat *valueFormats) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ unsigned int len1 = valueFormats[0].get_len ();
+ unsigned int len2 = valueFormats[1].get_len ();
+ unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
+
+ const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
+ for (unsigned int i = 0; i < count; i++)
+ {
+ c->input->add (record->secondGlyph);
+ record = &StructAtOffset<PairValueRecord> (record, record_size);
+ }
+ }
+
inline bool apply (hb_apply_context_t *c,
const ValueFormat *valueFormats,
unsigned int pos) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = USHORT::static_size * (1 + len1 + len2);
- unsigned int count = len;
const PairValueRecord *record = CastP<PairValueRecord> (array);
+ unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
{
if (c->buffer->info[pos].codepoint == record->secondGlyph)
};
inline bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!(c->check_struct (this)
&& c->check_array (array, USHORT::static_size * closure->stride, len))) return TRACE_RETURN (false);
struct PairPosFormat1
{
- friend struct PairPos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ unsigned int count = pairSet.len;
+ for (unsigned int i = 0; i < count; i++)
+ (this+pairSet[i]).collect_glyphs (c, &valueFormat1);
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len ();
struct PairPosFormat2
{
- friend struct PairPos;
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ /* (this+coverage).add_coverage (c->input); // Don't need this. */
- private:
+ /* TODO only add values for pairs that have nonzero adjustments. */
+
+ unsigned int count1 = class1Count;
+ const ClassDef &klass1 = this+classDef1;
+ for (unsigned int i = 0; i < count1; i++)
+ klass1.add_class (c->input, i);
+
+ unsigned int count2 = class2Count;
+ const ClassDef &klass2 = this+classDef2;
+ for (unsigned int i = 0; i < count2; i++)
+ klass2.add_class (c->input, i);
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- unsigned int index = (this+coverage) (c->buffer->cur().codepoint);
+ unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
unsigned int len2 = valueFormat2.get_len ();
unsigned int record_len = len1 + len2;
- unsigned int klass1 = (this+classDef1) (c->buffer->cur().codepoint);
- unsigned int klass2 = (this+classDef2) (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int klass1 = (this+classDef1).get_class (c->buffer->cur().codepoint);
+ unsigned int klass2 = (this+classDef2).get_class (c->buffer->info[skippy_iter.idx].codepoint);
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return TRACE_RETURN (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!(c->check_struct (this)
&& coverage.sanitize (c, this)
&& classDef1.sanitize (c, this)
struct PairPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- case 2: return u.format2.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- case 2: return TRACE_RETURN (u.format2.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ case 2: return TRACE_RETURN (c->process (u.format2));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
friend struct CursivePosFormat1;
inline bool sanitize (hb_sanitize_context_t *c, void *base) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
}
struct CursivePosFormat1
{
- friend struct CursivePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+coverage).add_coverage (c->input);
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_APPLY (this);
/* We don't handle mark glyphs here. */
- if (c->property & HB_OT_LAYOUT_GLYPH_CLASS_MARK) return TRACE_RETURN (false);
+ if (c->property & HB_OT_LAYOUT_GLYPH_PROPS_MARK) return TRACE_RETURN (false);
hb_apply_context_t::mark_skipping_forward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (skippy_iter.has_no_chance ()) return TRACE_RETURN (false);
- const EntryExitRecord &this_record = entryExitRecord[(this+coverage) (c->buffer->cur().codepoint)];
+ const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->cur().codepoint)];
if (!this_record.exitAnchor) return TRACE_RETURN (false);
if (!skippy_iter.next ()) return TRACE_RETURN (false);
- const EntryExitRecord &next_record = entryExitRecord[(this+coverage) (c->buffer->info[skippy_iter.idx].codepoint)];
+ const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint)];
if (!next_record.entryAnchor) return TRACE_RETURN (false);
unsigned int i = c->buffer->idx;
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
}
struct CursivePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
struct MarkBasePosFormat1
{
- friend struct MarkBasePos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+markCoverage).add_coverage (c->input);
+ (this+baseCoverage).add_coverage (c->input);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
} while (1);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH)) {/*return TRACE_RETURN (false);*/}
- unsigned int base_index = (this+baseCoverage) (c->buffer->info[skippy_iter.idx].codepoint);
+ unsigned int base_index = (this+baseCoverage).get_coverage (c->buffer->info[skippy_iter.idx].codepoint);
if (base_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, skippy_iter.idx));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && baseCoverage.sanitize (c, this) &&
markArray.sanitize (c, this) && baseArray.sanitize (c, this, (unsigned int) classCount));
}
struct MarkBasePos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
struct MarkLigPosFormat1
{
- friend struct MarkLigPos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+markCoverage).add_coverage (c->input);
+ (this+ligatureCoverage).add_coverage (c->input);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark_index = (this+markCoverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark_index = (this+markCoverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a non-mark glyph */
if (!skippy_iter.prev (&property, LookupFlag::IgnoreMarks)) return TRACE_RETURN (false);
/* The following assertion is too strong, so we've disabled it. */
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE)) {/*return TRACE_RETURN (false);*/}
unsigned int j = skippy_iter.idx;
- unsigned int lig_index = (this+ligatureCoverage) (c->buffer->info[j].codepoint);
+ unsigned int lig_index = (this+ligatureCoverage).get_coverage (c->buffer->info[j].codepoint);
if (lig_index == NOT_COVERED) return TRACE_RETURN (false);
const LigatureArray& lig_array = this+ligatureArray;
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && markCoverage.sanitize (c, this) && ligatureCoverage.sanitize (c, this) &&
markArray.sanitize (c, this) && ligatureArray.sanitize (c, this, (unsigned int) classCount));
}
struct MarkLigPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
- {
- switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
struct MarkMarkPosFormat1
{
- friend struct MarkMarkPos;
-
- private:
+ inline void collect_glyphs (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ (this+mark1Coverage).add_coverage (c->input);
+ (this+mark2Coverage).add_coverage (c->input);
+ /* TODO only add combinations that have nonzero adjustment. */
+ }
inline const Coverage &get_coverage (void) const
{
inline bool apply (hb_apply_context_t *c) const
{
- TRACE_APPLY ();
- unsigned int mark1_index = (this+mark1Coverage) (c->buffer->cur().codepoint);
+ TRACE_APPLY (this);
+ unsigned int mark1_index = (this+mark1Coverage).get_coverage (c->buffer->cur().codepoint);
if (likely (mark1_index == NOT_COVERED)) return TRACE_RETURN (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_apply_context_t::mark_skipping_backward_iterator_t skippy_iter (c, c->buffer->idx, 1);
if (!skippy_iter.prev (&property)) return TRACE_RETURN (false);
- if (!(property & HB_OT_LAYOUT_GLYPH_CLASS_MARK)) return TRACE_RETURN (false);
+ if (!(property & HB_OT_LAYOUT_GLYPH_PROPS_MARK)) return TRACE_RETURN (false);
unsigned int j = skippy_iter.idx;
return TRACE_RETURN (false);
good:
- unsigned int mark2_index = (this+mark2Coverage) (c->buffer->info[j].codepoint);
+ unsigned int mark2_index = (this+mark2Coverage).get_coverage (c->buffer->info[j].codepoint);
if (mark2_index == NOT_COVERED) return TRACE_RETURN (false);
return TRACE_RETURN ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
return TRACE_RETURN (c->check_struct (this) && mark1Coverage.sanitize (c, this) &&
mark2Coverage.sanitize (c, this) && mark1Array.sanitize (c, this)
&& mark2Array.sanitize (c, this, (unsigned int) classCount));
struct MarkMarkPos
{
- friend struct PosLookupSubTable;
-
- private:
-
- inline const Coverage &get_coverage (void) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
{
+ TRACE_PROCESS (this);
switch (u.format) {
- case 1: return u.format1.get_coverage ();
- default:return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- switch (u.format) {
- case 1: return TRACE_RETURN (u.format1.apply (c));
- default:return TRACE_RETURN (false);
+ case 1: return TRACE_RETURN (c->process (u.format1));
+ default:return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return TRACE_RETURN (false);
switch (u.format) {
case 1: return TRACE_RETURN (u.format1.sanitize (c));
};
-static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index);
-
-struct ContextPos : Context
-{
- friend struct PosLookupSubTable;
-
- private:
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (Context::apply (c, position_lookup));
- }
-};
-
-struct ChainContextPos : ChainContext
-{
- friend struct PosLookupSubTable;
-
- private:
- inline bool apply (hb_apply_context_t *c) const
- {
- TRACE_APPLY ();
- return TRACE_RETURN (ChainContext::apply (c, position_lookup));
- }
-};
+struct ContextPos : Context {};
+struct ChainContextPos : ChainContext {};
-struct ExtensionPos : Extension
+struct ExtensionPos : Extension<ExtensionPos>
{
- friend struct PosLookupSubTable;
-
- private:
- inline const struct PosLookupSubTable& get_subtable (void) const
- {
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return Null(PosLookupSubTable);
- return StructAtOffset<PosLookupSubTable> (this, offset);
- }
-
- inline const Coverage &get_coverage (void) const;
-
- inline bool apply (hb_apply_context_t *c) const;
-
- inline bool sanitize (hb_sanitize_context_t *c);
+ typedef struct PosLookupSubTable LookupSubTable;
};
Extension = 9
};
- inline const Coverage &get_coverage (unsigned int lookup_type) const
- {
- switch (lookup_type) {
- case Single: return u.single.get_coverage ();
- case Pair: return u.pair.get_coverage ();
- case Cursive: return u.cursive.get_coverage ();
- case MarkBase: return u.markBase.get_coverage ();
- case MarkLig: return u.markLig.get_coverage ();
- case MarkMark: return u.markMark.get_coverage ();
- case Context: return u.context.get_coverage ();
- case ChainContext: return u.chainContext.get_coverage ();
- case Extension: return u.extension.get_coverage ();
- default: return Null(Coverage);
- }
- }
-
- inline bool apply (hb_apply_context_t *c, unsigned int lookup_type) const
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c, unsigned int lookup_type) const
{
- TRACE_APPLY ();
+ TRACE_PROCESS (this);
switch (lookup_type) {
- case Single: return TRACE_RETURN (u.single.apply (c));
- case Pair: return TRACE_RETURN (u.pair.apply (c));
- case Cursive: return TRACE_RETURN (u.cursive.apply (c));
- case MarkBase: return TRACE_RETURN (u.markBase.apply (c));
- case MarkLig: return TRACE_RETURN (u.markLig.apply (c));
- case MarkMark: return TRACE_RETURN (u.markMark.apply (c));
- case Context: return TRACE_RETURN (u.context.apply (c));
- case ChainContext: return TRACE_RETURN (u.chainContext.apply (c));
- case Extension: return TRACE_RETURN (u.extension.apply (c));
- default: return TRACE_RETURN (false);
+ case Single: return TRACE_RETURN (u.single.process (c));
+ case Pair: return TRACE_RETURN (u.pair.process (c));
+ case Cursive: return TRACE_RETURN (u.cursive.process (c));
+ case MarkBase: return TRACE_RETURN (u.markBase.process (c));
+ case MarkLig: return TRACE_RETURN (u.markLig.process (c));
+ case MarkMark: return TRACE_RETURN (u.markMark.process (c));
+ case Context: return TRACE_RETURN (u.context.process (c));
+ case ChainContext: return TRACE_RETURN (u.chainContext.process (c));
+ case Extension: return TRACE_RETURN (u.extension.process (c));
+ default: return TRACE_RETURN (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int lookup_type) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (!u.header.sub_format.sanitize (c))
return TRACE_RETURN (false);
switch (lookup_type) {
protected:
union {
struct {
- USHORT sub_format;
+ USHORT sub_format;
} header;
SinglePos single;
PairPos pair;
inline const PosLookupSubTable& get_subtable (unsigned int i) const
{ return this+CastR<OffsetArrayOf<PosLookupSubTable> > (subTable)[i]; }
+ template <typename context_t>
+ inline typename context_t::return_t process (context_t *c) const
+ {
+ TRACE_PROCESS (this);
+ unsigned int lookup_type = get_type ();
+ unsigned int count = get_subtable_count ();
+ for (unsigned int i = 0; i < count; i++) {
+ typename context_t::return_t r = get_subtable (i).process (c, lookup_type);
+ if (c->stop_sublookup_iteration (r))
+ return TRACE_RETURN (r);
+ }
+ return TRACE_RETURN (c->default_return_value ());
+ }
+ template <typename context_t>
+ static inline typename context_t::return_t process_recurse_func (context_t *c, unsigned int lookup_index);
+
+ inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const
+ {
+ TRACE_COLLECT_GLYPHS (this);
+ c->set_recurse_func (NULL);
+ return TRACE_RETURN (process (c));
+ }
+
template <typename set_t>
inline void add_coverage (set_t *glyphs) const
{
+ hb_get_coverage_context_t c;
const Coverage *last = NULL;
unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) {
- const Coverage *c = &get_subtable (i).get_coverage (get_type ());
- if (c != last) {
- c->add_coverage (glyphs);
- last = c;
+ const Coverage *coverage = &get_subtable (i).process (&c, get_type ());
+ if (coverage != last) {
+ coverage->add_coverage (glyphs);
+ last = coverage;
}
}
}
inline bool apply_once (hb_apply_context_t *c) const
{
- unsigned int lookup_type = get_type ();
-
+ TRACE_APPLY (this);
if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props, &c->property))
- return false;
-
- unsigned int count = get_subtable_count ();
- for (unsigned int i = 0; i < count; i++)
- if (get_subtable (i).apply (c, lookup_type))
- return true;
-
- return false;
+ return TRACE_RETURN (false);
+ return TRACE_RETURN (process (c));
}
- inline bool apply_string (hb_apply_context_t *c) const
+ static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
+
+ inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const
{
bool ret = false;
- if (unlikely (!c->buffer->len))
+ if (unlikely (!c->buffer->len || !c->lookup_mask))
return false;
+ c->set_recurse_func (apply_recurse_func);
c->set_lookup (*this);
c->buffer->idx = 0;
while (c->buffer->idx < c->buffer->len)
{
if ((c->buffer->cur().mask & c->lookup_mask) &&
- c->digest.may_have (c->buffer->cur().codepoint) &&
+ digest->may_have (c->buffer->cur().codepoint) &&
apply_once (c))
ret = true;
else
}
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!Lookup::sanitize (c))) return TRACE_RETURN (false);
OffsetArrayOf<PosLookupSubTable> &list = CastR<OffsetArrayOf<PosLookupSubTable> > (subTable);
return TRACE_RETURN (list.sanitize (c, this, get_type ()));
inline const PosLookup& get_lookup (unsigned int i) const
{ return CastR<PosLookup> (GSUBGPOS::get_lookup (i)); }
- template <typename set_t>
- inline void add_coverage (set_t *glyphs, unsigned int lookup_index) const
- { get_lookup (lookup_index).add_coverage (glyphs); }
-
- 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_font_t *font, hb_buffer_t *buffer);
static inline void position_finish (hb_font_t *font, hb_buffer_t *buffer, hb_bool_t zero_width_attahced_marks);
inline bool sanitize (hb_sanitize_context_t *c) {
- TRACE_SANITIZE ();
+ TRACE_SANITIZE (this);
if (unlikely (!GSUBGPOS::sanitize (c))) return TRACE_RETURN (false);
OffsetTo<PosLookupList> &list = CastR<OffsetTo<PosLookupList> > (lookupList);
return TRACE_RETURN (list.sanitize (c, this));
static void
fix_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction)
{
- unsigned int j = pos[i].cursive_chain();
- if (likely (!j))
- return;
+ unsigned int j = pos[i].cursive_chain();
+ if (likely (!j))
+ return;
- j += i;
+ j += i;
- pos[i].cursive_chain() = 0;
+ pos[i].cursive_chain() = 0;
- fix_cursive_minor_offset (pos, j, direction);
+ fix_cursive_minor_offset (pos, j, direction);
- if (HB_DIRECTION_IS_HORIZONTAL (direction))
- pos[i].y_offset += pos[j].y_offset;
- else
- pos[i].x_offset += pos[j].x_offset;
+ if (HB_DIRECTION_IS_HORIZONTAL (direction))
+ pos[i].y_offset += pos[j].y_offset;
+ else
+ pos[i].x_offset += pos[j].x_offset;
}
static void
/* Out-of-class implementation for methods recursing */
-inline const Coverage & ExtensionPos::get_coverage (void) const
+template <typename context_t>
+inline typename context_t::return_t PosLookup::process_recurse_func (context_t *c, unsigned int lookup_index)
{
- return get_subtable ().get_coverage (get_type ());
-}
-
-inline bool ExtensionPos::apply (hb_apply_context_t *c) const
-{
- TRACE_APPLY ();
- return TRACE_RETURN (get_subtable ().apply (c, get_type ()));
-}
-
-inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c)
-{
- TRACE_SANITIZE ();
- if (unlikely (!Extension::sanitize (c))) return TRACE_RETURN (false);
- unsigned int offset = get_offset ();
- if (unlikely (!offset)) return TRACE_RETURN (true);
- return TRACE_RETURN (StructAtOffset<PosLookupSubTable> (this, offset).sanitize (c, get_type ()));
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
+ const PosLookup &l = gpos.get_lookup (lookup_index);
+ return l.process (c);
}
-static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index)
+inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
{
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
const PosLookup &l = gpos.get_lookup (lookup_index);
-
- if (unlikely (c->nesting_level_left == 0))
- return false;
-
- hb_apply_context_t new_c (*c);
- new_c.nesting_level_left--;
- new_c.set_lookup (l);
- return l.apply_once (&new_c);
+ unsigned int saved_lookup_props = c->lookup_props;
+ unsigned int saved_property = c->property;
+ c->set_lookup (l);
+ bool ret = l.apply_once (c);
+ c->lookup_props = saved_lookup_props;
+ c->property = saved_property;
+ return ret;
}
#undef cursive_chain
+} /* namespace OT */
+
#endif /* HB_OT_LAYOUT_GPOS_TABLE_HH */