fix(reader): inject @font-face rules into shadow DOM iframe for font switching

The paginator renders book content inside a sandboxed iframe within a
closed shadow DOM. @font-face declarations from the parent page's
reader-fonts.css are NOT available inside the iframe's document context.
All font-family rules fell back to the generic 'serif' system font,
making every reading font look identical.

Fix: prepend all @font-face declarations (Literata, Crimson Pro,
Source Serif 4, EB Garamond, Libertinus Serif, Noto Serif, Charis SIL,
IBM Plex Serif) into the CSS string returned by getCSS(), so they're
injected into the iframe via renderer.setStyles().
This commit is contained in:
2026-04-19 21:15:10 -04:00
parent 95202f1e28
commit db33771575
+136
View File
@@ -14,6 +14,141 @@ const FONT_MAP: Record<string, string> = {
"ibm-plex": '"IBM Plex Serif"',
};
const FONT_FACE_RULES = `
@font-face {
font-family: "Literata";
src: url("/static/fonts/literata/Literata-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: "Literata";
src: url("/static/fonts/literata/Literata-Italic-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: "Crimson Pro";
src: url("/static/fonts/crimson/CrimsonPro-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: "Crimson Pro";
src: url("/static/fonts/crimson/CrimsonPro-Italic-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: "Source Serif 4";
src: url("/static/fonts/source-serif/SourceSerif4-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: "Source Serif 4";
src: url("/static/fonts/source-serif/SourceSerif4-Italic-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: "EB Garamond";
src: url("/static/fonts/eb-garamond/EBGaramond-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: "EB Garamond";
src: url("/static/fonts/eb-garamond/EBGaramond-Italic-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: "Libertinus Serif";
src: url("/static/fonts/libertinus/LibertinusSerif-Regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "Libertinus Serif";
src: url("/static/fonts/libertinus/LibertinusSerif-Bold.woff2") format("woff2");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "Libertinus Serif";
src: url("/static/fonts/libertinus/LibertinusSerif-Italic.woff2") format("woff2");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "Libertinus Serif";
src: url("/static/fonts/libertinus/LibertinusSerif-BoldItalic.woff2") format("woff2");
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: "Noto Serif";
src: url("/static/fonts/noto-serif/NotoSerif-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
}
@font-face {
font-family: "Noto Serif";
src: url("/static/fonts/noto-serif/NotoSerif-Italic-Variable.woff2") format("woff2");
font-weight: 100 900;
font-style: italic;
}
@font-face {
font-family: "Charis SIL";
src: url("/static/fonts/charis-sil/CharisSIL-Regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "Charis SIL";
src: url("/static/fonts/charis-sil/CharisSIL-Bold.woff2") format("woff2");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "Charis SIL";
src: url("/static/fonts/charis-sil/CharisSIL-Italic.woff2") format("woff2");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "Charis SIL";
src: url("/static/fonts/charis-sil/CharisSIL-BoldItalic.woff2") format("woff2");
font-weight: 700;
font-style: italic;
}
@font-face {
font-family: "IBM Plex Serif";
src: url("/static/fonts/ibm-plex/IBMPlexSerif-Regular.woff2") format("woff2");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "IBM Plex Serif";
src: url("/static/fonts/ibm-plex/IBMPlexSerif-Bold.woff2") format("woff2");
font-weight: 700;
font-style: normal;
}
@font-face {
font-family: "IBM Plex Serif";
src: url("/static/fonts/ibm-plex/IBMPlexSerif-Italic.woff2") format("woff2");
font-weight: 400;
font-style: italic;
}
@font-face {
font-family: "IBM Plex Serif";
src: url("/static/fonts/ibm-plex/IBMPlexSerif-BoldItalic.woff2") format("woff2");
font-weight: 700;
font-style: italic;
}
`;
interface ThemeColors {
fg: string;
bg: string;
@@ -124,6 +259,7 @@ const getCSS = ({
}` : "";
return `
${FONT_FACE_RULES}
@namespace epub "http://www.idpf.org/2007/ops";
html {
color-scheme: light dark;