mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- Added BMF (ByteMap Font) support. This was complicated somewhat by the fact that BMF can
specify a character advance separately from the glyph width. GetChar and GetCharWidth now return this value in place of the glyph width. (For non-BMF fonts, these should still return the same values as before.) SVN r2180 (trunk)
This commit is contained in:
parent
8ecafcc15a
commit
d530fd7f90
4 changed files with 331 additions and 91 deletions
410
src/v_font.cpp
410
src/v_font.cpp
|
@ -130,7 +130,10 @@ protected:
|
||||||
bool rescale, PalEntry *out_palette);
|
bool rescale, PalEntry *out_palette);
|
||||||
void LoadFON1 (int lump, const BYTE *data);
|
void LoadFON1 (int lump, const BYTE *data);
|
||||||
void LoadFON2 (int lump, const BYTE *data);
|
void LoadFON2 (int lump, const BYTE *data);
|
||||||
|
void LoadBMF (int lump, const BYTE *data);
|
||||||
void CreateFontFromPic (FTextureID picnum);
|
void CreateFontFromPic (FTextureID picnum);
|
||||||
|
|
||||||
|
static int STACK_ARGS BMFCompare(const void *a, const void *b);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FSinglePicFont : public FFont
|
class FSinglePicFont : public FFont
|
||||||
|
@ -175,7 +178,7 @@ protected:
|
||||||
class FFontChar2 : public FTexture
|
class FFontChar2 : public FTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height);
|
FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||||
~FFontChar2 ();
|
~FFontChar2 ();
|
||||||
|
|
||||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||||
|
@ -399,21 +402,26 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count,
|
||||||
if (charlumps[i] != NULL)
|
if (charlumps[i] != NULL)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||||
|
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('N'-first>=0 && 'N'-first<count && Chars['N' - first].Pic)
|
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||||
{
|
{
|
||||||
SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2;
|
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpaceWidth = 4;
|
SpaceWidth = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
|
||||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL);
|
||||||
|
|
||||||
delete[] luminosity;
|
delete[] luminosity;
|
||||||
|
@ -717,6 +725,33 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const
|
||||||
return &Ranges[range];
|
return &Ranges[range];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FFont :: GetCharCode
|
||||||
|
//
|
||||||
|
// If the character code is in the font, returns it. If it is not, but it
|
||||||
|
// is lowercase and has an uppercase variant present, return that. Otherwise
|
||||||
|
// return -1.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int FFont::GetCharCode(int code, bool needpic) const
|
||||||
|
{
|
||||||
|
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
if (myislower[code])
|
||||||
|
{
|
||||||
|
code -= 32;
|
||||||
|
if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL))
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FFont :: GetChar
|
// FFont :: GetChar
|
||||||
|
@ -725,31 +760,28 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range) const
|
||||||
|
|
||||||
FTexture *FFont::GetChar (int code, int *const width) const
|
FTexture *FFont::GetChar (int code, int *const width) const
|
||||||
{
|
{
|
||||||
if (code < FirstChar ||
|
code = GetCharCode(code, false);
|
||||||
code > LastChar ||
|
int xmove = SpaceWidth;
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
|
if (code >= 0)
|
||||||
{
|
{
|
||||||
if (myislower[code])
|
code -= FirstChar;
|
||||||
|
xmove = Chars[code].XMove;
|
||||||
|
if (Chars[code].Pic == NULL)
|
||||||
{
|
{
|
||||||
code -= 32;
|
code = GetCharCode(code + FirstChar, true);
|
||||||
if (code < FirstChar ||
|
if (code >= 0)
|
||||||
code > LastChar ||
|
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
{
|
||||||
if (width != NULL) *width = SpaceWidth;
|
code -= FirstChar;
|
||||||
return NULL;
|
xmove = Chars[code].XMove;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (width != NULL) *width = SpaceWidth;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (width != NULL)
|
||||||
code -= FirstChar;
|
{
|
||||||
if (width != NULL) *width = Chars[code].Pic->GetScaledWidth();
|
*width = xmove;
|
||||||
return Chars[code].Pic;
|
}
|
||||||
|
return (code < 0) ? NULL : Chars[code].Pic;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -760,27 +792,8 @@ FTexture *FFont::GetChar (int code, int *const width) const
|
||||||
|
|
||||||
int FFont::GetCharWidth (int code) const
|
int FFont::GetCharWidth (int code) const
|
||||||
{
|
{
|
||||||
if (code < FirstChar ||
|
code = GetCharCode(code, false);
|
||||||
code > LastChar ||
|
return (code < 0) ? SpaceWidth : Chars[code - FirstChar].XMove;
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
if (myislower[code])
|
|
||||||
{
|
|
||||||
code -= 32;
|
|
||||||
if (code < FirstChar ||
|
|
||||||
code > LastChar ||
|
|
||||||
Chars[code - FirstChar].Pic == NULL)
|
|
||||||
{
|
|
||||||
return SpaceWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return SpaceWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Chars[code - FirstChar].Pic->GetScaledWidth();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -858,7 +871,11 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump)
|
||||||
FMemLump data1 = Wads.ReadLump (lump);
|
FMemLump data1 = Wads.ReadLump (lump);
|
||||||
const BYTE *data = (const BYTE *)data1.GetMem();
|
const BYTE *data = (const BYTE *)data1.GetMem();
|
||||||
|
|
||||||
if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
|
if (data[0] == 0xE1 && data[1] == 0xE6 && data[2] == 0xD5 && data[3] == 0x1A)
|
||||||
|
{
|
||||||
|
LoadBMF(lump, data);
|
||||||
|
}
|
||||||
|
else if (data[0] != 'F' || data[1] != 'O' || data[2] != 'N' ||
|
||||||
(data[3] != '1' && data[3] != '2'))
|
(data[3] != '1' && data[3] != '2'))
|
||||||
{
|
{
|
||||||
I_FatalError ("%s is not a recognizable font", name);
|
I_FatalError ("%s is not a recognizable font", name);
|
||||||
|
@ -1012,6 +1029,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
||||||
for (i = 0; i < count; ++i)
|
for (i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
int destSize = widths2[i] * FontHeight;
|
int destSize = widths2[i] * FontHeight;
|
||||||
|
Chars[i].XMove = widths2[i];
|
||||||
if (destSize <= 0)
|
if (destSize <= 0)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
@ -1045,6 +1063,157 @@ void FSingleLumpFont::LoadFON2 (int lump, const BYTE *data)
|
||||||
delete[] widths2;
|
delete[] widths2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FSingleLumpFont :: LoadBMF
|
||||||
|
//
|
||||||
|
// Loads a BMF font. The file format is described at
|
||||||
|
// <http://bmf.wz.cz/bmf-format.htm>
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSingleLumpFont::LoadBMF(int lump, const BYTE *data)
|
||||||
|
{
|
||||||
|
const BYTE *chardata;
|
||||||
|
int numchars, count, totalwidth, nwidth;
|
||||||
|
int infolen;
|
||||||
|
int i, chari;
|
||||||
|
BYTE raw_palette[256*3];
|
||||||
|
PalEntry sort_palette[256];
|
||||||
|
PalEntry local_palette[256];
|
||||||
|
double luminosity[256];
|
||||||
|
BYTE identity[256];
|
||||||
|
|
||||||
|
FontHeight = data[5];
|
||||||
|
GlobalKerning = (SBYTE)data[8];
|
||||||
|
ActiveColors = data[16];
|
||||||
|
SpaceWidth = -1;
|
||||||
|
nwidth = -1;
|
||||||
|
|
||||||
|
infolen = data[17 + ActiveColors*3];
|
||||||
|
chardata = data + 18 + ActiveColors*3 + infolen;
|
||||||
|
numchars = chardata[0] + 256*chardata[1];
|
||||||
|
chardata += 2;
|
||||||
|
|
||||||
|
// Scan for lowest and highest characters defined and total font width.
|
||||||
|
FirstChar = 256;
|
||||||
|
LastChar = 0;
|
||||||
|
totalwidth = 0;
|
||||||
|
for (i = chari = 0; i < numchars; ++i, chari += 6 + chardata[chari+1] * chardata[chari+2])
|
||||||
|
{
|
||||||
|
if ((chardata[chari+1] == 0 || chardata[chari+2] == 0) && chardata[chari+5] == 0)
|
||||||
|
{ // Don't count empty characters.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (chardata[chari] < FirstChar)
|
||||||
|
{
|
||||||
|
FirstChar = chardata[chari];
|
||||||
|
}
|
||||||
|
if (chardata[chari] > LastChar)
|
||||||
|
{
|
||||||
|
LastChar = chardata[chari];
|
||||||
|
}
|
||||||
|
totalwidth += chardata[chari+1];
|
||||||
|
}
|
||||||
|
if (LastChar < FirstChar)
|
||||||
|
{
|
||||||
|
I_FatalError("BMF font defines no characters");
|
||||||
|
}
|
||||||
|
count = LastChar - FirstChar + 1;
|
||||||
|
Chars = new CharData[count];
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// BMF palettes are only six bits per component. Fix that.
|
||||||
|
for (i = 0; i < ActiveColors*3; ++i)
|
||||||
|
{
|
||||||
|
raw_palette[i] = (data[17 + i] << 2) | (data[17 + i] >> 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
}
|
||||||
|
qsort(sort_palette + 1, ActiveColors - 1, sizeof(PalEntry), BMFCompare);
|
||||||
|
|
||||||
|
// Create the PatchRemap table from the sorted "alpha" values.
|
||||||
|
PatchRemap = new BYTE[ActiveColors];
|
||||||
|
PatchRemap[0] = 0;
|
||||||
|
for (i = 1; i < ActiveColors; ++i)
|
||||||
|
{
|
||||||
|
PatchRemap[sort_palette[i].a] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
FixupPalette(identity, luminosity, raw_palette, true, local_palette);
|
||||||
|
|
||||||
|
// 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])
|
||||||
|
{
|
||||||
|
assert(chardata[chari] - FirstChar >= 0);
|
||||||
|
assert(chardata[chari] - FirstChar < count);
|
||||||
|
if (chardata[chari] == ' ')
|
||||||
|
{
|
||||||
|
SpaceWidth = chardata[chari+5];
|
||||||
|
}
|
||||||
|
else if (chardata[chari] == 'N')
|
||||||
|
{
|
||||||
|
nwidth = chardata[chari+5];
|
||||||
|
}
|
||||||
|
Chars[chardata[chari] - FirstChar].XMove = chardata[chari+5];
|
||||||
|
if (chardata[chari+1] == 0 || chardata[chari+2] == 0)
|
||||||
|
{ // Empty character: skip it.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, PatchRemap, int(chardata + chari + 6 - data),
|
||||||
|
chardata[chari+1], // width
|
||||||
|
chardata[chari+2], // height
|
||||||
|
-(SBYTE)chardata[chari+3], // x offset
|
||||||
|
-(SBYTE)chardata[chari+4] // y offset
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the font did not define a space character, determine a suitable space width now.
|
||||||
|
if (SpaceWidth < 0)
|
||||||
|
{
|
||||||
|
if (nwidth >= 0)
|
||||||
|
{
|
||||||
|
SpaceWidth = nwidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpaceWidth = totalwidth * 2 / (3 * count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
BuildTranslations(luminosity, identity, &TranslationParms[0][0], ActiveColors, local_palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FSingleLumpFont :: BMFCompare STATIC
|
||||||
|
//
|
||||||
|
// Helper to sort BMF palettes.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int STACK_ARGS 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
|
// FSingleLumpFont :: CheckFON1Chars
|
||||||
|
@ -1069,6 +1238,7 @@ void FSingleLumpFont::CheckFON1Chars (int lump, const BYTE *data, double *lumino
|
||||||
int destSize = SpaceWidth * FontHeight;
|
int destSize = SpaceWidth * FontHeight;
|
||||||
|
|
||||||
Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight);
|
Chars[i].Pic = new FFontChar2 (lump, PatchRemap, int(data_p - data), SpaceWidth, FontHeight);
|
||||||
|
Chars[i].XMove = SpaceWidth;
|
||||||
|
|
||||||
// Advance to next char's data and count the used colors.
|
// Advance to next char's data and count the used colors.
|
||||||
do
|
do
|
||||||
|
@ -1332,14 +1502,14 @@ FFontChar1::~FFontChar1 ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FFontChar2::FFontChar2 (int sourcelump, const BYTE *sourceremap, int sourcepos, int width, int height)
|
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)
|
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(sourceremap)
|
||||||
{
|
{
|
||||||
UseType = TEX_FontChar;
|
UseType = TEX_FontChar;
|
||||||
Width = width;
|
Width = width;
|
||||||
Height = height;
|
Height = height;
|
||||||
TopOffset = 0;
|
LeftOffset = leftofs;
|
||||||
LeftOffset = 0;
|
TopOffset = topofs;
|
||||||
CalcBitSize ();
|
CalcBitSize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,10 +1597,11 @@ void FFontChar2::MakeTexture ()
|
||||||
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
FWadLump lump = Wads.OpenLumpNum (SourceLump);
|
||||||
int destSize = Width * Height;
|
int destSize = Width * Height;
|
||||||
BYTE max = 255;
|
BYTE max = 255;
|
||||||
|
bool rle = true;
|
||||||
|
|
||||||
// This is to "fix" bad fonts
|
// This is to "fix" bad fonts
|
||||||
{
|
{
|
||||||
BYTE buff[8];
|
BYTE buff[16];
|
||||||
lump.Read (buff, 4);
|
lump.Read (buff, 4);
|
||||||
if (buff[3] == '2')
|
if (buff[3] == '2')
|
||||||
{
|
{
|
||||||
|
@ -1438,6 +1609,13 @@ void FFontChar2::MakeTexture ()
|
||||||
max = buff[6];
|
max = buff[6];
|
||||||
lump.Seek (SourcePos - 11, SEEK_CUR);
|
lump.Seek (SourcePos - 11, SEEK_CUR);
|
||||||
}
|
}
|
||||||
|
else if (buff[3] == 0x1A)
|
||||||
|
{
|
||||||
|
lump.Read(buff, 13);
|
||||||
|
max = buff[12] - 1;
|
||||||
|
lump.Seek (SourcePos - 17, SEEK_CUR);
|
||||||
|
rle = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lump.Seek (SourcePos - 4, SEEK_CUR);
|
lump.Seek (SourcePos - 4, SEEK_CUR);
|
||||||
|
@ -1452,55 +1630,81 @@ void FFontChar2::MakeTexture ()
|
||||||
int dest_adv = Height;
|
int dest_adv = Height;
|
||||||
int dest_rew = destSize - 1;
|
int dest_rew = destSize - 1;
|
||||||
|
|
||||||
for (int y = Height; y != 0; --y)
|
if (rle)
|
||||||
{
|
{
|
||||||
for (int x = Width; x != 0; )
|
for (int y = Height; y != 0; --y)
|
||||||
{
|
{
|
||||||
if (runlen != 0)
|
for (int x = Width; x != 0; )
|
||||||
{
|
{
|
||||||
BYTE color;
|
if (runlen != 0)
|
||||||
|
|
||||||
lump >> color;
|
|
||||||
*dest_p = MIN (color, max);
|
|
||||||
if (SourceRemap != NULL)
|
|
||||||
{
|
|
||||||
*dest_p = SourceRemap[*dest_p];
|
|
||||||
}
|
|
||||||
dest_p += dest_adv;
|
|
||||||
x--;
|
|
||||||
runlen--;
|
|
||||||
}
|
|
||||||
else if (setlen != 0)
|
|
||||||
{
|
|
||||||
*dest_p = setval;
|
|
||||||
dest_p += dest_adv;
|
|
||||||
x--;
|
|
||||||
setlen--;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SBYTE code;
|
|
||||||
|
|
||||||
lump >> code;
|
|
||||||
if (code >= 0)
|
|
||||||
{
|
|
||||||
runlen = code + 1;
|
|
||||||
}
|
|
||||||
else if (code != -128)
|
|
||||||
{
|
{
|
||||||
BYTE color;
|
BYTE color;
|
||||||
|
|
||||||
lump >> color;
|
lump >> color;
|
||||||
setlen = (-code) + 1;
|
color = MIN (color, max);
|
||||||
setval = MIN (color, max);
|
|
||||||
if (SourceRemap != NULL)
|
if (SourceRemap != NULL)
|
||||||
{
|
{
|
||||||
setval = SourceRemap[setval];
|
color = SourceRemap[color];
|
||||||
|
}
|
||||||
|
*dest_p = color;
|
||||||
|
dest_p += dest_adv;
|
||||||
|
x--;
|
||||||
|
runlen--;
|
||||||
|
}
|
||||||
|
else if (setlen != 0)
|
||||||
|
{
|
||||||
|
*dest_p = setval;
|
||||||
|
dest_p += dest_adv;
|
||||||
|
x--;
|
||||||
|
setlen--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SBYTE code;
|
||||||
|
|
||||||
|
lump >> code;
|
||||||
|
if (code >= 0)
|
||||||
|
{
|
||||||
|
runlen = code + 1;
|
||||||
|
}
|
||||||
|
else if (code != -128)
|
||||||
|
{
|
||||||
|
BYTE color;
|
||||||
|
|
||||||
|
lump >> color;
|
||||||
|
setlen = (-code) + 1;
|
||||||
|
setval = MIN (color, max);
|
||||||
|
if (SourceRemap != NULL)
|
||||||
|
{
|
||||||
|
setval = SourceRemap[setval];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dest_p -= dest_rew;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int y = Height; y != 0; --y)
|
||||||
|
{
|
||||||
|
for (int x = Width; x != 0; --x)
|
||||||
|
{
|
||||||
|
BYTE color;
|
||||||
|
lump >> color;
|
||||||
|
if (color > max)
|
||||||
|
{
|
||||||
|
color = max;
|
||||||
|
}
|
||||||
|
if (SourceRemap != NULL)
|
||||||
|
{
|
||||||
|
color = SourceRemap[color];
|
||||||
|
}
|
||||||
|
*dest_p = color;
|
||||||
|
dest_p += dest_adv;
|
||||||
|
}
|
||||||
|
dest_p -= dest_rew;
|
||||||
}
|
}
|
||||||
dest_p -= dest_rew;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (destSize < 0)
|
if (destSize < 0)
|
||||||
|
@ -1593,23 +1797,27 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
if (charlumps[i] != NULL)
|
if (charlumps[i] != NULL)
|
||||||
{
|
{
|
||||||
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
Chars[i].Pic = new FFontChar1 (charlumps[i], PatchRemap);
|
||||||
|
Chars[i].XMove = Chars[i].Pic->GetScaledWidth();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Chars[i].Pic = NULL;
|
Chars[i].Pic = NULL;
|
||||||
|
Chars[i].XMove = INT_MIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special fonts normally don't have all characters so be careful here!
|
// Special fonts normally don't have all characters so be careful here!
|
||||||
if ('N'-first>=0 && 'N'-first<count && Chars['N' - first].Pic)
|
if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL)
|
||||||
{
|
{
|
||||||
SpaceWidth = (Chars['N' - first].Pic->GetScaledWidth() + 1) / 2;
|
SpaceWidth = (Chars['N' - first].XMove + 1) / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SpaceWidth = 4;
|
SpaceWidth = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FixXMoves();
|
||||||
|
|
||||||
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
|
BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL);
|
||||||
|
|
||||||
// add the untranslated colors to the Ranges tables
|
// add the untranslated colors to the Ranges tables
|
||||||
|
@ -1632,6 +1840,36 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l
|
||||||
delete[] charlumps;
|
delete[] charlumps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// FFont :: FixXMoves
|
||||||
|
//
|
||||||
|
// If a font has gaps in its characters, set the missing characters'
|
||||||
|
// XMoves to either SpaceWidth or the uppercase variant's XMove. Missing
|
||||||
|
// XMoves must be initialized with INT_MIN beforehand.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FFont::FixXMoves()
|
||||||
|
{
|
||||||
|
for (int i = 0; i <= LastChar - FirstChar; ++i)
|
||||||
|
{
|
||||||
|
if (Chars[i].XMove == INT_MIN)
|
||||||
|
{
|
||||||
|
if (myislower[i + FirstChar])
|
||||||
|
{
|
||||||
|
int upper = i - 32;
|
||||||
|
if (upper >= 0)
|
||||||
|
{
|
||||||
|
Chars[i].XMove = Chars[upper].XMove;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Chars[i].XMove = SpaceWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
|
|
|
@ -94,11 +94,14 @@ public:
|
||||||
int StringWidth (const BYTE *str) const;
|
int StringWidth (const BYTE *str) const;
|
||||||
inline int StringWidth (const char *str) const { return StringWidth ((const BYTE *)str); }
|
inline int StringWidth (const char *str) const { return StringWidth ((const BYTE *)str); }
|
||||||
|
|
||||||
|
int GetCharCode(int code, bool needpic) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FFont ();
|
FFont ();
|
||||||
|
|
||||||
void BuildTranslations (const double *luminosity, const BYTE *identity,
|
void BuildTranslations (const double *luminosity, const BYTE *identity,
|
||||||
const void *ranges, int total_colors, const PalEntry *palette);
|
const void *ranges, int total_colors, const PalEntry *palette);
|
||||||
|
void FixXMoves();
|
||||||
|
|
||||||
static int SimpleTranslation (BYTE *colorsused, BYTE *translation,
|
static int SimpleTranslation (BYTE *colorsused, BYTE *translation,
|
||||||
BYTE *identity, double **luminosity);
|
BYTE *identity, double **luminosity);
|
||||||
|
@ -110,6 +113,7 @@ protected:
|
||||||
struct CharData
|
struct CharData
|
||||||
{
|
{
|
||||||
FTexture *Pic;
|
FTexture *Pic;
|
||||||
|
int XMove;
|
||||||
} *Chars;
|
} *Chars;
|
||||||
int ActiveColors;
|
int ActiveColors;
|
||||||
TArray<FRemapTable> Ranges;
|
TArray<FRemapTable> Ranges;
|
||||||
|
|
|
@ -1935,15 +1935,13 @@ void WI_loadData(void)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int dummywidth;
|
star = BigFont->GetChar('*', NULL);
|
||||||
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
||||||
bstar = star;
|
bstar = star;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Strife needs some handling, too!
|
else // Strife needs some handling, too!
|
||||||
{
|
{
|
||||||
int dummywidth;
|
star = BigFont->GetChar('*', NULL);
|
||||||
star = BigFont->GetChar('*', &dummywidth); // just a dummy to avoid an error if it is being used
|
|
||||||
bstar = star;
|
bstar = star;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1291,7 +1291,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
|
||||||
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
|
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
|
||||||
|
|
||||||
// Use this to break at a specific allocation number.
|
// Use this to break at a specific allocation number.
|
||||||
//_crtBreakAlloc = 3660;
|
//_crtBreakAlloc = 30055;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DoMain (hInstance);
|
DoMain (hInstance);
|
||||||
|
|
Loading…
Reference in a new issue