- handle CR_UNTRANSLATED so that it doesn't force CR_UNTRANSLATED to the palette.

Since the entire font setup is very much incapable of handling this during rendering, short of a complete rewrite, it was necessary to put the relevant code into the places which process the characters for drawing so that it can disable the translation table (which needs to be passed as raw data to the draw functions) and keep track of both the translatable and the original variant of the character graphics.
This commit is contained in:
Christoph Oelckers 2018-12-15 14:25:30 +01:00
parent 48d87e3dcf
commit 056b2c3a80
6 changed files with 100 additions and 77 deletions

View file

@ -1379,7 +1379,8 @@ public:
width = font->GetCharWidth((unsigned char) *str);
else
width = font->GetCharWidth((unsigned char) script->spacingCharacter);
FTexture* c = font->GetChar((unsigned char) *str, &width);
bool redirected = false;
FTexture* c = font->GetChar((unsigned char) *str, fontcolor, &width);
if(c == NULL) //missing character.
{
str++;

View file

@ -1513,7 +1513,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
}
int width;
FTexture* c = font->GetChar((unsigned char)ch, &width);
FTexture* c = font->GetChar((unsigned char)ch, fontcolor, &width);
if (c == NULL) //missing character.
{
continue;

View file

@ -337,7 +337,7 @@ void DIntermissionScreenText::Drawer ()
continue;
}
pic = SmallFont->GetChar (c, &w);
pic = SmallFont->GetChar (c, mTextColor, &w);
w += kerning;
w *= CleanXfac;
if (cx + w > SCREENWIDTH)

View file

