[name] More
It assumes all names are encoded in UTF16-BE. Other than that, and not
listing languages correctly, it's *supposed* to work.
diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh
index d22e880..265651b 100644
--- a/src/hb-dsalgs.hh
+++ b/src/hb-dsalgs.hh
@@ -313,6 +313,27 @@
*/
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 *
hb_bsearch_r (const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *_key, const void *_item, void *_arg),
diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh
index 8967fcb..f2eb496 100644
--- a/src/hb-ot-name-table.hh
+++ b/src/hb-ot-name-table.hh
@@ -107,20 +107,31 @@
};
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 *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)
return a->name_id < b->name_id ? -1 : +1;
- int e = strcmp (hb_language_to_string (a->language),
- hb_language_to_string (b->language));
- if (e)
- return e;
+ return strcmp (hb_language_to_string (a->language),
+ hb_language_to_string (b->language));
+}
+
+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)
return a->entry_score < b->entry_score ? -1 : +1;
@@ -199,13 +210,25 @@
this->names.resize (j);
}
-
inline void fini (void)
{
this->names.fini ();
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:
hb_blob_t *blob;
public:
diff --git a/src/hb-ot-name.cc b/src/hb-ot-name.cc
index fe1276c..626e063 100644
--- a/src/hb-ot-name.cc
+++ b/src/hb-ot-name.cc
@@ -105,11 +105,15 @@
typename utf_t::codepoint_t *text /* OUT */)
{
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*/)
- return hb_ot_name_convert_utf<hb_utf16_be_t, utf_t> (&bytes, text_size, text);
+ int idx = name.get_index (name_id, language);
+ 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)
{
diff --git a/src/hb-ot-os2-unicode-ranges.hh b/src/hb-ot-os2-unicode-ranges.hh
index 1978008..b0ccd00 100644
--- a/src/hb-ot-os2-unicode-ranges.hh
+++ b/src/hb-ot-os2-unicode-ranges.hh
@@ -34,7 +34,7 @@
struct OS2Range
{
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);
const OS2Range *range = (OS2Range *) _item;
@@ -233,10 +233,10 @@
static unsigned int
_hb_ot_os2_get_unicode_range_bit (hb_codepoint_t cp)
{
- OS2Range *range = (OS2Range*) hb_bsearch_r (&cp, _hb_os2_unicode_ranges,
- ARRAY_LENGTH (_hb_os2_unicode_ranges),
- sizeof (OS2Range),
- OS2Range::cmp, nullptr);
+ OS2Range *range = (OS2Range*) hb_bsearch (&cp, _hb_os2_unicode_ranges,
+ ARRAY_LENGTH (_hb_os2_unicode_ranges),
+ sizeof (OS2Range),
+ OS2Range::cmp);
if (range != nullptr)
return range->bit;
return -1;
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
index 596e76d..a08f888 100644
--- a/src/hb-unicode.cc
+++ b/src/hb-unicode.cc
@@ -576,8 +576,8 @@
bool
_hb_unicode_is_emoji_Extended_Pictographic (hb_codepoint_t cp)
{
- return hb_bsearch_r (&cp, _hb_unicode_emoji_Extended_Pictographic_table,
- ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table),
- sizeof (hb_unicode_range_t),
- hb_unicode_range_t::cmp, nullptr);
+ return hb_bsearch (&cp, _hb_unicode_emoji_Extended_Pictographic_table,
+ ARRAY_LENGTH (_hb_unicode_emoji_Extended_Pictographic_table),
+ sizeof (hb_unicode_range_t),
+ hb_unicode_range_t::cmp);
}
diff --git a/src/hb-unicode.hh b/src/hb-unicode.hh
index 6d6a4fa..4326798 100644
--- a/src/hb-unicode.hh
+++ b/src/hb-unicode.hh
@@ -369,7 +369,7 @@
struct hb_unicode_range_t
{
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);
const hb_unicode_range_t *range = (hb_unicode_range_t *) _item;