From 71e6adf1e2d65eb905a0ba247672fe36169955ef Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 16 Dec 2017 11:07:37 -0500 Subject: [PATCH] [collect_glyphs] handle ClassDef better --- src/hb-ot-layout-common-private.hh | 63 +++++++++++++++++++++++----- src/hb-ot-layout-gdef-table.hh | 2 +- src/hb-ot-layout-gpos-table.hh | 5 +-- src/hb-ot-layout-gsubgpos-private.hh | 2 +- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 554364854..f75f8b4ff 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -1020,12 +1020,33 @@ struct ClassDefFormat1 } template - inline bool add_class (set_t *glyphs, unsigned int min_klass, unsigned int max_klass) const { + inline bool add_coverage (set_t *glyphs) const { + unsigned int start = 0; unsigned int count = classValue.len; for (unsigned int i = 0; i < count; i++) { - unsigned int klass = classValue[i]; - if (min_klass <= klass && klass <= max_klass) + if (classValue[i]) + continue; + + if (start != i) + if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i))) + return true;//XXXXXXXXfalse + + start = i + 1; + } + if (start != count) + if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + count))) + return true;//XXXXXXXXfalse + + return true; + } + + template + inline bool add_class (set_t *glyphs, unsigned int klass) const { + unsigned int count = classValue.len; + for (unsigned int i = 0; i < count; i++) + { + if (classValue[i] == klass) glyphs->add (startGlyph + i); } return true; @@ -1081,14 +1102,23 @@ struct ClassDefFormat2 } template - inline bool add_class (set_t *glyphs, unsigned int min_klass, unsigned int max_klass) const { + inline bool add_coverage (set_t *glyphs) const { + unsigned int count = rangeRecord.len; + for (unsigned int i = 0; i < count; i++) + if (rangeRecord[i].value) + if (unlikely (!rangeRecord[i].add_coverage (glyphs))) + return true;//XXXXXXXXXXXXfalse; + return true; + } + + template + inline bool add_class (set_t *glyphs, unsigned int klass) const { unsigned int count = rangeRecord.len; for (unsigned int i = 0; i < count; i++) { - unsigned int klass = rangeRecord[i].value; - if (min_klass <= klass && klass <= max_klass) + if (rangeRecord[i].value == klass) if (unlikely (!rangeRecord[i].add_coverage (glyphs))) - return false; + return true;//XXXXXXXXXXXXfalse; } return true; } @@ -1148,11 +1178,24 @@ struct ClassDef } } + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ template - inline bool add_class (set_t *glyphs, unsigned int min_klass, unsigned int max_klass) const { + inline bool add_coverage (set_t *glyphs) const { switch (u.format) { - case 1: return u.format1.add_class (glyphs, min_klass, max_klass); - case 2: return u.format2.add_class (glyphs, min_klass, max_klass); + case 1: return u.format1.add_coverage (glyphs); + case 2: return u.format2.add_coverage (glyphs); + default:return true;//XXXXXXXXXXXfalse; + } + } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template + inline bool add_class (set_t *glyphs, unsigned int klass) const { + switch (u.format) { + case 1: return u.format1.add_class (glyphs, klass); + case 2: return u.format2.add_class (glyphs, klass); default:return false; } } diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index b2924f6be..eed46dd67 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -352,7 +352,7 @@ struct GDEF inline unsigned int get_glyph_class (hb_codepoint_t glyph) const { return (this+glyphClassDef).get_class (glyph); } inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const - { (this+glyphClassDef).add_class (glyphs, klass, klass); } + { (this+glyphClassDef).add_class (glyphs, klass); } inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; } inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index f44888b61..b344d793c 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -751,10 +751,7 @@ struct PairPosFormat2 { TRACE_COLLECT_GLYPHS (this); if (unlikely (!(this+coverage).add_coverage (c->input))) return; - - unsigned int count2 = class2Count; - if (count2) - (this+classDef2).add_class (c->input, 0, count2 - 1); + if (unlikely (!(this+classDef2).add_coverage (c->input))) return; } inline const Coverage &get_coverage (void) const diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index a30fa6de2..b08a59138 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -621,7 +621,7 @@ static inline void collect_glyph (hb_set_t *glyphs, const UINT16 &value, const v static inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data) { const ClassDef &class_def = *reinterpret_cast(data); - class_def.add_class (glyphs, value, value); + class_def.add_class (glyphs, value); } static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data) {