From 8cebf6e31931bb904eb5e429c7a0de053f4a9b55 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Sat, 2 May 2026 23:38:19 +0200 Subject: [PATCH 1/2] Fix button race --- src/activities/browser/OpdsBookBrowserActivity.cpp | 11 +++++++---- src/activities/home/GlobalBookmarksActivity.cpp | 10 ++++++---- src/activities/home/RecentBooksActivity.cpp | 12 ++++++++---- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/activities/browser/OpdsBookBrowserActivity.cpp b/src/activities/browser/OpdsBookBrowserActivity.cpp index 2035217c..98ad8053 100644 --- a/src/activities/browser/OpdsBookBrowserActivity.cpp +++ b/src/activities/browser/OpdsBookBrowserActivity.cpp @@ -164,19 +164,22 @@ void OpdsBookBrowserActivity::loop() { } if (!entries.empty()) { - buttonNavigator.onNextRelease([this] { + // Navigator is restricted to Up/Down so a Left release used to launch + // search (line above) cannot also be consumed here as a previous-item + // step on the same tick. + buttonNavigator.onRelease({MappedInputManager::Button::Down}, [this] { selectorIndex = ButtonNavigator::nextIndex(selectorIndex, entries.size()); requestUpdate(); }); - buttonNavigator.onPreviousRelease([this] { + buttonNavigator.onRelease({MappedInputManager::Button::Up}, [this] { selectorIndex = ButtonNavigator::previousIndex(selectorIndex, entries.size()); requestUpdate(); }); - buttonNavigator.onNextContinuous([this] { + buttonNavigator.onContinuous({MappedInputManager::Button::Down}, [this] { selectorIndex = ButtonNavigator::nextPageIndex(selectorIndex, entries.size(), PAGE_ITEMS); requestUpdate(); }); - buttonNavigator.onPreviousContinuous([this] { + buttonNavigator.onContinuous({MappedInputManager::Button::Up}, [this] { selectorIndex = ButtonNavigator::previousPageIndex(selectorIndex, entries.size(), PAGE_ITEMS); requestUpdate(); }); diff --git a/src/activities/home/GlobalBookmarksActivity.cpp b/src/activities/home/GlobalBookmarksActivity.cpp index 5e50c6c9..8295fb6c 100644 --- a/src/activities/home/GlobalBookmarksActivity.cpp +++ b/src/activities/home/GlobalBookmarksActivity.cpp @@ -252,17 +252,19 @@ void GlobalBookmarksActivity::loop() { const int pageItems = UITheme::getInstance().getNumberOfItemsPerPage(renderer, true, false, true, false); - buttonNavigator.onNextRelease([this] { + // Navigator is restricted to Up/Down so the Left (rename) and Right (delete) + // handlers above cannot race default cursor movement on the same release tick. + buttonNavigator.onRelease({MappedInputManager::Button::Down}, [this] { selectorIndex = buttonNavigator.nextIndex(selectorIndex); requestUpdate(); }); - buttonNavigator.onPreviousRelease([this] { + buttonNavigator.onRelease({MappedInputManager::Button::Up}, [this] { selectorIndex = buttonNavigator.previousIndex(selectorIndex); requestUpdate(); }); - buttonNavigator.onNextContinuous([this, total, pageItems] { + buttonNavigator.onContinuous({MappedInputManager::Button::Down}, [this, total, pageItems] { int next = ButtonNavigator::nextPageIndex(selectorIndex, total, pageItems); if (isSeparatorRow(next)) { const int adj = ButtonNavigator::nextIndex(next, total, [this](int i) { return !isSeparatorRow(i); }); @@ -272,7 +274,7 @@ void GlobalBookmarksActivity::loop() { requestUpdate(); }); - buttonNavigator.onPreviousContinuous([this, total, pageItems] { + buttonNavigator.onContinuous({MappedInputManager::Button::Up}, [this, total, pageItems] { int prev = ButtonNavigator::previousPageIndex(selectorIndex, total, pageItems); if (isSeparatorRow(prev)) { const int adj = ButtonNavigator::previousIndex(prev, total, [this](int i) { return !isSeparatorRow(i); }); diff --git a/src/activities/home/RecentBooksActivity.cpp b/src/activities/home/RecentBooksActivity.cpp index 1102ec5a..fe09fff3 100644 --- a/src/activities/home/RecentBooksActivity.cpp +++ b/src/activities/home/RecentBooksActivity.cpp @@ -125,22 +125,26 @@ void RecentBooksActivity::loop() { int listSize = static_cast(recentBooks.size()); - buttonNavigator.onNextRelease([this, listSize] { + // Navigator is restricted to Up/Down so it cannot race the Left/Right Short + // handlers above: with a double-click action configured, Short events are + // deferred 300ms while wasReleased() is immediate, which would otherwise let + // the cursor move before the custom action runs on the wrong entry. + buttonNavigator.onRelease({MappedInputManager::Button::Down}, [this, listSize] { selectorIndex = ButtonNavigator::nextIndex(static_cast(selectorIndex), listSize); requestUpdate(); }); - buttonNavigator.onPreviousRelease([this, listSize] { + buttonNavigator.onRelease({MappedInputManager::Button::Up}, [this, listSize] { selectorIndex = ButtonNavigator::previousIndex(static_cast(selectorIndex), listSize); requestUpdate(); }); - buttonNavigator.onNextContinuous([this, listSize, pageItems] { + buttonNavigator.onContinuous({MappedInputManager::Button::Down}, [this, listSize, pageItems] { selectorIndex = ButtonNavigator::nextPageIndex(static_cast(selectorIndex), listSize, pageItems); requestUpdate(); }); - buttonNavigator.onPreviousContinuous([this, listSize, pageItems] { + buttonNavigator.onContinuous({MappedInputManager::Button::Up}, [this, listSize, pageItems] { selectorIndex = ButtonNavigator::previousPageIndex(static_cast(selectorIndex), listSize, pageItems); requestUpdate(); }); From 2e2d78147e702799fec544bb1b3c63dfb0427dd6 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Sat, 2 May 2026 23:51:53 +0200 Subject: [PATCH 2/2] Fix malformed sd-fonts symlink entry --- assets/sd-fonts/sd-fonts.yaml | 586 +++++++++++++++++----------------- 1 file changed, 293 insertions(+), 293 deletions(-) mode change 120000 => 100644 assets/sd-fonts/sd-fonts.yaml diff --git a/assets/sd-fonts/sd-fonts.yaml b/assets/sd-fonts/sd-fonts.yaml deleted file mode 120000 index 36b39c31..00000000 --- a/assets/sd-fonts/sd-fonts.yaml +++ /dev/null @@ -1,293 +0,0 @@ -# SD Card Font Families for CrossPoint++ Reader -# -# This file is the single source of truth for which fonts are generated, -# how they're sourced, and how they're described in the download manifest. -# -# Adding a new font family = adding a block here. No code changes needed. -# -# Fields: -# name: Output family name (used in filenames and on-device UI) -# description: Human-readable description (shown in download UI and manifest) -# intervals: Comma-separated Unicode interval presets for fontconvert_sdcard.py -# sizes: Point sizes to generate -# force_autohint: (optional) Force FreeType auto-hinter instead of native hinting -# styles: Map of style name -> font source -# path: relative to lib/EpdFont (for committed fonts) -# url: download URL (for fonts not in the repo) -# -# Variable fonts: -# Some fonts (Bitter, Inter, Alegreya) are distributed as variable fonts. -# freetype-py can't set variable font axis values, so the build script -# uses fonttools.instancer to extract static instances automatically. -# -# To use a variable font, add a 'variable' key to the style spec with -# axis values to pin: -# -# styles: -# regular: {url: "https://...Font[wght].ttf", variable: {wght: 400}} -# bold: {url: "https://...Font[wght].ttf", variable: {wght: 700}} -# -# Extracted static fonts are cached in instanced_fonts/ (gitignored). -# Requires fonttools: pip install -r requirements.txt - -families: - # ── Serif ────────────────────────────────────────────────────────────── - - - name: Literata - description: "Screen-optimized serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-BoldItalic.ttf"} - - - name: SourceSerif4 - description: "Adobe transitional serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-It.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-BoldIt.ttf"} - - - name: NotoSerifExtended - description: "Serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif-Italic/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif-Italic/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-BoldItalic.ttf"} - - - name: Merriweather - description: "Warm serif for long-form reading (Latin, Cyrillic)" - intervals: latin-ext,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-BoldItalic.ttf"} - - - name: Lora - description: "Calligraphic serif for literary reading (Latin, Cyrillic)" - intervals: latin-ext,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-BoldItalic.ttf"} - - - name: Gelasio - description: "Readable old-style serif (Latin, Cyrillic)" - intervals: latin-ext,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio%5Bwght%5D.ttf", variable: {wght: 400}} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio%5Bwght%5D.ttf", variable: {wght: 700}} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio-Italic%5Bwght%5D.ttf", variable: {wght: 400}} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio-Italic%5Bwght%5D.ttf", variable: {wght: 700}} - - - name: GentiumBookPlus - description: "Scholarly serif with wide Unicode coverage (Latin, Greek, Cyrillic, IPA)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-BoldItalic.ttf"} - - - name: IBMPlexSerif - description: "Professional serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-BoldItalic.ttf"} - - - name: Bitter - description: "Slab serif designed for e-ink (Latin, Cyrillic)" - intervals: latin-ext,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter%5Bwght%5D.ttf", variable: {wght: 400}} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter%5Bwght%5D.ttf", variable: {wght: 700}} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter-Italic%5Bwght%5D.ttf", variable: {wght: 400}} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter-Italic%5Bwght%5D.ttf", variable: {wght: 700}} - - # ── Sans-serif ───────────────────────────────────────────────────────── - - - name: NotoSansExtended - description: "Sans-serif (Latin, Greek, Cyrillic, Georgian, Armenian, Ethiopic)" - intervals: latin-ext,greek,cyrillic,georgian,armenian,ethiopic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {path: "builtinFonts/source/NotoSans/NotoSans-Regular.ttf"} - bold: {path: "builtinFonts/source/NotoSans/NotoSans-Bold.ttf"} - italic: {path: "builtinFonts/source/NotoSans/NotoSans-Italic.ttf"} - bolditalic: {path: "builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf"} - - - name: Inter - description: "Modern sans-serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter%5Bopsz%2Cwght%5D.ttf", variable: {wght: 400, opsz: 14}} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter%5Bopsz%2Cwght%5D.ttf", variable: {wght: 700, opsz: 14}} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter-Italic%5Bopsz%2Cwght%5D.ttf", variable: {wght: 400, opsz: 14}} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter-Italic%5Bopsz%2Cwght%5D.ttf", variable: {wght: 700, opsz: 14}} - - - name: SourceSans3 - description: "Adobe humanist sans-serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-It.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-BoldIt.ttf"} - - - name: IBMPlexSans - description: "IBM corporate sans-serif (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-BoldItalic.ttf"} - - - name: Alegreya - description: "Calligraphic serif/display (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya%5Bwght%5D.ttf", variable: {wght: 400}} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya%5Bwght%5D.ttf", variable: {wght: 700}} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya-Italic%5Bwght%5D.ttf", variable: {wght: 400}} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya-Italic%5Bwght%5D.ttf", variable: {wght: 700}} - - # ── Monospace ────────────────────────────────────────────────────────── - - - name: IBMPlexMono - description: "Monospace for code and technical reading (Latin, Greek, Cyrillic)" - intervals: latin-ext,greek,cyrillic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-BoldItalic.ttf"} - - - name: SourceCodePro - description: "Adobe monospace with excellent hinting (Latin)" - intervals: latin-ext - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-It.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-BoldIt.ttf"} - - # ── Accessibility ────────────────────────────────────────────────────── - - - name: AtkinsonHyperlegibleNext - description: "Accessibility font for low vision (Latin)" - intervals: latin-ext - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-BoldItalic.ttf"} - - - name: LexicaUltralegible - description: "Accessibility font for low vision / dyslexia (Latin)" - intervals: latin-ext - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Regular.ttf"} - bold: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Bold.ttf"} - italic: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Italic.ttf"} - bolditalic: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-BoldItalic.ttf"} - - # OpenDyslexic was previously baked into the firmware. It is now distributed - # as an SD-card font so users who don't need it don't pay the ~3MB flash cost. - # Sizes 8/10 retained for backward compatibility with the previous built-in mapping. - - name: OpenDyslexic - description: "Dyslexia-friendly font (Latin, Latin-Extended)" - intervals: latin-ext - sizes: [8, 10, 12, 14, 16] - styles: - regular: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Regular.otf"} - bold: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Bold.otf"} - italic: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Italic.otf"} - bolditalic: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-BoldItalic.otf"} - - # ── CJK & Hangul ────────────────────────────────────────────────────── - - - name: NotoSansCJK - description: "Sans-serif (Chinese, Japanese, Korean)" - intervals: ascii,latin1,punctuation,cjk - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf"} - - - name: NotoSerifCJK - description: "Serif (Chinese, Japanese, Korean)" - intervals: ascii,latin1,punctuation,cjk - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Serif/OTF/SimplifiedChinese/NotoSerifCJKsc-Regular.otf"} - - - name: NotoSansHangul - description: "Sans-serif (Korean Hangul)" - intervals: ascii,latin1,punctuation,hangul - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/Korean/NotoSansCJKkr-Regular.otf"} - - # ── Additional scripts (no complex shaping needed) ───────────────────── - - - name: NotoSansArmenian - description: "Armenian script" - intervals: armenian - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansarmenian/NotoSansArmenian%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} - - - name: NotoSansGeorgian - description: "Georgian script" - intervals: georgian - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansgeorgian/NotoSansGeorgian%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} - - - name: NotoSansEthiopic - description: "Ethiopic/Ge'ez script" - intervals: ethiopic - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansethiopic/NotoSansEthiopic%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} - - - name: NotoSansCherokee - description: "Cherokee syllabary" - intervals: cherokee - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanscherokee/NotoSansCherokee%5Bwght%5D.ttf", variable: {wght: 400}} - - - name: NotoSansTifinagh - description: "Tifinagh script" - intervals: tifinagh - sizes: [10, 12, 14, 16, 18] - styles: - regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanstifinagh/NotoSansTifinagh-Regular.ttf"} diff --git a/assets/sd-fonts/sd-fonts.yaml b/assets/sd-fonts/sd-fonts.yaml new file mode 100644 index 00000000..876dc43d --- /dev/null +++ b/assets/sd-fonts/sd-fonts.yaml @@ -0,0 +1,293 @@ +# SD Card Font Families for CrossPoint Reader +# +# This file is the single source of truth for which fonts are generated, +# how they're sourced, and how they're described in the download manifest. +# +# Adding a new font family = adding a block here. No code changes needed. +# +# Fields: +# name: Output family name (used in filenames and on-device UI) +# description: Human-readable description (shown in download UI and manifest) +# intervals: Comma-separated Unicode interval presets for fontconvert_sdcard.py +# sizes: Point sizes to generate +# force_autohint: (optional) Force FreeType auto-hinter instead of native hinting +# styles: Map of style name -> font source +# path: relative to lib/EpdFont (for committed fonts) +# url: download URL (for fonts not in the repo) +# +# Variable fonts: +# Some fonts (Bitter, Inter, Alegreya) are distributed as variable fonts. +# freetype-py can't set variable font axis values, so the build script +# uses fonttools.instancer to extract static instances automatically. +# +# To use a variable font, add a 'variable' key to the style spec with +# axis values to pin: +# +# styles: +# regular: {url: "https://...Font[wght].ttf", variable: {wght: 400}} +# bold: {url: "https://...Font[wght].ttf", variable: {wght: 700}} +# +# Extracted static fonts are cached in instanced_fonts/ (gitignored). +# Requires fonttools: pip install -r requirements.txt + +families: + # ── Serif ────────────────────────────────────────────────────────────── + + - name: Literata + description: "Screen-optimized serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/googlefonts/literata/main/fonts/ttf/Literata-BoldItalic.ttf"} + + - name: SourceSerif4 + description: "Adobe transitional serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-It.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-serif/release/TTF/SourceSerif4-BoldIt.ttf"} + + - name: NotoSerifExtended + description: "Serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif-Italic/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/notofonts/NotoSerif-Italic/main/fonts/ttf/unhinted/instance_ttf/NotoSerif-BoldItalic.ttf"} + + - name: Merriweather + description: "Warm serif for long-form reading (Latin, Cyrillic)" + intervals: latin-ext,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/SorkinType/Merriweather/master/fonts/ttf/Merriweather-BoldItalic.ttf"} + + - name: Lora + description: "Calligraphic serif for literary reading (Latin, Cyrillic)" + intervals: latin-ext,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/cyrealtype/Lora-Cyrillic/main/fonts/ttf/Lora-BoldItalic.ttf"} + + - name: Gelasio + description: "Readable old-style serif (Latin, Cyrillic)" + intervals: latin-ext,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio%5Bwght%5D.ttf", variable: {wght: 400}} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio%5Bwght%5D.ttf", variable: {wght: 700}} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio-Italic%5Bwght%5D.ttf", variable: {wght: 400}} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gelasio/Gelasio-Italic%5Bwght%5D.ttf", variable: {wght: 700}} + + - name: GentiumBookPlus + description: "Scholarly serif with wide Unicode coverage (Latin, Greek, Cyrillic, IPA)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/gentiumbookplus/GentiumBookPlus-BoldItalic.ttf"} + + - name: IBMPlexSerif + description: "Professional serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexserif/IBMPlexSerif-BoldItalic.ttf"} + + - name: Bitter + description: "Slab serif designed for e-ink (Latin, Cyrillic)" + intervals: latin-ext,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter%5Bwght%5D.ttf", variable: {wght: 400}} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter%5Bwght%5D.ttf", variable: {wght: 700}} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter-Italic%5Bwght%5D.ttf", variable: {wght: 400}} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/bitter/Bitter-Italic%5Bwght%5D.ttf", variable: {wght: 700}} + + # ── Sans-serif ───────────────────────────────────────────────────────── + + - name: NotoSansExtended + description: "Sans-serif (Latin, Greek, Cyrillic, Georgian, Armenian, Ethiopic)" + intervals: latin-ext,greek,cyrillic,georgian,armenian,ethiopic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {path: "builtinFonts/source/NotoSans/NotoSans-Regular.ttf"} + bold: {path: "builtinFonts/source/NotoSans/NotoSans-Bold.ttf"} + italic: {path: "builtinFonts/source/NotoSans/NotoSans-Italic.ttf"} + bolditalic: {path: "builtinFonts/source/NotoSans/NotoSans-BoldItalic.ttf"} + + - name: Inter + description: "Modern sans-serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter%5Bopsz%2Cwght%5D.ttf", variable: {wght: 400, opsz: 14}} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter%5Bopsz%2Cwght%5D.ttf", variable: {wght: 700, opsz: 14}} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter-Italic%5Bopsz%2Cwght%5D.ttf", variable: {wght: 400, opsz: 14}} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/inter/Inter-Italic%5Bopsz%2Cwght%5D.ttf", variable: {wght: 700, opsz: 14}} + + - name: SourceSans3 + description: "Adobe humanist sans-serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-It.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-sans/release/TTF/SourceSans3-BoldIt.ttf"} + + - name: IBMPlexSans + description: "IBM corporate sans-serif (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/IBM/plex/master/packages/plex-sans/fonts/complete/ttf/IBMPlexSans-BoldItalic.ttf"} + + - name: Alegreya + description: "Calligraphic serif/display (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya%5Bwght%5D.ttf", variable: {wght: 400}} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya%5Bwght%5D.ttf", variable: {wght: 700}} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya-Italic%5Bwght%5D.ttf", variable: {wght: 400}} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/alegreya/Alegreya-Italic%5Bwght%5D.ttf", variable: {wght: 700}} + + # ── Monospace ────────────────────────────────────────────────────────── + + - name: IBMPlexMono + description: "Monospace for code and technical reading (Latin, Greek, Cyrillic)" + intervals: latin-ext,greek,cyrillic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/ibmplexmono/IBMPlexMono-BoldItalic.ttf"} + + - name: SourceCodePro + description: "Adobe monospace with excellent hinting (Latin)" + intervals: latin-ext + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-It.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/adobe-fonts/source-code-pro/release/TTF/SourceCodePro-BoldIt.ttf"} + + # ── Accessibility ────────────────────────────────────────────────────── + + - name: AtkinsonHyperlegibleNext + description: "Accessibility font for low vision (Latin)" + intervals: latin-ext + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/googlefonts/atkinson-hyperlegible-next/main/fonts/ttf/AtkinsonHyperlegibleNext-BoldItalic.ttf"} + + - name: LexicaUltralegible + description: "Accessibility font for low vision / dyslexia (Latin)" + intervals: latin-ext + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Regular.ttf"} + bold: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Bold.ttf"} + italic: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-Italic.ttf"} + bolditalic: {url: "https://raw.githubusercontent.com/jacobxperez/lexica-ultralegible/main/fonts/ttf/LexicaUltralegible-BoldItalic.ttf"} + + # OpenDyslexic was previously baked into the firmware. It is now distributed + # as an SD-card font so users who don't need it don't pay the ~3MB flash cost. + # Sizes 8/10 retained for backward compatibility with the previous built-in mapping. + - name: OpenDyslexic + description: "Dyslexia-friendly font (Latin, Latin-Extended)" + intervals: latin-ext + sizes: [8, 10, 12, 14, 16] + styles: + regular: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Regular.otf"} + bold: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Bold.otf"} + italic: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-Italic.otf"} + bolditalic: {path: "builtinFonts/source/OpenDyslexic/OpenDyslexic-BoldItalic.otf"} + + # ── CJK & Hangul ────────────────────────────────────────────────────── + + - name: NotoSansCJK + description: "Sans-serif (Chinese, Japanese, Korean)" + intervals: ascii,latin1,punctuation,cjk + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/SimplifiedChinese/NotoSansCJKsc-Regular.otf"} + + - name: NotoSerifCJK + description: "Serif (Chinese, Japanese, Korean)" + intervals: ascii,latin1,punctuation,cjk + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Serif/OTF/SimplifiedChinese/NotoSerifCJKsc-Regular.otf"} + + - name: NotoSansHangul + description: "Sans-serif (Korean Hangul)" + intervals: ascii,latin1,punctuation,hangul + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://github.com/notofonts/noto-cjk/raw/main/Sans/OTF/Korean/NotoSansCJKkr-Regular.otf"} + + # ── Additional scripts (no complex shaping needed) ───────────────────── + + - name: NotoSansArmenian + description: "Armenian script" + intervals: armenian + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansarmenian/NotoSansArmenian%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} + + - name: NotoSansGeorgian + description: "Georgian script" + intervals: georgian + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansgeorgian/NotoSansGeorgian%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} + + - name: NotoSansEthiopic + description: "Ethiopic/Ge'ez script" + intervals: ethiopic + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansethiopic/NotoSansEthiopic%5Bwdth%2Cwght%5D.ttf", variable: {wght: 400, wdth: 100}} + + - name: NotoSansCherokee + description: "Cherokee syllabary" + intervals: cherokee + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanscherokee/NotoSansCherokee%5Bwght%5D.ttf", variable: {wght: 400}} + + - name: NotoSansTifinagh + description: "Tifinagh script" + intervals: tifinagh + sizes: [10, 12, 14, 16, 18] + styles: + regular: {url: "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanstifinagh/NotoSansTifinagh-Regular.ttf"} \ No newline at end of file