#pragma once #include #include #include class GfxRenderer; class SdCardFont; struct SdCardFontFamilyInfo; class SdCardFontManager { public: SdCardFontManager() = default; ~SdCardFontManager(); SdCardFontManager(const SdCardFontManager&) = delete; SdCardFontManager& operator=(const SdCardFontManager&) = delete; // Load the single size whose pointSize is closest to targetPtSize. Only one // .cpfont file is loaded; other sizes remain on disk. This keeps resident // interval + kern/ligature tables to one size's worth of memory. // // Closest-pt selection is robust against families that don't ship the // canonical {12,14,16,18}: a family with only [10,14,18] still resolves // any reasonable target, where ordinal slot-mapping by SMALL..EXTRA_LARGE // would mis-select. // Returns true on success. bool loadFamily(const SdCardFontFamilyInfo& family, GfxRenderer& renderer, uint8_t targetPtSize); // Unload everything, unregister from renderer. void unloadAll(GfxRenderer& renderer); // Look up the font ID for the loaded family. Returns 0 if nothing loaded // or familyName doesn't match. int getFontId(const std::string& familyName) const; // Get name of currently loaded family (empty if none). const std::string& currentFamilyName() const { return loadedFamilyName_; }; // Point size that was actually loaded (closest match to targetPtSize). // 0 if nothing loaded. uint8_t currentPointSize() const { return loadedPointSize_; }; private: struct LoadedFont { SdCardFont* font; // heap-allocated, owned int fontId; uint8_t size; }; static int computeFontId(uint32_t contentHash, const char* familyName, uint8_t pointSize); std::string loadedFamilyName_; uint8_t loadedPointSize_ = 0; std::vector loaded_; };