void FFont::LoadTranslations() { unsigned int count = LastChar - FirstChar + 1; uint32_t usedcolors[256] = {}; uint8_t identity[256]; TArray<double> Luminosity; for (unsigned int i = 0; i < count; i++) { if (Chars[i].TranslatedPic) { FFontChar1 *pic = static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage()); if (pic) { pic->SetSourceRemap(nullptr); // 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].TranslatedPic) static_cast<FFontChar1 *>(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } BuildTranslations (Luminosity.Data(), identity, &TranslationParms[TranslationType][0], ActiveColors, nullptr); }
void FSingleLumpFont::LoadFON1 (int lump, const BYTE *data) { double luminosity[256]; int w, h; Chars = new CharData[256]; w = data[4] + data[5]*256; h = data[6] + data[7]*256; FontHeight = h; SpaceWidth = w; FirstChar = 0; LastChar = 255; GlobalKerning = 0; PatchRemap = new BYTE[256]; CheckFON1Chars (lump, data, luminosity); BuildTranslations (luminosity, NULL, &TranslationParms[1][0]); }
void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data) { int count, i, totalwidth; int *widths2; BYTE identity[256]; double luminosity[256]; WORD *widths; const BYTE *palette; const BYTE *data_p; FontHeight = data[4] + data[5]*256; FirstChar = data[6]; LastChar = data[7]; ActiveColors = data[10]; Ranges = NULL; count = LastChar - FirstChar + 1; Chars = new CharData[count]; widths2 = new int[count]; if (data[11] & 1) { GlobalKerning = LittleShort(*(SWORD *)&data[12]); widths = (WORD *)(data + 14); } else { GlobalKerning = 0; widths = (WORD *)(data + 12); } totalwidth = 0; if (data[8]) { totalwidth = LittleShort(widths[0]); for (i = 0; i < count; ++i) { widths2[i] = totalwidth; } totalwidth *= count; palette = (BYTE *)&widths[1]; } else { for (i = 0; i < count; ++i) { widths2[i] = LittleShort(widths[i]); totalwidth += widths2[i]; } palette = (BYTE *)(widths + i); } if (FirstChar <= ' ' && LastChar >= ' ') { SpaceWidth = widths2[' '-FirstChar]; } else if (FirstChar <= 'N' && LastChar >= 'N') { SpaceWidth = (widths2['N' - FirstChar] + 1) / 2; } else { SpaceWidth = totalwidth * 2 / (3 * count); } FixupPalette (identity, luminosity, palette, data[9] == 0); data_p = palette + (ActiveColors+1)*3; for (i = 0; i < count; ++i) { int destSize = widths2[i] * FontHeight; if (destSize <= 0) { Chars[i].Pic = NULL; } else { Chars[i].Pic = new FFontChar2 (lump, NULL, data_p - data, widths2[i], FontHeight); do { SBYTE code = *data_p++; if (code >= 0) { data_p += code+1; destSize -= code+1; } else if (code != -128) { data_p++; destSize -= (-code)+1; } } while (destSize > 0); } if (destSize < 0) { i += FirstChar; I_FatalError ("Overflow decompressing char %d (%c) of %s", i, i, Name); } } BuildTranslations (luminosity, identity, &TranslationParms[0][0]); delete[] widths2; }
FFont::FFont (const char *name, const char *nametemplate, int first, int count, int start) { int i, lump; char buffer[12]; int *charlumps; BYTE usedcolors[256], identity[256]; double *luminosity; int maxyoffs; bool doomtemplate = gameinfo.gametype == GAME_Doom ? strncmp (nametemplate, "STCFN", 5) == 0 : false; Chars = new CharData[count]; charlumps = new int[count]; PatchRemap = new BYTE[256]; Ranges = NULL; FirstChar = first; LastChar = first + count - 1; FontHeight = 0; GlobalKerning = false; memset (usedcolors, 0, 256); Name = copystring (name); Next = FirstFont; FirstFont = this; maxyoffs = 0; for (i = 0; i < count; i++) { sprintf (buffer, nametemplate, i + start); lump = Wads.CheckNumForName (buffer, ns_graphics); if (doomtemplate && lump >= 0 && i + start == 121) { // HACKHACK: Don't load STCFN121 in doom(2), because // it's not really a lower-case 'y' but an upper-case 'I'. // Because a lot of wads with their own font seem to foolishly // copy STCFN121 and make it an 'I' themselves, wads must // provide STCFN120 (x) and STCFN122 (z) for STCFN121 to load. if (Wads.CheckNumForName ("STCFN120", ns_graphics) == -1 || Wads.CheckNumForName ("STCFN122", ns_graphics) == -1) { lump = -1; } } charlumps[i] = lump; if (lump >= 0) { FTexture *pic = TexMan[TexMan.AddPatch (buffer)]; int height = pic->GetScaledHeight(); int yoffs = pic->GetScaledTopOffset(); if (yoffs > maxyoffs) { maxyoffs = yoffs; } height += abs (yoffs); if (height > FontHeight) { FontHeight = height; } RecordTextureColors (pic, usedcolors); } } ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); for (i = 0; i < count; i++) { if (charlumps[i] >= 0) { Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap); } else { Chars[i].Pic = NULL; } } if ('N'-first>=0 && 'N'-first<count && Chars['N' - first].Pic) { SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2; } else { SpaceWidth = 4; } BuildTranslations (luminosity, identity, &TranslationParms[0][0]); delete[] luminosity; delete[] charlumps; }