- let the fonts use image sources, not textures as their base class for glyphs.

This commit is contained in:
Christoph Oelckers 2020-05-24 16:32:52 +02:00
parent be8813f962
commit 83e2a342d2
12 changed files with 115 additions and 105 deletions

View file

@ -734,7 +734,6 @@ set (PCH_SOURCES
core/fonts/singlelumpfont.cpp
core/fonts/v_font.cpp
core/fonts/v_text.cpp
core/fonts/fontchars.cpp
core/console/c_console.cpp
core/console/d_event.cpp
@ -754,6 +753,7 @@ set (PCH_SOURCES
common/textures/m_png.cpp
common/textures/image.cpp
common/textures/texturemanager.cpp
common/textures/formats/fontchars.cpp
common/textures/formats/automaptexture.cpp
common/textures/formats/brightmaptexture.cpp
common/textures/formats/buildtexture.cpp

View file

@ -71,9 +71,7 @@ int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion)
return 0;
}
#if 0
FTexture *CreateBrightmapTexture(FImageSource *tex)
{
return CreateImageTexture(new FBrightmapTexture(tex));
}
#endif

View file

@ -39,7 +39,7 @@
#include "image.h"
#include "imagehelpers.h"
#include "fontchars.h"
#include "printf.h"
#include "engineerrors.h"
//==========================================================================
//
@ -49,12 +49,13 @@
//
//==========================================================================
FFontChar1::FFontChar1 (FTexture *sourcelump)
FFontChar1::FFontChar1 (FImageSource *sourcelump)
: BaseTexture(sourcelump), SourceRemap (nullptr)
{
// now copy all the properties from the base texture
assert(BaseTexture != nullptr);
CopySize(BaseTexture);
CopySize(*BaseTexture);
bUseGamePalette = false;
}
//==========================================================================
@ -65,20 +66,21 @@ FFontChar1::FFontChar1 (FTexture *sourcelump)
//
//==========================================================================
void FFontChar1::Create8BitPixels (uint8_t *data)
TArray<uint8_t> FFontChar1::CreatePalettedPixels (int)
{
// Make the texture as normal, then remap it so that all the colors
// are at the low end of the palette
// Why? It only creates unnecessary work!
BaseTexture->Create8BitPixels(data);
auto Pixels = BaseTexture->GetPalettedPixels(normal);
if (SourceRemap)
{
for (int x = 0; x < GetWidth() * GetHeight(); ++x)
for (int x = 0; x < Width*Height; ++x)
{
data[x] = SourceRemap[data[x]];
Pixels[x] = SourceRemap[Pixels[x]];
}
}
return Pixels;
}
//==========================================================================
@ -89,13 +91,13 @@ void FFontChar1::Create8BitPixels (uint8_t *data)
//
//==========================================================================
FFontChar2::FFontChar2 (TArray<uint8_t>& sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
: sourceData (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr)
FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr)
{
Size.x = width;
Size.y = height;
leftoffset = leftofs;
topoffset = topofs;
Width = width;
Height = height;
LeftOffset = leftofs;
TopOffset = topofs;
}
//==========================================================================
@ -117,11 +119,10 @@ void FFontChar2::SetSourceRemap(const uint8_t *sourceremap)
//
//==========================================================================
void FFontChar2::Create8BitPixels(uint8_t *Pixels)
TArray<uint8_t> FFontChar2::CreatePalettedPixels(int)
{
FileReader lump;
lump.OpenMemory(sourceData.Data(), sourceData.Size());
int destSize = GetWidth() * GetHeight();
auto lump = fileSystem.OpenFileReader (SourceLump);
int destSize = Width * Height;
uint8_t max = 255;
bool rle = true;
@ -148,22 +149,24 @@ void FFontChar2::Create8BitPixels(uint8_t *Pixels)
}
}
TArray<uint8_t> Pixels(destSize, true);
int runlen = 0, setlen = 0;
uint8_t setval = 0; // Shut up, GCC!
uint8_t *dest_p = Pixels;
int dest_adv = GetHeight();
uint8_t *dest_p = Pixels.Data();
int dest_adv = Height;
int dest_rew = destSize - 1;
if (rle)
{
for (int y = GetHeight(); y != 0; --y)
for (int y = Height; y != 0; --y)
{
for (int x = GetWidth(); x != 0; )
for (int x = Width; x != 0; )
{
if (runlen != 0)
{
uint8_t color = lump.ReadUInt8();
color = std::min(color, max);
color = MIN (color, max);
if (SourceRemap != nullptr)
{
color = SourceRemap[color];
@ -191,7 +194,7 @@ void FFontChar2::Create8BitPixels(uint8_t *Pixels)
{
uint8_t color = lump.ReadUInt8();
setlen = (-code) + 1;
setval = std::min(color, max);
setval = MIN (color, max);
if (SourceRemap != nullptr)
{
setval = SourceRemap[setval];
@ -204,9 +207,9 @@ void FFontChar2::Create8BitPixels(uint8_t *Pixels)
}
else
{
for (int y = GetHeight(); y != 0; --y)
for (int y = Height; y != 0; --y)
{
for (int x = GetWidth(); x != 0; --x)
for (int x = Width; x != 0; --x)
{
uint8_t color = lump.ReadUInt8();
if (color > max)
@ -226,23 +229,11 @@ void FFontChar2::Create8BitPixels(uint8_t *Pixels)
if (destSize < 0)
{
I_Error ("The font %s is corrupt", GetName().GetChars());
char name[9];
fileSystem.GetFileShortName (name, SourceLump);
name[8] = 0;
I_FatalError ("The font %s is corrupt", name);
}
return Pixels;
}
FBitmap FFontChar2::GetBgraBitmap(const PalEntry* remap, int* ptrans)
{
FBitmap bmp;
TArray<uint8_t> buffer;
bmp.Create(Size.x, Size.y);
const uint8_t* ppix = Get8BitPixels();
if (!ppix)
{
// This is needed for tiles with a palette remap.
buffer.Resize(Size.x * Size.y);
Create8BitPixels(buffer.Data());
ppix = buffer.Data();
}
if (ppix) bmp.CopyPixelData(0, 0, ppix, Size.x, Size.y, Size.y, 1, 0, remap);
return bmp;
}

View file

@ -1,33 +1,32 @@
// This is a font character that loads a texture and recolors it.
class FFontChar1 : public FTexture
class FFontChar1 : public FImageSource
{
public:
FFontChar1 (FTexture *sourcelump);
void Create8BitPixels(uint8_t *) override;
FFontChar1 (FImageSource *sourcelump);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
void SetSourceRemap(const uint8_t *sourceremap) { SourceRemap = sourceremap; }
const uint8_t *ResetSourceRemap() { auto p = SourceRemap; SourceRemap = nullptr; return p; }
FTexture *GetBase() const { return BaseTexture; }
FImageSource *GetBase() const { return BaseTexture; }
protected:
FTexture *BaseTexture;
FImageSource *BaseTexture;
const uint8_t *SourceRemap;
};
// This is a font character that reads RLE compressed data.
class FFontChar2 : public FTexture
class FFontChar2 : public FImageSource
{
public:
FFontChar2 (TArray<uint8_t>& sourceData, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
void Create8BitPixels(uint8_t*) override;
FBitmap GetBgraBitmap(const PalEntry* remap, int* ptrans) override;
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
void SetSourceRemap(const uint8_t *sourceremap);
protected:
TArray<uint8_t>& sourceData;
int SourceLump;
int SourcePos;
const uint8_t *SourceRemap;
};

View file

@ -63,7 +63,7 @@ protected:
struct TexInit
{
FString TexName;
//ETextureType UseType = ETextureType::Null;
ETextureType UseType = ETextureType::Null;
FTexture *Texture = nullptr;
bool Silent = false;
bool HasLine = false;

View file

@ -128,11 +128,9 @@ private:
};
#if 0
FTexture *CreateShaderTexture(bool vertical, bool reverse)
{
FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f');
return CreateImageTexture(new FBarShader(vertical, reverse), name.GetChars());
}
#endif

View file

@ -191,3 +191,4 @@ public:
};
FTexture* CreateImageTexture(FImageSource* img, const char *name = nullptr) noexcept;

View file

@ -1311,7 +1311,7 @@ int FTextureManager::CountLumpTextures (int lumpnum)
void FTextureManager::AdjustSpriteOffsets()
{
int lump, lastlump = 0;
int /*lump,*/ lastlump = 0;
int sprid;
TMap<int, bool> donotprocess;

View file

@ -54,6 +54,7 @@
#include "imagehelpers.h"
#include "glbackend/glbackend.h"
#include "palettecontainer.h"
#include "textures.h"
#include "fontinternals.h"
@ -161,13 +162,12 @@ FFont *FFont::FindFont (FName name)
//
//==========================================================================
void RecordTextureColors (FTexture *pic, uint32_t *usedcolors)
void RecordTextureColors (FImageSource *pic, uint32_t *usedcolors)
{
auto size = pic->GetWidth() * pic->GetHeight();
TArray<uint8_t> pixels(size, 1);
int x;
pic->Create8BitPixels(pixels.Data());
auto pixels = pic->GetPalettedPixels(false);
auto size = pic->GetWidth() * pic->GetHeight();
for(x = 0;x < size; x++)
{
@ -190,7 +190,7 @@ void FFont::RecordAllTextureColors(uint32_t *usedcolors)
{
if (Chars[i].TranslatedPic)
{
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic);
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
if (pic)
{
// The remap must be temporarily reset here because this can be called on an initialized font.
@ -221,7 +221,8 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
SimpleTranslation(mycolors, mytranslation, myreverse, myluminosity);
SimpleTranslation(othercolors, othertranslation, otherreverse, otherluminosity);
FRemapTable remap;
FRemapTable remap(ActiveColors);
remap.Remap[0] = 0;
remap.Palette[0] = 0;
for (unsigned l = 1; l < myluminosity.Size(); l++)
@ -244,6 +245,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
remap.Remap[l] = ColorMatcher.Pick(r, g, b);
remap.Palette[l] = PalEntry(255, r, g, b);
break;
}
@ -568,10 +570,12 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red
if (redirected) *redirected = redirect;
if (redirect)
{
assert(Chars[code].OriginalPic->GetUseType() == ETextureType::FontChar);
return Chars[code].OriginalPic;
}
}
if (redirected) *redirected = false;
assert(Chars[code].TranslatedPic->GetUseType() == ETextureType::FontChar);
return Chars[code].TranslatedPic;
}
@ -600,8 +604,8 @@ double GetBottomAlignOffset(FFont *font, int c)
FTexture *tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
FTexture *texc = font->GetChar(c, CR_UNDEFINED, &w);
double offset = 0;
if (texc) offset += texc->GetTopOffset();
if (tex_zero) offset += -tex_zero->GetTopOffset() + tex_zero->GetHeight();
if (texc) offset += texc->GetDisplayTopOffset();
if (tex_zero) offset += -tex_zero->GetDisplayTopOffset() + tex_zero->GetDisplayHeight();
return offset;
}
@ -730,7 +734,7 @@ int FFont::GetMaxAscender(const uint8_t* string) const
auto ctex = GetChar(chr, CR_UNTRANSLATED, nullptr);
if (ctex)
{
auto offs = int(ctex->GetTopOffset());
auto offs = int(ctex->GetDisplayTopOffset());
if (offs > retval) retval = offs;
}
}
@ -756,7 +760,7 @@ void FFont::LoadTranslations()
{
if (Chars[i].TranslatedPic)
{
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic);
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
if (pic)
{
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
@ -770,7 +774,7 @@ void FFont::LoadTranslations()
for (unsigned int i = 0; i < count; i++)
{
if(Chars[i].TranslatedPic)
static_cast<FFontChar1 *>(Chars[i].TranslatedPic)->SetSourceRemap(PatchRemap);
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
}
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr);
@ -832,7 +836,7 @@ void FFont::FixXMoves()
}
if (Chars[i].OriginalPic)
{
int ofs = Chars[i].OriginalPic->GetTopOffset();
int ofs = Chars[i].OriginalPic->GetDisplayTopOffset();
if (ofs > Displacement) Displacement = ofs;
}
}

View file

@ -41,7 +41,7 @@
#include "v_draw.h"
#include "glbackend/glbackend.h"
#include "palettecontainer.h"
#include "buildtiles.h"
#include "texturemanager.h"
#include "fontinternals.h"
@ -90,12 +90,12 @@ struct HexDataSource
static HexDataSource hexdata;
// This is a font character that reads RLE compressed data.
class FHexFontChar : public FTileTexture
class FHexFontChar : public FImageSource
{
public:
FHexFontChar(uint8_t *sourcedata, int swidth, int width, int height);
void Create8BitPixels(uint8_t *buffer) override;
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
protected:
int SourceWidth;
@ -115,8 +115,10 @@ FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int heig
: SourceData (sourcedata)
{
SourceWidth = swidth;
Size.x = width;
Size.y = height;
Width = width;
Height = height;
LeftOffset = 0;
TopOffset = 0;
}
//==========================================================================
@ -127,33 +129,35 @@ FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int heig
//
//==========================================================================
void FHexFontChar::Create8BitPixels(uint8_t *Pixels)
TArray<uint8_t> FHexFontChar::CreatePalettedPixels(int)
{
int destSize = Size.x * Size.y;
uint8_t *dest_p = Pixels;
int destSize = Width * Height;
TArray<uint8_t> Pixels(destSize, true);
uint8_t *dest_p = Pixels.Data();
const uint8_t *src_p = SourceData;
memset(dest_p, 0, destSize);
for (int y = 0; y < Size.y; y++)
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < SourceWidth; x++)
{
int byte = *src_p++;
uint8_t *pixelstart = dest_p + 8 * x * Size.y + y;
uint8_t *pixelstart = dest_p + 8 * x * Height + y;
for (int bit = 0; bit < 8; bit++)
{
if (byte & (128 >> bit))
{
pixelstart[bit*Size.y] = y+2;
pixelstart[bit*Height] = y+2;
// Add a shadow at the bottom right, similar to the old console font.
if (y != Size.y - 1)
if (y != Height - 1)
{
pixelstart[bit*Size.y + Size.y + 1] = 1;
pixelstart[bit*Height + Height + 1] = 1;
}
}
}
}
}
return Pixels;
}
class FHexFontChar2 : public FHexFontChar
@ -161,7 +165,7 @@ class FHexFontChar2 : public FHexFontChar
public:
FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int height);
void Create8BitPixels(uint8_t* buffer) override;
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
};
@ -186,10 +190,11 @@ FHexFontChar2::FHexFontChar2(uint8_t *sourcedata, int swidth, int width, int hei
//
//==========================================================================
void FHexFontChar2::Create8BitPixels(uint8_t* Pixels)
TArray<uint8_t> FHexFontChar2::CreatePalettedPixels(int)
{
int destSize = Size.x * Size.y;
uint8_t *dest_p = Pixels;
int destSize = Width * Height;
TArray<uint8_t> Pixels(destSize, true);
uint8_t *dest_p = Pixels.Data();
assert(SourceData);
if (SourceData)
@ -197,17 +202,17 @@ void FHexFontChar2::Create8BitPixels(uint8_t* Pixels)
auto drawLayer = [&](int ix, int iy, int color)
{
const uint8_t *src_p = SourceData;
for (int y = 0; y < Size.y - 2; y++)
for (int y = 0; y < Height - 2; y++)
{
for (int x = 0; x < SourceWidth; x++)
{
int byte = *src_p++;
uint8_t *pixelstart = dest_p + (ix + 8 * x) * Size.y + (iy + y);
uint8_t *pixelstart = dest_p + (ix + 8 * x) * Height + (iy + y);
for (int bit = 0; bit < 8; bit++)
{
if (byte & (128 >> bit))
{
pixelstart[bit*Size.y] = color;
pixelstart[bit*Height] = color;
}
}
}
@ -221,6 +226,7 @@ void FHexFontChar2::Create8BitPixels(uint8_t* Pixels)
drawLayer(xx, yy, darkcolor);
drawLayer(1, 1, brightcolor);
}
return Pixels;
}
@ -281,9 +287,10 @@ public:
{
auto offset = hexdata.glyphmap[i];
int size = hexdata.glyphdata[offset] / 16;
Chars[i - FirstChar].TranslatedPic = new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16);
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar (&hexdata.glyphdata[offset+1], size, size * 9, 16));
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i - FirstChar].XMove = size * spacing;
TileFiles.AllTiles.Push(Chars[i - FirstChar].TranslatedPic); // store it in the tile list for automatic deletion.
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
}
else Chars[i - FirstChar].XMove = spacing;
@ -352,9 +359,10 @@ public:
{
auto offset = hexdata.glyphmap[i];
int size = hexdata.glyphdata[offset] / 16;
Chars[i - FirstChar].TranslatedPic = new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18);
Chars[i - FirstChar].TranslatedPic = new FImageTexture(new FHexFontChar2(&hexdata.glyphdata[offset + 1], size, 2 + size * 8, 18));
Chars[i - FirstChar].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i - FirstChar].XMove = size * spacing;
TileFiles.AllTiles.Push(Chars[i - FirstChar].TranslatedPic); // store it in the tile list for automatic deletion.
TexMan.AddTexture(Chars[i - FirstChar].TranslatedPic);
}
else Chars[i - FirstChar].XMove = spacing;
@ -377,7 +385,8 @@ public:
SimpleTranslation(colors, othertranslation, otherreverse, otherluminosity);
FRemapTable remap;
FRemapTable remap(ActiveColors);
remap.Remap[0] = 0;
remap.Palette[0] = 0;
for (unsigned l = 1; l < 18; l++)
@ -400,6 +409,7 @@ public:
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
remap.Remap[l] = ColorMatcher.Pick(r, g, b);
remap.Palette[l] = PalEntry(255, r, g, b);
break;
}

