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

Behdad Esfahbod behdad at kemper.freedesktop.org
Sun Oct 29 02:51:34 UTC 2017


 src/hb-ot-font.cc            |   13 +--
 src/hb-ot-post-table.hh      |  169 ++++++++++++++++++-------------------------
 src/test-buffer-serialize.cc |    4 -
 3 files changed, 83 insertions(+), 103 deletions(-)

New commits:
commit 5de83fab947e23cc729d69f8d44a28311298af9d
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 28 19:54:04 2017 -0600

    [ot] Speed up get_glyph_name()
    
    get_glyph_from_name() coming soon.

diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 10c1cb2c..5759a30d 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -304,25 +304,24 @@ struct hb_ot_face_cbdt_accelerator_t
 struct hb_ot_face_post_accelerator_t
 {
   hb_blob_t *post_blob;
-  unsigned int post_len;
-  const OT::post *post;
+  OT::post::accelerator_t accel;
 
   inline void init (hb_face_t *face)
   {
-    this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post));
-    this->post = OT::Sanitizer<OT::post>::lock_instance (this->post_blob);
-    this->post_len = hb_blob_get_length (this->post_blob);
+    hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post));
+    accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob));
   }
 
   inline void fini (void)
   {
+    accel.fini ();
     hb_blob_destroy (this->post_blob);
   }
 
   inline bool get_glyph_name (hb_codepoint_t glyph,
 			      char *name, unsigned int size) const
   {
-    return this->post->get_glyph_name (glyph, name, size, this->post_len);
+    return this->accel.get_glyph_name (glyph, name, size);
   }
 
   inline bool get_glyph_from_name (const char *name, int len,
@@ -331,7 +330,7 @@ struct hb_ot_face_post_accelerator_t
     if (unlikely (!len))
       return false;
 
-    return this->post->get_glyph_from_name (name, len, glyph, this->post_len);
+    return this->accel.get_glyph_from_name (name, len, glyph);
   }
 };
 
diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 0b3b806b..472e5f7a 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -81,132 +81,116 @@ struct post
     return_trace (true);
   }
 
-  inline bool get_glyph_name (hb_codepoint_t glyph,
-			      char *buffer, unsigned int buffer_length,
-			      unsigned int blob_len) const
+  struct accelerator_t
   {
-    if (version.to_int () == 0x00010000)
+    inline void init (const post *table, unsigned int post_len)
     {
-      if (glyph >= NUM_FORMAT1_NAMES)
-	return false;
+      version = table->version.to_int ();
+      index_to_offset.init ();
+      if (version != 0x00020000)
+        return;
 
-      if (!buffer_length)
-	return true;
-      strncpy (buffer, format1_names (glyph), buffer_length);
-      buffer[buffer_length - 1] = '\0';
-      return true;
+      const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
+
+      glyphNameIndex = &v2.glyphNameIndex;
+      pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
+
+      const uint8_t *end = (uint8_t *) table + post_len;
+      for (const uint8_t *data = pool; data < end && data + *data <= end; data += *data)
+      {
+	uint32_t *offset = index_to_offset.push ();
+	if (unlikely (!offset))
+	  break;
+	*offset = data - pool;
+      }
+    }
+    inline void fini (void)
+    {
+      index_to_offset.finish ();
     }
 
-    if (version.to_int () == 0x00020000)
+    inline bool get_glyph_name (hb_codepoint_t glyph,
+				char *buf, unsigned int buf_len) const
     {
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
+      if (version == 0x00010000)
+      {
+	if (glyph >= NUM_FORMAT1_NAMES)
+	  return false;
 
-      if (glyph >= v2.glyphNameIndex.len)
+	if (!buf_len)
+	  return true;
+	strncpy (buf, format1_names (glyph), buf_len);
+	buf[buf_len - 1] = '\0';
+	return true;
+      }
+
+      if (version != 0x00020000)
+        return false;
+
+      if (glyph >= glyphNameIndex->len)
 	return false;
 
-      if (!buffer_length)
+      if (!buf_len)
 	return true;
 
-      unsigned int index = v2.glyphNameIndex[glyph];
+      unsigned int index = glyphNameIndex->array[glyph];
       if (index < NUM_FORMAT1_NAMES)
       {
-	if (!buffer_length)
+	if (!buf_len)
 	  return true;
-	strncpy (buffer, format1_names (index), buffer_length);
-	buffer[buffer_length - 1] = '\0';
+	strncpy (buf, format1_names (index), buf_len);
+	buf[buf_len - 1] = '\0';
 	return true;
       }
       index -= NUM_FORMAT1_NAMES;
 
-      const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex);
-      const uint8_t *end = (uint8_t *) this + blob_len;
-      for (unsigned int i = 0; data < end; i++)
-      {
-	unsigned int name_length = data[0];
-	data++;
-	if (i == index)
-	{
-	  if (unlikely (!name_length))
-	    return false;
-
-	  unsigned int remaining = end - data;
-	  name_length = MIN (name_length, buffer_length - 1);
-	  name_length = MIN (name_length, remaining);
-	  memcpy (buffer, data, name_length);
-	  buffer[name_length] = '\0';
-	  return true;
-	}
-	data += name_length;
-      }
-
-      return false;
-    }
+      if (index >= index_to_offset.len)
+        return false;
+      unsigned int offset = index_to_offset[index];
 
