diff --git a/lib/EpdFont/SdCardFont.cpp b/lib/EpdFont/SdCardFont.cpp index 952dcf85..5530816a 100644 --- a/lib/EpdFont/SdCardFont.cpp +++ b/lib/EpdFont/SdCardFont.cpp @@ -9,6 +9,8 @@ #include #include +#include "EpdFontFamily.h" + static_assert(sizeof(EpdGlyph) == 16, "EpdGlyph must be 16 bytes to match .cpfont file layout"); static_assert(sizeof(EpdUnicodeInterval) == 12, "EpdUnicodeInterval must be 12 bytes to match .cpfont file layout"); static_assert(sizeof(EpdKernClassEntry) == 3, "EpdKernClassEntry must be 3 bytes to match .cpfont file layout"); @@ -617,6 +619,8 @@ int32_t SdCardFont::findGlobalGlyphIndex(const PerStyle& s, uint32_t codepoint) int SdCardFont::prewarm(const char* utf8Text, uint8_t styleMask, bool metadataOnly) { if (!loaded_) return -1; + styleMask = resolveStyleMask(styleMask); + if (styleMask == 0) return 0; unsigned long startMs = millis(); @@ -1211,6 +1215,35 @@ EpdFont* SdCardFont::getEpdFont(uint8_t style) { bool SdCardFont::hasStyle(uint8_t style) const { return styles_[style & (MAX_STYLES - 1)].present; } +uint8_t SdCardFont::resolveStyle(uint8_t style) const { + static const uint8_t kFallbacks[MAX_STYLES][MAX_STYLES] = { + // REGULAR: REGULAR -> BOLD -> ITALIC -> BOLD_ITALIC + {EpdFontFamily::REGULAR, EpdFontFamily::BOLD, EpdFontFamily::ITALIC, EpdFontFamily::BOLD_ITALIC}, + // BOLD: BOLD -> REGULAR -> BOLD_ITALIC -> ITALIC + {EpdFontFamily::BOLD, EpdFontFamily::REGULAR, EpdFontFamily::BOLD_ITALIC, EpdFontFamily::ITALIC}, + // ITALIC: ITALIC -> REGULAR -> BOLD_ITALIC -> BOLD + {EpdFontFamily::ITALIC, EpdFontFamily::REGULAR, EpdFontFamily::BOLD_ITALIC, EpdFontFamily::BOLD}, + // BOLD_ITALIC: BOLD_ITALIC -> BOLD -> ITALIC -> REGULAR + {EpdFontFamily::BOLD_ITALIC, EpdFontFamily::BOLD, EpdFontFamily::ITALIC, EpdFontFamily::REGULAR}, + }; + + const uint8_t styleBits = style & (MAX_STYLES - 1); + for (uint8_t candidate : kFallbacks[styleBits]) { + if (styles_[candidate].present) return candidate; + } + return EpdFontFamily::REGULAR; +} + +uint8_t SdCardFont::resolveStyleMask(uint8_t styleMask) const { + uint8_t resolvedMask = 0; + for (uint8_t si = 0; si < MAX_STYLES; si++) { + if (styleMask & (1 << si)) { + resolvedMask |= static_cast(1u << resolveStyle(si)); + } + } + return resolvedMask; +} + // --- On-demand glyph loading (overflow buffer) --- const EpdGlyph* SdCardFont::onGlyphMiss(void* ctx, uint32_t codepoint) { diff --git a/lib/EpdFont/SdCardFont.h b/lib/EpdFont/SdCardFont.h index ad6958a5..d4d680ed 100644 --- a/lib/EpdFont/SdCardFont.h +++ b/lib/EpdFont/SdCardFont.h @@ -74,6 +74,13 @@ class SdCardFont { // Returns true if the given style is present in this font file. bool hasStyle(uint8_t style) const; + // Resolve requested style bits to the closest present style. + uint8_t resolveStyle(uint8_t style) const; + + // Resolve every requested style bit through fallback and return the actual + // styles that need cache/advance preparation. + uint8_t resolveStyleMask(uint8_t styleMask) const; + // Number of styles present in this font file. uint8_t styleCount() const { return styleCount_; } diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index 7949ac1b..993b2cb7 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -19,23 +19,7 @@ const char* resolveVisualText(const char* text, std::string& visualBuffer, int p * Falls back gracefully when the font lacks the requested variant. */ uint8_t resolveSdCardStyle(const SdCardFont& font, const EpdFontFamily::Style style) { - // Indexed by styleBits (0=REGULAR, 1=BOLD, 2=ITALIC, 3=BOLD_ITALIC) - static const uint8_t kFallbacks[4][4] = { - // REGULAR: REGULAR → BOLD → ITALIC → BOLD_ITALIC - {EpdFontFamily::REGULAR, EpdFontFamily::BOLD, EpdFontFamily::ITALIC, EpdFontFamily::BOLD_ITALIC}, - // BOLD: BOLD → BOLD_ITALIC → REGULAR → ITALIC - {EpdFontFamily::BOLD, EpdFontFamily::BOLD_ITALIC, EpdFontFamily::REGULAR, EpdFontFamily::ITALIC}, - // ITALIC: ITALIC → REGULAR → BOLD → BOLD_ITALIC (REGULAR before BOLD!) - {EpdFontFamily::ITALIC, EpdFontFamily::REGULAR, EpdFontFamily::BOLD, EpdFontFamily::BOLD_ITALIC}, - // BOLD_ITALIC: BOLD_ITALIC → BOLD → ITALIC → REGULAR - {EpdFontFamily::BOLD_ITALIC, EpdFontFamily::BOLD, EpdFontFamily::ITALIC, EpdFontFamily::REGULAR}, - }; - - const uint8_t styleBits = static_cast(style) & 0x03; - for (uint8_t candidate : kFallbacks[styleBits]) { - if (font.hasStyle(candidate)) return candidate; - } - return EpdFontFamily::REGULAR; // no-variant-at-all safety net + return font.resolveStyle(static_cast(style)); } } // namespace