[name] More

It assumes all names are encoded in UTF16-BE.  Other than that, and not
listing languages correctly, it's *supposed* to work.
This commit is contained in:
Behdad Esfahbod 2018-10-23 20:30:40 -07:00
parent 64334aff8c
commit 69f5da0629
6 changed files with 69 additions and 21 deletions

View File

@ -312,6 +312,27 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
* Sort and search. * Sort and search.
*/ */
static inline void *
hb_bsearch (const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *_key, const void *_item))
{
int min = 0, max = (int) nmemb - 1;
while (min <= max)
{
int mid = (min + max) / 2;
const void *p = (const void *) (((const char *) base) + (mid * size));
int c = compar (key, p);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
return (void *) p;
}
return nullptr;
}
static inline void * static inline void *
hb_bsearch_r (const void *key, const void *base, hb_bsearch_r (const void *key, const void *base,
size_t nmemb, size_t size, size_t nmemb, size_t size,

View File

@ -107,20 +107,31 @@ struct NameRecord
}; };
static int static int
_hb_ot_name_entry_cmp (const void *pa, const void *pb) _hb_ot_name_entry_cmp_key (const void *pa, const void *pb)
{ {
const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa; const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb; const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
/* Sort by name_id, then language, then score, then index. */ /* Compare by name_id, then language. */
if (a->name_id != b->name_id) if (a->name_id != b->name_id)
return a->name_id < b->name_id ? -1 : +1; return a->name_id < b->name_id ? -1 : +1;
int e = strcmp (hb_language_to_string (a->language), return strcmp (hb_language_to_string (a->language),
hb_language_to_string (b->language)); hb_language_to_string (b->language));
if (e) }
return e;
static int
_hb_ot_name_entry_cmp (const void *pa, const void *pb)
{
/* Compare by name_id, then language, then score, then index. */
int v = _hb_ot_name_entry_cmp_key (pa, pb);
if (v)
return v;
const hb_ot_name_entry_t *a = (const hb_ot_name_entry_t *) pa;
const hb_ot_name_entry_t *b = (const hb_ot_name_entry_t *) pb;
if (a->entry_score != b->entry_score) if (a->entry_score != b->entry_score)
return a->entry_score < b->entry_score ? -1 : +1; return a->entry_score < b->entry_score ? -1 : +1;
@ -199,13 +210,25 @@ struct name
this->names.resize (j); this->names.resize (j);
} }
inline void fini (void) inline void fini (void)
{ {
this->names.fini (); this->names.fini ();
hb_blob_destroy (this->blob); hb_blob_destroy (this->blob);
} }
inline int get_index (hb_name_id_t name_id,
hb_language_t language) const
{
const hb_ot_name_entry_t key = {name_id, {0}, language};
const hb_ot_name_entry_t *entry = (const hb_ot_name_entry_t *)
hb_bsearch (&key,
this->names.arrayZ(),
this->names.len,
sizeof (key),
_hb_ot_name_entry_cmp_key);
return entry ? entry->entry_index : -1;
}
private: private:
hb_blob_t *blob; hb_blob_t *blob;
public: public:

View File

@ -105,11 +105,15 @@ hb_ot_name_get_utf (hb_face_t *face,
typename utf_t::codepoint_t *text /* OUT */) typename utf_t::codepoint_t *text /* OUT */)
{ {
const OT::name_accelerator_t &name = _get_name (face); const OT::name_accelerator_t &name = _get_name (face);
unsigned int idx = 0; // XXX bsearch and find
hb_bytes_t bytes = name.table->get_name (idx);
if (true /*UTF16-BE*/) int idx = name.get_index (name_id, language);
return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (&bytes, text_size, text); if (idx != -1)
{
hb_bytes_t bytes = name.table->get_name (idx);
if (true /*UTF16-BE*/)
return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (&bytes, text_size, text);
}
if (text_size) if (text_size)
{ {

View File

@ -34,7 +34,7 @@ namespace OT {
struct OS2Range struct OS2Range
{ {
static int static int
cmp (const void *_key, const void *_item, void *_arg) cmp (const void *_key, const void *_item)
{ {
hb_codepoint_t cp = *((hb_codepoint_t *) _key); hb_codepoint_t cp = *((hb_codepoint_t *) _key);
const OS2Range *range = (OS2Range *) _item; const OS2Range *range = (OS2Range *) _item;
@ -233,10 +233,10 @@ static const OS2Range _hb_os2_unicode_ranges[] =
static unsigned int static unsigned int
_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp) _hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
{ {
OS2Range *range = (OS2Range*) hb_bsearch_r (&cp, _hb_os2_unicode_ranges, OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges,
ARRAY_LENGTH (_hb_os2_unicode_ranges), ARRAY_LENGTH (_hb_os2_unicode_ranges),
sizeof (OS2Range), sizeof (OS2Range),
OS2Range::cmp, nullptr); OS2Range::cmp);
if (range != nullptr) if (range != nullptr)
return range->bit; return range->bit;
return -1; return -1;

View File

@ -576,8 +576,8 @@ _hb_modified_combining_class[256] =
bool bool
_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp) _hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
{ {
return hb_bsearch_r (&cp, _hb_unicode_emoji_Extended_Pictographic_table, return hb_bsearch (&cp, _hb_unicode_emoji_Extended_Pictographic_table,
ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table), ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table),
sizeof (hb_unicode_range_t), sizeof (hb_unicode_range_t),
hb_unicode_range_t::cmp, nullptr); hb_unicode_range_t::cmp);
} }

View File

@ -369,7 +369,7 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
struct hb_unicode_range_t struct hb_unicode_range_t
{ {
static int static int
cmp (const void *_key, const void *_item, void *_arg) cmp (const void *_key, const void *_item)
{ {
hb_codepoint_t cp = *((hb_codepoint_t *) _key); hb_codepoint_t cp = *((hb_codepoint_t *) _key);
const hb_unicode_range_t *range = (hb_unicode_range_t *) _item; const hb_unicode_range_t *range = (hb_unicode_range_t *) _item;