From 5de83fab947e23cc729d69f8d44a28311298af9d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 28 Oct 2017 19:54:04 -0600 Subject: [PATCH] [ot] Speed up get_glyph_name() get_glyph_from_name() coming soon. --- src/hb-ot-font.cc | 13 ++- src/hb-ot-post-table.hh | 160 ++++++++++++++++------------------- src/test-buffer-serialize.cc | 4 +- 3 files changed, 81 insertions(+), 96 deletions(-) diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 10c1cb2c7..5759a30d3 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::sanitize (face->reference_table (HB_OT_TAG_post)); - this->post = OT::Sanitizer::lock_instance (this->post_blob); - this->post_len = hb_blob_get_length (this->post_blob); + hb_blob_t *blob = this->post_blob = OT::Sanitizer::sanitize (face->reference_table (HB_OT_TAG_post)); + accel.init (OT::Sanitizer::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 0b3b806b1..472e5f7a7 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 (*table); + + glyphNameIndex = &v2.glyphNameIndex; + pool = &StructAfter (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 (*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 (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 (*this); - const uint8_t *data = &StructAfter (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 (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 *glyphNameIndex; + hb_prealloced_array_t 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 74de9a0e7..4b429eab3 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;