From 9769f346eca70e7fceee3e0eaa656559786b9842 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 24 May 2021 19:01:35 +0200 Subject: [PATCH] - refactored the special fonts away from BuildTranslation so that this function and the entire large heap of ugly baggage it drags in can finally be deleted. Function is gone, baggage will come next. --- source/common/fonts/font.cpp | 96 ----------------------------- source/common/fonts/fontinternals.h | 1 - source/common/fonts/specialfont.cpp | 85 ++++++++++++------------- source/common/fonts/v_font.h | 3 +- 4 files changed, 41 insertions(+), 144 deletions(-) diff --git a/source/common/fonts/font.cpp b/source/common/fonts/font.cpp index d8dbc5045..2f1016b19 100644 --- a/source/common/fonts/font.cpp +++ b/source/common/fonts/font.cpp @@ -750,102 +750,6 @@ int FFont::SimpleTranslation (uint32_t *colorsused, uint8_t *translation, uint8_ return j; } -//========================================================================== -// -// FFont :: BuildTranslations -// -// Build color translations for this font. Luminosity is an array of -// brightness levels. The ActiveColors member must be set to indicate how -// large this array is. Identity is an array that remaps the colors to -// their original values; it is only used for CR_UNTRANSLATED. Ranges -// is an array of TranslationParm structs defining the ranges for every -// possible color, in order. Palette is the colors to use for the -// untranslated version of the font. -// -//========================================================================== - -void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity, - const void *ranges, int total_colors, const PalEntry *palette, std::function post) -{ - int i, j; - const TranslationParm *parmstart = (const TranslationParm *)ranges; - - FRemapTable remap(total_colors); - remap.ForFont = true; - - // Create different translations for different color ranges - Translations.Clear(); - for (i = 0; i < NumTextColors; i++) - { - if (i == CR_UNTRANSLATED) - { - if (identity != nullptr) - { - memcpy(remap.Remap, identity, ActiveColors); - if (palette != nullptr) - { - memcpy(remap.Palette, palette, ActiveColors * sizeof(PalEntry)); - } - else - { - remap.Palette[0] = GPalette.BaseColors[identity[0]] & MAKEARGB(0, 255, 255, 255); - for (j = 1; j < ActiveColors; ++j) - { - remap.Palette[j] = GPalette.BaseColors[identity[j]] | MAKEARGB(255, 0, 0, 0); - } - } - Translations.Push(GPalette.StoreTranslation(TRANSLATION_Internal, &remap)); - } - else - { - Translations.Push(Translations[0]); - } - continue; - } - - assert(parmstart->RangeStart >= 0); - - remap.Remap[0] = 0; - remap.Palette[0] = 0; - remap.ForFont = true; - - for (j = 1; j < ActiveColors; j++) - { - int v = int(luminosity[j] * 256.0); - - // Find the color range that this luminosity value lies within. - const TranslationParm *parms = parmstart - 1; - do - { - parms++; - if (parms->RangeStart <= v && parms->RangeEnd >= v) - break; - } - while (parms[1].RangeStart > parms[0].RangeEnd); - - // Linearly interpolate to find out which color this luminosity level gets. - int rangev = ((v - parms->RangeStart) << 8) / (parms->RangeEnd - parms->RangeStart); - int r = ((parms->Start[0] << 8) + rangev * (parms->End[0] - parms->Start[0])) >> 8; // red - int g = ((parms->Start[1] << 8) + rangev * (parms->End[1] - parms->Start[1])) >> 8; // green - int b = ((parms->Start[2] << 8) + rangev * (parms->End[2] - parms->Start[2])) >> 8; // blue - r = clamp(r, 0, 255); - g = clamp(g, 0, 255); - b = clamp(b, 0, 255); - remap.Remap[j] = ColorMatcher.Pick(r, g, b); - remap.Palette[j] = PalEntry(255,r,g,b); - } - if (post) post(&remap); - Translations.Push(GPalette.StoreTranslation(TRANSLATION_Internal, &remap)); - - // Advance to the next color range. - while (parmstart[1].RangeStart > parmstart[0].RangeEnd) - { - parmstart++; - } - parmstart++; - } -} - //========================================================================== // // FFont :: GetColorTranslation diff --git a/source/common/fonts/fontinternals.h b/source/common/fonts/fontinternals.h index dc942319e..b74750c57 100644 --- a/source/common/fonts/fontinternals.h +++ b/source/common/fonts/fontinternals.h @@ -3,7 +3,6 @@ #include #include "tarray.h" -// This structure is used by BuildTranslations() to hold color information. struct TranslationParm { short RangeStart; // First level for this range diff --git a/source/common/fonts/specialfont.cpp b/source/common/fonts/specialfont.cpp index d57efda02..f5ddba1e7 100644 --- a/source/common/fonts/specialfont.cpp +++ b/source/common/fonts/specialfont.cpp @@ -152,61 +152,56 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FGameTexture void FSpecialFont::LoadTranslations() { - int count = LastChar - FirstChar + 1; - uint32_t usedcolors[256] = {}; - uint8_t identity[256]; - TArray Luminosity; - int TotalColors; - int i; - - for (i = 0; i < count; i++) - { - if (Chars[i].OriginalPic) - { - auto pic = Chars[i].OriginalPic->GetTexture()->GetImage(); - if (pic) RecordTextureColors(pic, usedcolors); - } - } + FFont::LoadTranslations(); + bool needsnotrans = false; // exclude the non-translated colors from the translation calculation - for (i = 0; i < 256; i++) - if (notranslate[i]) - usedcolors[i] = false; - - TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity); - - // Map all untranslated colors into the table of used colors - for (i = 0; i < 256; i++) - { + for (int i = 0; i < 256; i++) if (notranslate[i]) { - PatchRemap[i] = TotalColors; - identity[TotalColors] = i; - TotalColors++; + needsnotrans = true; + break; } - } - for (i = 0; i < count; i++) + // If we have no non-translateable colors, we can use the base data as-is. + if (!needsnotrans) { - if(Chars[i].TranslatedPic) - static_cast(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(PatchRemap); + return; } - BuildTranslations(Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr, [=](FRemapTable* remap) - { - // add the untranslated colors to the Ranges tables - if (ActiveColors < TotalColors) - { - for (int j = ActiveColors; j < TotalColors; ++j) - { - remap->Remap[j] = identity[j]; - remap->Palette[j] = GPalette.BaseColors[identity[j]]; - remap->Palette[j].a = 0xff; - } - } - }); + // we only need to add special handling if there's colors that should not be translated. + // Obviously 'notranslate' should only be used on data that uses the base palette, otherwise results are undefined! + for (auto &trans : Translations) + { + if (!IsLuminosityTranslation(trans)) continue; // this should only happen for CR_UNTRANSLATED. - ActiveColors = TotalColors; + FRemapTable remap(256); + remap.ForFont = true; + + uint8_t workpal[1024]; + for (int i = 0; i < 256; i++) + { + workpal[i * 4 + 0] = GPalette.BaseColors[i].b; + workpal[i * 4 + 1] = GPalette.BaseColors[i].g; + workpal[i * 4 + 2] = GPalette.BaseColors[i].r; + workpal[i * 4 + 3] = GPalette.BaseColors[i].a; + } + V_ApplyLuminosityTranslation(trans, workpal, 256); + for (int i = 0; i < 256; i++) + { + if (!notranslate[i]) + { + remap.Palette[i] = PalEntry(workpal[i * 4 + 3], workpal[i * 4 + 2], workpal[i * 4 + 1], workpal[i * 4 + 0]); + remap.Remap[i] = ColorMatcher.Pick(remap.Palette[i]); + } + else + { + remap.Palette[i] = GPalette.BaseColors[i]; + remap.Remap[i] = i; + } + } + trans = GPalette.StoreTranslation(TRANSLATION_Internal, &remap); + } } FFont *CreateSpecialFont (const char *name, int first, int count, FGameTexture **lumplist, const bool *notranslate, int lump, bool donttranslate) diff --git a/source/common/fonts/v_font.h b/source/common/fonts/v_font.h index 747ae71c8..222e82748 100644 --- a/source/common/fonts/v_font.h +++ b/source/common/fonts/v_font.h @@ -137,8 +137,6 @@ public: protected: FFont (int lump); - void BuildTranslations (const double *luminosity, const uint8_t *identity, - const void *ranges, int total_colors, const PalEntry *palette, std::function post = nullptr); void FixXMoves(); static int SimpleTranslation (uint32_t *colorsused, uint8_t *translation, @@ -192,6 +190,7 @@ EColorRange V_ParseFontColor (const uint8_t *&color_value, int normalcolor, int FFont *V_GetFont(const char *fontname, const char *fontlumpname = nullptr); void V_InitFontColors(); char* CleanseString(char* str); +void V_ApplyLuminosityTranslation(int translation, uint8_t* pixel, int size); void V_LoadTranslations(); class FBitmap;