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 <beh...@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 <beh...@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;
_______________________________________________
HarfBuzz mailing list
HarfBuzz@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to