[ot] Speed up get_glyph_name()
get_glyph_from_name() coming soon.
This commit is contained in:
parent
feadee079e
commit
5de83fab94
|
@ -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
|
||||||
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
|
||||||
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;
|
const uint8_t *data = pool + offset;
|
||||||
|
unsigned int name_length = *data;
|
||||||
|
data++;
|
||||||
|
|
||||||
|
if (unlikely (!name_length || buf_len <= name_length))
|
||||||
|
return false;
|
||||||
|
memcpy (buf, data, name_length);
|
||||||
|
buf[name_length] = '\0';
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
inline bool get_glyph_from_name (const char *name, int len,
|
||||||
}
|
hb_codepoint_t *glyph) const
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (version.to_int () == 0x00010000)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
|
if (len < 0)
|
||||||
|
len = strlen (name);
|
||||||
|
|
||||||
|
if (unlikely (!len))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (version == 0x00010000)
|
||||||
{
|
{
|
||||||
if (strncmp (name, format1_names (i), len) == 0 && format1_names (i)[len] == '\0')
|
for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
|
||||||
{
|
{
|
||||||
*glyph = i;
|
if (strncmp (name, format1_names (i), len) == 0 && format1_names (i)[len] == '\0')
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version.to_int () == 0x00020000)
|
|
||||||
{
|
|
||||||
const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
|
|
||||||
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.glyphNameIndex.len; gid++)
|
|
||||||
{
|
|
||||||
unsigned int index = v2.glyphNameIndex[gid];
|
|
||||||
if (index < NUM_FORMAT1_NAMES)
|
|
||||||
{
|
|
||||||
if (strncmp (name, format1_names (index), len) == 0 && format1_names (index)[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 @@
|
||||||
#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)
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue