Update font files with simplified naming and add reader font CSS
- Rename font files from VariableFont_wght/opsz,wght to Variable format - Add reader-fonts.css with @font-face definitions for 10 serif fonts - Fonts: Crimson Pro, EB Garamond, Literata, Noto Serif, Source Serif 4 - Each font includes regular and italic variants
This commit is contained in:
1 parent
c1bc9dceb5
commit
d52937e578
12 files changed
+289
-24
No files matched your search
@@ -2,33 +2,72 @@
|
||||
// Procedural style: Functions, not classes
|
||||
|
||||
interface TypographyConfig {
|
||||
readingFont:
|
||||
| "literata"
|
||||
| "crimson"
|
||||
| "source-serif"
|
||||
| "eb-garamond"
|
||||
| "libertinus"
|
||||
| "noto-serif"
|
||||
| "charis-sil"
|
||||
| "ibm-plex"; // Bundled libre fonts
|
||||
fontSize: number;
|
||||
lineHeight: number;
|
||||
textAlign: "left" | "justify";
|
||||
marginTop: number;
|
||||
marginBottom: number;
|
||||
marginLeft: number;
|
||||
marginRight: number;
|
||||
textAlign: "left" | "right" | "center" | "justify";
|
||||
textIndent: number;
|
||||
hyphenate: boolean;
|
||||
ligatures: boolean;
|
||||
fontSmoothing: "auto" | "grayscale";
|
||||
fontSmoothing: "auto" | "antialiased" | "subpixel-antialiased";
|
||||
}
|
||||
|
||||
export function applyTypographyConfig(
|
||||
element: HTMLElement,
|
||||
function applyTypography(
|
||||
container: HTMLElement,
|
||||
config: TypographyConfig,
|
||||
): void {
|
||||
// Enable/disable ligatures
|
||||
setLigatures(element, config.ligatures);
|
||||
const content = container.querySelector(".ebook-content");
|
||||
if (!content) return;
|
||||
|
||||
const fontStack = getFontStack(config.readingFont);
|
||||
|
||||
content.setAttribute(
|
||||
"style",
|
||||
`
|
||||
font-family: ${fontStack};
|
||||
font-size: ${config.fontSize}px;
|
||||
line-height: ${config.lineHeight};
|
||||
text-align: ${config.textAlign};
|
||||
margin-top: ${config.marginTop}px;
|
||||
margin-bottom: ${config.marginBottom}px;
|
||||
margin-left: ${config.marginLeft}px;
|
||||
margin-right: ${config.marginRight}px;
|
||||
text-indent: ${config.textIndent}px;
|
||||
-webkit-font-smoothing: ${config.fontSmoothing};
|
||||
-moz-osx-font-smoothing: ${config.fontSmoothing === "grayscale" ? "grayscale" : "auto"};
|
||||
`,
|
||||
);
|
||||
|
||||
// Enable/disable hyphenation
|
||||
if (config.hyphenate) {
|
||||
enableHyphenation(element);
|
||||
enableHyphenation(container, content as HTMLElement);
|
||||
}
|
||||
|
||||
// Apply justification settings
|
||||
setLigatures(content as HTMLElement, config.ligatures);
|
||||
|
||||
if (config.textAlign === "justify") {
|
||||
enableJustification(element);
|
||||
enableJustification(content as HTMLElement);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply font smoothing
|
||||
element.style.fontSmooth = config.fontSmoothing;
|
||||
function enableHyphenation(container: HTMLElement, element: HTMLElement): void {
|
||||
element.style.hyphens = "auto";
|
||||
element.style.hyphenateLimitChars = "6 3 3";
|
||||
|
||||
const lang =
|
||||
container.closest("[data-language]")?.getAttribute("data-language") || "en";
|
||||
element.setAttribute("lang", lang);
|
||||
}
|
||||
|
||||
function setLigatures(element: HTMLElement, enabled: boolean): void {
|
||||
@@ -41,16 +80,6 @@ function setLigatures(element: HTMLElement, enabled: boolean): void {
|
||||
}
|
||||
}
|
||||
|
||||
function enableHyphenation(element: HTMLElement): void {
|
||||
element.style.hyphens = "auto";
|
||||
element.style.hyphenateLimitChars = "6 3 3";
|
||||
|
||||
// Add language attribute from EPUB metadata
|
||||
const lang =
|
||||
element.closest("[data-language]")?.getAttribute("data-language") || "en";
|
||||
element.setAttribute("lang", lang);
|
||||
}
|
||||
|
||||
function enableJustification(element: HTMLElement): void {
|
||||
element.style.wordBreak = "normal";
|
||||
element.style.overflowWrap = "break-word";
|
||||
@@ -58,7 +87,14 @@ function enableJustification(element: HTMLElement): void {
|
||||
element.style.letterSpacing = "0.01em";
|
||||
}
|
||||
|
||||
export function measureReadingTime(
|
||||
function updateTypographyConfig(
|
||||
currentConfig: TypographyConfig,
|
||||
newConfig: Partial<TypographyConfig>,
|
||||
): TypographyConfig {
|
||||
return { ...currentConfig, ...newConfig };
|
||||
}
|
||||
|
||||
function measureReadingTime(
|
||||
container: HTMLElement,
|
||||
wordsPerMinute: number = 250,
|
||||
): number {
|
||||
@@ -72,7 +108,7 @@ export function measureReadingTime(
|
||||
return Math.ceil(minutes);
|
||||
}
|
||||
|
||||
export function getWordCount(container: HTMLElement): number {
|
||||
function getWordCount(container: HTMLElement): number {
|
||||
const content = container.querySelector(".ebook-content");
|
||||
if (!content) return 0;
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,229 @@
|
||||
/* Libre reading fonts for Bookhoard ebook reader */
|
||||
|
||||
/* Literata - Designed for Google Play Books */
|
||||
@font-face {
|
||||
font-family: "Literata";
|
||||
src: url("/static/fonts/literata/Literata-Variable.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Literata";
|
||||
src: url("/static/fonts/literata/Literata-Variable.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Literata";
|
||||
src: url("/static/fonts/literata/Literata-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Literata";
|
||||
src: url("/static/fonts/literata/Literata-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Crimson Text - Optimized for screen reading */
|
||||
@font-face {
|
||||
font-family: "Crimson Pro";
|
||||
src: url("/static/fonts/crimson/CrimsonPro-Variable.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Crimson Pro";
|
||||
src: url("/static/fonts/crimson/CrimsonPro-Variable.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Crimson Pro";
|
||||
src: url("/static/fonts/crimson/CrimsonPro-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Crimson Pro";
|
||||
src: url("/static/fonts/crimson/CrimsonPro-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Source Serif 4 - Adobe professional quality */
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
src: url("/static/fonts/source-serif/SourceSerif4-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
src: url("/static/fonts/source-serif/SourceSerif4-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
src: url("/static/fonts/source-serif/SourceSerif4-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Source Serif 4";
|
||||
src: url("/static/fonts/source-serif/SourceSerif4-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* EB Garamond - Classic elegance */
|
||||
@font-face {
|
||||
font-family: "EB Garamond";
|
||||
src: url("/static/fonts/eb-garamond/EBGaramond-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "EB Garamond";
|
||||
src: url("/static/fonts/eb-garamond/EBGaramond-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "EB Garamond";
|
||||
src: url("/static/fonts/eb-garamond/EBGaramond-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "EB Garamond";
|
||||
src: url("/static/fonts/eb-garamond/EBGaramond-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Libertinus Serif - Academic/technical */
|
||||
@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-style: normal;
|
||||
font-weight: 700;
|
||||
}
|
||||
@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;
|
||||
}
|
||||
|
||||
/* Noto Serif - Maximum language support */
|
||||
@font-face {
|
||||
font-family: "Noto Serif";
|
||||
src: url("/static/fonts/noto-serif/NotoSerif-Variable.woff2") format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Noto Serif";
|
||||
src: url("/static/fonts/noto-serif/NotoSerif-Variable.woff2") format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Noto Serif";
|
||||
src: url("/static/fonts/noto-serif/NotoSerif-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Noto Serif";
|
||||
src: url("/static/fonts/noto-serif/NotoSerif-Italic-Variable.woff2")
|
||||
format("woff2");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Charis SIL - Multilingual specialist */
|
||||
@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;
|
||||
}
|
||||
|
||||
/* IBM Plex Serif - Modern & versatile */
|
||||
@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;
|
||||
}
|
||||
Reference in new issue
Block a user