From 705e2f5056d60c28154004e0c5d3b0ec67fe93c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 13 Dec 2018 17:48:42 -0500 Subject: [PATCH] [subset] Implement for ClassDef --- src/hb-ot-layout-common.hh | 80 ++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-layout-gsub-table.hh | 8 ++--- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout-common.hh b/src/hb-ot-layout-common.hh index d3f75af..c95eca7 100644 --- a/src/hb-ot-layout-common.hh +++ b/src/hb-ot-layout-common.hh @@ -1190,6 +1190,11 @@ struct Coverage * Class Definition Table */ +static inline void ClassDef_serialize (hb_serialize_context_t *c, + Supplier &glyphs, + Supplier &klasses, + unsigned int num_glyphs); + struct ClassDefFormat1 { friend struct ClassDef; @@ -1233,6 +1238,27 @@ struct ClassDefFormat1 return_trace (true); } + inline bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_map_t &glyph_map = *c->plan->glyph_map; + hb_vector_t glyphs; + hb_codepoint_t first_glyph = startGlyph; + unsigned int count = classValue.len; + glyphs.resize (count); + for (unsigned i = 0; i < count; i++) + glyphs[i].set (glyph_map[first_glyph + i]); + c->serializer->err (glyphs.in_error ()); + + Supplier glyphs_supplier (glyphs); + Supplier klasses_supplier (classValue.as_array ()); + ClassDef_serialize (c->serializer, + glyphs_supplier, + klasses_supplier, + glyphs.len); + return_trace (glyphs.len); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1356,6 +1382,39 @@ struct ClassDefFormat2 return_trace (true); } + inline bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset; + const hb_map_t &glyph_map = *c->plan->glyph_map; + hb_vector_t glyphs; + hb_vector_t klasses; + + unsigned int count = rangeRecord.len; + for (unsigned int i = 0; i < count; i++) + { + unsigned int value = rangeRecord[i].value; + if (!value) continue; + hb_codepoint_t start = rangeRecord[i].start; + hb_codepoint_t end = rangeRecord[i].end + 1; + for (hb_codepoint_t g = start; g < end; g++) + { + if (!glyphset.has (g)) continue; + glyphs.push ()->set (glyph_map[g]); + klasses.push ()->set (value); + } + } + c->serializer->err (glyphs.in_error () || klasses.in_error ()); + + Supplier glyphs_supplier (glyphs); + Supplier klasses_supplier (klasses); + ClassDef_serialize (c->serializer, + glyphs_supplier, + klasses_supplier, + glyphs.len); + return_trace (glyphs.len); + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1469,6 +1528,16 @@ struct ClassDef } } + inline bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + switch (u.format) { + case 1: return_trace (u.format1.subset (c)); + case 2: return_trace (u.format2.subset (c)); + default:return_trace (false); + } + } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -1527,6 +1596,17 @@ struct ClassDef DEFINE_SIZE_UNION (2, format); }; +static inline void ClassDef_serialize (hb_serialize_context_t *c, + Supplier &glyphs, + Supplier &klasses, + unsigned int num_glyphs) +{ + c->start_embed ()->serialize (c, + glyphs, + klasses, + num_glyphs); +} + /* * Item Variation Store diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 9ce4b16..e2c90d2 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -110,14 +110,14 @@ struct SingleSubstFormat1 inline bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset; const hb_map_t &glyph_map = *c->plan->glyph_map; hb_vector_t from; hb_vector_t to; hb_codepoint_t delta = deltaGlyphID; for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { - if (!c->plan->glyphset->has (iter.get_glyph ())) - continue; + if (!glyphset.has (iter.get_glyph ())) continue; from.push ()->set (glyph_map[iter.get_glyph ()]); to.push ()->set (glyph_map[(iter.get_glyph () + delta) & 0xFFFF]); } @@ -217,13 +217,13 @@ struct SingleSubstFormat2 inline bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset; const hb_map_t &glyph_map = *c->plan->glyph_map; hb_vector_t from; hb_vector_t to; for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ()) { - if (!c->plan->glyphset->has (iter.get_glyph ())) - continue; + if (!glyphset.has (iter.get_glyph ())) continue; from.push ()->set (glyph_map[iter.get_glyph ()]); to.push ()->set (glyph_map[substitute[iter.get_coverage ()]]); } -- 2.7.4