Add hb_language_matches()

New API:
+ hb_language_matches()
This commit is contained in:
Behdad Esfahbod 2022-07-17 22:15:42 -06:00
parent d57ce30054
commit f7f6d278bb
6 changed files with 44 additions and 10 deletions

View File

@ -135,6 +135,7 @@ hb_script_get_horizontal_direction
hb_language_from_string hb_language_from_string
hb_language_to_string hb_language_to_string
hb_language_get_default hb_language_get_default
hb_language_matches
hb_feature_from_string hb_feature_from_string
hb_feature_to_string hb_feature_to_string
hb_variation_from_string hb_variation_from_string

View File

@ -983,7 +983,7 @@ struct Chain
#ifndef HB_NO_AAT #ifndef HB_NO_AAT
else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting && else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting &&
/* TODO: Rudimentary language matching. */ /* TODO: Rudimentary language matching. */
map->face->table.ltag->get_language (setting - 1) == map->props.language) hb_language_matches (map->face->table.ltag->get_language (setting - 1), map->props.language))
{ {
flags &= feature.disableFlags; flags &= feature.disableFlags;
flags |= feature.enableFlags; flags |= feature.enableFlags;

View File

@ -441,6 +441,38 @@ hb_language_get_default ()
return language; return language;
} }
/**
* hb_language_matches:
* @language: The #hb_language_t to work on
* @specific: Another #hb_language_t
*
* Check whether a second language tag is the same or a more
* specific version of the provided language tag. For example,
* "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR".
*
* Return value: `true` if languages match, `false` otherwise.
*
* Since: REPLACEME
**/
hb_bool_t
hb_language_matches (hb_language_t language,
hb_language_t specific)
{
if (language == specific) return true;
if (!language || !specific) return false;
const char *l = language->s;
const char *s = specific->s;
unsigned ll = strlen (l);
unsigned sl = strlen (s);
if (ll > sl)
return false;
return strncmp (l, s, ll) == 0 &&
(s[ll] == '\0' || s[ll] == '-');
}
/* hb_script_t */ /* hb_script_t */

View File

@ -326,6 +326,9 @@ hb_language_to_string (hb_language_t language);
HB_EXTERN hb_language_t HB_EXTERN hb_language_t
hb_language_get_default (void); hb_language_get_default (void);
HB_EXTERN hb_bool_t
hb_language_matches (hb_language_t language,
hb_language_t specific);
/** /**
* hb_script_t: * hb_script_t:

View File

@ -175,15 +175,11 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact)
signed c = strcmp (astr, bstr); 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. // '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 eg. user asks for "en-us" and font has "en", approve.
if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb)) if (!exact && c &&
hb_language_matches (b->language, a->language))
return 0; return 0;
}
return c; return c;
} }

View File

@ -214,6 +214,8 @@ lang_matches (const char *lang_str,
const char *spec, const char *spec,
unsigned spec_len) unsigned spec_len)
{ {
/* Same as hb_language_matches(); duplicated. */
if (likely ((unsigned) (limit - lang_str) < spec_len)) if (likely ((unsigned) (limit - lang_str) < spec_len))
return false; return false;