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;