font: load CJK fonts only in CJK env or the book has CJK languages, closes #1298 (#1323)

This commit is contained in:
Huang Xin
2025-06-03 14:55:40 +08:00
committed by GitHub
parent 734e22d92c
commit 146a71fdef
9 changed files with 136 additions and 103 deletions
+109
View File
@@ -0,0 +1,109 @@
import { isCJKEnv } from './misc';
const basicGoogleFonts = [
{ family: 'Bitter', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Fira Code', weights: 'wght@300..700' },
{ family: 'Literata', weights: 'ital,opsz,wght@0,7..72,200..900;1,7..72,200..900' },
{ family: 'Merriweather', weights: 'ital,opsz,wght@0,18..144,300..900;1,18..144,300..900' },
{ family: 'Noto Sans', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Open Sans', weights: 'ital,wght@0,300..800;1,300..800' },
{ family: 'Roboto', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Vollkorn', weights: 'ital,wght@0,400..900;1,400..900' },
];
const cjkGoogleFonts = [
{ family: 'LXGW WenKai TC', weights: '' },
{ family: 'Noto Sans SC', weights: '' },
{ family: 'Noto Sans TC', weights: '' },
{ family: 'Noto Serif JP', weights: '' },
];
const getAdditionalBasicFontLinks = () => `
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?${basicGoogleFonts
.map(
({ family, weights }) =>
`family=${encodeURIComponent(family)}${weights ? `:${weights}` : ''}`,
)
.join('&')}&display=swap" crossorigin="anonymous">
`;
const getAdditionalCJKFontLinks = () => `
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/misans-webfont@1.0.4/misans-l3/misans-l3/result.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cn-fontsource-lxgw-wen-kai-gb-screen@1.0.6/font.min.css" crossorigin="anonymous">
<link rel='stylesheet' href='https://fontsapi.zeoseven.com/431/main/result.css' crossorigin="anonymous"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?${cjkGoogleFonts
.map(
({ family, weights }) =>
`family=${encodeURIComponent(family)}${weights ? `:${weights}` : ''}`,
)
.join('&')}&display=swap" crossorigin="anonymous">
`;
const getAdditionalCJKFontFaces = () => `
@font-face {
font-family: "FangSong";
font-display: swap;
src: local("Fang Song"), local("FangSong"), local("Noto Serif CJK"), local("Source Han Serif SC VF"), url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.eot");
src: url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.eot?#iefix") format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.woff2") format("woff2"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.woff") format("woff"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.ttf") format("truetype"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.svg#FangSong") format("svg");
}
@font-face {
font-family: "Kaiti";
font-display: swap;
src: local("Kai"), local("KaiTi"), local("AR PL UKai"), local("LXGW WenKai GB Screen"), url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.eot");
src: url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.svg#STKaiti")format("svg");
}
@font-face {
font-family: "Heiti";
font-display: swap;
src: local("Hei"), local("SimHei"), local("WenQuanYi Zen Hei"), local("Source Han Sans SC VF"), url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.eot");
src: url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.svg#WenQuanYi Micro Hei")format("svg");
}
@font-face {
font-family: "XiHeiti";
font-display: swap;
src: local("PingFang SC"), local("Microsoft YaHei"), local("WenQuanYi Micro Hei"), local("FZHei-B01"), url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.eot");
src: url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.svg#STHeiti J Light")format("svg");
}
`;
export const mountAdditionalFonts = (document: Document, isCJK = false) => {
const mountCJKFonts = isCJK || isCJKEnv();
let links = getAdditionalBasicFontLinks();
if (mountCJKFonts) {
const style = document.createElement('style');
style.textContent = getAdditionalCJKFontFaces();
document.head.appendChild(style);
links = `${links}\n${getAdditionalCJKFontLinks()}`;
}
const parser = new DOMParser();
const parsedDocument = parser.parseFromString(links, 'text/html');
Array.from(parsedDocument.head.children).forEach((child) => {
if (child.tagName === 'LINK') {
const link = document.createElement('link');
link.rel = child.getAttribute('rel') || '';
link.href = child.getAttribute('href') || '';
link.crossOrigin = child.getAttribute('crossorigin') || '';
document.head.appendChild(link);
}
});
};
+6
View File
@@ -2,6 +2,12 @@ export const isCJKStr = (str: string) => {
return /[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u.test(str ?? '');
};
export const isCJKLang = (lang: string | null | undefined): boolean => {
if (!lang) return false;
const normalizedLang = lang.split('-')[0]!.toLowerCase();
return ['zh', 'ja', 'ko'].includes(normalizedLang);
};
export const langToDefaultLocale = (langCode: string): string => {
const mapping: Record<string, string> = {
en: 'en-US',
+1 -1
View File
@@ -1,7 +1,7 @@
import { openUrl } from '@tauri-apps/plugin-opener';
import { isTauriAppPlatform } from '@/services/environment';
export const interceptGlobalOpen = () => {
export const interceptWindowOpen = () => {
const windowOpen = window.open;
globalThis.open = function (
url?: string | URL,
-92
View File
@@ -14,7 +14,6 @@ import {
generateLightPalette,
generateDarkPalette,
} from '@/styles/themes';
import { getOSPlatform } from './misc';
const getFontStyles = (
@@ -101,75 +100,6 @@ const getFontStyles = (
return fontStyles;
};
const googleFontsData = [
{ family: 'Bitter', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Fira Code', weights: 'wght@300..700' },
{ family: 'Literata', weights: 'ital,opsz,wght@0,7..72,200..900;1,7..72,200..900' },
{ family: 'Merriweather', weights: 'ital,opsz,wght@0,18..144,300..900;1,18..144,300..900' },
{ family: 'Noto Sans', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Roboto', weights: 'ital,wght@0,100..900;1,100..900' },
{ family: 'Vollkorn', weights: 'ital,wght@0,400..900;1,400..900' },
{ family: 'LXGW WenKai TC' },
{ family: 'Noto Sans SC' },
{ family: 'Noto Sans TC' },
{ family: 'Noto Serif JP' },
];
const getAdditionalFontLinks = () => `
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/misans-webfont@1.0.4/misans-l3/misans-l3/result.min.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/cn-fontsource-lxgw-wen-kai-gb-screen@1.0.6/font.min.css" crossorigin="anonymous">
<link rel='stylesheet' href='https://fontsapi.zeoseven.com/431/main/result.css' crossorigin="anonymous"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?${googleFontsData
.map(
({ family, weights }) =>
`family=${encodeURIComponent(family)}${weights ? `:${weights}` : ''}`,
)
.join('&')}&display=swap" crossorigin="anonymous">
`;
const getAdditionalFontFaces = () => `
@font-face {
font-family: "FangSong";
font-display: swap;
src: local("Fang Song"), local("FangSong"), local("Noto Serif CJK"), local("Source Han Serif SC VF"), url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.eot");
src: url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.eot?#iefix") format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.woff2") format("woff2"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.woff") format("woff"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.ttf") format("truetype"),
url("https://db.onlinewebfonts.com/t/2ecbfe1d9bfc191c6f15c0ccc23cbd43.svg#FangSong") format("svg");
}
@font-face {
font-family: "Kaiti";
font-display: swap;
src: local("Kai"), local("KaiTi"), local("AR PL UKai"), local("LXGW WenKai GB Screen"), url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.eot");
src: url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/1ee9941f1b8c128110ca4307dda59917.svg#STKaiti")format("svg");
}
@font-face {
font-family: "Heiti";
font-display: swap;
src: local("Hei"), local("SimHei"), local("WenQuanYi Zen Hei"), local("Source Han Sans SC VF"), url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.eot");
src: url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/a4948b9d43a91468825a5251df1ec58d.svg#WenQuanYi Micro Hei")format("svg");
}
@font-face {
font-family: "XiHeiti";
font-display: swap;
src: local("PingFang SC"), local("Microsoft YaHei"), local("WenQuanYi Micro Hei"), local("FZHei-B01"), url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.eot");
src: url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.eot?#iefix")format("embedded-opentype"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.woff2")format("woff2"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.woff")format("woff"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.ttf")format("truetype"),
url("https://db.onlinewebfonts.com/t/4f0b783ba4a1b381fc7e7af81ecab481.svg#STHeiti J Light")format("svg");
}
`;
const getLayoutStyles = (
overrideLayout: boolean,
paragraphMargin: number,
@@ -463,28 +393,6 @@ export const getStyles = (viewSettings: ViewSettings, themeCode?: ThemeCode) =>
return `${layoutStyles}\n${fontStyles}\n${translationStyles}\n${userStylesheet}`;
};
export const mountAdditionalFonts = (document: Document) => {
const links = getAdditionalFontLinks();
const parser = new DOMParser();
const parsedDocument = parser.parseFromString(links, 'text/html');
Array.from(parsedDocument.head.children).forEach((child) => {
if (child.tagName === 'LINK') {
const link = document.createElement('link');
link.rel = child.getAttribute('rel') || '';
link.href = child.getAttribute('href') || '';
link.crossOrigin = child.getAttribute('crossorigin') || '';
document.head.appendChild(link);
}
});
const style = document.createElement('style');
style.textContent = getAdditionalFontFaces();
document.head.appendChild(style);
};
export const transformStylesheet = (
viewSettings: ViewSettings,
width: number,