diff --git a/src/v_font.cpp b/src/v_font.cpp index e95613f7b..8fb0a2400 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -124,16 +124,26 @@ public: FSingleLumpFont (const char *fontname, int lump); protected: - void CheckFON1Chars (int lump, const BYTE *data, double *luminosity); + void CheckFON1Chars (double *luminosity); void BuildTranslations2 (); void FixupPalette (BYTE *identity, double *luminosity, const BYTE *palette, bool rescale, PalEntry *out_palette); + void LoadTranslations (); void LoadFON1 (int lump, const BYTE *data); void LoadFON2 (int lump, const BYTE *data); void LoadBMF (int lump, const BYTE *data); void CreateFontFromPic (FTextureID picnum); static int STACK_ARGS BMFCompare(const void *a, const void *b); + + enum + { + FONT1, + FONT2, + BMFFONT + } FontType; + BYTE PaletteData[768]; + bool RescalePalette; }; class FSinglePicFont : public FFont @@ -153,16 +163,22 @@ protected: class FSpecialFont : public FFont { public: - FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate); + FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump); + + void LoadTranslations(); + +protected: + bool notranslate[256]; }; // This is a font character that loads a texture and recolors it. class FFontChar1 : public FTexture { public: - FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap); + FFontChar1 (FTexture *sourcelump); const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); + void SetSourceRemap(const BYTE *sourceremap); void Unload (); ~FFontChar1 (); @@ -178,11 +194,12 @@ protected: class FFontChar2 : public FTexture { public: - FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0); + FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); const BYTE *GetColumn (unsigned int column, const Span **spans_out); const BYTE *GetPixels (); + void SetSourceRemap(const BYTE *sourceremap); void Unload (); protected: @@ -322,18 +339,17 @@ FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font) // //========================================================================== -FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start) +FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start, int fdlump) { int i; FTextureID lump; char buffer[12]; FTexture **charlumps; - BYTE usedcolors[256], identity[256]; - double *luminosity; int maxyoffs; bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false; bool stcfn121 = false; + Lump = fdlump; Chars = new CharData[count]; charlumps = new FTexture *[count]; PatchRemap = new BYTE[256]; @@ -341,7 +357,6 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; - memset (usedcolors, 0, 256); Name = copystring (name); Next = FirstFont; FirstFont = this; @@ -392,18 +407,12 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { FontHeight = height; } - RecordTextureColors (pic, usedcolors); } } - } - ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); - - for (i = 0; i < count; i++) - { if (charlumps[i] != NULL) { - Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap); + Chars[i].Pic = new FFontChar1 (charlumps[i]); Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); } else @@ -424,9 +433,8 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, FixXMoves(); - BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); + LoadTranslations(); - delete[] luminosity; delete[] charlumps; } @@ -803,6 +811,42 @@ int FFont::GetCharWidth (int code) const return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove; } +//========================================================================== +// +// FFont :: LoadTranslations +// +//========================================================================== + +void FFont::LoadTranslations() +{ + unsigned int count = LastChar - FirstChar + 1; + BYTE usedcolors[256], identity[256]; + double *luminosity; + + memset (usedcolors, 0, 256); + for (unsigned int i = 0; i < count; i++) + { + FFontChar1 *pic = static_cast(Chars[i].Pic); + if(pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + RecordTextureColors (pic, usedcolors); + } + } + + ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); + + for (unsigned int i = 0; i < count; i++) + { + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + } + + BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); + + delete[] luminosity; +} + //========================================================================== // // FFont :: Preload @@ -854,8 +898,9 @@ void FFont::StaticPreloadFonts() // //========================================================================== -FFont::FFont () +FFont::FFont (int lump) { + Lump = lump; Chars = NULL; PatchRemap = NULL; Name = NULL; @@ -869,7 +914,7 @@ FFont::FFont () // //========================================================================== -FSingleLumpFont::FSingleLumpFont (const char *name, int lump) +FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) { assert(lump >= 0); @@ -927,6 +972,51 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) ActiveColors = 0; } +//========================================================================== +// +// FSingleLumpFont :: LoadTranslations +// +//========================================================================== + +void FSingleLumpFont::LoadTranslations() +{ + double luminosity[256]; + BYTE identity[256]; + PalEntry local_palette[256]; + bool useidentity = true; + bool usepalette = false; + const void* ranges; + unsigned int count = LastChar - FirstChar + 1; + + switch(FontType) + { + case FONT1: + useidentity = false; + ranges = &TranslationParms[1][0]; + CheckFON1Chars (luminosity); + break; + + case BMFFONT: + case FONT2: + usepalette = true; + FixupPalette (identity, luminosity, PaletteData, RescalePalette, local_palette); + + ranges = &TranslationParms[0][0]; + break; + + default: + break; + } + + for(unsigned int i = 0;i < count;++i) + { + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + } + + BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL); +} + //========================================================================== // // FSingleLumpFont :: LoadFON1 @@ -937,7 +1027,6 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) { - double luminosity[256]; int w, h; Chars = new CharData[256]; @@ -945,6 +1034,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) w = data[4] + data[5]*256; h = data[6] + data[7]*256; + FontType = FONT1; FontHeight = h; SpaceWidth = w; FirstChar = 0; @@ -952,8 +1042,10 @@ void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) GlobalKerning = 0; PatchRemap = new BYTE[256]; - CheckFON1Chars (lump, data, luminosity); - BuildTranslations (luminosity, NULL, &TranslationParms[1][0], ActiveColors, NULL); + for(unsigned int i = 0;i < 256;++i) + Chars[i].Pic = NULL; + + LoadTranslations(); } //========================================================================== @@ -969,17 +1061,17 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) { int count, i, totalwidth; int *widths2; - BYTE identity[256]; - double luminosity[256]; - PalEntry local_palette[256]; WORD *widths; const BYTE *palette; const BYTE *data_p; + FontType = FONT2; FontHeight = data[4] + data[5]*256; FirstChar = data[6]; LastChar = data[7]; ActiveColors = data[10]; + PatchRemap = NULL; + RescalePalette = data[9] == 0; count = LastChar - FirstChar + 1; Chars = new CharData[count]; @@ -1029,7 +1121,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) SpaceWidth = totalwidth * 2 / (3 * count); } - FixupPalette (identity, luminosity, palette, data[9] == 0, local_palette); + memcpy(PaletteData, palette, 768); data_p = palette + (ActiveColors+1)*3; @@ -1043,7 +1135,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) } else { - Chars[i].Pic = new FFontChar2 (lump, NULL, int(data_p - data), widths2[i], FontHeight); + Chars[i].Pic = new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight); do { SBYTE code = *data_p++; @@ -1066,7 +1158,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) } } - BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette); + LoadTranslations(); delete[] widths2; } @@ -1087,15 +1179,14 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) int i, chari; BYTE raw_palette[256*3]; PalEntry sort_palette[256]; - PalEntry local_palette[256]; - double luminosity[256]; - BYTE identity[256]; + FontType = BMFFONT; FontHeight = data[5]; GlobalKerning = (SBYTE)data[8]; ActiveColors = data[16]; SpaceWidth = -1; nwidth = -1; + RescalePalette = true; infolen = data[17 + ActiveColors*3]; chardata = data + 18 + ActiveColors*3 + infolen; @@ -1160,7 +1251,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) PatchRemap[sort_palette[i].a] = i; } - FixupPalette(identity, luminosity, raw_palette, true, local_palette); + memcpy(PaletteData, raw_palette, 768); // 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]) @@ -1180,7 +1271,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) { // Empty character: skip it. continue; } - Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data), + Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, int(chardata + chari + 6 - data), chardata[chari+1], // width chardata[chari+2], // height -(SBYTE)chardata[chari+3], // x offset @@ -1202,7 +1293,7 @@ void FSingleLumpFont::LoadBMF(int lump, const BYTE *data) } FixXMoves(); - BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette); + LoadTranslations(); } //========================================================================== @@ -1232,8 +1323,11 @@ int STACK_ARGS FSingleLumpFont::BMFCompare(const void *a, const void *b) // //========================================================================== -void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *luminosity) +void FSingleLumpFont::CheckFON1Chars (double *luminosity) { + FMemLump memLump = Wads.ReadLump(Lump); + const BYTE* data = (const BYTE*) memLump.GetMem(); + BYTE used[256], reverse[256]; const BYTE *data_p; int i, j; @@ -1245,8 +1339,11 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino { int destSize = SpaceWidth * FontHeight; - Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight); - Chars[i].XMove = SpaceWidth; + if(!Chars[i].Pic) + { + Chars[i].Pic = new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight); + Chars[i].XMove = SpaceWidth; + } // Advance to next char's data and count the used colors. do @@ -1347,7 +1444,8 @@ void FSingleLumpFont::FixupPalette (BYTE *identity, double *luminosity, const BY // //========================================================================== -FSinglePicFont::FSinglePicFont(const char *picname) +FSinglePicFont::FSinglePicFont(const char *picname) : + FFont(-1) // Since lump is only needed for priority information we don't need to worry about this here. { FTextureID picnum = TexMan.CheckForTexture (picname, FTexture::TEX_Any); @@ -1413,8 +1511,8 @@ int FSinglePicFont::GetCharWidth (int code) const // //========================================================================== -FFontChar1::FFontChar1 (FTexture *sourcelump, const BYTE *sourceremap) -: SourceRemap (sourceremap) +FFontChar1::FFontChar1 (FTexture *sourcelump) +: SourceRemap (NULL) { UseType = FTexture::TEX_FontChar; BaseTexture = sourcelump; @@ -1453,9 +1551,16 @@ void FFontChar1::MakeTexture () Pixels = new BYTE[Width*Height]; const BYTE *pix = BaseTexture->GetPixels(); - for (int x = 0; x < Width*Height; ++x) + if (!SourceRemap) { - Pixels[x] = SourceRemap[pix[x]]; + memcpy(Pixels, pix, Width*Height); + } + else + { + for (int x = 0; x < Width*Height; ++x) + { + Pixels[x] = SourceRemap[pix[x]]; + } } } @@ -1476,6 +1581,18 @@ const BYTE *FFontChar1::GetColumn (unsigned int column, const Span **spans_out) return Pixels + column*Height; } +//========================================================================== +// +// FFontChar1 :: SetSourceRemap +// +//========================================================================== + +void FFontChar1::SetSourceRemap(const BYTE *sourceremap) +{ + Unload(); + SourceRemap = sourceremap; +} + //========================================================================== // // FFontChar1 :: Unload @@ -1510,8 +1627,8 @@ FFontChar1::~FFontChar1 () // //========================================================================== -FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap) +FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) +: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(NULL) { UseType = TEX_FontChar; Width = width; @@ -1594,6 +1711,18 @@ const BYTE *FFontChar2::GetColumn (unsigned int column, const Span **spans_out) return Pixels + column*Height; } +//========================================================================== +// +// FFontChar2 :: SetSourceRemap +// +//========================================================================== + +void FFontChar2::SetSourceRemap(const BYTE *sourceremap) +{ + Unload(); + SourceRemap = sourceremap; +} + //========================================================================== // // FFontChar2 :: MakeTexture @@ -1730,16 +1859,15 @@ void FFontChar2::MakeTexture () // //========================================================================== -FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate) +FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump) : FFont(lump) { int i, j; FTexture **charlumps; - BYTE usedcolors[256], identity[256]; - double *luminosity; int maxyoffs; - int TotalColors; FTexture *pic; - + + memcpy(this->notranslate, notranslate, 256*sizeof(bool)); + Name = copystring(name); Chars = new CharData[count]; charlumps = new FTexture*[count]; @@ -1748,7 +1876,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; - memset (usedcolors, 0, 256); Next = FirstFont; FirstFont = this; @@ -1771,7 +1898,58 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l { FontHeight = height; } + } + if (charlumps[i] != NULL) + { + Chars[i].Pic = new FFontChar1 (charlumps[i]); + Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); + } + else + { + Chars[i].Pic = NULL; + 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) + { + SpaceWidth = (Chars['N' - first].XMove + 1) / 2; + } + else + { + SpaceWidth = 4; + } + + FixXMoves(); + + LoadTranslations(); + + delete[] charlumps; +} + +//========================================================================== +// +// FSpecialFont :: LoadTranslations +// +//========================================================================== + +void FSpecialFont::LoadTranslations() +{ + int count = LastChar - FirstChar + 1; + BYTE usedcolors[256], identity[256]; + double *luminosity; + int TotalColors; + int i, j; + + memset (usedcolors, 0, 256); + for (i = 0; i < count; i++) + { + FFontChar1 *pic = static_cast(Chars[i].Pic); + if(pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture RecordTextureColors (pic, usedcolors); } } @@ -1802,30 +1980,10 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l for (i = 0; i < count; i++) { - if (charlumps[i] != NULL) - { - Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap); - Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); - } - else - { - Chars[i].Pic = NULL; - Chars[i].XMove = INT_MIN; - } + if(Chars[i].Pic) + static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); } - // Special fonts normally don't have all characters so be careful here! - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) - { - SpaceWidth = (Chars['N' - first].XMove + 1) / 2; - } - else - { - SpaceWidth = 4; - } - - FixXMoves(); - BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL); // add the untranslated colors to the Ranges tables @@ -1845,7 +2003,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l ActiveColors = TotalColors; delete[] luminosity; - delete[] charlumps; } //========================================================================== @@ -1994,7 +2151,7 @@ void V_InitCustomFonts() } if (format == 1) { - FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start); + FFont *fnt = new FFont (namebuffer, templatebuf, first, count, start, llump); fnt->SetCursor(cursor); } else if (format == 2) @@ -2017,7 +2174,7 @@ void V_InitCustomFonts() } if (count > 0) { - FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate); + FFont *fnt = new FSpecialFont (namebuffer, first, count, &lumplist[first], notranslate, llump); fnt->SetCursor(cursor); } } @@ -2396,19 +2553,19 @@ void V_InitFonts() } else if (Wads.CheckNumForName ("FONTA_S") >= 0) { - SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1); + SmallFont = new FFont ("SmallFont", "FONTA%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1); SmallFont->SetCursor('['); } else { - SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART); + SmallFont = new FFont ("SmallFont", "STCFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } } if (!(SmallFont2 = FFont::FindFont("SmallFont2"))) // Only used by Strife { if (Wads.CheckNumForName ("STBFN033", ns_graphics) >= 0) { - SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART); + SmallFont2 = new FFont ("SmallFont2", "STBFN%.3d", HU_FONTSTART, HU_FONTSIZE, HU_FONTSTART, -1); } else { @@ -2427,7 +2584,7 @@ void V_InitFonts() } else { - BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1); + BigFont = new FFont ("BigFont", "FONTB%02u", HU_FONTSTART, HU_FONTSIZE, 1, -1); } } if (!(ConFont = FFont::FindFont("ConsoleFont"))) @@ -2455,4 +2612,14 @@ void V_ClearFonts() } FFont::FirstFont = NULL; SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL; -} \ No newline at end of file +} + +void V_RetranslateFonts() +{ + FFont *font = FFont::FirstFont; + while(font) + { + font->LoadTranslations(); + font = font->Next; + } +} diff --git a/src/v_font.h b/src/v_font.h index 27cf50b2c..0b510612d 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -76,15 +76,17 @@ extern int NumTextColors; class FFont { public: - FFont (const char *fontname, const char *nametemplate, int first, int count, int base); + FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump); virtual ~FFont (); virtual FTexture *GetChar (int code, int *const width) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range) const; + int GetLump() const { return Lump; } int GetSpaceWidth () const { return SpaceWidth; } int GetHeight () const { return FontHeight; } int GetDefaultKerning () const { return GlobalKerning; } + virtual void LoadTranslations(); void Preload() const; static FFont *FindFont (const char *fontname); @@ -99,7 +101,7 @@ public: void SetCursor(char c) { Cursor = c; } protected: - FFont (); + FFont (int lump); void BuildTranslations (const double *luminosity, const BYTE *identity, const void *ranges, int total_colors, const PalEntry *palette); @@ -122,6 +124,7 @@ protected: TArray Ranges; BYTE *PatchRemap; + int Lump; char *Name; FFont *Next; @@ -129,6 +132,7 @@ protected: friend struct FontsDeleter; friend void V_ClearFonts(); + friend void V_RetranslateFonts(); friend FArchive &SerializeFFontPtr (FArchive &arc, FFont* &font); }; @@ -143,5 +147,6 @@ PalEntry V_LogColorFromColorRange (EColorRange range); EColorRange V_ParseFontColor (const BYTE *&color_value, int normalcolor, int boldcolor); FFont *V_GetFont(const char *); void V_InitFontColors(); +void V_RetranslateFonts(); #endif //__V_FONT_H__