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

Behdad Esfahbod behdad at kemper.freedesktop.org
Wed Feb 24 11:27:32 UTC 2016


 src/hb-ot-cmap-table.hh |  125 +++++++++++++++++++++++++-----------------------
 src/hb-ot-font.cc       |   48 +++++++++++++++---
 2 files changed, 107 insertions(+), 66 deletions(-)

New commits:
commit 23335deaad9d4d9824ff41343264514d3f9f7e37
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 24 20:27:13 2016 +0900

    [ot-font] Accelerate cmap format4 get_glyph

diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 886d348..d7a94a1 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -69,61 +69,78 @@ struct CmapSubtableFormat0
 
 struct CmapSubtableFormat4
 {
-  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  struct accelerator_t
   {
-    unsigned int segCount;
-    const USHORT *endCount;
-    const USHORT *startCount;
-    const USHORT *idDelta;
-    const USHORT *idRangeOffset;
-    const USHORT *glyphIdArray;
-    unsigned int glyphIdArrayLength;
+    inline void init (const CmapSubtableFormat4 *subtable)
+    {
+      segCount = subtable->segCountX2 / 2;
+      endCount = subtable->values;
+      startCount = endCount + segCount + 1;
+      idDelta = startCount + segCount;
+      idRangeOffset = idDelta + segCount;
+      glyphIdArray = idRangeOffset + segCount;
+      glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
+    }
 
-    segCount = this->segCountX2 / 2;
-    endCount = this->values;
-    startCount = endCount + segCount + 1;
-    idDelta = startCount + segCount;
-    idRangeOffset = idDelta + segCount;
-    glyphIdArray = idRangeOffset + segCount;
-    glyphIdArrayLength = (this->length - 16 - 8 * segCount) / 2;
-
-    /* Custom two-array bsearch. */
-    int min = 0, max = (int) segCount - 1;
-    unsigned int i;
-    while (min <= max)
+    static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
     {
-      int mid = (min + max) / 2;
-      if (codepoint < startCount[mid])
-        max = mid - 1;
-      else if (codepoint > endCount[mid])
-        min = mid + 1;
+      const accelerator_t *thiz = (const accelerator_t *) obj;
+
+      /* Custom two-array bsearch. */
+      int min = 0, max = (int) thiz->segCount - 1;
+      const USHORT *startCount = thiz->startCount;
+      const USHORT *endCount = thiz->endCount;
+      unsigned int i;
+      while (min <= max)
+      {
+	int mid = (min + max) / 2;
+	if (codepoint < startCount[mid])
+	  max = mid - 1;
+	else if (codepoint > endCount[mid])
+	  min = mid + 1;
+	else
+	{
+	  i = mid;
+	  goto found;
+	}
+      }
+      return false;
+
+    found:
+      hb_codepoint_t gid;
+      unsigned int rangeOffset = thiz->idRangeOffset[i];
+      if (rangeOffset == 0)
+	gid = codepoint + thiz->idDelta[i];
       else
       {
-	i = mid;
-	goto found;
+	/* Somebody has been smoking... */
+	unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount;
+	if (unlikely (index >= thiz->glyphIdArrayLength))
+	  return false;
+	gid = thiz->glyphIdArray[index];
+	if (unlikely (!gid))
+	  return false;
+	gid += thiz->idDelta[i];
       }
-    }
-    return false;
-
-  found:
-    hb_codepoint_t gid;
-    unsigned int rangeOffset = idRangeOffset[i];
-    if (rangeOffset == 0)
-      gid = codepoint + idDelta[i];
-    else
-    {
-      /* Somebody has been smoking... */
-      unsigned int index = rangeOffset / 2 + (codepoint - startCount[i]) + i - segCount;
-      if (unlikely (index >= glyphIdArrayLength))
-	return false;
-      gid = glyphIdArray[index];
-      if (unlikely (!gid))
-	return false;
-      gid += idDelta[i];
+
+      *glyph = gid & 0xFFFFu;
+      return true;
     }
 
-    *glyph = gid & 0xFFFFu;
-    return true;
+    const USHORT *endCount;
+    const USHORT *startCount;
+    const USHORT *idDelta;
+    const USHORT *idRangeOffset;
+    const USHORT *glyphIdArray;
+    unsigned int segCount;
+    unsigned int glyphIdArrayLength;
+  };
+
+  inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
+  {
+    accelerator_t accel;
+    accel.init (this);
+    return accel.get_glyph_func (&accel, codepoint, glyph);
   }
 
   inline bool sanitize (hb_sanitize_context_t *c) const
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index e7dbcff..61c7036 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -218,6 +218,7 @@ struct hb_ot_face_cmap_accelerator_t
 {
   hb_cmap_get_glyph_func_t get_glyph_func;
   const void *get_glyph_data;
+  OT::CmapSubtableFormat4::accelerator_t format4_accel;
 
   const OT::CmapSubtableFormat14 *uvs_table;
   hb_blob_t *blob;
@@ -255,8 +256,19 @@ struct hb_ot_face_cmap_accelerator_t
 
     this->uvs_table = subtable_uvs;
 
-    this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
     this->get_glyph_data = subtable;
+    switch (subtable->u.format) {
+    /* Accelerate format 4 and format 12. */
+    default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;		break;
+    case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;	break;
+    case  4:
+      {
+        this->format4_accel.init (&subtable->u.format4);
+	this->get_glyph_data = &this->format4_accel;
+        this->get_glyph_func = this->format4_accel.get_glyph_func;
+      }
+      break;
+    }
   }
 
   inline void fini (void)
commit e0f16a715bc3e621ff21a8be88102e9672630574
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 24 19:52:36 2016 +0900

    [ot-font] Towards accelerating get_glyph()

diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index fe6f806..e7dbcff 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -201,9 +201,24 @@ struct hb_ot_face_glyf_accelerator_t
   }
 };
 
+typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
+					  hb_codepoint_t codepoint,
+					  hb_codepoint_t *glyph);
+
+template <typename Type>
+static inline bool get_glyph_from (const void *obj,
+				   hb_codepoint_t codepoint,
+				   hb_codepoint_t *glyph)
+{
+  const Type *typed_obj = (const Type *) obj;
+  return typed_obj->get_glyph (codepoint, glyph);
+}
+
 struct hb_ot_face_cmap_accelerator_t
 {
-  const OT::CmapSubtable *table;
+  hb_cmap_get_glyph_func_t get_glyph_func;
+  const void *get_glyph_data;
+
   const OT::CmapSubtableFormat14 *uvs_table;
   hb_blob_t *blob;
 
@@ -238,8 +253,10 @@ struct hb_ot_face_cmap_accelerator_t
     /* Meh. */
     if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
 
-    this->table = subtable;
     this->uvs_table = subtable_uvs;
+
+    this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
+    this->get_glyph_data = subtable;
   }
 
   inline void fini (void)
@@ -250,7 +267,7 @@ struct hb_ot_face_cmap_accelerator_t
   inline bool get_nominal_glyph (hb_codepoint_t  unicode,
 				 hb_codepoint_t *glyph) const
   {
-    return this->table->get_glyph (unicode, glyph);
+    return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
   }
 
   inline bool get_variation_glyph (hb_codepoint_t  unicode,
commit 5473ebfb84c7b6059ac16e04676b363acc51aa00
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Wed Feb 24 19:32:43 2016 +0900

    [ot-font] Remove level of indirection in get_glyph_variant

diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index c9161f0..886d348 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -388,7 +388,7 @@ struct CmapSubtableFormat14
   }
 
   protected:
-  USHORT	format;		/* Format number is set to 0. */
+  USHORT	format;		/* Format number is set to 14. */
   ULONG		lengthZ;	/* Byte length of this subtable. */
   SortedArrayOf<VariationSelectorRecord, ULONG>
 		record;		/* Variation selector records; sorted
@@ -416,16 +416,6 @@ struct CmapSubtable
     }
   }
 
-  inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
-					    hb_codepoint_t variation_selector,
-					    hb_codepoint_t *glyph) const
-  {
-    switch (u.format) {
-    case 14: return u.format14.get_glyph_variant(codepoint, variation_selector, glyph);
-    default: return GLYPH_VARIANT_NOT_FOUND;
-    }
-  }
-
   inline bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -442,7 +432,7 @@ struct CmapSubtable
     }
   }
 
-  protected:
+  public:
   union {
   USHORT		format;		/* Format identifier */
   CmapSubtableFormat0	format0;
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index bba6132..fe6f806 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -204,7 +204,7 @@ struct hb_ot_face_glyf_accelerator_t
 struct hb_ot_face_cmap_accelerator_t
 {
   const OT::CmapSubtable *table;
-  const OT::CmapSubtable *uvs_table;
+  const OT::CmapSubtableFormat14 *uvs_table;
   hb_blob_t *blob;
 
   inline void init (hb_face_t *face)
@@ -212,7 +212,7 @@ struct hb_ot_face_cmap_accelerator_t
     this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
     const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
     const OT::CmapSubtable *subtable = NULL;
-    const OT::CmapSubtable *subtable_uvs = NULL;
+    const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
 
     /* 32-bit subtables. */
     if (!subtable) subtable = cmap->find_subtable (3, 10);
@@ -229,9 +229,14 @@ struct hb_ot_face_cmap_accelerator_t
     if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
 
     /* UVS subtable. */
-    if (!subtable_uvs) subtable_uvs = cmap->find_subtable (0, 5);
+    if (!subtable_uvs)
+    {
+      const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
+      if (st && st->u.format == 14)
+        subtable_uvs = &st->u.format14;
+    }
     /* Meh. */
-    if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtable);
+    if (!subtable_uvs) subtable_uvs = &OT::Null(OT::CmapSubtableFormat14);
 
     this->table = subtable;
     this->uvs_table = subtable_uvs;


More information about the HarfBuzz mailing list