- Fixed loading of folder based fonts and added a config lump per font.

This is done by putting a font.inf file into the folder.
Current options are "Kerning", "Scale", "FontHeight" and "SpaceWidth"

# Conflicts:
#	src/textures/textures.h
#	src/v_font.cpp

# Conflicts:
#	src/v_font.cpp
This commit is contained in:
Christoph Oelckers 2019-02-13 00:02:39 +01:00 committed by drfrag
parent 1252042e33
commit d8c13bed5e
3 changed files with 104 additions and 36 deletions

View file

@ -329,6 +329,11 @@ public:
}
void SetScaledSize(int fitwidth, int fitheight);
void SetScale(const DVector2 &scale)
{
Scale = scale;
}
PalEntry GetSkyCapColor(bool bottom);
static PalEntry averageColor(const uint32_t *data, int size, int maxout);

View file

@ -1098,7 +1098,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;
@ -1118,7 +1118,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;
@ -1130,12 +1131,74 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
FirstFont = this;
Cursor = '_';
ActiveColors = 0;
SpaceWidth = 0;
FontHeight = 0;
maxyoffs = 0;
TMap<int, FTexture*> 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<FolderEntry> 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++)
@ -1165,29 +1228,24 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
}
}
}
if (filetemplate != nullptr)
if (folderdata.Size() > 0)
{
TArray<FolderEntry> 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[lump]);
}
if ((int)position < minchar) minchar = (int)position;
if ((int)position > maxchar) maxchar = (int)position;
auto tex = TexMan[lump];
tex->SetScale(Scale);
charMap.Insert((int)position, tex);
}
}
}
@ -1197,6 +1255,7 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
LastChar = maxchar;
auto count = maxchar - minchar + 1;
Chars = new CharData[count];
int fontheight = 0;
for (i = 0; i < count; i++)
{
@ -1214,9 +1273,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;
}
}
@ -1230,19 +1289,23 @@ FFont::FFont (const char *name, const char *nametemplate, const char *filetempla
Chars[i].XMove = INT_MIN;
}
}
if (spacewidth != -1)
if (SpaceWidth == 0) // An explicit override from the .inf file must always take precedence
{
SpaceWidth = spacewidth;
}
else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].Pic != nullptr)
{
SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2;
}
else
{
SpaceWidth = 4;
if (spacewidth != -1)
{
SpaceWidth = spacewidth;
}
else if ('N'-FirstChar >= 0 && 'N'-FirstChar < count && Chars['N' - FirstChar].Pic != nullptr)
{
SpaceWidth = (Chars['N' - FirstChar].XMove + 1) / 2;
}
else
{
SpaceWidth = 4;
}
}
if (FontHeight == 0) FontHeight = fontheight;
FixXMoves();
@ -1577,7 +1640,7 @@ int FFont::GetCharCode(int code, bool needpic) const
return code;
}
// Special handling for the ß which may only exist as lowercase, so for this we need an additional upper -> lower check for all fonts aside from the generic substitution logic.
// Special handling for the ß which may only exist as lowercase, so for this we need an additional upper -> lower check for all fonts aside from the generic substitution logic.
if (code == 0x1e9e)
{
if (LastChar <= 0xdf && (!needpic || Chars[0xdf - FirstChar].Pic != nullptr))

View file

@ -1300,7 +1300,7 @@ unsigned FWadCollection::GetLumpsInFolder(const char *inpath, TArray<FolderEntry
// Delete everything from older files.
for (int i = result.Size() - 1; i >= 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);