- refactored the use of tag lists so that they do not have to be passed around between functions.
This means that the varargs functions themselves are now responsible for parsing them into DrawParms. This was done because DrawTextV made a blanket assumption that every single vararg has the size of a 32 bit integer and caused crashes when anything else was passed. It also failed to eliminate any tag that is incompatible with text display. These will now abort DrawText and trigger an assert.
This commit is contained in:
parent
e2ae7d8f5d
commit
a827bab576
4 changed files with 250 additions and 234 deletions
185
src/v_text.cpp
185
src/v_text.cpp
|
|
@ -52,7 +52,7 @@
|
|||
//
|
||||
// Write a single character using the given font
|
||||
//
|
||||
void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...)
|
||||
void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...)
|
||||
{
|
||||
if (font == NULL)
|
||||
return;
|
||||
|
|
@ -65,11 +65,17 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B
|
|||
|
||||
if (NULL != (pic = font->GetChar (character, &dummy)))
|
||||
{
|
||||
const FRemapTable *range = font->GetColorTranslation ((EColorRange)normalcolor);
|
||||
va_list taglist;
|
||||
va_start (taglist, character);
|
||||
DrawTexture (pic, x, y, DTA_Translation, range, TAG_MORE, &taglist);
|
||||
va_end (taglist);
|
||||
DrawParms parms;
|
||||
va_list tags;
|
||||
va_start(tags, tag_first);
|
||||
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
|
||||
va_end(tags);
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
parms.remap = font->GetColorTranslation((EColorRange)normalcolor);
|
||||
DrawTextureParms(pic, parms);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,135 +84,53 @@ void STACK_ARGS DCanvas::DrawChar (FFont *font, int normalcolor, int x, int y, B
|
|||
//
|
||||
// Write a string using the given font
|
||||
//
|
||||
void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *string, va_list taglist)
|
||||
void STACK_ARGS DCanvas::DrawText(FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...)
|
||||
{
|
||||
INTBOOL boolval;
|
||||
va_list tags;
|
||||
uint32 tag;
|
||||
|
||||
int maxstrlen = INT_MAX;
|
||||
int w, maxwidth;
|
||||
int w;
|
||||
const BYTE *ch;
|
||||
int c;
|
||||
int cx;
|
||||
int cy;
|
||||
int boldcolor;
|
||||
const FRemapTable *range;
|
||||
int height;
|
||||
int forcedwidth = 0;
|
||||
int scalex, scaley;
|
||||
FRemapTable *range;
|
||||
int kerning;
|
||||
FTexture *pic;
|
||||
DrawParms parms;
|
||||
|
||||
va_list tags;
|
||||
|
||||
if (font == NULL || string == NULL)
|
||||
return;
|
||||
|
||||
va_start(tags, tag_first);
|
||||
bool res = ParseDrawTextureTags(nullptr, 0, 0, tag_first, tags, &parms, true);
|
||||
va_end(tags);
|
||||
if (!res)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (parms.celly == 0) parms.celly = font->GetHeight() + 1;
|
||||
parms.celly *= parms.scaley;
|
||||
|
||||
if (normalcolor >= NumTextColors)
|
||||
normalcolor = CR_UNTRANSLATED;
|
||||
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
|
||||
|
||||
range = font->GetColorTranslation ((EColorRange)normalcolor);
|
||||
height = font->GetHeight () + 1;
|
||||
|
||||
kerning = font->GetDefaultKerning ();
|
||||
|
||||
ch = (const BYTE *)string;
|
||||
cx = x;
|
||||
cy = y;
|
||||
|
||||
// Parse the tag list to see if we need to adjust for scaling.
|
||||
maxwidth = Width;
|
||||
scalex = scaley = 1;
|
||||
|
||||
#ifndef NO_VA_COPY
|
||||
va_copy(tags, taglist);
|
||||
#else
|
||||
tags = taglist;
|
||||
#endif
|
||||
tag = va_arg(tags, uint32);
|
||||
|
||||
while (tag != TAG_DONE)
|
||||
{
|
||||
va_list *more_p;
|
||||
DWORD data;
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case TAG_IGNORE:
|
||||
default:
|
||||
data = va_arg (tags, DWORD);
|
||||
break;
|
||||
|
||||
case TAG_MORE:
|
||||
more_p = va_arg (tags, va_list*);
|
||||
va_end (tags);
|
||||
#ifndef NO_VA_COPY
|
||||
va_copy (tags, *more_p);
|
||||
#else
|
||||
tags = *more_p;
|
||||
#endif
|
||||
break;
|
||||
|
||||
// We don't handle these. :(
|
||||
case DTA_DestWidth:
|
||||
case DTA_DestHeight:
|
||||
case DTA_Translation:
|
||||
assert("Bad parameter for DrawText" && false);
|
||||
return;
|
||||
|
||||
case DTA_CleanNoMove_1:
|
||||
boolval = va_arg (tags, INTBOOL);
|
||||
if (boolval)
|
||||
{
|
||||
scalex = CleanXfac_1;
|
||||
scaley = CleanYfac_1;
|
||||
maxwidth = Width - (Width % scalex);
|
||||
}
|
||||
break;
|
||||
|
||||
case DTA_CleanNoMove:
|
||||
boolval = va_arg (tags, INTBOOL);
|
||||
if (boolval)
|
||||
{
|
||||
scalex = CleanXfac;
|
||||
scaley = CleanYfac;
|
||||
maxwidth = Width - (Width % scalex);
|
||||
}
|
||||
break;
|
||||
|
||||
case DTA_Clean:
|
||||
case DTA_320x200:
|
||||
boolval = va_arg (tags, INTBOOL);
|
||||
if (boolval)
|
||||
{
|
||||
scalex = scaley = 1;
|
||||
maxwidth = 320;
|
||||
}
|
||||
break;
|
||||
|
||||
case DTA_VirtualWidth:
|
||||
maxwidth = va_arg (tags, int);
|
||||
scalex = scaley = 1;
|
||||
break;
|
||||
|
||||
case DTA_TextLen:
|
||||
maxstrlen = va_arg (tags, int);
|
||||
break;
|
||||
|
||||
case DTA_CellX:
|
||||
forcedwidth = va_arg (tags, int);
|
||||
break;
|
||||
|
||||
case DTA_CellY:
|
||||
height = va_arg (tags, int);
|
||||
break;
|
||||
}
|
||||
tag = va_arg (tags, uint32);
|
||||
}
|
||||
va_end(tags);
|
||||
|
||||
height *= scaley;
|
||||
|
||||
while ((const char *)ch - string < maxstrlen)
|
||||
while ((const char *)ch - string < parms.maxstrlen)
|
||||
{
|
||||
c = *ch++;
|
||||
if (!c)
|
||||
|
|
@ -225,53 +149,26 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
|||
if (c == '\n')
|
||||
{
|
||||
cx = x;
|
||||
cy += height;
|
||||
cy += parms.celly;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL != (pic = font->GetChar (c, &w)))
|
||||
{
|
||||
#ifndef NO_VA_COPY
|
||||
va_copy(tags, taglist);
|
||||
#else
|
||||
tags = taglist;
|
||||
#endif
|
||||
if (forcedwidth)
|
||||
parms.remap = range;
|
||||
SetTextureParms(&parms, pic, cx, cy);
|
||||
if (parms.cellx)
|
||||
{
|
||||
w = forcedwidth;
|
||||
DrawTexture (pic, cx, cy,
|
||||
DTA_Translation, range,
|
||||
DTA_DestWidth, forcedwidth,
|
||||
DTA_DestHeight, height,
|
||||
TAG_MORE, &tags);
|
||||
w = parms.cellx;
|
||||
parms.destwidth = parms.cellx;
|
||||
parms.destheight = parms.celly;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawTexture (pic, cx, cy,
|
||||
DTA_Translation, range,
|
||||
TAG_MORE, &tags);
|
||||
}
|
||||
va_end (tags);
|
||||
DrawTextureParms(pic, parms);
|
||||
}
|
||||
cx += (w + kerning) * scalex;
|
||||
cx += (w + kerning) * parms.scalex;
|
||||
}
|
||||
va_end(taglist);
|
||||
}
|
||||
|
||||
void STACK_ARGS DCanvas::DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...)
|
||||
{
|
||||
va_list tags;
|
||||
va_start(tags, string);
|
||||
DrawTextV(font, normalcolor, x, y, string, tags);
|
||||
}
|
||||
|
||||
// A synonym so that this can still be used in files that #include Windows headers
|
||||
void STACK_ARGS DCanvas::DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...)
|
||||
{
|
||||
va_list tags;
|
||||
va_start(tags, string);
|
||||
DrawTextV(font, normalcolor, x, y, string, tags);
|
||||
}
|
||||
|
||||
//
|
||||
// Find string width using this font
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue