[subset] Extract maxp subsetting into hb-ot-maxp-table.
authorGarret Rieger <grieger@google.com>
Tue, 13 Feb 2018 01:56:17 +0000 (17:56 -0800)
committerGarret Rieger <grieger@google.com>
Wed, 14 Feb 2018 18:19:50 +0000 (10:19 -0800)
src/hb-ot-maxp-table.hh
src/hb-subset.cc
test/api/test-subset-glyf.c

index fb2209c..52b9388 100644 (file)
@@ -28,7 +28,7 @@
 #define HB_OT_MAXP_TABLE_HH
 
 #include "hb-open-type-private.hh"
-
+#include "hb-subset-plan.hh"
 
 namespace OT {
 
@@ -61,6 +61,23 @@ struct maxp
                          (version.major == 0 && version.minor == 0x5000u)));
   }
 
+  inline hb_blob_t * subset (hb_subset_plan_t *plan, hb_face_t *source) const
+  {
+    hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (hb_face_reference_table (source, HB_OT_TAG_maxp));
+    hb_blob_t *maxp_prime_blob = hb_blob_create_sub_blob (maxp_blob, 0, -1);
+    hb_blob_destroy (maxp_blob);
+
+    OT::maxp *maxp_prime = (OT::maxp *) hb_blob_get_data_writable (maxp_prime_blob, nullptr);
+    if (unlikely (!maxp_prime)) {
+      hb_blob_destroy (maxp_prime_blob);
+      return nullptr;
+    }
+
+    maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
+
+    return maxp_prime_blob;
+  }
+
   /* We only implement version 0.5 as none of the extra fields in version 1.0 are useful. */
   protected:
   FixedVersion<>version;               /* Version of the maxp table (0.5 or 1.0),
index 15730bf..dda9f3e 100644 (file)
@@ -280,31 +280,6 @@ _add_head_and_set_loca_version (hb_face_t *source, bool use_short_loca, hb_face_
 }
 
 static bool
-_add_maxp_and_set_glyph_count (hb_subset_plan_t *plan, hb_face_t *source, hb_face_t *dest)
-{
-  hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (hb_face_reference_table (source, HB_OT_TAG_maxp));
-  const OT::maxp *maxp = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
-  bool has_maxp = (maxp != nullptr);
-  if (has_maxp) {
-    unsigned int length = hb_blob_get_length (maxp_blob);
-    OT::maxp *maxp_prime = (OT::maxp *) calloc (length, 1);
-    memcpy (maxp_prime, maxp, length);
-    maxp_prime->set_num_glyphs (plan->gids_to_retain_sorted.len);
-
-    hb_blob_t *maxp_prime_blob = hb_blob_create ((const char*) maxp_prime,
-                                                 length,
-                                                 HB_MEMORY_MODE_READONLY,
-                                                 maxp_prime,
-                                                 free);
-    has_maxp = hb_subset_face_add_table (dest, HB_OT_TAG_maxp, maxp_prime_blob);
-    hb_blob_destroy (maxp_prime_blob);
-  }
-
-  hb_blob_destroy (maxp_blob);
-  return has_maxp;
-}
-
-static bool
 _subset_glyf (hb_subset_plan_t *plan, hb_face_t *source, hb_face_t *dest)
 {
   hb_blob_t *glyf_prime = nullptr;
@@ -343,7 +318,8 @@ _subset_table (hb_subset_plan_t *plan,
       // SKIP head, it's handled by glyf
       return true;
     case HB_OT_TAG_maxp:
-      return _add_maxp_and_set_glyph_count (plan, source, dest);
+      dest_blob = _subset<const OT::maxp> (plan, source);
+      break;
     case HB_OT_TAG_loca:
       // SKIP loca, it's handle by glyf
       return true;
index 8db053c..3c9d8fe 100644 (file)
@@ -34,8 +34,8 @@
 static void
 test_subset_glyf (void)
 {
-  hb_face_t *face_abc = hb_subset_test_open_font("fonts/Roboto-Regular.abc.ttf");  
-  hb_face_t *face_ac = hb_subset_test_open_font("fonts/Roboto-Regular.ac.ttf");
+  hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf");
+  hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.ttf");
 
   hb_set_t *codepoints = hb_set_create();
   hb_set_add (codepoints, 97);
@@ -45,6 +45,7 @@ test_subset_glyf (void)
 
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
   hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+  hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('m','a','x', 'p'));
 
   hb_face_destroy (face_abc_subset);
   hb_face_destroy (face_abc);