Fix font loading: V1 support, V0 header fix, flexible discovery, doc cleanup
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user