[subset] Implement for ClassDef
authorBehdad Esfahbod <behdad@behdad.org>
Thu, 13 Dec 2018 22:48:42 +0000 (17:48 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Thu, 13 Dec 2018 22:48:42 +0000 (17:48 -0500)
src/hb-ot-layout-common.hh
src/hb-ot-layout-gsub-table.hh

index d3f75af..c95eca7 100644 (file)
@@ -1190,6 +1190,11 @@ struct Coverage
  * Class Definition Table
  */
 
+static inline void ClassDef_serialize (hb_serialize_context_t *c,
+                                      Supplier<GlyphID> &glyphs,
+                                      Supplier<HBUINT16> &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<GlyphID> 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<GlyphID> glyphs_supplier (glyphs);
+    Supplier<HBUINT16> 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<GlyphID> glyphs;
+    hb_vector_t<GlyphID> 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<GlyphID> glyphs_supplier (glyphs);
+    Supplier<GlyphID> 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<GlyphID> &glyphs,
+                                      Supplier<HBUINT16> &klasses,
+                                      unsigned int num_glyphs)
+{
+  c->start_embed<ClassDef> ()->serialize (c,
+                                         glyphs,
+                                         klasses,
+                                         num_glyphs);
+}
+
 
 /*
  * Item Variation Store
index 9ce4b16..e2c90d2 100644 (file)
@@ -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<GlyphID> from;
     hb_vector_t<GlyphID> 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<GlyphID> from;
     hb_vector_t<GlyphID> 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 ()]]);
     }