[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:
parent
64334aff8c
commit
69f5da0629
|
@ -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,
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue