#pragma once #include #include #include class GfxRenderer; /// Facade that owns the SD card font registry, manager, and resolver logic. /// Hides implementation details behind a single begin() + ensureLoaded() API. class SdCardFontSystem { public: SdCardFontSystem() = default; SdCardFontSystem(const SdCardFontSystem&) = delete; SdCardFontSystem& operator=(const SdCardFontSystem&) = delete; /// Discover SD card fonts and load user's saved selection. Call once during setup. void begin(GfxRenderer& renderer); /// Ensure the correct SD font family is loaded for the current settings. /// Call before entering the reader or after settings change. /// Also re-discovers if the registry has been marked dirty (e.g. by web upload). void ensureLoaded(GfxRenderer& renderer); /// Resolve an SD card font ID from family name + fontSize enum. /// Returns 0 if not found. Used by CrossPointSettings::getReaderFontId(). int resolveFontId(const char* familyName, uint8_t fontSizeEnum) const; /// Access the registry (e.g. for settings UI to enumerate available fonts). const SdCardFontRegistry& registry() const { return registry_; } /// Non-const access to the registry (for FontInstaller). SdCardFontRegistry& registry() { return registry_; } /// Mark the registry as needing re-discovery. /// Thread-safe: can be called from the web server task. void markRegistryDirty() { registryDirty_.store(true, std::memory_order_release); } /// If the registry is dirty, re-scan the SD card now and clear the flag. /// Used by the web UI so uploaded/deleted fonts appear in the list /// without waiting for the reader activity to run ensureLoaded(). void refreshIfDirty() { if (registryDirty_.exchange(false, std::memory_order_acquire)) { registry_.discover(); } } private: SdCardFontRegistry registry_; SdCardFontManager manager_; std::atomic registryDirty_{false}; };