-    return false;
-  }
 
-  inline bool get_glyph_from_name (const char *name, int len,
-				   hb_codepoint_t *glyph,
-				   unsigned int blob_len) const
-  {
-    if (len < 0)
-      len = strlen (name);
+      const uint8_t *data = pool + offset;
+      unsigned int name_length = *data;
+      data++;
 
-    if (version.to_int () == 0x00010000)
-    {
-      for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
-      {
-	if (strncmp (name, format1_names (i), len) == 0 && format1_names (i)[len] == '\0')
-	{
-	  *glyph = i;
-	  return true;
-	}
-      }
-      return false;
+      if (unlikely (!name_length || buf_len <= name_length))
+	return false;
+      memcpy (buf, data, name_length);
+      buf[name_length] = '\0';
+      return true;
     }
 
-    if (version.to_int () == 0x00020000)
+    inline bool get_glyph_from_name (const char *name, int len,
+				     hb_codepoint_t *glyph) const
     {
-      const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
-      const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex);
+      if (len < 0)
+	len = strlen (name);
 
+      if (unlikely (!len))
+        return false;
 
-      /* XXX The following code is wrong. */
-      return false;
-      for (hb_codepoint_t gid = 0; gid < v2.glyphNameIndex.len; gid++)
+      if (version == 0x00010000)
       {
-	unsigned int index = v2.glyphNameIndex[gid];
-	if (index < NUM_FORMAT1_NAMES)
+	for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
 	{
-	  if (strncmp (name, format1_names (index), len) == 0 && format1_names (index)[len] == '\0')
+	  if (strncmp (name, format1_names (i), len) == 0 && format1_names (i)[len] == '\0')
 	  {
-	    *glyph = gid;
+	    *glyph = i;
 	    return true;
 	  }
-	  continue;
-	}
-	index -= NUM_FORMAT1_NAMES;
-
-	for (unsigned int i = 0; data < (uint8_t *) this + blob_len; i++)
-	{
-	  unsigned int name_length = data[0];
-	  unsigned int remaining = CastP<uint8_t> (this) + blob_len - data - 1;
-	  name_length = MIN (name_length, remaining);
-	  if (name_length == (unsigned int) len && strncmp (name, (const char *) data + 1, len) == 0)
-	  {
-	    *glyph = gid;
-	    return true;
-	  }
-	  data += name_length + 1;
 	}
 	return false;
       }
 
+      /* TODO format2 */
       return false;
     }
 
