[collect_glyphs] handle ClassDef better

This commit is contained in:
Behdad Esfahbod 2017-12-16 11:07:37 -05:00
parent 87cc5a65cb
commit 71e6adf1e2
4 changed files with 56 additions and 16 deletions

View File

@ -1020,12 +1020,33 @@ struct ClassDefFormat1
} }
template <typename set_t> template <typename set_t>
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; unsigned int count = classValue.len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
unsigned int klass = classValue[i]; if (classValue[i])
if (min_klass <= klass && klass <= max_klass) 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 <typename set_t>
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); glyphs->add (startGlyph + i);
} }
return true; return true;
@ -1081,14 +1102,23 @@ struct ClassDefFormat2
} }
template <typename set_t> template <typename set_t>
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 <typename set_t>
inline bool add_class (set_t *glyphs, unsigned int klass) const {
unsigned int count = rangeRecord.len; unsigned int count = rangeRecord.len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
unsigned int klass = rangeRecord[i].value; if (rangeRecord[i].value == klass)
if (min_klass <= klass && klass <= max_klass)
if (unlikely (!rangeRecord[i].add_coverage (glyphs))) if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
return false; return true;//XXXXXXXXXXXXfalse;
} }
return true; return true;
} }
@ -1148,11 +1178,24 @@ struct ClassDef
} }
} }
/* Might return false if array looks unsorted.
* Used for faster rejection of corrupt data. */
template <typename set_t> template <typename set_t>
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) { switch (u.format) {
case 1: return u.format1.add_class (glyphs, min_klass, max_klass); case 1: return u.format1.add_coverage (glyphs);
case 2: return u.format2.add_class (glyphs, min_klass, max_klass); 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 <typename set_t>
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; default:return false;
} }
} }

View File

@ -352,7 +352,7 @@ struct GDEF
inline unsigned int get_glyph_class (hb_codepoint_t glyph) const inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
{ return (this+glyphClassDef).get_class (glyph); } { return (this+glyphClassDef).get_class (glyph); }
inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const 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 bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const

View File

@ -751,10 +751,7 @@ struct PairPosFormat2
{ {
TRACE_COLLECT_GLYPHS (this); TRACE_COLLECT_GLYPHS (this);
if (unlikely (!(this+coverage).add_coverage (c->input))) return; if (unlikely (!(this+coverage).add_coverage (c->input))) return;
if (unlikely (!(this+classDef2).add_coverage (c->input))) return;
unsigned int count2 = class2Count;
if (count2)
(this+classDef2).add_class (c->input, 0, count2 - 1);
} }
inline const Coverage &get_coverage (void) const inline const Coverage &get_coverage (void) const

View File

@ -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) static inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data)
{ {
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(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) static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data)
{ {