From e95e031b5682809488cc965883e15404cb9cfb6a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 8 Jan 2013 16:15:46 -0600 Subject: [PATCH] [GPOS] If an Anchor offset is NULL, return false MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If in a MarkPos table, a base has no anchor for a particular mark class, return NULL such that the subsequent subtables get a chance at it. Test case: hb-shape ./EBGaramond12-Regular.otf ἂ --features="ss20","smcp" --- src/hb-open-type-private.hh | 14 ++++++++++++-- src/hb-ot-layout-gpos-table.hh | 10 ++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index 5bfeb1654..90f283640 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -616,10 +616,20 @@ struct Index : USHORT { DEFINE_NULL_DATA (Index, "\xff\xff"); /* Offset to a table, same as uint16 (length = 16 bits), Null offset = 0x0000 */ -typedef USHORT Offset; +struct Offset : USHORT +{ + inline bool is_null (void) const { return 0 == *this; } + public: + DEFINE_SIZE_STATIC (2); +}; /* LongOffset to a table, same as uint32 (length = 32 bits), Null offset = 0x00000000 */ -typedef ULONG LongOffset; +struct LongOffset : ULONG +{ + inline bool is_null (void) const { return 0 == *this; } + public: + DEFINE_SIZE_STATIC (4); +}; /* CheckSum */ diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index d27ce4f71..3e436946b 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -336,8 +336,10 @@ struct Anchor 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]; } @@ -392,7 +394,11 @@ struct MarkArray : ArrayOf /* Array of MarkRecords--in Coverage orde 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;