View file

@ -38,11 +38,11 @@
#include "v_font.h"
#include "utf8.h"
#include "fontchars.h"
#include "texturemanager.h"
#include "printf.h"
#include "imagehelpers.h"
#include "filesystem.h"
#include "colormatcher.h"
#include "buildtiles.h"
#include "fontinternals.h"
@ -201,7 +201,7 @@ void FSingleLumpFont::LoadTranslations()
for(unsigned int i = 0;i < count;++i)
{
if(Chars[i].TranslatedPic)
static_cast<FFontChar2*>(Chars[i].TranslatedPic)->SetSourceRemap(PatchRemap);
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
}
BuildTranslations (luminosity, useidentity ? identity : nullptr, ranges, ActiveColors, usepalette ? local_palette : nullptr);
@ -332,8 +332,9 @@ void FSingleLumpFont::LoadFON2 (const char * lump, const uint8_t *data)
}
else
{
Chars[i].TranslatedPic = new FFontChar2 (rawData, int(data_p - data), widths2[i], FontHeight);
TileFiles.AllTiles.Push(Chars[i].TranslatedPic);
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (fileSystem.FindFile(lump), int(data_p - data), widths2[i], FontHeight));
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
TexMan.AddTexture(Chars[i].TranslatedPic);
do
{
int8_t code = *data_p++;
@ -461,14 +462,15 @@ void FSingleLumpFont::LoadBMF(const char *lump, const uint8_t *data)
{ // Empty character: skip it.
continue;
}
auto tex = new FFontChar2(rawData, int(chardata + chari + 6 - data),
auto tex = new FImageTexture(new FFontChar2(fileSystem.FindFile(lump), int(chardata + chari + 6 - data),
chardata[chari+1], // width
chardata[chari+2], // height
-(int8_t)chardata[chari+3], // x offset
-(int8_t)chardata[chari+4] // y offset
);
));
tex->SetUseType(ETextureType::FontChar);
Chars[chardata[chari] - FirstChar].TranslatedPic = tex;
TileFiles.AllTiles.Push(tex);
TexMan.AddTexture(tex);
}
// If the font did not define a space character, determine a suitable space width now.
@ -533,9 +535,10 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
if(!Chars[i].TranslatedPic)
{
Chars[i].TranslatedPic = new FFontChar2 (rawData, int(data_p - data.Data()), SpaceWidth, FontHeight);
Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (0, int(data_p - data.Data()), SpaceWidth, FontHeight));
Chars[i].TranslatedPic->SetUseType(ETextureType::FontChar);
Chars[i].XMove = SpaceWidth;
TileFiles.AllTiles.Push(Chars[i].TranslatedPic);
TexMan.AddTexture(Chars[i].TranslatedPic);
}
// Advance to next char's data and count the used colors.

View file

@ -86,3 +86,9 @@ void FImageTexture::Create8BitPixels(uint8_t* buffer)
auto buf = mImage->GetPalettedPixels(FImageSource::normal);
memcpy(buffer, buf.Data(), buf.Size());
}
FTexture* CreateImageTexture(FImageSource* img, const char *name) noexcept
{
return new FImageTexture(img, name);
}