From 84dbfacfec3818478a1e5ac2b9922d25917493ef Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 15 Apr 2021 16:52:11 -0700 Subject: [PATCH] [subset] fix collect_variation_idx in PairPosFormat2 --- src/hb-ot-layout-common.hh | 15 ++++++++++----- src/hb-ot-layout-gdef-table.hh | 4 ++-- src/hb-ot-layout-gpos-table.hh | 22 ++++++++++++++++++---- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index 9ff409f9c..d4e82249d 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -91,7 +91,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_map_t &gid_klass_map, hb_sorted_vector_t &glyphs, const hb_set_t &klasses, - bool use_class_zero, + bool use_class_zero, hb_map_t *klass_map /*INOUT*/); @@ -1894,6 +1894,7 @@ struct ClassDefFormat1 if (unlikely (!it)) { + classFormat = 1; startGlyph = 0; classValue.len = 0; return_trace (true); @@ -1917,6 +1918,7 @@ struct ClassDefFormat1 bool subset (hb_subset_context_t *c, hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, bool use_class_zero = true, const Coverage* glyph_filter = nullptr) const { @@ -1950,7 +1952,7 @@ struct ClassDefFormat1 use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, glyphs, orig_klasses, use_class_zero, klass_map); - return_trace ((bool) glyphs); + return_trace (keep_empty_table || (bool) glyphs); } bool sanitize (hb_sanitize_context_t *c) const @@ -2071,6 +2073,7 @@ struct ClassDefFormat2 if (unlikely (!it)) { + classFormat = 2; rangeRecord.len = 0; return_trace (true); } @@ -2117,6 +2120,7 @@ struct ClassDefFormat2 bool subset (hb_subset_context_t *c, hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, bool use_class_zero = true, const Coverage* glyph_filter = nullptr) const { @@ -2151,7 +2155,7 @@ struct ClassDefFormat2 use_class_zero = use_class_zero && glyph_count <= gid_org_klass_map.get_population (); ClassDef_remap_and_serialize (c->serializer, gid_org_klass_map, glyphs, orig_klasses, use_class_zero, klass_map); - return_trace ((bool) glyphs); + return_trace (keep_empty_table || (bool) glyphs); } bool sanitize (hb_sanitize_context_t *c) const @@ -2350,13 +2354,14 @@ struct ClassDef bool subset (hb_subset_context_t *c, hb_map_t *klass_map = nullptr /*OUT*/, + bool keep_empty_table = true, bool use_class_zero = true, const Coverage* glyph_filter = nullptr) const { TRACE_SUBSET (this); switch (u.format) { - case 1: return_trace (u.format1.subset (c, klass_map, use_class_zero, glyph_filter)); - case 2: return_trace (u.format2.subset (c, klass_map, use_class_zero, glyph_filter)); + case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); default:return_trace (false); } } diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 00138866b..edb35dabf 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -643,10 +643,10 @@ struct GDEF auto *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this); + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); bool subset_markglyphsetsdef = true; if (version.to_int () >= 0x00010002u) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 917b6f0e2..fe64f215d 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1488,14 +1488,28 @@ struct PairPosFormat2 void closure_lookups (hb_closure_lookups_context_t *c) const {} void collect_variation_indices (hb_collect_variation_indices_context_t *c) const { + if (!intersects (c->glyph_set)) return; if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return; + hb_set_t klass1_glyphs, klass2_glyphs; + if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return; + if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return; + hb_set_t class1_set, class2_set; for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage)) { - unsigned klass1 = (this+classDef1).get (cp); + if (!klass1_glyphs.has (cp)) class1_set.add (0); + else + { + unsigned klass1 = (this+classDef1).get (cp); + class1_set.add (klass1); + } + } + + class2_set.add (0); + for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs)) + { unsigned klass2 = (this+classDef2).get (cp); - class1_set.add (klass1); class2_set.add (klass2); } @@ -1569,11 +1583,11 @@ struct PairPosFormat2 out->format = format; hb_map_t klass1_map; - out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, &(this + coverage)); + out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage)); out->class1Count = klass1_map.get_population (); hb_map_t klass2_map; - out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, false); + out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false); out->class2Count = klass2_map.get_population (); unsigned len1 = valueFormat1.get_len ();