summaryrefslogtreecommitdiff
path: root/src/hb-ot-post-table.hh
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@behdad.org>2017-10-28 19:54:04 -0600
committerBehdad Esfahbod <behdad@behdad.org>2017-10-28 19:54:04 -0600
commit5de83fab947e23cc729d69f8d44a28311298af9d (patch)
tree54866879ff7e0aeaa0873acfe9a32531e3d7fe08 /src/hb-ot-post-table.hh
parentfeadee079e09e43e5f712a66816605e19155594e (diff)
[ot] Speed up get_glyph_name()
get_glyph_from_name() coming soon.
Diffstat (limited to 'src/hb-ot-post-table.hh')
-rw-r--r--src/hb-ot-post-table.hh160
1 files changed, 72 insertions, 88 deletions
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