Match ja and ko by subtag and test the string lang path apps use
This commit is contained in:
1 parent
ab028e80eb
commit
600734790c
2 files changed
+92
-29
No files matched your search
@@ -12,21 +12,76 @@ fi
|
||||
test_tmp=$(mktemp -d)
|
||||
trap 'rm -rf "$test_tmp"' EXIT
|
||||
|
||||
candidate="$ROOT/default/fontconfig/conf.avail/50-omarchy.conf"
|
||||
{
|
||||
echo '<?xml version="1.0"?><!DOCTYPE fontconfig SYSTEM "fonts.dtd"><fontconfig>'
|
||||
echo "<dir>/usr/share/fonts</dir><cachedir>$test_tmp/cache</cachedir>"
|
||||
placed=false
|
||||
for conf in /etc/fonts/conf.d/*.conf; do
|
||||
if [[ ${conf##*/} == "50-omarchy.conf" ]]; then
|
||||
echo "<include>$ROOT/default/fontconfig/conf.avail/50-omarchy.conf</include>"
|
||||
else
|
||||
echo "<include>$conf</include>"
|
||||
name=${conf##*/}
|
||||
[[ $name == "50-omarchy.conf" ]] && continue
|
||||
if ! $placed && [[ $name > "50-omarchy.conf" ]]; then
|
||||
echo "<include>$candidate</include>"
|
||||
placed=true
|
||||
fi
|
||||
echo "<include>$conf</include>"
|
||||
done
|
||||
$placed || echo "<include>$candidate</include>"
|
||||
echo '</fontconfig>'
|
||||
} >"$test_tmp/fonts.conf"
|
||||
export FONTCONFIG_FILE="$test_tmp/fonts.conf"
|
||||
fc-cache >/dev/null
|
||||
|
||||
# Pango, Qt and Skia add lang as a string, which fc-match never does.
|
||||
cat >"$test_tmp/string-lang.py" <<'PY'
|
||||
import ctypes, sys
|
||||
fc = ctypes.CDLL("libfontconfig.so.1")
|
||||
fc.FcPatternCreate.restype = ctypes.c_void_p
|
||||
fc.FcPatternAddString.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_char_p]
|
||||
fc.FcConfigSubstitute.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
||||
fc.FcDefaultSubstitute.argtypes = [ctypes.c_void_p]
|
||||
fc.FcPatternFormat.restype = ctypes.c_char_p
|
||||
fc.FcPatternFormat.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
|
||||
fc.FcCharSetCreate.restype = ctypes.c_void_p
|
||||
fc.FcCharSetAddChar.argtypes = [ctypes.c_void_p, ctypes.c_uint32]
|
||||
fc.FcPatternAddCharSet.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p]
|
||||
fc.FcFontMatch.restype = ctypes.c_void_p
|
||||
fc.FcFontMatch.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.POINTER(ctypes.c_int)]
|
||||
for line in sys.stdin:
|
||||
family, lang, char = line.split()
|
||||
pattern = fc.FcPatternCreate()
|
||||
fc.FcPatternAddString(pattern, b"family", family.encode())
|
||||
if lang != "-":
|
||||
fc.FcPatternAddString(pattern, b"lang", lang.encode())
|
||||
if char == "families":
|
||||
fc.FcConfigSubstitute(None, pattern, 0)
|
||||
print(fc.FcPatternFormat(pattern, b"%{family}").decode())
|
||||
continue
|
||||
if char != "-":
|
||||
charset = fc.FcCharSetCreate()
|
||||
fc.FcCharSetAddChar(charset, int(char, 16))
|
||||
fc.FcPatternAddCharSet(pattern, b"charset", charset)
|
||||
fc.FcConfigSubstitute(None, pattern, 0)
|
||||
fc.FcDefaultSubstitute(pattern)
|
||||
result = ctypes.c_int()
|
||||
print(fc.FcPatternFormat(fc.FcFontMatch(None, pattern, ctypes.byref(result)), b"%{family[0]}").decode())
|
||||
PY
|
||||
|
||||
# resolve <locale> <string|langset> reads "family lang char" lines
|
||||
resolve() {
|
||||
if [[ $2 == "string" ]]; then
|
||||
LANG=$1 python3 "$test_tmp/string-lang.py"
|
||||
else
|
||||
local family lang char query
|
||||
while read -r family lang char; do
|
||||
query=$family
|
||||
[[ $lang == "-" ]] || query+=":lang=$lang"
|
||||
[[ $char == "-" ]] || query+=":charset=$char"
|
||||
LANG=$1 fc-match -f '%{family[0]}\n' "$query"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
declare -A latin=([sans-serif]="Liberation Sans" [serif]="Liberation Serif" [monospace]="JetBrainsMono Nerd Font")
|
||||
declare -A cjk=([sans-serif]="Noto Sans CJK" [serif]="Noto Serif CJK" [monospace]="Noto Sans Mono CJK")
|
||||
declare -A variant=(
|
||||
@@ -38,33 +93,41 @@ declare -A variant=(
|
||||
[ja]=JP [ja-jp]=JP [ko]=KR [ko-kr]=KR
|
||||
)
|
||||
|
||||
family() { LANG=$1 fc-match -f '%{family[0]}' "$2"; }
|
||||
queries=() expected=()
|
||||
for tag in "${!variant[@]}"; do
|
||||
for generic in sans-serif serif monospace; do
|
||||
queries+=("$generic $tag -") expected+=("${latin[$generic]}")
|
||||
queries+=("$generic $tag 9aa8") expected+=("${cjk[$generic]} ${variant[$tag]}")
|
||||
done
|
||||
done
|
||||
for generic in sans-serif serif monospace; do
|
||||
queries+=("$generic - -") expected+=("${latin[$generic]}")
|
||||
done
|
||||
|
||||
for locale in C.UTF-8 zh_CN.UTF-8; do
|
||||
for tag in "${!variant[@]}"; do
|
||||
for generic in sans-serif serif monospace; do
|
||||
actual=$(family "$locale" "$generic:lang=$tag")
|
||||
[[ $actual == "${latin[$generic]}" ]] || fail "$locale $generic:lang=$tag keeps Latin in ${latin[$generic]}" "$actual"
|
||||
actual=$(family "$locale" "$generic:lang=$tag:charset=9aa8")
|
||||
expected="${cjk[$generic]} ${variant[$tag]}"
|
||||
[[ $actual == "$expected" ]] || fail "$locale $generic:lang=$tag sets Han in $expected" "$actual"
|
||||
for path in string langset; do
|
||||
mapfile -t actual < <(printf '%s\n' "${queries[@]}" | resolve "$locale" "$path")
|
||||
for i in "${!queries[@]}"; do
|
||||
[[ ${actual[i]} == "${expected[i]}" ]] ||
|
||||
fail "$locale $path lang: ${queries[i]} resolves to ${expected[i]}" "${actual[i]}"
|
||||
done
|
||||
done
|
||||
pass "$locale: tagged CJK keeps Omarchy's Latin families and sets Han in the tag's variant"
|
||||
done
|
||||
|
||||
for generic in sans-serif serif monospace; do
|
||||
actual=$(family zh_CN.UTF-8 "$generic")
|
||||
[[ $actual == "${latin[$generic]}" ]] || fail "zh_CN untagged $generic keeps ${latin[$generic]}" "$actual"
|
||||
actual=$(family zh_CN.UTF-8 "$generic:charset=9aa8")
|
||||
[[ $actual == "${cjk[$generic]} SC" ]] || fail "zh_CN untagged $generic sets Han in SC" "$actual"
|
||||
for path in string langset; do
|
||||
for generic in sans-serif serif monospace; do
|
||||
actual=$(echo "$generic - 9aa8" | resolve zh_CN.UTF-8 "$path")
|
||||
[[ $actual == "${cjk[$generic]} SC" ]] || fail "zh_CN $path: untagged Han in $generic is SC" "$actual"
|
||||
done
|
||||
done
|
||||
pass "a Chinese locale keeps Omarchy's Latin families and sets untagged Han in SC"
|
||||
pass "a Chinese locale sets untagged Han in SC"
|
||||
|
||||
[[ $(LANG=C.UTF-8 fc-pattern --config "sans-serif:lang=ja" family) == *'"Noto Sans CJK JP"(s)'* ]] ||
|
||||
fail "lang=ja binds its variant strongly, so the prefix check below can see one"
|
||||
for tag in jam kok; do
|
||||
actual=$(LANG=C.UTF-8 fc-pattern --config "sans-serif:lang=$tag" family)
|
||||
[[ ! $actual =~ CJK\ [A-Z]+\"\(s\) ]] || fail "lang=$tag is not taken for Japanese or Korean" "$actual"
|
||||
untouched=$(echo "sans-serif en families" | resolve C.UTF-8 string)
|
||||
[[ $(echo "sans-serif ja families" | resolve C.UTF-8 string) != "$untouched" ]] ||
|
||||
fail "lang=ja changes the family list, so the prefix check below can see a match"
|
||||
for tag in jam jav kok koi; do
|
||||
actual=$(echo "sans-serif $tag families" | resolve C.UTF-8 string)
|
||||
[[ $actual == "$untouched" ]] || fail "string lang=$tag is not taken for Japanese or Korean" "$actual"
|
||||
done
|
||||
pass "languages that only share a prefix with ja or ko get no CJK variant"
|
||||
Reference in new issue
Block a user