diff --git a/src/gamedata/textures/textures.h b/src/gamedata/textures/textures.h index f23d3c3d6b5..42affa0366d 100644 --- a/src/gamedata/textures/textures.h +++ b/src/gamedata/textures/textures.h @@ -482,6 +482,10 @@ class FTexture } void SetScaledSize(int fitwidth, int fitheight); + void SetScale(const DVector2 &scale) + { + Scale = scale; + } protected: uint16_t Width, Height; diff --git a/src/gamedata/w_wad.cpp b/src/gamedata/w_wad.cpp index 3ef9a7640f5..d20eebe2345 100644 --- a/src/gamedata/w_wad.cpp +++ b/src/gamedata/w_wad.cpp @@ -1315,7 +1315,7 @@ unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray= 0; i--) { - if ((int)result[i].lumpnum != maxfile) result.Delete(i); + if (Wads.GetLumpFile(result[i].lumpnum) != maxfile) result.Delete(i); } } qsort(result.Data(), result.Size(), sizeof(FolderEntry), folderentrycmp); diff --git a/src/v_font.cpp b/src/v_font.cpp index 598f7d6ea21..d8899676693 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1000,7 +1000,7 @@ FFont *V_GetFont(const char *name, const char *fontlumpname) } if (folderdata.Size() > 0) { - return new FFont(name, nullptr, path, HU_FONTSTART, HU_FONTSIZE, 1, -1); + return new FFont(name, nullptr, name, HU_FONTSTART, HU_FONTSIZE, 1, -1); } } return font; @@ -1020,7 +1020,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla FTextureID lump; char buffer[12]; int maxyoffs; - bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false; + bool doomtemplate = (nametemplate && (gameinfo.gametype & GAME_DoomChex)) ? strncmp (nametemplate, "STCFN", 5) == 0 : false; + DVector2 Scale = { 1, 1 }; noTranslate = notranslate; Lump = fdlump; @@ -1031,6 +1032,8 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla FirstFont = this; Cursor = '_'; ActiveColors = 0; + SpaceWidth = 0; + FontHeight = 0; uint8_t pp = 0; for (auto &p : PatchRemap) p = pp++; translateUntranslated = false; @@ -1040,6 +1043,66 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla TMap charMap; int minchar = INT_MAX; int maxchar = INT_MIN; + + // Read the font's configuration. + // This will not be done for the default fonts, because they are not atomic and the default content does not need it. + + TArray folderdata; + if (filetemplate != nullptr) + { + FStringf path("fonts/%s/", filetemplate); + // If a name template is given, collect data from all resource files. + // For anything else, each folder is being treated as an atomic, self-contained unit and mixing from different glyph sets is blocked. + Wads.GetLumpsInFolder(path, folderdata, nametemplate == nullptr); + + if (nametemplate == nullptr) + { + // Only take font.inf from the actual folder we are processing but not from an older folder that may have been superseded. + FStringf infpath("fonts/%s/font.inf", filetemplate); + + unsigned index = folderdata.FindEx([=](const FolderEntry &entry) + { + return infpath.CompareNoCase(entry.name) == 0; + }); + + if (index < folderdata.Size()) + { + FScanner sc; + sc.OpenLumpNum(folderdata[index].lumpnum); + while (sc.GetToken()) + { + sc.TokenMustBe(TK_Identifier); + if (sc.Compare("Kerning")) + { + sc.MustGetValue(false); + GlobalKerning = sc.Number; + } + else if (sc.Compare("Scale")) + { + sc.MustGetValue(true); + Scale.Y = Scale.X = sc.Float; + if (sc.CheckToken(',')) + { + sc.MustGetValue(true); + Scale.Y = sc.Float; + } + } + else if (sc.Compare("SpaceWidth")) + { + sc.MustGetValue(false); + SpaceWidth = sc.Number; + } + else if (sc.Compare("FontHeight")) + { + sc.MustGetValue(false); + FontHeight = sc.Number; + } + } + } + } + } + + if (nametemplate != nullptr) { for (i = 0; i < lcount; i++) @@ -1069,29 +1132,24 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla } } } - if (filetemplate != nullptr) + if (folderdata.Size() > 0) { - TArray folderdata; - FStringf path("fonts/%s/", filetemplate); - // If a name template is given, collect data from all resource files. - // For anything else, each folder is being treated as an atomic, self-contained unit and mixing from different glyph sets is blocked. - if (Wads.GetLumpsInFolder(path, folderdata, nametemplate == nullptr)) + // all valid lumps must be named with a hex number that represents its Unicode character index. + for (auto &entry : folderdata) { - // all valid lumps must be named with a hex number that represents its Unicode character index. - for (auto &entry : folderdata) + char *endp; + auto base = ExtractFileBase(entry.name); + auto position = strtoll(base.GetChars(), &endp, 16); + if ((*endp == 0 || (*endp == '.' && position >= '!' && position < 0xffff))) { - char *endp; - auto base = ExtractFileBase(entry.name); - auto position = strtoll(base.GetChars(), &endp, 16); - if ((*endp == 0 || (*endp == '.' && position >= '!' && position < 0xffff))) + auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch); + if (lump.isValid()) { - auto lump = TexMan.CheckForTexture(entry.name, ETextureType::MiscPatch); - if (lump.isValid()) - { - if ((int)position < minchar) minchar = (int)position; - if ((int)position > maxchar) maxchar = (int)position; - charMap.Insert((int)position, TexMan.GetTexture(lump)); - } + if ((int)position < minchar) minchar = (int)position; + if ((int)position > maxchar) maxchar = (int)position; + auto tex = TexMan.GetTexture(lump); + tex->SetScale(Scale); + charMap.Insert((int)position, tex); } } } @@ -1101,6 +1159,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla LastChar = maxchar; auto count = maxchar - minchar + 1; Chars.Resize(count); + int fontheight = 0; for (i = 0; i < count; i++) { @@ -1118,9 +1177,9 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla maxyoffs = yoffs; } height += abs(yoffs); - if (height > FontHeight) + if (height > fontheight) { - FontHeight = height; + fontheight = height; } } @@ -1146,19 +1205,23 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla Chars[i].XMove = INT_MIN; } } - - if (spacewidth != -1) - { - SpaceWidth = spacewidth; - } - else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].TranslatedPic != nullptr) - { - SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2; - } - else + + if (SpaceWidth == 0) // An explicit override from the .inf file must always take precedence { - SpaceWidth = 4; + if (spacewidth != -1) + { + SpaceWidth = spacewidth; + } + else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].TranslatedPic != nullptr) + { + SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2; + } + else + { + SpaceWidth = 4; + } } + if (FontHeight == 0) FontHeight = fontheight; FixXMoves(); @@ -2430,7 +2493,7 @@ void FFont::FixXMoves() // Try an uppercase character. if (myislower(i + FirstChar)) { - int upper = i - 32; + int upper = upperforlower[FirstChar + i]; if (upper >= 0) { Chars[i].XMove = Chars[upper].XMove;