Files
Crosspoint/src/fontIds.h
7993b2bb97 feat: add SD card font support with on-device download and web management
Add a complete SD card font subsystem that enables users to install and
use custom fonts beyond the three built-in families. This combines the
back-end firmware support (#1327) with the font configuration, build
pipeline, CI distribution, and user-facing management UI (#1392).

Core font system:
- Custom .cpfont binary format (v4) with multi-style support (regular,
  bold, italic, bold-italic) packed into a single file per size
- On-demand glyph loading from SD card with two-pass prewarm rendering
  to bulk-read glyphs per page, achieving near-flash performance for
  Latin text (~697ms vs ~681ms) and viable CJK rendering (~32% slower)
- Persistent advance cache for layout measurement without SD I/O
- Overflow ring buffer for glyph cache misses during rendering
- Memory-conscious design: only advance tables kept in RAM; glyph
  bitmaps, kern tables, and ligatures loaded on demand from SD

Font management:
- On-device WiFi download from GitHub Releases with manifest-based
  discovery, install/update detection, and progress UI
- Web interface font upload, listing, and deletion via /fonts page
- Manual SD card copy to /fonts/ or /.fonts/ directories
- Font selection integrated into Settings > Reader > Font Family

Build pipeline:
- Declarative YAML config (sd-fonts.yaml) as single source of truth
  for the 17-family font library (serif, sans, mono, accessibility)
- Python converter (fontconvert_sdcard.py) for TTF/OTF to .cpfont with
  FreeType rasterization, class-based kerning, and ligature extraction
- Parallel build orchestrator with variable font instance extraction
- CI workflow publishing versioned + stable releases to a dedicated
  crosspoint-fonts repository with auto-incrementing revision tags
- Centralized version constants (cpfont_version.py) shared across
  build tooling and CI, with firmware headers as manual sync points

Additional fixes:
- CJK characters no longer get hyphens inserted at line breaks
- Advance table eliminates 30+ second stalls during CJK section
  indexing for paragraphs with >512 unique codepoints

Closes #930

Co-authored-by: Zach Nelson <zach@zdnelson.com>
Co-authored-by: Justin <itsthisjustin@users.noreply.github.com>
Co-authored-by: jpirnay <jens@pirnay.com>
Co-authored-by: mcrosson <kemonine@kemonine.info>
2026-05-08 21:50:06 -05:00

37 lines
1.9 KiB
C

// The contents of this file are generated by ./lib/EpdFont/scripts/build-font-ids.sh
#pragma once
#define NOTOSERIF_12_FONT_ID (85340443)
#define NOTOSERIF_14_FONT_ID (-1367885987)
#define NOTOSERIF_16_FONT_ID (1428909134)
#define NOTOSERIF_18_FONT_ID (-501438527)
#define NOTOSANS_12_FONT_ID (2057568286)
#define NOTOSANS_14_FONT_ID (-1589315735)
#define NOTOSANS_16_FONT_ID (1669013660)
#define NOTOSANS_18_FONT_ID (37077304)
#define OPENDYSLEXIC_8_FONT_ID (-853313197)
#define OPENDYSLEXIC_10_FONT_ID (963754926)
#define OPENDYSLEXIC_12_FONT_ID (858950283)
#define OPENDYSLEXIC_14_FONT_ID (1877344218)
#define UI_10_FONT_ID (22918846)
#define UI_12_FONT_ID (1635686837)
#define SMALL_FONT_ID (674098198)
// Font ID 0 is reserved as the "not found" sentinel.
// Guard against any hash accidentally producing 0.
static_assert(NOTOSERIF_12_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSERIF_14_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSERIF_16_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSERIF_18_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSANS_12_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSANS_14_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSANS_16_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(NOTOSANS_18_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(OPENDYSLEXIC_8_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(OPENDYSLEXIC_10_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(OPENDYSLEXIC_12_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(OPENDYSLEXIC_14_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(UI_10_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(UI_12_FONT_ID != 0, "Font ID collision with sentinel");
static_assert(SMALL_FONT_ID != 0, "Font ID collision with sentinel");