[post] Implement glyph_from_name()
This concludes https://github.com/behdad/harfbuzz/pull/568
This commit is contained in:
parent
6c738f353e
commit
e35a763c07
|
@ -108,9 +108,97 @@ struct post
|
|||
inline void fini (void)
|
||||
{
|
||||
index_to_offset.finish ();
|
||||
free (gids_sorted_by_name);
|
||||
}
|
||||
|
||||
inline hb_string_t _find_glyph_name (hb_codepoint_t glyph) const
|
||||
inline bool get_glyph_name (hb_codepoint_t glyph,
|
||||
char *buf, unsigned int buf_len) const
|
||||
{
|
||||
hb_string_t s = find_glyph_name (glyph);
|
||||
if (!s.len)
|
||||
return false;
|
||||
if (!buf_len)
|
||||
return true;
|
||||
if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
|
||||
return false;
|
||||
strncpy (buf, s.bytes, s.len);
|
||||
buf[s.len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool get_glyph_from_name (const char *name, int len,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
unsigned int count = get_glyph_count ();
|
||||
if (unlikely (!count))
|
||||
return false;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (name);
|
||||
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
retry:
|
||||
uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name);
|
||||
|
||||
if (unlikely (!gids))
|
||||
{
|
||||
gids = (uint16_t *) malloc (count * sizeof (gids[0]));
|
||||
if (unlikely (!gids))
|
||||
return false; /* Anything better?! */
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
gids[i] = i;
|
||||
hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) {
|
||||
free (gids);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
hb_string_t st (name, len);
|
||||
const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
|
||||
if (gid)
|
||||
{
|
||||
*glyph = *gid;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
inline unsigned int get_glyph_count (void) const
|
||||
{
|
||||
if (version == 0x00010000)
|
||||
return NUM_FORMAT1_NAMES;
|
||||
|
||||
if (version == 0x00020000)
|
||||
return glyphNameIndex->len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cmp_gids (const void *pa, const void *pb, void *arg)
|
||||
{
|
||||
const accelerator_t *thiz = (const accelerator_t *) arg;
|
||||
uint16_t a = * (const uint16_t *) pa;
|
||||
uint16_t b = * (const uint16_t *) pb;
|
||||
return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
|
||||
}
|
||||
|
||||
static inline int cmp_key (const void *pk, const void *po, void *arg)
|
||||
{
|
||||
const accelerator_t *thiz = (const accelerator_t *) arg;
|
||||
const hb_string_t *key = (const hb_string_t *) pk;
|
||||
uint16_t o = * (const uint16_t *) po;
|
||||
return thiz->find_glyph_name (o).cmp (*key);
|
||||
}
|
||||
|
||||
inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (version == 0x00010000)
|
||||
{
|
||||
|
@ -139,38 +227,11 @@ struct post
|
|||
return hb_string_t ((const char *) data, name_length);
|
||||
}
|
||||
|
||||
inline bool get_glyph_name (hb_codepoint_t glyph,
|
||||
char *buf, unsigned int buf_len) const
|
||||
{
|
||||
hb_string_t s = _find_glyph_name (glyph);
|
||||
if (!s.len)
|
||||
return false;
|
||||
if (!buf_len)
|
||||
return true;
|
||||
if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
|
||||
return false;
|
||||
strncpy (buf, s.bytes, s.len);
|
||||
buf[s.len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool get_glyph_from_name (const char *name, int len,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
if (len < 0)
|
||||
len = strlen (name);
|
||||
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
/* TODO format2 */
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t version;
|
||||
const ArrayOf<USHORT> *glyphNameIndex;
|
||||
hb_prealloced_array_t<uint32_t, 1> index_to_offset;
|
||||
const uint8_t *pool;
|
||||
mutable uint16_t *gids_sorted_by_name;
|
||||
};
|
||||
|
||||
public:
|
||||
|
|
|
@ -1145,18 +1145,18 @@ struct hb_string_t
|
|||
inline hb_string_t (void) : bytes (nullptr), len (0) {}
|
||||
inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
|
||||
|
||||
inline int cmp (const hb_string_t *a) const
|
||||
inline int cmp (const hb_string_t &a) const
|
||||
{
|
||||
if (len != a->len)
|
||||
return (int) a->len - (int) len;
|
||||
if (len != a.len)
|
||||
return (int) a.len - (int) len;
|
||||
|
||||
return memcmp (a->bytes, bytes, len);
|
||||
return memcmp (a.bytes, bytes, len);
|
||||
}
|
||||
static inline int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
hb_string_t *a = (hb_string_t *) pa;
|
||||
hb_string_t *b = (hb_string_t *) pb;
|
||||
return b->cmp (a);
|
||||
return b->cmp (*a);
|
||||
}
|
||||
|
||||
const char *bytes;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
static inline void *
|
||||
hb_bsearch_r(const void *key, const void *base,
|
||||
size_t nmemb, size_t size,
|
||||
int (*compar)(const void *_a, const void *_b, const void *_arg),
|
||||
int (*compar)(const void *_key, const void *_item, void *_arg),
|
||||
void *arg)
|
||||
{
|
||||
int min = 0, max = (int) nmemb - 1;
|
||||
|
|
Loading…
Reference in New Issue