[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
|
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 *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;
|
||||||
|
@ -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 == b->language) return 0;
|
||||||
if (!a->language) return -1;
|
if (!a->language) return -1;
|
||||||
if (!b->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
|
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. */
|
/* 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)
|
if (v)
|
||||||
return 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,
|
const hb_ot_name_entry_t *entry = hb_bsearch (key, (const hb_ot_name_entry_t *) this->names,
|
||||||
this->names.length,
|
this->names.length,
|
||||||
sizeof (hb_ot_name_entry_t),
|
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)
|
if (!entry)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -93,10 +93,17 @@ test_ot_name (void)
|
||||||
name_id = entries[3].name_id;
|
name_id = entries[3].name_id;
|
||||||
g_assert_cmpuint (3, ==, name_id);
|
g_assert_cmpuint (3, ==, name_id);
|
||||||
lang = entries[3].language;
|
lang = entries[3].language;
|
||||||
|
|
||||||
g_assert_cmpstr (hb_language_to_string (lang), ==, "en");
|
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 (27, ==, hb_ot_name_get_utf8 (face, name_id, lang, &text_size, text));
|
||||||
g_assert_cmpuint (9, ==, text_size);
|
g_assert_cmpuint (9, ==, text_size);
|
||||||
g_assert_cmpstr (text, ==, "FontForge");
|
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
|
int
|
||||||
|
|
Loading…
Reference in New Issue