Merge pull request #1015 from FeiLiuEM/font/chinese-script-families
This commit is contained in:
commit
ec86cdb584
|
|
@ -588,21 +588,16 @@ const JAPANESE_FAMILIES: &[&str] = &[
|
|||
"IPAGothic",
|
||||
"VL Gothic",
|
||||
];
|
||||
const CHINESE_FAMILIES: &[&str] = &[
|
||||
"Microsoft YaHei",
|
||||
"Microsoft JhengHei",
|
||||
"SimSun",
|
||||
"MingLiU",
|
||||
"PingFang SC",
|
||||
"PingFang TC",
|
||||
"Noto Sans CJK SC",
|
||||
"Noto Sans CJK TC",
|
||||
"Noto Sans SC",
|
||||
"Noto Sans TC",
|
||||
"Source Han Sans SC",
|
||||
"Source Han Sans TC",
|
||||
"WenQuanYi Micro Hei",
|
||||
];
|
||||
/// Han ideograph families for Simplified Chinese, in the order the platforms' own fallback tables
|
||||
/// prefer them (Windows, macOS, then the Linux/Noto names). Missing ones cost one name lookup each.
|
||||
const SIMPLIFIED_CHINESE_FAMILIES: &[&str] =
|
||||
&["Microsoft YaHei", "SimSun", "PingFang SC", "Noto Sans CJK SC", "Noto Sans SC", "Source Han Sans SC", "WenQuanYi Micro Hei"];
|
||||
/// The same for Traditional Chinese. The two scripts share almost all of their code points but not
|
||||
/// the glyph forms (`东` against `東`'s neighbours, `直`, `骨`), so one list for both drew a
|
||||
/// Traditional interface with Simplified forms - the faces do not differ in *coverage*, which is
|
||||
/// what the fallback search checks, so the script has to pick the list.
|
||||
const TRADITIONAL_CHINESE_FAMILIES: &[&str] =
|
||||
&["Microsoft JhengHei", "MingLiU", "PingFang TC", "Heiti TC", "Hiragino Sans CNS", "Noto Sans CJK TC", "Noto Sans TC", "Source Han Sans TC"];
|
||||
const KOREAN_FAMILIES: &[&str] = &["Malgun Gothic", "Gulim", "Apple SD Gothic Neo", "Noto Sans CJK KR", "Noto Sans KR", "Source Han Sans KR", "NanumGothic"];
|
||||
/// The platforms' plain text families for the other scripts the bundled fonts lack, in the same
|
||||
/// order (Windows, macOS, then the Linux/Noto names).
|
||||
|
|
@ -691,10 +686,29 @@ fn han_order() -> [FallbackScript; 3] {
|
|||
han_order_for(&active_cjk_locale())
|
||||
}
|
||||
|
||||
/// Whether a CJK tag asks for Traditional Chinese: a `Hant` script, or a Taiwan, Hong Kong or
|
||||
/// Macao region (`zh-TW`, `zh_HK`, `zh_MO.UTF-8`). Anything else Chinese - including a bare `zh` -
|
||||
/// is Simplified, as in the interface's own locale mapping.
|
||||
fn asks_traditional_chinese(tag: &str) -> bool {
|
||||
tag.to_ascii_lowercase().split(['-', '_', '.']).any(|p| matches!(p, "hant" | "tw" | "hk" | "mo"))
|
||||
}
|
||||
|
||||
/// The Chinese families to try first for `tag`: one list per script, since coverage does not tell
|
||||
/// the two apart - a Simplified face covers the Traditional glyphs' code points, so the fallback
|
||||
/// search would keep it and draw the wrong forms.
|
||||
fn chinese_families_for(tag: &str) -> &'static [&'static str] {
|
||||
if asks_traditional_chinese(tag) { TRADITIONAL_CHINESE_FAMILIES } else { SIMPLIFIED_CHINESE_FAMILIES }
|
||||
}
|
||||
|
||||
/// [`chinese_families_for`] for the locale in force ([`active_cjk_locale`]).
|
||||
fn chinese_families() -> &'static [&'static str] {
|
||||
chinese_families_for(&active_cjk_locale())
|
||||
}
|
||||
|
||||
fn families_for(s: FallbackScript) -> &'static [&'static str] {
|
||||
match s {
|
||||
FallbackScript::Japanese => JAPANESE_FAMILIES,
|
||||
FallbackScript::Han => CHINESE_FAMILIES,
|
||||
FallbackScript::Han => chinese_families(),
|
||||
FallbackScript::Korean => KOREAN_FAMILIES,
|
||||
FallbackScript::Arabic => ARABIC_FAMILIES,
|
||||
FallbackScript::Hebrew => HEBREW_FAMILIES,
|
||||
|
|
@ -1079,6 +1093,28 @@ mod tests {
|
|||
assert_eq!(han_order(), han_order_for(&active_cjk_locale()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_chinese_family_list_follows_the_script_the_locale_asks_for() {
|
||||
for tag in ["zh", "zh-CN", "zh_Hans", "zh_CN.UTF-8", "zh-SG"] {
|
||||
assert_eq!(chinese_families_for(tag), SIMPLIFIED_CHINESE_FAMILIES, "{tag}");
|
||||
}
|
||||
for tag in ["zh-Hant", "zh-Hant-TW", "zh_TW", "zh-HK", "zh_MO.UTF-8"] {
|
||||
assert_eq!(chinese_families_for(tag), TRADITIONAL_CHINESE_FAMILIES, "{tag}");
|
||||
}
|
||||
// Each list carries its own script's faces and not the other's, which is the point of
|
||||
// splitting them: `PingFang SC` covers the same code points as `PingFang TC`, so the
|
||||
// fallback search would have kept it and drawn Simplified forms in a Traditional interface.
|
||||
assert!(SIMPLIFIED_CHINESE_FAMILIES.iter().any(|f| f.contains("PingFang SC") && !f.contains("Source")));
|
||||
assert!(!SIMPLIFIED_CHINESE_FAMILIES.iter().any(|f| f.contains("TC") || f.contains("JhengHei")));
|
||||
assert!(TRADITIONAL_CHINESE_FAMILIES.iter().any(|f| f.contains("PingFang TC")));
|
||||
assert!(!TRADITIONAL_CHINESE_FAMILIES.iter().any(|f| f.contains(" SC") || f.contains("YaHei") || f.contains("WenQuanYi")));
|
||||
assert!(TRADITIONAL_CHINESE_FAMILIES.iter().any(|f| f.contains("Heiti TC") || f.contains("Hiragino Sans CNS")));
|
||||
// The arm the fallback itself walks: Han hands over the list the locale's script picked.
|
||||
assert_eq!(families_for(FallbackScript::Han), chinese_families_for(&active_cjk_locale()));
|
||||
// Han text is the only thing these lists serve; the Japanese order does not change.
|
||||
assert_eq!(han_order_for("ja_JP.UTF-8")[0], FallbackScript::Japanese);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bundled_ui_fonts_cover_the_ukrainian_alphabet() {
|
||||
const ALPHABET: &str = "АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯабвгґдеєжзиіїйклмнопрстуфхцчшщьюя’«»";
|
||||
|
|
|
|||
Loading…
Reference in New Issue