[HarfBuzz] harfbuzz: Branch 'master' - 5 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Feb 7 23:28:49 UTC 2018


 src/hb-open-file-private.hh |    6 +-
 src/hb-ot-glyf-table.hh     |   26 ++++++++----
 src/hb-subset-glyf.cc       |   93 ++++++++++++++++++++++++++++++++++++++++----
 src/hb-subset.cc            |   37 ++++++++++++-----
 4 files changed, 133 insertions(+), 29 deletions(-)

New commits:
commit c9acab3cfbe4a21e86ad309ebb452f103b1c1b04
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 7 17:12:55 2018 -0600

    Whitespace

diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 1e5676e8..762783f3 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -64,9 +64,9 @@ typedef struct TableRecord
 
   Tag		tag;		/* 4-byte identifier. */
   CheckSum	checkSum;	/* CheckSum for this table. */
-  HBUINT32		offset;		/* Offset from beginning of TrueType font
+  HBUINT32	offset;		/* Offset from beginning of TrueType font
 				 * file. */
-  HBUINT32		length;		/* Length of this table. */
+  HBUINT32	length;		/* Length of this table. */
   public:
   DEFINE_SIZE_STATIC (16);
 } OpenTypeTable;
@@ -81,7 +81,7 @@ typedef struct OffsetTable
   {
     return tables[i];
   }
