#pragma once #include #include #include struct SdCardFontFileInfo { std::string path; // v4 on-disk naming: "/.crosspoint/fonts//_.cpfont" // e.g. "/.crosspoint/fonts/NotoSansCJK/NotoSansCJK_14.cpfont" uint8_t pointSize; // parsed from filename: 14 uint8_t style; // always 0 in v4 (all 4 styles bundled in one file); // kept for potential future formats }; struct SdCardFontFamilyInfo { std::string name; // directory name, e.g. "NotoSansCJK" std::vector files; const SdCardFontFileInfo* findFile(uint8_t size, uint8_t style = 0) const; bool hasSize(uint8_t size) const; std::vector availableSizes() const; }; class SdCardFontRegistry { public: static constexpr int MAX_SD_FAMILIES = 128; static constexpr const char* FONTS_DIR = "/.crosspoint/fonts"; // Scan SD card, populate families_. Returns true if any families found. bool discover(); const std::vector& getFamilies() const { return families_; } const SdCardFontFamilyInfo* findFamily(const std::string& name) const; int getFamilyIndex(const std::string& name) const; int getFamilyCount() const { return static_cast(families_.size()); } private: std::vector families_; // sorted alphabetically static bool parseFilename(const char* filename, uint8_t& size, uint8_t& style); void scanDirectory(const char* dirPath, SdCardFontFamilyInfo& family); };