- 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); width = font->GetCharWidth((unsigned char) *str);
else else
width = font->GetCharWidth((unsigned char) script->spacingCharacter); 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. if(c == NULL) //missing character.
{ {
str++; str++;

View File

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

View File

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

View File

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

View File

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