|
|
@@ -22,15 +22,16 @@ function fontFormat(ext: string): string { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
async function findItalicSibling(regularFilename: string): Promise<string | null> { |
|
|
|
|
|
|
|
|
async function findSibling(regularFilename: string, suffix: string): Promise<string | null> { |
|
|
const m = regularFilename.match(/^(.*)(\.(?:woff2?|ttf|otf))$/i); |
|
|
const m = regularFilename.match(/^(.*)(\.(?:woff2?|ttf|otf))$/i); |
|
|
if (!m) return null; |
|
|
if (!m) return null; |
|
|
const [, base, ext] = m; |
|
|
const [, base, ext] = m; |
|
|
|
|
|
const lower = suffix.toLowerCase(); |
|
|
const candidates = [ |
|
|
const candidates = [ |
|
|
`${base}-Italic${ext}`, `${base}-italic${ext}`, |
|
|
|
|
|
`${base}_Italic${ext}`, `${base}_italic${ext}`, |
|
|
|
|
|
`${base} Italic${ext}`, `${base} italic${ext}`, |
|
|
|
|
|
`${base}Italic${ext}`, `${base}italic${ext}`, |
|
|
|
|
|
|
|
|
`${base}-${suffix}${ext}`, `${base}-${lower}${ext}`, |
|
|
|
|
|
`${base}_${suffix}${ext}`, `${base}_${lower}${ext}`, |
|
|
|
|
|
`${base} ${suffix}${ext}`, `${base} ${lower}${ext}`, |
|
|
|
|
|
`${base}${suffix}${ext}`, `${base}${lower}${ext}`, |
|
|
]; |
|
|
]; |
|
|
try { |
|
|
try { |
|
|
const files = await fs.readdir(path.join(process.cwd(), "data", "fonts")); |
|
|
const files = await fs.readdir(path.join(process.cwd(), "data", "fonts")); |
|
|
@@ -54,27 +55,27 @@ export default async function RootLayout({ |
|
|
|
|
|
|
|
|
let fontStyleCss = ""; |
|
|
let fontStyleCss = ""; |
|
|
if (chosenFont) { |
|
|
if (chosenFont) { |
|
|
const regularExt = path.extname(chosenFont); |
|
|
|
|
|
const italicFile = await findItalicSibling(chosenFont); |
|
|
|
|
|
const italicExt = italicFile ? path.extname(italicFile) : ""; |
|
|
|
|
|
const regularUrl = `/api/fonts?name=${encodeURIComponent(chosenFont)}`; |
|
|
|
|
|
const italicUrl = italicFile ? `/api/fonts?name=${encodeURIComponent(italicFile)}` : ""; |
|
|
|
|
|
|
|
|
|
|
|
fontStyleCss = ` |
|
|
|
|
|
@font-face { |
|
|
|
|
|
font-family: 'PortalFont'; |
|
|
|
|
|
src: url('${regularUrl}') format('${fontFormat(regularExt)}'); |
|
|
|
|
|
font-style: normal; |
|
|
|
|
|
font-display: swap; |
|
|
|
|
|
}${italicFile ? ` |
|
|
|
|
|
|
|
|
const fontUrl = (name: string) => `/api/fonts?name=${encodeURIComponent(name)}`; |
|
|
|
|
|
const faceBlock = (file: string, weight: 400 | 700, style: 'normal' | 'italic') => ` |
|
|
@font-face { |
|
|
@font-face { |
|
|
font-family: 'PortalFont'; |
|
|
font-family: 'PortalFont'; |
|
|
src: url('${italicUrl}') format('${fontFormat(italicExt)}'); |
|
|
|
|
|
font-style: italic; |
|
|
|
|
|
|
|
|
src: url('${fontUrl(file)}') format('${fontFormat(path.extname(file))}'); |
|
|
|
|
|
font-style: ${style}; |
|
|
|
|
|
font-weight: ${weight}; |
|
|
font-display: swap; |
|
|
font-display: swap; |
|
|
}` : ""} |
|
|
|
|
|
body { font-family: 'PortalFont', Arial, Helvetica, sans-serif; } |
|
|
|
|
|
`; |
|
|
|
|
|
|
|
|
}`; |
|
|
|
|
|
|
|
|
|
|
|
const italicFile = await findSibling(chosenFont, 'Italic'); |
|
|
|
|
|
const boldFile = await findSibling(chosenFont, 'Bold'); |
|
|
|
|
|
const boldItalicFile = await findSibling(chosenFont, 'BoldItalic'); |
|
|
|
|
|
|
|
|
|
|
|
fontStyleCss = [ |
|
|
|
|
|
faceBlock(chosenFont, 400, 'normal'), |
|
|
|
|
|
italicFile ? faceBlock(italicFile, 400, 'italic') : '', |
|
|
|
|
|
boldFile ? faceBlock(boldFile, 700, 'normal') : '', |
|
|
|
|
|
boldItalicFile ? faceBlock(boldItalicFile, 700, 'italic') : '', |
|
|
|
|
|
`\nbody { font-family: 'PortalFont', Arial, Helvetica, sans-serif; }\n`, |
|
|
|
|
|
].join(''); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
|