Fix font loading: V1 support, V0 header fix, flexible discovery, doc cleanup

This commit is contained in:
Antigravity Agent
2026-01-20 12:52:53 -05:00
parent 6f05731189
commit 0a3a2cef5d
8 changed files with 260 additions and 100 deletions

View File

@@ -56,10 +56,21 @@ void FontManager::scanFonts() {
String name = String(filename);
if (name.endsWith(".epdfont")) {
// Expected format: Family-Style-Size.epdfont
int firstDash = name.indexOf('-');
if (firstDash > 0) {
String family = name.substring(0, firstDash);
// Expected format: Family-Style-Size.epdfont or Family_Size.epdfont
// Or just Family.epdfont (V1 single file)
String family;
int separator = name.indexOf('-');
if (separator < 0) separator = name.indexOf('_');
if (separator > 0) {
family = name.substring(0, separator);
} else {
// No separator, take the whole name (minus .epdfont)
family = name.substring(0, name.length() - 8);
}
if (family.length() > 0) {
if (std::find(availableFamilies.begin(), availableFamilies.end(), family.c_str()) ==
availableFamilies.end()) {
availableFamilies.push_back(family.c_str());
@@ -124,23 +135,83 @@ CustomEpdFont* loadFontFile(const String& path) {
return nullptr;
}
uint32_t intervalCount = buf[1];
uint32_t fileSize = buf[2];
uint32_t height = buf[3];
uint32_t glyphCount = buf[4];
int32_t ascender = (int32_t)buf[5];
int32_t descender = (int32_t)buf[7];
Serial.printf("[FontMgr] Header Dump %s: ", path.c_str());
for (int i = 0; i < 12; i++) Serial.printf("%08X ", buf[i]);
Serial.println();
uint32_t offsetIntervals = buf[9];
uint32_t offsetGlyphs = buf[10];
uint32_t offsetBitmaps = buf[11];
/*
* Version Detection Improved
*
* V1:
* Offset 20 (buf[5]) is OffsetIntervals. It matches header size = 32.
* Offset 4 (buf[1]) low 16 bits is Version = 1.
*
* V0:
* Offset 36 (buf[9]) is OffsetIntervals. It matches header size = 48.
*/
Serial.printf("[FontMgr] parsed header: intv=%u, glyphs=%u, fileSz=%u, h=%u, asc=%d, desc=%d\n", intervalCount,
glyphCount, fileSize, height, ascender, descender);
Serial.printf("[FontMgr] offsets: intv=%u, gly=%u, bmp=%u\n", offsetIntervals, offsetGlyphs, offsetBitmaps);
int version = -1;
// Check for V1
if (buf[5] == 32 && (buf[1] & 0xFFFF) == 1) {
version = 1;
}
// Check for V0
else if (buf[9] == 48) {
version = 0;
}
// Fallback: Use the old file size check if offsets are weird (detected from legacy files?)
else if (buf[2] > 10000) {
// V0 has fileSize at offset 8 (buf[2])
version = 0;
}
uint32_t intervalCount, fileSize, glyphCount, offsetIntervals, offsetGlyphs, offsetBitmaps;
uint8_t height, advanceY;
int32_t ascender, descender;
bool is2Bit;
if (version == 1) {
// V1 Parsing
uint8_t* b8 = (uint8_t*)buf;
is2Bit = (b8[6] != 0);
advanceY = b8[8];
ascender = (int8_t)b8[9];
descender = (int8_t)b8[10];
intervalCount = b8[12] | (b8[13] << 8) | (b8[14] << 16) | (b8[15] << 24);
glyphCount = b8[16] | (b8[17] << 8) | (b8[18] << 16) | (b8[19] << 24);
offsetIntervals = b8[20] | (b8[21] << 8) | (b8[22] << 16) | (b8[23] << 24);
offsetGlyphs = b8[24] | (b8[25] << 8) | (b8[26] << 16) | (b8[27] << 24);
offsetBitmaps = b8[28] | (b8[29] << 8) | (b8[30] << 16) | (b8[31] << 24);
height = advanceY;
fileSize = 0; // Unknown
} else if (version == 0) {
// V0 Parsing
// We already read 48 bytes into buf
intervalCount = buf[1];
fileSize = buf[2];
height = buf[3];
glyphCount = buf[4];
ascender = (int32_t)buf[5];
descender = (int32_t)buf[7];
is2Bit = (buf[8] != 0);
offsetIntervals = buf[9];
offsetGlyphs = buf[10];
offsetBitmaps = buf[11];
} else {
Serial.printf("[FontMgr] Unknown version for %s\n", path.c_str());
f.close();
return nullptr;
}
// Validation
if (offsetIntervals >= fileSize || offsetGlyphs >= fileSize || offsetBitmaps >= fileSize) {
// For V1, we trust offsets generated by the tool
if (offsetIntervals == 0 || offsetGlyphs == 0 || offsetBitmaps == 0) {
Serial.println("[FontMgr] Invalid offsets in header");
f.close();
return nullptr;
@@ -178,11 +249,10 @@ CustomEpdFont* loadFontFile(const String& path) {
fontData->advanceY = (uint8_t)height;
fontData->ascender = ascender;
fontData->descender = descender;
fontData->descender = descender;
fontData->is2Bit = (buf[8] != 0);
fontData->is2Bit = is2Bit;
fontData->bitmap = nullptr;
return new CustomEpdFont(path, fontData, offsetIntervals, offsetGlyphs, offsetBitmaps);
return new CustomEpdFont(path, fontData, offsetIntervals, offsetGlyphs, offsetBitmaps, version);
}
EpdFontFamily* FontManager::getCustomFontFamily(const std::string& familyName, int fontSize) {
@@ -194,9 +264,29 @@ EpdFontFamily* FontManager::getCustomFontFamily(const std::string& familyName, i
String sizeStr = String(fontSize);
CustomEpdFont* regular = loadFontFile(basePath + "Regular-" + sizeStr + ".epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Regular_" + sizeStr + ".epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + "_" + sizeStr + ".epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + ".epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + "-Regular.epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Regular.epdfont");
if (!regular) regular = loadFontFile("/fonts/" + String(familyName.c_str()) + "-" + sizeStr + ".epdfont");
CustomEpdFont* bold = loadFontFile(basePath + "Bold-" + sizeStr + ".epdfont");
if (!bold) bold = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Bold_" + sizeStr + ".epdfont");
if (!bold) bold = loadFontFile("/fonts/" + String(familyName.c_str()) + "-Bold.epdfont");
if (!bold) bold = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Bold.epdfont");
CustomEpdFont* italic = loadFontFile(basePath + "Italic-" + sizeStr + ".epdfont");
if (!italic) italic = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Italic_" + sizeStr + ".epdfont");
if (!italic) italic = loadFontFile("/fonts/" + String(familyName.c_str()) + "-Italic.epdfont");
if (!italic) italic = loadFontFile("/fonts/" + String(familyName.c_str()) + "_Italic.epdfont");
CustomEpdFont* boldItalic = loadFontFile(basePath + "BoldItalic-" + sizeStr + ".epdfont");
if (!boldItalic)
boldItalic = loadFontFile("/fonts/" + String(familyName.c_str()) + "_BoldItalic_" + sizeStr + ".epdfont");
if (!boldItalic) boldItalic = loadFontFile("/fonts/" + String(familyName.c_str()) + "-BoldItalic.epdfont");
if (!boldItalic) boldItalic = loadFontFile("/fonts/" + String(familyName.c_str()) + "_BoldItalic.epdfont");
if (!regular) {
if (bold) regular = bold;