提交 5de83fab 编写于 作者: B Behdad Esfahbod

[ot] Speed up get_glyph_name()

get_glyph_from_name() coming soon.
上级 feadee07
...@@ -304,25 +304,24 @@ struct hb_ot_face_cbdt_accelerator_t ...@@ -304,25 +304,24 @@ struct hb_ot_face_cbdt_accelerator_t
struct hb_ot_face_post_accelerator_t struct hb_ot_face_post_accelerator_t
{ {
hb_blob_t *post_blob; hb_blob_t *post_blob;
unsigned int post_len; OT::post::accelerator_t accel;
const OT::post *post;
inline void init (hb_face_t *face) inline void init (hb_face_t *face)
{ {
this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post)); hb_blob_t *blob = 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); accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob));
this->post_len = hb_blob_get_length (this->post_blob);
} }
inline void fini (void) inline void fini (void)
{ {
accel.fini ();
hb_blob_destroy (this->post_blob); hb_blob_destroy (this->post_blob);
} }
inline bool get_glyph_name (hb_codepoint_t glyph, inline bool get_glyph_name (hb_codepoint_t glyph,
char *name, unsigned int size) const 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, inline bool get_glyph_from_name (const char *name, int len,
...@@ -331,7 +330,7 @@ struct hb_ot_face_post_accelerator_t ...@@ -331,7 +330,7 @@ struct hb_ot_face_post_accelerator_t
if (unlikely (!len)) if (unlikely (!len))
return false; 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);
} }
}; };
......
...@@ -81,132 +81,116 @@ struct post ...@@ -81,132 +81,116 @@ struct post
return_trace (true); return_trace (true);
} }
inline bool get_glyph_name (hb_codepoint_t glyph, struct accelerator_t
char *buffer, unsigned int buffer_length,
unsigned int blob_len) const
{ {
if (version.to_int () == 0x00010000) inline void init (const post *table, unsigned int post_len)
{ {
if (glyph >= NUM_FORMAT1_NAMES) version = table->version.to_int ();
return false; index_to_offset.init ();
if (version != 0x00020000)
return;
if (!buffer_length) const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
return true;
strncpy (buffer, format1_names (glyph), buffer_length); glyphNameIndex = &v2.glyphNameIndex;
buffer[buffer_length - 1] = '\0'; pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
return true;
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; return false;
if (!buffer_length) if (!buf_len)
return true; return true;
unsigned int index = v2.glyphNameIndex[glyph]; unsigned int index = glyphNameIndex->array[glyph];
if (index < NUM_FORMAT1_NAMES) if (index < NUM_FORMAT1_NAMES)
{ {
if (!buffer_length) if (!buf_len)
return true; return true;
strncpy (buffer, format1_names (index), buffer_length); strncpy (buf, format1_names (index), buf_len);
buffer[buffer_length - 1] = '\0'; buf[buf_len - 1] = '\0';
return true; return true;
} }
index -= NUM_FORMAT1_NAMES; index -= NUM_FORMAT1_NAMES;
const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex); if (index >= index_to_offset.len)
const uint8_t *end = (uint8_t *) this + blob_len; return false;
for (unsigned int i = 0; data < end; i++) unsigned int offset = index_to_offset[index];
{
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;
}
return false;
}
inline bool get_glyph_from_name (const char *name, int len, const uint8_t *data = pool + offset;
hb_codepoint_t *glyph, unsigned int name_length = *data;
unsigned int blob_len) const data++;
{
if (len < 0)
len = strlen (name);
if (version.to_int () == 0x00010000) if (unlikely (!name_length || buf_len <= name_length))
{ return false;
for (int i = 0; i < NUM_FORMAT1_NAMES; i++) memcpy (buf, data, name_length);
{ buf[name_length] = '\0';
if (strncmp (name, format1_names (i), len) == 0 && format1_names (i)[len] == '\0') return true;
{
*glyph = i;
return true;
}
}
return false;
} }
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); if (len < 0)
const uint8_t *data = &StructAfter<uint8_t> (v2.glyphNameIndex); len = strlen (name);
if (unlikely (!len))
return false;
/* XXX The following code is wrong. */ if (version == 0x00010000)
return false;
for (hb_codepoint_t gid = 0; gid < v2.glyphNameIndex.len; gid++)
{ {
unsigned int index = v2.glyphNameIndex[gid]; for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
if (index < NUM_FORMAT1_NAMES)
{ {
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; 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; return false;
} }
/* TODO format2 */
return false; 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: public:
FixedVersion<>version; /* 0x00010000 for version 1.0 FixedVersion<>version; /* 0x00010000 for version 1.0
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "hb-private.hh" #include "hb-private.hh"
#include "hb.h" #include "hb.h"
#include "hb-ot.h"
#ifdef HAVE_FREETYPE #ifdef HAVE_FREETYPE
#include "hb-ft.h" #include "hb-ft.h"
#endif #endif
...@@ -90,8 +91,9 @@ main (int argc, char **argv) ...@@ -90,8 +91,9 @@ main (int argc, char **argv)
hb_font_t *font = hb_font_create (face); hb_font_t *font = hb_font_create (face);
hb_face_destroy (face); hb_face_destroy (face);
hb_font_set_scale (font, upem, upem); hb_font_set_scale (font, upem, upem);
hb_ot_font_set_funcs (font);
#ifdef HAVE_FREETYPE #ifdef HAVE_FREETYPE
hb_ft_font_set_funcs (font); //hb_ft_font_set_funcs (font);
#endif #endif
hb_buffer_t *buf; hb_buffer_t *buf;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册