@ -195,7 +195,7 @@ extern int PrintColors[];
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FFont *FFont::FirstFont = NULL;
FFont *FFont::FirstFont = nullptr;
int NumTextColors;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -266,7 +266,7 @@ static int stripaccent(int code)
FFont *V_GetFont(const char *name)
{
FFont *font = FFont::FindFont (name);
if (font == NULL)
if (font == nullptr)
{
int lump = -1;
@ -285,7 +285,7 @@ FFont *V_GetFont(const char *name)
font = new FSingleLumpFont (name, lump);
}
}
if (font == NULL)
if (font == nullptr)
{
FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any);
if (picnum.isValid())
@ -327,13 +327,15 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
FirstFont = this;
Cursor = '_';
ActiveColors = 0;
uint8_t pp = 0;
for (auto &p : PatchRemap) p = pp++;
translateUntranslated = false;
maxyoffs = 0;
for (i = 0; i < count; i++)
{
charLumps[i] = NULL;
charLumps[i] = nullptr;
mysnprintf (buffer, countof(buffer), nametemplate, i + start);
lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch);
@ -356,7 +358,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
if (lump.isValid())
{
FTexture *pic = TexMan.GetTexture(lump);
if (pic != NULL)
if (pic != nullptr)
{
// set the lump here only if it represents a valid texture
if (i != 124-start || !stcfn121)
@ -379,17 +381,20 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
if (charLumps[i] != nullptr)
{
Chars[i].OriginalPic = charLumps[i];
if (!noTranslate)
{
Chars[i].Pic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()));
TexMan.AddTexture(Chars[i].Pic);
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), "");
TexMan.AddTexture(Chars[i].TranslatedPic);
}
else Chars[i].Pic = charLumps[i];
Chars[i].XMove = Chars[i].Pic->GetDisplayWidth();
else Chars[i].TranslatedPic = charLumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth();
}
else
{
Chars[i].Pic = NULL;
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].XMove = INT_MIN;
}
}
@ -398,7 +403,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
{
SpaceWidth = spacewidth;
}
else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr)
{
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
}
@ -423,13 +428,13 @@ FFont::~FFont ()
FFont **prev = &FirstFont;
FFont *font = *prev;
while (font != NULL && font != this)
while (font != nullptr && font != this)
{
prev = &font->Next;
font = *prev;
}
if (font != NULL)
if (font != nullptr)
{
*prev = font->Next;
}
@ -593,10 +598,10 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
{
if (i == CR_UNTRANSLATED)
{
if (identity != NULL)
if (identity != nullptr)
{
memcpy (remap.Remap, identity, ActiveColors);
if (palette != NULL)
if (palette != nullptr)
{
memcpy (remap.Palette, palette, ActiveColors*sizeof(PalEntry));
}
@ -677,7 +682,7 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range, PalEntry *color) con
if (color != nullptr) *color = retcolor;
}
if (ActiveColors == 0)
return NULL;
return nullptr;
else if (range >= NumTextColors)
range = CR_UNTRANSLATED;
//if (range == CR_UNTRANSLATED && !translateUntranslated) return nullptr;
@ -701,7 +706,7 @@ int FFont::GetCharCode(int code, bool needpic) const
// regular chars turn negative when the 8th bit is set.
code &= 255;
}
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr))
{
return code;
}
@ -709,7 +714,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (myislower(code))
{
code -= 32;
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr))
{
return code;
}
@ -719,7 +724,7 @@ int FFont::GetCharCode(int code, bool needpic) const
if (newcode != code)
{
code = newcode;
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr))
{
return code;
}
@ -733,7 +738,7 @@ int FFont::GetCharCode(int code, bool needpic) const
//
//==========================================================================
FTexture *FFont::GetChar (int code, int *const width) const
FTexture *FFont::GetChar (int code, int translation, int *const width, bool *redirected) const
{
code = GetCharCode(code, false);
int xmove = SpaceWidth;
@ -742,7 +747,7 @@ FTexture *FFont::GetChar (int code, int *const width) const
{
code -= FirstChar;
xmove = Chars[code].XMove;
if (Chars[code].Pic == NULL)
if (Chars[code].OriginalPic == nullptr)
{
code = GetCharCode(code + FirstChar, true);
if (code >= 0)
@ -752,11 +757,21 @@ FTexture *FFont::GetChar (int code, int *const width) const
}
}
}
if (width != NULL)
if (width != nullptr)
{
*width = xmove;
}
return (code < 0) ? NULL : Chars[code].Pic;
if (code < 0) return nullptr;
if (translation == CR_UNTRANSLATED)
{
if (redirected)
*redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic;
return Chars[code].OriginalPic;
}
if (redirected) *redirected = false;
return Chars[code].TranslatedPic;
}
//==========================================================================
@ -780,8 +795,8 @@ int FFont::GetCharWidth (int code) const
double GetBottomAlignOffset(FFont *font, int c)
{
int w;
FTexture *tex_zero = font->GetChar('0', &w);
FTexture *texc = font->GetChar(c, &w);
FTexture *tex_zero = font->GetChar('0', CR_UNDEFINED, &w);
FTexture *texc = font->GetChar(c, CR_UNDEFINED, &w);
double offset = 0;
if (texc) offset += texc->GetDisplayTopOffsetDouble();
if (tex_zero) offset += -tex_zero->GetDisplayTopOffsetDouble() + tex_zero->GetDisplayHeightDouble();
@ -848,12 +863,12 @@ void FFont::LoadTranslations()
memset (usedcolors, 0, 256);
for (unsigned int i = 0; i < count; i++)
{
if (Chars[i].Pic)
if (Chars[i].TranslatedPic)
{
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].Pic->GetImage());
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
if (pic)
{
pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
RecordTextureColors(pic, usedcolors);
}
}
@ -865,11 +880,11 @@ void FFont::LoadTranslations()
for (unsigned int i = 0; i < count; i++)
{
if(Chars[i].Pic)
static_cast<FFontChar1 *>(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap);
if(Chars[i].TranslatedPic)
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
}
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, NULL);
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, nullptr);
}
//==========================================================================
@ -946,7 +961,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
FirstChar = LastChar = 'A';
Chars.Resize(1);
Chars[0].Pic = pic;
Chars[0].TranslatedPic = Chars[0].OriginalPic = pic;
// Only one color range. Don't bother with the others.
ActiveColors = 0;
@ -992,11 +1007,11 @@ void FSingleLumpFont::LoadTranslations()
for(unsigned int i = 0;i < count;++i)
{
if(Chars[i].Pic)
static_cast<FFontChar2*>(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap);
if(Chars[i].TranslatedPic)
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
}
BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL);
BuildTranslations (luminosity, useidentity ? identity : nullptr, ranges, ActiveColors, usepalette ? local_palette : nullptr);
}
//==========================================================================
@ -1025,7 +1040,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
translateUntranslated = true;
for(unsigned int i = 0;i < 256;++i)
Chars[i].Pic = nullptr;
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
LoadTranslations();
}
@ -1111,12 +1126,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
Chars[i].XMove = widths2[i];
if (destSize <= 0)
{
Chars[i].Pic = NULL;
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
}
else
{
Chars[i].Pic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
TexMan.AddTexture(Chars[i].Pic);
Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight));
TexMan.AddTexture(Chars[i].OriginalPic);
do
{
int8_t code = *data_p++;
@ -1201,7 +1216,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
Chars.Resize(count);
for (i = 0; i < count; ++i)
{
Chars[i].Pic = NULL;
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].XMove = INT_MIN;
}
@ -1256,7 +1271,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
-(int8_t)chardata[chari+3], // x offset
-(int8_t)chardata[chari+4] // y offset
));
Chars[chardata[chari] - FirstChar].Pic = tex;
Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex;
TexMan.AddTexture(tex);
}
@ -1320,12 +1335,13 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
{
int destSize = SpaceWidth * FontHeight;
if(!Chars[i].Pic)
if(!Chars[i].OriginalPic)
{
Chars[i].Pic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight));
Chars[i].XMove = SpaceWidth;
TexMan.AddTexture(Chars[i].Pic);
TexMan.AddTexture(Chars[i].OriginalPic);
}
Chars[i].TranslatedPic = Chars[i].OriginalPic;
// Advance to next char's data and count the used colors.
do
@ -1454,7 +1470,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) :
//
// FSinglePicFont :: GetChar
//
// Returns the texture if code is 'a' or 'A', otherwise NULL.
// Returns the texture if code is 'a' or 'A', otherwise nullptr.
//
//==========================================================================
@ -1467,7 +1483,7 @@ FTexture *FSinglePicFont::GetChar (int code, int *const width) const
}
else
{
return NULL;
return nullptr;
}
}
@ -1534,23 +1550,24 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
if (charlumps[i] != nullptr)
{
Chars[i].OriginalPic = charlumps[i];
if (!noTranslate)
{
Chars[i].Pic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()));
TexMan.AddTexture(Chars[i].Pic);
Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), "");
TexMan.AddTexture(Chars[i].TranslatedPic);
}
else Chars[i].Pic = charlumps[i];
Chars[i].XMove = Chars[i].Pic->GetDisplayWidth();
else Chars[i].TranslatedPic = charlumps[i];
Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth();
}
else
{
Chars[i].Pic = NULL;
Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr;
Chars[i].XMove = INT_MIN;
}
}
// Special fonts normally don't have all characters so be careful here!
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr)
{
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
}
@ -1588,12 +1605,12 @@ void FSpecialFont::LoadTranslations()
memset (usedcolors, 0, 256);
for (i = 0; i < count; i++)
{
if (Chars[i].Pic)
if (Chars[i].TranslatedPic)
{
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].Pic->GetImage());
FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage());
if (pic)
{
pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture
pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture
RecordTextureColors(pic, usedcolors);
}
}
@ -1619,11 +1636,11 @@ void FSpecialFont::LoadTranslations()
for (i = 0; i < count; i++)
{
if(Chars[i].Pic)
static_cast<FFontChar1 *>(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap);
if(Chars[i].TranslatedPic)
static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap);
}
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, NULL);
BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr);
// add the untranslated colors to the Ranges tables
if (ActiveColors < TotalColors)
@ -1809,7 +1826,7 @@ void V_InitCustomFonts()
{
for (i = 0; i < 256; i++)
{
if (lumplist[i] != NULL)
if (lumplist[i] != nullptr)
{
first = i;
break;
@ -1817,7 +1834,7 @@ void V_InitCustomFonts()
}
for (i = 255; i >= 0; i--)
{
if (lumplist[i] != NULL)
if (lumplist[i] != nullptr)
{
count = i - first + 1;
break;
@ -1921,19 +1938,19 @@ void V_InitFontColors ()
else if (sc.Compare ("Flat:"))
{
sc.MustGetString();
logcolor = V_GetColor (NULL, sc);
logcolor = V_GetColor (nullptr, sc);
}
else
{
// Get first color
c = V_GetColor (NULL, sc);
c = V_GetColor (nullptr, sc);
tparm.Start[0] = RPART(c);
tparm.Start[1] = GPART(c);
tparm.Start[2] = BPART(c);
// Get second color
sc.MustGetString();
c = V_GetColor (NULL, sc);
c = V_GetColor (nullptr, sc);
tparm.End[0] = RPART(c);
tparm.End[1] = GPART(c);
tparm.End[2] = BPART(c);
@ -2261,7 +2278,7 @@ void V_InitFonts()
{
IntermissionFont = FFont::FindFont("IntermissionFont_Doom");
}
if (IntermissionFont == NULL)
if (IntermissionFont == nullptr)
{
IntermissionFont = BigFont;
}
@ -2270,11 +2287,11 @@ void V_InitFonts()
void V_ClearFonts()
{
while (FFont::FirstFont != NULL)
while (FFont::FirstFont != nullptr)
{
delete FFont::FirstFont;
}
FFont::FirstFont = NULL;
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL;
FFont::FirstFont = nullptr;
SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr;
}

View file

@ -82,7 +82,7 @@ public:
FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false);
virtual ~FFont ();
FTexture *GetChar (int code, int *const width) const;
FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
virtual int GetCharWidth (int code) const;
FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
int GetLump() const { return Lump; }
@ -123,7 +123,8 @@ protected:
bool translateUntranslated;
struct CharData
{
FTexture *Pic;
FTexture *TranslatedPic; // Texture for use with font translations.
FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization.
int XMove;
};
TArray<CharData> Chars;

View file

@ -139,8 +139,9 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i
FTexture *pic;
int dummy;
bool redirected;
if (NULL != (pic = font->GetChar (character, &dummy)))
if (NULL != (pic = font->GetChar (character, normalcolor, &dummy, &redirected)))
{
DrawParms parms;
Va_List tags;
@ -152,7 +153,7 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i
return;
}
PalEntry color = 0xffffffff;
parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.remap = redirected? nullptr : font->GetColorTranslation((EColorRange)normalcolor, &color);
parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255);
DrawTextureParms(pic, parms);
}
@ -169,7 +170,7 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in
FTexture *pic;
int dummy;
if (NULL != (pic = font->GetChar(character, &dummy)))
if (NULL != (pic = font->GetChar(character, normalcolor, &dummy)))
{
DrawParms parms;
uint32_t tag = ListGetInt(args);
@ -238,6 +239,7 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
cy = y;
auto currentcolor = normalcolor;
while ((const char *)ch - string < parms.maxstrlen)
{
c = GetCharFromString(ch);
@ -251,6 +253,7 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
{
range = font->GetColorTranslation(newcolor, &color);
parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255);
currentcolor = newcolor;
}
continue;
}
@ -262,9 +265,10 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double
continue;
}
if (NULL != (pic = font->GetChar(c, &w)))
bool redirected = false;
if (NULL != (pic = font->GetChar(c, currentcolor, &w, &redirected)))
{
parms.remap = range;
parms.remap = redirected? nullptr : range;
SetTextureParms(&parms, pic, cx, cy);
if (parms.cellx)
{