-    return false;
-  }
+    uint32_t version;
+    const ArrayOf<USHORT> *glyphNameIndex;
+    hb_prealloced_array_t<uint32_t, 1> index_to_offset;
+    const uint8_t *pool;
+  };
 
   public:
   FixedVersion<>version;		/* 0x00010000 for version 1.0
diff --git a/src/test-buffer-serialize.cc b/src/test-buffer-serialize.cc
index 74de9a0e..4b429eab 100644
--- a/src/test-buffer-serialize.cc
+++ b/src/test-buffer-serialize.cc
@@ -27,6 +27,7 @@
 #include "hb-private.hh"
 
 #include "hb.h"
+#include "hb-ot.h"
 #ifdef HAVE_FREETYPE
 #include "hb-ft.h"
 #endif
@@ -90,8 +91,9 @@ main (int argc, char **argv)
   hb_font_t *font = hb_font_create (face);
   hb_face_destroy (face);
   hb_font_set_scale (font, upem, upem);
+  hb_ot_font_set_funcs (font);
 #ifdef HAVE_FREETYPE
-  hb_ft_font_set_funcs (font);
+  //hb_ft_font_set_funcs (font);
 #endif
 
   hb_buffer_t *buf;
commit feadee079e09e43e5f712a66816605e19155594e
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Sat Oct 28 16:58:56 2017 -0600

    [post] Refactor a bit, use our data types

diff --git a/src/hb-ot-post-table.hh b/src/hb-ot-post-table.hh
index 6e4a23af..0b3b806b 100644
--- a/src/hb-ot-post-table.hh
+++ b/src/hb-ot-post-table.hh
@@ -52,13 +52,10 @@ struct postV2Tail
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (numberOfGlyphs.sanitize (c) &&
-		  c->check_array (glyphNameIndex, sizeof (USHORT), numberOfGlyphs));
+    return_trace (glyphNameIndex.sanitize (c));
   }
 
-  USHORT	numberOfGlyphs;		/* Number of glyphs (this should be the
-					 * same as numGlyphs in 'maxp' table). */
-  USHORT	glyphNameIndex[VAR];	/* This is not an offset, but is the
+  ArrayOf<USHORT>glyphNameIndex;	/* This is not an offset, but is the
 					 * ordinal number of the glyph in 'post'
 					 * string tables. */
   BYTE		namesX[VAR];		/* Glyph names with length bytes [variable]
@@ -104,7 +101,7 @@ struct post
     {
       const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
 
-      if (glyph >= v2.numberOfGlyphs)
+      if (glyph >= v2.glyphNameIndex.len)
 	return false;
 
       if (!buffer_length)
@@ -121,9 +118,8 @@ struct post
       }
       index -= NUM_FORMAT1_NAMES;
 
-      unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
-      unsigned char *data = (unsigned char *) this + offset;
-      unsigned char *end = (unsigned char *) this + blob_len;
+      const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex);
+      const uint8_t *end = (uint8_t *) this + blob_len;
       for (unsigned int i = 0; data < end; i++)
       {
 	unsigned int name_length = data[0];
@@ -172,13 +168,12 @@ struct post
     if (version.to_int () == 0x00020000)
     {
       const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
-      unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
-      char* data = (char*) this + offset;
+      const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex);
 
 
       /* XXX The following code is wrong. */
       return false;
-      for (hb_codepoint_t gid = 0; gid < v2.numberOfGlyphs; gid++)
+      for (hb_codepoint_t gid = 0; gid < v2.glyphNameIndex.len; gid++)
       {
 	unsigned int index = v2.glyphNameIndex[gid];
 	if (index < NUM_FORMAT1_NAMES)
@@ -192,12 +187,12 @@ struct post
 	}
 	index -= NUM_FORMAT1_NAMES;
 
-	for (unsigned int i = 0; data < (char*) this + blob_len; i++)
+	for (unsigned int i = 0; data < (uint8_t *) this + blob_len; i++)
 	{
 	  unsigned int name_length = data[0];
-	  unsigned int remaining = (char*) this + blob_len - data - 1;
+	  unsigned int remaining = CastP<uint8_t> (this) + blob_len - data - 1;
 	  name_length = MIN (name_length, remaining);
-	  if (name_length == (unsigned int) len && strncmp (name, data + 1, len) == 0)
+	  if (name_length == (unsigned int) len && strncmp (name, (const char *) data + 1, len) == 0)
 	  {
 	    *glyph = gid;
 	    return true;


More information about the HarfBuzz mailing list