-  inline unsigned int get_table_tags (unsigned int start_offset,
+  inline unsigned int get_table_tags (unsigned int  start_offset,
 				      unsigned int *table_count, /* IN/OUT */
 				      hb_tag_t     *table_tags /* OUT */) const
   {
commit 7fd0b61dee18380c302009f8be9cd68dadab7308
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 7 16:44:52 2018 -0600

    [subset] Create new face and copy all tables to it
    
    test-subset fails now because subset-face does not know how to compile itself.

diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index a1c6833e..61f38a0a 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -194,10 +194,9 @@ hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
 
 /**
  * hb_subset:
+ * @source: font face data to be subset.
  * @profile: profile to use for the subsetting.
  * @input: input to use for the subsetting.
- * @face: font face data to be subset.
- * @result: subsetting result.
  *
  * Subsets a font according to provided profile and input.
  **/
@@ -210,13 +209,32 @@ hb_subset (hb_face_t *source,
 
   hb_subset_plan_t *plan = hb_subset_plan_create (source, profile, input);
 
+  hb_face_t *face = hb_subset_face_create ();
+
+  /* Copy tables to new face. */
+  {
+    hb_tag_t table_tags[32];
+    unsigned int offset = 0, count;
+    do {
+      count == ARRAY_LENGTH (table_tags);
+      hb_face_get_table_tags (source, offset, &count, table_tags);
+      for (unsigned int i = 0; i < count; i++)
+      {
+	hb_tag_t tag = table_tags[i];
+	hb_blob_t *blob = hb_face_reference_table (source, tag);
+	hb_subset_face_add_table (face, tag, blob);
+	hb_blob_destroy (blob);
+      }
+    } while (count == ARRAY_LENGTH (table_tags));
+  }
+
   hb_codepoint_t old_gid = -1;
-  while (hb_set_next(plan->glyphs_to_retain, &old_gid)) {
+  while (hb_set_next (plan->glyphs_to_retain, &old_gid)) {
     hb_codepoint_t new_gid;
-    if (hb_subset_plan_new_gid_for_old_id(plan, old_gid, &new_gid)) {
-      DEBUG_MSG(SUBSET, nullptr, "Remap %d : %d", old_gid, new_gid);
+    if (hb_subset_plan_new_gid_for_old_id (plan, old_gid, &new_gid)) {
+      DEBUG_MSG (SUBSET, nullptr, "Remap %d : %d", old_gid, new_gid);
     } else {
-      DEBUG_MSG(SUBSET, nullptr, "Remap %d : DOOM! No new ID", old_gid);
+      DEBUG_MSG (SUBSET, nullptr, "Remap %d : DOOM! No new ID", old_gid);
     }
   }
   // TODO:
@@ -226,16 +244,13 @@ hb_subset (hb_face_t *source,
   //   - copy the table into the output.
   // - Fix header + table directory.
 
-  bool success = true;
-
   hb_blob_t *glyf_prime = nullptr;
   if (hb_subset_glyf (plan, source, &glyf_prime)) {
     // TODO: write new glyf to new face.
-  } else {
-    success = false;
   }
   hb_blob_destroy (glyf_prime);
 
   hb_subset_plan_destroy (plan);
-  return success ? hb_face_reference (source) : nullptr;
+
+  return face;
 }
commit 4e1abe2ce0b5163cbbbb8f8be0e9f7deba5ab2cb
Author: Garret Rieger <grieger at google.com>
Date:   Wed Feb 7 13:28:11 2018 -0800

    Refactor subset glyf to remove multiple calls to glyf.fini()

diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index e0ae5d80..6581754b 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -74,46 +74,30 @@ write_glyf_prime (const OT::glyf::accelerator_t &glyf,
   return true;
 }
 
-/**
- * hb_subset_glyf:
- * Subsets the glyph table according to a provided plan.
- *
- * Return value: subsetted glyf table.
- *
- * Since: 1.7.5
- **/
 bool
-hb_subset_glyf (hb_subset_plan_t *plan,
-                hb_face_t        *face,
-                hb_blob_t       **glyf_prime /* OUT */)
+_hb_subset_glyf (const OT::glyf::accelerator_t  &glyf,
+                 const char                     *glyf_data,
+                 hb_set_t                       *glyphs_to_retain,
+                 hb_blob_t                     **glyf_prime /* OUT */)
 {
   // TODO(grieger): Sanity check writes to make sure they are in-bounds.
   // TODO(grieger): Sanity check allocation size for the new table.
   // TODO(grieger): Subset loca simultaneously.
 
-  hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
-  const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
-
-  OT::glyf::accelerator_t glyf;
-  glyf.init(face);
-
   unsigned int glyf_prime_size;
   if (!calculate_glyf_prime_size (glyf,
-                                  plan->glyphs_to_retain,
+                                  glyphs_to_retain,
                                   &glyf_prime_size)) {
-    glyf.fini();
     return false;
   }
 
   char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1);
-  if (!write_glyf_prime (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime_size,
+  if (!write_glyf_prime (glyf, glyf_data, glyphs_to_retain, glyf_prime_size,
                          glyf_prime_data)) {
-    glyf.fini();
     free (glyf_prime_data);
     return false;
   }
 
-  glyf.fini();
   *glyf_prime = hb_blob_create (glyf_prime_data,
                                 glyf_prime_size,
                                 HB_MEMORY_MODE_READONLY,
@@ -121,3 +105,27 @@ hb_subset_glyf (hb_subset_plan_t *plan,
                                 free);
   return true;
 }
+
+/**
+ * hb_subset_glyf:
+ * Subsets the glyph table according to a provided plan.
+ *
+ * Return value: subsetted glyf table.
+ *
+ * Since: 1.7.5
+ **/
+bool
+hb_subset_glyf (hb_subset_plan_t *plan,
+                hb_face_t        *face,
+                hb_blob_t       **glyf_prime /* OUT */)
+{
+  hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
+  const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
+
+  OT::glyf::accelerator_t glyf;
+  glyf.init(face);
+  bool result = _hb_subset_glyf (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime);
+  glyf.fini();
+
+  return result;
+}
commit 0a5d1440f829f07454592adde9dd3aa93ad74442
Author: Garret Rieger <grieger at google.com>
Date:   Wed Feb 7 13:09:54 2018 -0800

    Add implementation of glyf subsetting.

diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index 5a3dff6d..e0ae5d80 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -24,9 +24,56 @@
  * Google Author(s): Garret Rieger
  */
 
+#include "hb-open-type-private.hh"
 #include "hb-ot-glyf-table.hh"
+#include "hb-set.h"
 #include "hb-subset-glyf.hh"
 
+bool
+calculate_glyf_prime_size (const OT::glyf::accelerator_t &glyf,
+                           hb_set_t *glyph_ids,
+                           unsigned int *size /* OUT */)
+{
+  unsigned int total = 0;
+  hb_codepoint_t next_glyph = -1;
+  while (hb_set_next(glyph_ids, &next_glyph)) {
+    unsigned int start_offset, end_offset;
+    if (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)) {
+      *size = 0;
+      return false;
+    }
+
+    total += end_offset - start_offset;
+  }
+
+  *size = total;
+  return true;
+}
+
+bool
+write_glyf_prime (const OT::glyf::accelerator_t &glyf,
+                  const char                    *glyf_data,
+                  hb_set_t                      *glyph_ids,
+                  int                            glyf_prime_size,
+                  char                          *glyf_prime_data /* OUT */)
+{
+  char *glyf_prime_data_next = glyf_prime_data;
+
+  hb_codepoint_t next_glyph = -1;
+  while (hb_set_next(glyph_ids, &next_glyph)) {
+    unsigned int start_offset, end_offset;
+    if (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)) {
+      return false;
+    }
+
+    int length = end_offset - start_offset;
+    memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
+    glyf_prime_data_next += length;
+  }
+
+  return true;
+}
+
 /**
  * hb_subset_glyf:
  * Subsets the glyph table according to a provided plan.
@@ -40,13 +87,37 @@ hb_subset_glyf (hb_subset_plan_t *plan,
                 hb_face_t        *face,
                 hb_blob_t       **glyf_prime /* OUT */)
 {
-  OT::glyf::accelerator_t glyf_accelerator;
-  glyf_accelerator.init(face);
+  // TODO(grieger): Sanity check writes to make sure they are in-bounds.
+  // TODO(grieger): Sanity check allocation size for the new table.
+  // TODO(grieger): Subset loca simultaneously.
+
+  hb_blob_t *glyf_blob = OT::Sanitizer<OT::glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
+  const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
+
+  OT::glyf::accelerator_t glyf;
+  glyf.init(face);
 
-  // TODO
+  unsigned int glyf_prime_size;
+  if (!calculate_glyf_prime_size (glyf,
+                                  plan->glyphs_to_retain,
+                                  &glyf_prime_size)) {
+    glyf.fini();
+    return false;
+  }
 
-  glyf_accelerator.fini();
+  char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1);
+  if (!write_glyf_prime (glyf, glyf_data, plan->glyphs_to_retain, glyf_prime_size,
+                         glyf_prime_data)) {
+    glyf.fini();
+    free (glyf_prime_data);
+    return false;
+  }
 
-  *glyf_prime = hb_blob_get_empty ();
+  glyf.fini();
+  *glyf_prime = hb_blob_create (glyf_prime_data,
+                                glyf_prime_size,
+                                HB_MEMORY_MODE_READONLY,
+                                glyf_prime_data,
+                                free);
   return true;
 }
commit 05d65baa1bb64664ba838993fd35f3899d52eb8d
Author: Garret Rieger <grieger at google.com>
Date:   Wed Feb 7 10:55:30 2018 -0800

    Extract glyf offset calculation into it's own method.

diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 67143c63..e6b07a86 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -122,29 +122,39 @@ struct glyf
       hb_blob_destroy (glyf_blob);
     }
 
-    inline bool get_extents (hb_codepoint_t glyph,
-			     hb_glyph_extents_t *extents) const
+    inline bool get_offsets (hb_codepoint_t  glyph,
+                             unsigned int   *start_offset /* OUT */,
+                             unsigned int   *end_offset   /* OUT */) const
     {
       if (unlikely (glyph >= num_glyphs))
 	return false;
 
-      unsigned int start_offset, end_offset;
       if (short_offset)
       {
         const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX;
-	start_offset = 2 * offsets[glyph];
-	end_offset   = 2 * offsets[glyph + 1];
+	*start_offset = 2 * offsets[glyph];
+	*end_offset   = 2 * offsets[glyph + 1];
       }
       else
       {
         const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX;
-	start_offset = offsets[glyph];
-	end_offset   = offsets[glyph + 1];
+	*start_offset = offsets[glyph];
+	*end_offset   = offsets[glyph + 1];
       }
 
-      if (start_offset > end_offset || end_offset > glyf_len)
+      if (*start_offset > *end_offset || *end_offset > glyf_len)
 	return false;
 
+      return true;
+    }
+
+    inline bool get_extents (hb_codepoint_t glyph,
+			     hb_glyph_extents_t *extents) const
+    {
+      unsigned int start_offset, end_offset;
+      if (!get_offsets (glyph, &start_offset, &end_offset))
+        return false;
+
       if (end_offset - start_offset < GlyphHeader::static_size)
 	return true; /* Empty glyph; zero extents. */
 


More information about the HarfBuzz mailing list