From ef78d0f92345eb452e94c73301bc929822755b27 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 5 Jan 2021 10:16:50 -0800 Subject: [PATCH] [subset] optimize glyph closure method: step 2 Add function intersects_class_glyphs that collects set of glyphs matching class in ClassDef table --- src/hb-ot-layout-common.hh | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index a5d7804c7..abf76cc62 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1838,6 +1838,24 @@ struct ClassDefFormat1 return false; } + void intersects_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) + { + unsigned count = classValue.len; + if (klass == 0) + { + hb_codepoint_t endGlyph = startGlyph + count -1; + for (hb_codepoint_t g : glyphs->iter ()) + if (g < startGlyph || g > endGlyph) + intersect_glyphs->add (g); + + return; + } + + for (unsigned i = 0; i < count; i++) + if (classValue[i] == klass && glyphs->has (startGlyph + i)) + intersect_glyphs->add (startGlyph + i); + } + protected: HBUINT16 classFormat; /* Format identifier--format = 1 */ HBGlyphID startGlyph; /* First GlyphID of the classValueArray */ @@ -2021,6 +2039,54 @@ struct ClassDefFormat2 return false; } + void intersects_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) + { + unsigned count = rangeRecord.len; + if (klass == 0) + { + hb_codepoint_t g = HB_SET_VALUE_INVALID; + for (unsigned int i = 0; i < count; i++) + { + if (!hb_set_next (glyphs, &g)) + break; + while (g != HB_SET_VALUE_INVALID && g < rangeRecord[i].first) + { + intersect_glyphs->add (g); + hb_set_next (glyphs, &g); + } + g = rangeRecord[i].last; + } + while (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) + intersect_glyphs->add (g); + + return; + } + + hb_codepoint_t g = HB_SET_VALUE_INVALID; + for (unsigned int i = 0; i < count; i++) + { + if (rangeRecord[i].value == klass) + { + if (g != HB_SET_VALUE_INVALID) + { + if (g >= rangeRecord[i].first && + g <= rangeRecord[i].last) + intersect_glyphs->add (g); + if (g > rangeRecord[i].last) + continue; + } + + while (hb_set_next (glyphs, &g)) + { + if (g >= rangeRecord[i].first && g <= rangeRecord[i].last) + intersect_glyphs->add (g); + else if (g > rangeRecord[i].last) + break; + } + } + } + } + protected: HBUINT16 classFormat; /* Format identifier--format = 2 */ SortedArrayOf @@ -2161,6 +2227,15 @@ struct ClassDef } } + void intersects_class_glyphs (const hb_set_t *glyphs, unsigned klass, hb_set_t *intersect_glyphs) + { + switch (u.format) { + case 1: return u.format1.intersects_class_glyphs (glyphs, klass, intersect_glyphs); + case 2: return u.format2.intersects_class_glyphs (glyphs, klass, intersect_glyphs); + default:return; + } + } + protected: union { HBUINT16 format; /* Format identifier */