From 056b2c3a800cc9155379e578bb7608466d105bf3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 14:25:30 +0100 Subject: [PATCH] - 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. --- src/g_statusbar/sbarinfo.cpp | 3 +- src/g_statusbar/shared_sbar.cpp | 2 +- src/intermission/intermission.cpp | 2 +- src/v_font.cpp | 151 +++++++++++++++++------------- src/v_font.h | 5 +- src/v_text.cpp | 14 ++- 6 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index aade1b1f9..7b1184cec 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -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++; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 1ed349d3a..12b66bf88 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -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; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index e4cd6ac30..4b3826261 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -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) diff --git a/src/v_font.cpp b/src/v_font.cpp index 4cccf32a4..e1e5998ba 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -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(Chars[i].Pic->GetImage()); + FFontChar1 *pic = static_cast(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(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(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(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(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(Chars[i].Pic->GetImage()); + FFontChar1 *pic = static_cast(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(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(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; } diff --git a/src/v_font.h b/src/v_font.h index 4bc20884e..b15790844 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -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 Chars; diff --git a/src/v_text.cpp b/src/v_text.cpp index e9a78bee4..ea977168f 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -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) {