- use luminosity translations for single lump fonts and let them use their original palette.

This commit is contained in:
Christoph Oelckers 2021-05-24 17:04:07 +02:00
parent 377829d6a2
commit 372d425e01
4 changed files with 90 additions and 198 deletions

View file

@ -90,17 +90,12 @@ public:
void RecordAllTextureColors(uint32_t* usedcolors) override;
protected:
void CheckFON1Chars (double *luminosity);
void BuildTranslations2 ();
void FixupPalette (uint8_t *identity, double *luminosity, const uint8_t *palette,
bool rescale, PalEntry *out_palette);
void CheckFON1Chars ();
void FixupPalette (uint8_t *identity, const PalEntry *palette, int* minlum ,int* maxlum);
void LoadTranslations ();
void LoadFON1 (int lump, const uint8_t *data);
void LoadFON2 (int lump, const uint8_t *data);
void LoadBMF (int lump, const uint8_t *data);
void CreateFontFromPic (FTextureID picnum);
static int BMFCompare(const void *a, const void *b);
enum
{
@ -108,7 +103,7 @@ protected:
FONT2,
BMFFONT
} FontType;
uint8_t PaletteData[768];
PalEntry Palette[256];
bool RescalePalette;
};
@ -160,29 +155,6 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump)
FirstFont = this;
}
//==========================================================================
//
// FSingleLumpFont :: CreateFontFromPic
//
//==========================================================================
void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
{
auto pic = TexMan.GetGameTexture(picnum);
FontHeight = (int)pic->GetDisplayHeight ();
SpaceWidth = (int)pic->GetDisplayWidth ();
GlobalKerning = 0;
FirstChar = LastChar = 'A';
Chars.Resize(1);
Chars[0].TranslatedPic = pic;
Chars[0].OriginalPic = pic;
// Only one color range. Don't bother with the others.
ActiveColors = 0;
}
//==========================================================================
//
// FSingleLumpFont :: LoadTranslations
@ -191,28 +163,21 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum)
void FSingleLumpFont::LoadTranslations()
{
double luminosity[256];
uint8_t identity[256];
PalEntry local_palette[256];
bool useidentity = true;
bool usepalette = false;
const void* ranges;
unsigned int count = LastChar - FirstChar + 1;
int minlum, maxlum;
switch(FontType)
{
case FONT1:
useidentity = false;
ranges = &TranslationParms[1][0];
CheckFON1Chars (luminosity);
CheckFON1Chars();
minlum = 1;
maxlum = 255;
break;
case BMFFONT:
case FONT2:
usepalette = true;
FixupPalette (identity, luminosity, PaletteData, RescalePalette, local_palette);
ranges = &TranslationParms[0][0];
FixupPalette (identity, Palette, &minlum, &maxlum);
break;
default:
@ -224,10 +189,15 @@ void FSingleLumpFont::LoadTranslations()
for(unsigned int i = 0;i < count;++i)
{
if(Chars[i].TranslatedPic)
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(PatchRemap);
static_cast<FFontChar2*>(Chars[i].TranslatedPic->GetTexture()->GetImage())->SetSourceRemap(Palette);
}
BuildTranslations (luminosity, useidentity ? identity : nullptr, ranges, ActiveColors, usepalette ? local_palette : nullptr);
Translations.Resize(NumTextColors);
for (int i = 0; i < NumTextColors; i++)
{
if (i == CR_UNTRANSLATED) Translations[i] = 0;
else Translations[i] = LuminosityTranslation(i * 2 + (FontType == FONT1 ? 1 : 0), minlum, maxlum);
}
}
//==========================================================================
@ -262,19 +232,20 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data)
// Move the Windows-1252 characters to their proper place.
for (int i = 0x80; i < 0xa0; i++)
{
if (win1252map[i-0x80] != i && Chars[i].TranslatedPic != nullptr && Chars[win1252map[i - 0x80]].TranslatedPic == nullptr)
if (win1252map[i-0x80] != i && Chars[i].OriginalPic != nullptr && Chars[win1252map[i - 0x80]].OriginalPic == nullptr)
{
std::swap(Chars[i], Chars[win1252map[i - 0x80]]);
}
}
Palette[0] = 0;
for (int i = 1; i < 256; i++) Palette[i] = PalEntry(255, i, i, i);
}
//==========================================================================
//
// FSingleLumpFont :: LoadFON2
//
// FON2 is used for everything but the console font. The console font should
// probably use FON2 as well, but oh well.
// FON2 is used for everything but the console font.
//
//==========================================================================
@ -340,7 +311,11 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data)
SpaceWidth = totalwidth * 2 / (3 * count);
}
memcpy(PaletteData, palette, ActiveColors*3);
Palette[0] = 0;
for (int i = 1; i < ActiveColors; i++)
{
Palette[i] = PalEntry(255, palette[i * 3], palette[i * 3 + 1], palette[i * 3 + 2]);
}
data_p = palette + ActiveColors*3;
@ -396,8 +371,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
int numchars, count, totalwidth, nwidth;
int infolen;
int i, chari;
uint8_t raw_palette[256*3];
PalEntry sort_palette[256];
FontType = BMFFONT;
FontHeight = data[5];
@ -439,31 +412,14 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
count = LastChar - FirstChar + 1;
Chars.Resize(count);
// BMF palettes are only six bits per component. Fix that.
for (i = 0; i < ActiveColors*3; ++i)
{
raw_palette[i+3] = (data[17 + i] << 2) | (data[17 + i] >> 4);
}
ActiveColors++;
// Sort the palette by increasing brightness
for (i = 0; i < ActiveColors; ++i)
{
PalEntry *pal = &sort_palette[i];
pal->a = i; // Use alpha part to point back to original entry
pal->r = raw_palette[i*3 + 0];
pal->g = raw_palette[i*3 + 1];
pal->b = raw_palette[i*3 + 2];
int r = (data[17 + i * 3] << 2) | (data[17 + i * 3] >> 4);
int g = (data[18 + i * 3] << 2) | (data[18 + i * 3] >> 4);
int b = (data[19 + i * 3] << 2) | (data[19 + i * 3] >> 4);
Palette[i + 1] = PalEntry(255, r, g, b); // entry 0 (transparent) is not stored in the font file.
}
qsort(sort_palette + 1, ActiveColors - 1, sizeof(PalEntry), BMFCompare);
// Create the PatchRemap table from the sorted "alpha" values.
PatchRemap[0] = 0;
for (i = 1; i < ActiveColors; ++i)
{
PatchRemap[sort_palette[i].a] = i;
}
memcpy(PaletteData, raw_palette, 768);
ActiveColors++;
// Now scan through the characters again, creating glyphs for each one.
for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2])
@ -510,23 +466,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data)
FixXMoves();
}
//==========================================================================
//
// FSingleLumpFont :: BMFCompare STATIC
//
// Helper to sort BMF palettes.
//
//==========================================================================
int FSingleLumpFont::BMFCompare(const void *a, const void *b)
{
const PalEntry *pa = (const PalEntry *)a;
const PalEntry *pb = (const PalEntry *)b;
return (pa->r * 299 + pa->g * 587 + pa->b * 114) -
(pb->r * 299 + pb->g * 587 + pb->b * 114);
}
//==========================================================================
//
// FSingleLumpFont :: CheckFON1Chars
@ -537,19 +476,15 @@ int FSingleLumpFont::BMFCompare(const void *a, const void *b)
//
//==========================================================================
void FSingleLumpFont::CheckFON1Chars (double *luminosity)
void FSingleLumpFont::CheckFON1Chars()
{
FileData memLump = fileSystem.ReadFile(Lump);
const uint8_t* data = (const uint8_t*)memLump.GetMem();
uint8_t used[256], reverse[256];
const uint8_t* data_p;
int i, j;
memset (used, 0, 256);
data_p = data + 8;
for (i = 0; i < 256; ++i)
for (int i = 0; i < 256; ++i)
{
int destSize = SpaceWidth * FontHeight;
@ -570,84 +505,49 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity)
destSize -= code + 1;
while (code-- >= 0)
{
used[*data_p++] = 1;
data_p++;
}
}
else if (code != -128)
{
used[*data_p++] = 1;
data_p++;
destSize -= 1 - code;
}
} while (destSize > 0);
}
memset (PatchRemap, 0, 256);
reverse[0] = 0;
for (i = 1, j = 1; i < 256; ++i)
{
if (used[i])
{
reverse[j++] = i;
}
}
for (i = 1; i < j; ++i)
{
PatchRemap[reverse[i]] = i;
luminosity[i] = (reverse[i] - 1) / 254.0;
}
ActiveColors = j;
ActiveColors = 256;
}
//==========================================================================
//
// FSingleLumpFont :: FixupPalette
//
// Finds the best matches for the colors used by a FON2 font and sets up
// some tables like SimpleTranslation.
// Finds the best matches for the colors used by a FON2 font and finds thr
// used luminosity range
//
//==========================================================================
void FSingleLumpFont::FixupPalette (uint8_t *identity, double *luminosity, const uint8_t *palette, bool rescale, PalEntry *out_palette)
void FSingleLumpFont::FixupPalette (uint8_t *identity, const PalEntry *palette, int *pminlum, int *pmaxlum)
{
int i;
double maxlum = 0.0;
double minlum = 100000000.0;
double diver;
identity[0] = 0;
palette += 3; // Skip the transparent color
for (i = 1; i < ActiveColors; ++i, palette += 3)
for (int i = 1; i < ActiveColors; ++i, palette ++)
{
int r = palette[0];
int g = palette[1];
int b = palette[2];
int r = palette->r;
int g = palette->g;
int b = palette->b;
double lum = r*0.299 + g*0.587 + b*0.114;
identity[i] = ColorMatcher.Pick(r, g, b);
luminosity[i] = lum;
out_palette[i].r = r;
out_palette[i].g = g;
out_palette[i].b = b;
out_palette[i].a = 255;
if (lum > maxlum)
maxlum = lum;
if (lum < minlum)
minlum = lum;
if (lum > maxlum) maxlum = lum;
if (lum < minlum) minlum = lum;
}
out_palette[0] = 0;
if (rescale)
{
diver = 1.0 / (maxlum - minlum);
}
else
{
diver = 1.0 / 255.0;
}
for (i = 1; i < ActiveColors; ++i)
{
luminosity[i] = (luminosity[i] - minlum) * diver;
}
if (pminlum) *pminlum = int(minlum);
if (pmaxlum) *pmaxlum = int(maxlum);
}
//==========================================================================
@ -661,13 +561,11 @@ void FSingleLumpFont::FixupPalette (uint8_t *identity, double *luminosity, const
void FSingleLumpFont::RecordAllTextureColors(uint32_t* usedcolors)
{
double luminosity[256];
uint8_t identity[256];
PalEntry local_palette[256];
if (FontType == BMFFONT || FontType == FONT2)
{
FixupPalette(identity, luminosity, PaletteData, RescalePalette, local_palette);
FixupPalette(identity, Palette, nullptr, nullptr);
for (int i = 0; i < 256; i++)
{
if (identity[i] != 0) usedcolors[identity[i]]++;

View file

@ -92,7 +92,7 @@ TArray<uint8_t> FFontChar1::CreatePalettedPixels (int)
//==========================================================================
FFontChar2::FFontChar2(int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr)
: SourceLump(sourcelump), SourcePos(sourcepos)
{
Width = width;
Height = height;
@ -100,17 +100,6 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in
TopOffset = topofs;
}
//==========================================================================
//
// FFontChar2 :: SetSourceRemap
//
//==========================================================================
void FFontChar2::SetSourceRemap(const uint8_t *sourceremap)
{
SourceRemap = sourceremap;
}
//==========================================================================
//
// FFontChar2 :: Get8BitPixels
@ -167,10 +156,6 @@ TArray<uint8_t> FFontChar2::CreatePalettedPixels(int)
{
uint8_t color = lump.ReadUInt8();
color = MIN(color, max);
if (SourceRemap != nullptr)
{
color = SourceRemap[color];
}
*dest_p = color;
dest_p += dest_adv;
x--;
@ -195,10 +180,6 @@ TArray<uint8_t> FFontChar2::CreatePalettedPixels(int)
uint8_t color = lump.ReadUInt8();
setlen = (-code) + 1;
setval = MIN(color, max);
if (SourceRemap != nullptr)
{
setval = SourceRemap[setval];
}
}
}
}
@ -216,10 +197,6 @@ TArray<uint8_t> FFontChar2::CreatePalettedPixels(int)
{
color = max;
}
if (SourceRemap != nullptr)
{
color = SourceRemap[color];
}
*dest_p = color;
dest_p += dest_adv;
}
@ -237,3 +214,10 @@ TArray<uint8_t> FFontChar2::CreatePalettedPixels(int)
return Pixels;
}
int FFontChar2::CopyPixels(FBitmap* bmp, int conversion)
{
if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source.
auto ppix = CreatePalettedPixels(conversion);
bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, SourceRemap, nullptr);
return 0;
}

View file

@ -23,10 +23,15 @@ public:
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
TArray<uint8_t> CreatePalettedPixels(int conversion) override;
void SetSourceRemap(const uint8_t *sourceremap);
int CopyPixels(FBitmap* bmp, int conversion);
void SetSourceRemap(const PalEntry* sourceremap)
{
SourceRemap = sourceremap;
}
protected:
int SourceLump;
int SourcePos;
const uint8_t *SourceRemap;
const PalEntry *SourceRemap;
};

View file

@ -191,8 +191,13 @@ void UpdateStatusBar(SummaryInfo* info)
for (int i = 0; i < NumTextColors; i++)
{
FStringf buffer("This is font color %d", i);
DrawText(twod, SmallFont, i, 40, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
DrawText(twod, NewSmallFont, i, 340, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
//DrawText(twod, SmallFont, i, 40, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
//DrawText(twod, V_GetFont("doomfont"), i, 40, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
//DrawText(twod, NewSmallFont, i, 340, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
DrawText(twod, V_GetFont("condfont"), i, 40, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
DrawText(twod, NewConsoleFont, i, 340, i * 15, buffer, DTA_FullscreenScale, FSMode_Fit640x400, TAG_DONE);
}
#endif
}