- 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:
Christoph Oelckers 2016-04-09 20:47:54 +02:00
commit a827bab576
4 changed files with 250 additions and 234 deletions

View file

@ -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