fix(theme)!: route cjk punctuation to matching system fonts

The Inter Core faces (previously Inter4CJK) leave East Asian ambiguous
punctuation and symbols uncovered so that the document's CJK font can
render them, but the next family in the stack was a Latin system font,
which claimed most of those characters before the language-aware system
fallback could pick the right CJK font - and characters it lacked could
land in an unrelated one (like Apple SD Gothic Neo on Chinese pages in
Chrome on macOS). The zh/ja/ko stacks now name the platform defaults
explicitly (PingFang SC / Microsoft YaHei / Noto Sans CJK SC, Hiragino
Sans / Meiryo / Yu Gothic / Noto Sans CJK JP, Apple SD Gothic Neo /
Malgun Gothic / Noto Sans CJK KR), so per-glyph matching lands there
deterministically, and sites can splice a CJK webfont between
'Inter Core' and the system families. Traditional Chinese currently
shares the zh (Hans) rule; the TC variant is documented in the script.

BREAKING CHANGE: the Inter4CJK font family has been renamed to
'Inter Core'. Custom --vp-font-family-base overrides referencing
Inter4CJK must be updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
pull/5335/head
Divyansh Singh 2 days ago
parent fa24c6d67b
commit 91b06b67a3

@ -50,17 +50,50 @@ BASE_VAR = """\
}
"""
# The 'Inter Core' faces leave the `cjkExclusions` characters uncovered so that
# they fall through to the next family in the stack, which therefore must be
# an explicit CJK font: a Latin system font (or `sans-serif`) would claim most
# of the excluded punctuation before the language-aware system fallback ever
# got a chance to pick the right CJK font. The names below cover the defaults
# of macOS / Windows / Linux (fonts-noto-cjk); families that are not installed
# are simply skipped, and sites can splice a CJK webfont between 'Inter Core'
# and the system families. Bare zh means Hans per BCP 47 likely subtags, and
# with no Traditional Chinese rule it also covers zh-Hant/zh-TW/zh-HK/zh-MO
# pages. If Hant handling is ever requested, add after the zh rule (same
# specificity, so the later rule wins; the region tags must be enumerated
# because `:lang(zh-Hant)` cannot match e.g. `lang="zh-TW"`):
# [lang]:where(:lang(zh-Hant), :lang(zh-TW), :lang(zh-HK), :lang(zh-MO)) {
# --vp-font-family-base:
# 'Inter Core', 'PingFang TC', 'Microsoft JhengHei', 'Noto Sans CJK TC',
# ...;
# }
# (Hong Kong variants also exist: 'PingFang HK' / 'Noto Sans CJK HK'.)
CJK_BASE_VAR = """\
[lang]:where(:lang(zh), :lang(ja), :lang(ko)) {
[lang]:where(:lang(zh)) {
--vp-font-family-base:
'Inter4CJK', -apple-system, BlinkMacSystemFont, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
'Inter Core', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans CJK SC',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
[lang]:where(:lang(ja)) {
--vp-font-family-base:
'Inter Core', 'Hiragino Sans', 'Meiryo', 'Yu Gothic', 'Noto Sans CJK JP',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
[lang]:where(:lang(ko)) {
--vp-font-family-base:
'Inter Core', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
"""
# used instead of everything else in this file when `useWebFonts` is enabled
# (only the content between the markers survives) - see
# src/node/plugins/webFontsPlugin.ts. There is no Inter4CJK on Google Fonts,
# src/node/plugins/webFontsPlugin.ts. There is no 'Inter Core' on Google Fonts,
# so CJK documents use the regular Inter there.
WEBFONT_IMPORT = f"""\
/* webfont-marker-begin */
@ -73,7 +106,7 @@ WEBFONT_IMPORT = f"""\
# The `cjkExclusions` key of the json lists characters that have both a
# Western (proportional) and an East Asian (em-square) form with no
# encoding-level distinction - mostly East Asian Ambiguous punctuation and
# symbols (UAX #11). The generated Inter4CJK faces reuse the same font files
# symbols (UAX #11). The generated 'Inter Core' faces reuse the same font files
# but leave these out of their unicode-ranges so that CJK fonts render them
# in CJK documents. References:
# https://www.unicode.org/L2/L2014/14006-sv-western-vs-cjk.pdf
@ -84,7 +117,7 @@ WEBFONT_IMPORT = f"""\
# & U+2015 (used like U+2014 in Japanese), U+203B (Japanese reference mark),
# U+007E (zh's request; both forms are fine in ja because it is unused there)
CJK_COMMENT = """\
/* Inter4CJK reuses the files above, but leaves out characters that should
/* 'Inter Core' reuses the files above, but leaves out characters that should
be rendered by CJK fonts in CJK documents - see scripts/subsetFonts.py */
"""
@ -187,7 +220,7 @@ def write_css(subsets: dict[str, str], cjk_exclusions: set[int]) -> None:
cjk_cps = parse_ranges(value) - cjk_exclusions
if cjk_cps:
cjk.append(
face("Inter4CJK", css_style, file, format_ranges(cjk_cps))
face("'Inter Core'", css_style, file, format_ranges(cjk_cps))
)
FONTS_CSS.write_text(

@ -154,11 +154,11 @@
unicode-range: U+02CD, U+02D8-02D9, U+02DB, U+0302, U+0306-0307, U+030A, U+030C, U+030F, U+0313, U+0315, U+031B, U+0326-0328, U+032C, U+0337-0338, U+0342-0343, U+0346-036F, U+0E3F, U+1DC0-1DF5, U+1DFC-1DFF, U+2070-2071, U+2074-208E, U+2090-209C, U+20DB-20DE, U+20E8, U+20F0, U+2100-2101, U+2103, U+2105-2106, U+2109, U+2117, U+211E-2121, U+2126, U+212A-212B, U+212E, U+2132, U+213B, U+214D, U+2150-217F, U+2183-2186, U+2189, U+2190, U+2192, U+2194-2199, U+21AA, U+21B0-21B1, U+21B3-21B5, U+21BA-21BB, U+21D0, U+21D2, U+21D4, U+21DE-21DF, U+21E4-21E5, U+21E7, U+21EA, U+2202, U+2205-2206, U+220F, U+2211, U+221A, U+221E, U+222B, U+2236, U+2248, U+2260, U+2264-2265, U+2295-2298, U+2303-2305, U+2325-2327, U+232B, U+2380, U+2387, U+238B, U+23CE-23CF, U+2423, U+2460-2468, U+24B6-24CF, U+24EA, U+25A0-25A2, U+25AA, U+25B2-25B3, U+25B6-25B7, U+25BA-25BD, U+25C0-25C1, U+25C4-25C7, U+25CA-25CB, U+25CF, U+25E6, U+25EF, U+2600, U+2605-2606, U+263C, U+2661, U+2665, U+266A-266B, U+26A0, U+2713, U+2717, U+2756, U+2764, U+2780-2788, U+27EF, U+27F5-27FA, U+2913, U+2A38, U+2B06, U+2B12-2B13, U+2B1C, U+2B24, U+2E18, U+A92E, U+1F12F-1F149, U+1F16A-1F16B, U+1F850, U+1F852;
}
/* Inter4CJK reuses the files above, but leaves out characters that should
/* 'Inter Core' reuses the files above, but leaves out characters that should
be rendered by CJK fonts in CJK documents - see scripts/subsetFonts.py */
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -167,7 +167,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -176,7 +176,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -185,7 +185,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -194,7 +194,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -203,7 +203,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -212,7 +212,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -221,7 +221,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: italic;
font-weight: 100 900;
font-display: swap;
@ -230,7 +230,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -239,7 +239,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -248,7 +248,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -257,7 +257,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -266,7 +266,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -275,7 +275,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -284,7 +284,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -293,7 +293,7 @@
}
@font-face {
font-family: Inter4CJK;
font-family: 'Inter Core';
font-style: normal;
font-weight: 100 900;
font-display: swap;
@ -307,8 +307,23 @@
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
[lang]:where(:lang(zh), :lang(ja), :lang(ko)) {
[lang]:where(:lang(zh)) {
--vp-font-family-base:
'Inter4CJK', -apple-system, BlinkMacSystemFont, sans-serif,
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
'Inter Core', 'PingFang SC', 'Microsoft YaHei', 'Noto Sans CJK SC',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
[lang]:where(:lang(ja)) {
--vp-font-family-base:
'Inter Core', 'Hiragino Sans', 'Meiryo', 'Yu Gothic', 'Noto Sans CJK JP',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}
[lang]:where(:lang(ko)) {
--vp-font-family-base:
'Inter Core', 'Apple SD Gothic Neo', 'Malgun Gothic', 'Noto Sans CJK KR',
-apple-system, BlinkMacSystemFont, sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
}

Loading…
Cancel
Save