Files
Canto/qwen3-tts-frontend/src/lib/fontManager.ts

149 lines
4.5 KiB
TypeScript

type Language = 'zh-CN' | 'zh-TW' | 'en-US' | 'ja-JP' | 'ko-KR'
interface FontConfig {
name: string
file: string
unicodeRange?: string
}
const fontConfigs: Record<Language, FontConfig[]> = {
'zh-CN': [
{
name: 'Noto Serif',
file: '/fonts/noto-serif-sc-regular.woff2',
unicodeRange: 'U+4E00-9FFF, U+3400-4DBF, U+20000-2A6DF, U+2A700-2B73F, U+2B740-2B81F, U+2B820-2CEAF, U+F900-FAFF, U+2F800-2FA1F',
},
{
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
},
],
'zh-TW': [
{
name: 'Noto Serif',
file: '/fonts/noto-serif-tc-regular.woff2',
unicodeRange: 'U+4E00-9FFF, U+3400-4DBF, U+F900-FAFF',
},
{
name: 'Noto Serif',
file: '/fonts/noto-serif-sc-regular.woff2',
unicodeRange: 'U+20000-2A6DF, U+2A700-2B73F, U+2B740-2B81F, U+2B820-2CEAF, U+2F800-2FA1F',
},
{
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
},
],
'en-US': [
{
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
},
],
'ja-JP': [
{
name: 'Noto Serif',
file: '/fonts/noto-serif-jp-regular.woff2',
unicodeRange: 'U+3000-30FF, U+4E00-9FFF, U+FF00-FFEF',
},
{
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
},
],
'ko-KR': [
{
name: 'Noto Serif',
file: '/fonts/noto-serif-kr-regular.woff2',
unicodeRange: 'U+AC00-D7AF, U+1100-11FF, U+3130-318F',
},
{
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
},
],
}
const loadedFonts = new Set<string>()
function createFontFace(config: FontConfig): FontFace {
const descriptors: FontFaceDescriptors = {
style: 'normal',
weight: '400',
display: 'swap',
}
if (config.unicodeRange) {
descriptors.unicodeRange = config.unicodeRange
}
return new FontFace(config.name, `url(${config.file}) format('woff2')`, descriptors)
}
export function loadFontsForLanguage(language: Language): void {
const configs = fontConfigs[language]
if (!configs) return
configs.forEach((config) => {
const fontKey = `${config.name}-${config.file}`
if (loadedFonts.has(fontKey)) {
return
}
try {
const fontFace = createFontFace(config)
document.fonts.add(fontFace)
loadedFonts.add(fontKey)
} catch (error) {
console.warn(`Failed to register font ${config.file}:`, error)
}
})
}
export function detectBrowserLanguage(): Language {
const browserLang = navigator.language.toLowerCase()
if (browserLang.startsWith('zh-tw') || browserLang.startsWith('zh-hk') || browserLang.startsWith('zh-mo')) {
return 'zh-TW'
}
if (browserLang.startsWith('zh')) {
return 'zh-CN'
}
if (browserLang.startsWith('ja')) {
return 'ja-JP'
}
if (browserLang.startsWith('ko')) {
return 'ko-KR'
}
return 'en-US'
}
export function preloadBaseFont(): void {
const baseConfig: FontConfig = {
name: 'Noto Serif',
file: '/fonts/noto-serif-latin-regular.woff2',
unicodeRange: 'U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD',
}
const fontKey = `${baseConfig.name}-${baseConfig.file}`
if (loadedFonts.has(fontKey)) {
return
}
try {
const fontFace = createFontFace(baseConfig)
document.fonts.add(fontFace)
loadedFonts.add(fontKey)
} catch (error) {
console.warn('Failed to register base font:', error)
}
}