[name] Implement approximate language matching
Very rudimentary. Fixes https://github.com/harfbuzz/harfbuzz/issues/3354
This commit is contained in:
parent
40d7d56e53
commit
b39b5f2f31
|
@ -156,7 +156,7 @@ struct NameRecord
|
|||
};
|
||||
|
||||
static int
|
||||
_hb_ot_name_entry_cmp_key (const void *pa, const void *pb)
|
||||
_hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
|
||||
{
|
||||
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;
|
||||
|
@ -169,8 +169,23 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb)
|
|||
if (a->language == b->language) return 0;
|
||||
if (!a->language) return -1;
|
||||
if (!b->language) return +1;
|
||||
return strcmp (hb_language_to_string (a->language),
|
||||
hb_language_to_string (b->language));
|
||||
|
||||
const char *astr = hb_language_to_string (a->language);
|
||||
const char *bstr = hb_language_to_string (b->language);
|
||||
|
||||
signed c = strcmp (astr, bstr);
|
||||
|
||||
if (!exact && c)
|
||||
{
|
||||
unsigned la = strlen (astr);
|
||||
unsigned lb = strlen (bstr);
|
||||
// 'a' is the user request, and 'b' is string in the font.
|
||||
// If eg. user asks for "en-us" and font has "en", approve.
|
||||
if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -178,7 +193,7 @@ _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);
|
||||
int v = _hb_ot_name_entry_cmp_key (pa, pb, true);
|
||||
if (v)
|
||||
return v;
|
||||
|
||||
|
@ -330,7 +345,18 @@ struct name
|
|||
const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
|
||||
this->names.length,
|
||||
sizeof (hb_ot_name_entry_t),
|
||||
_hb_ot_name_entry_cmp_key);
|
||||
_hb_ot_name_entry_cmp_key,
|
||||
true);
|
||||
|
||||
if (!entry)
|
||||
{
|
||||
entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
|
||||
this->names.length,
|
||||
sizeof (hb_ot_name_entry_t),
|
||||
_hb_ot_name_entry_cmp_key,
|
||||
false);
|
||||
}
|
||||
|
||||
if (!entry)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -93,10 +93,17 @@ test_ot_name (void)
|
|||
name_id = entries[3].name_id;
|
||||
g_assert_cmpuint (3, ==, name_id);
|
||||
lang = entries[3].language;
|
||||
|
||||
g_assert_cmpstr (hb_language_to_string (lang), ==, "en");
|
||||
g_assert_cmpuint (27, ==, hb_ot_name_get_utf8 (face, name_id, lang, &text_size, text));
|
||||
g_assert_cmpuint (9, ==, text_size);
|
||||
g_assert_cmpstr (text, ==, "FontForge");
|
||||
|
||||
g_assert_cmpuint (27, ==, hb_ot_name_get_utf8 (face, name_id, hb_language_from_string ("en_US", -1), &text_size, text));
|
||||
g_assert_cmpuint (8, ==, text_size);
|
||||
g_assert_cmpstr (text, ==, "FontForg");
|
||||
|
||||
g_assert_cmpuint (0, ==, hb_ot_name_get_utf8 (face, name_id, hb_language_from_string ("fa_IR", -1), &text_size, text));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in New Issue