mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 06:12:19 +00:00
- 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
273
src/v_draw.cpp
273
src/v_draw.cpp
|
@ -112,7 +112,9 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, double x, double y, int tag
|
||||||
va_start(tags, tags_first);
|
va_start(tags, tags_first);
|
||||||
DrawParms parms;
|
DrawParms parms;
|
||||||
|
|
||||||
if (!ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false))
|
bool res = ParseDrawTextureTags(img, x, y, tags_first, tags, &parms, false);
|
||||||
|
va_end(tags);
|
||||||
|
if (!res)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -249,10 +251,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
|
|
||||||
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
||||||
{
|
{
|
||||||
|
double wi = MIN(parms.windowright, parms.texwidth);
|
||||||
double xscale = parms.destwidth / parms.texwidth;
|
double xscale = parms.destwidth / parms.texwidth;
|
||||||
x0 += parms.windowleft * xscale;
|
x0 += parms.windowleft * xscale;
|
||||||
frac += FLOAT2FIXED(parms.windowleft);
|
frac += FLOAT2FIXED(parms.windowleft);
|
||||||
x2 -= (parms.texwidth - parms.windowright) * xscale;
|
x2 -= (parms.texwidth - wi) * xscale;
|
||||||
}
|
}
|
||||||
if (x0 < parms.lclip)
|
if (x0 < parms.lclip)
|
||||||
{
|
{
|
||||||
|
@ -330,18 +333,111 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy) const
|
||||||
|
{
|
||||||
|
if (img != NULL)
|
||||||
|
{
|
||||||
|
parms->x = xx;
|
||||||
|
parms->y = yy;
|
||||||
|
parms->texwidth = img->GetScaledWidthDouble();
|
||||||
|
parms->texheight = img->GetScaledHeightDouble();
|
||||||
|
if (parms->top == INT_MAX || parms->fortext)
|
||||||
|
{
|
||||||
|
parms->top = img->GetScaledTopOffset();
|
||||||
|
}
|
||||||
|
if (parms->left == INT_MAX || parms->fortext)
|
||||||
|
{
|
||||||
|
parms->left = img->GetScaledLeftOffset();
|
||||||
|
}
|
||||||
|
if (parms->destwidth == INT_MAX || parms->fortext)
|
||||||
|
{
|
||||||
|
parms->destwidth = img->GetScaledWidthDouble();
|
||||||
|
}
|
||||||
|
if (parms->destheight == INT_MAX || parms->fortext)
|
||||||
|
{
|
||||||
|
parms->destheight = img->GetScaledHeightDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (parms->cleanmode)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_Clean:
|
||||||
|
parms->x = (parms->x - 160.0) * CleanXfac + (Width * 0.5);
|
||||||
|
parms->y = (parms->y - 100.0) * CleanYfac + (Height * 0.5);
|
||||||
|
parms->destwidth = parms->texwidth * CleanXfac;
|
||||||
|
parms->destheight = parms->texheight * CleanYfac;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_CleanNoMove:
|
||||||
|
parms->destwidth = parms->texwidth * CleanXfac;
|
||||||
|
parms->destheight = parms->texheight * CleanYfac;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_CleanNoMove_1:
|
||||||
|
parms->destwidth = parms->texwidth * CleanXfac_1;
|
||||||
|
parms->destheight = parms->texheight * CleanYfac_1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_Fullscreen:
|
||||||
|
parms->x = parms->y = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_HUDRules:
|
||||||
|
case DTA_HUDRulesC:
|
||||||
|
{
|
||||||
|
bool xright = parms->x < 0;
|
||||||
|
bool ybot = parms->y < 0;
|
||||||
|
|
||||||
|
if (hud_scale)
|
||||||
|
{
|
||||||
|
parms->x *= CleanXfac;
|
||||||
|
if (parms->cleanmode == DTA_HUDRulesC)
|
||||||
|
parms->x += Width * 0.5;
|
||||||
|
else if (xright)
|
||||||
|
parms->x = Width + parms->x;
|
||||||
|
parms->y *= CleanYfac;
|
||||||
|
if (ybot)
|
||||||
|
parms->y = Height + parms->y;
|
||||||
|
parms->destwidth = parms->texwidth * CleanXfac;
|
||||||
|
parms->destheight = parms->texheight * CleanYfac;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (parms->cleanmode == DTA_HUDRulesC)
|
||||||
|
parms->x += Width * 0.5;
|
||||||
|
else if (xright)
|
||||||
|
parms->x = Width + parms->x;
|
||||||
|
if (ybot)
|
||||||
|
parms->y = Height + parms->y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parms->virtWidth != Width || parms->virtHeight != Height)
|
||||||
|
{
|
||||||
|
VirtualToRealCoords(parms->x, parms->y, parms->destwidth, parms->destheight,
|
||||||
|
parms->virtWidth, parms->virtHeight, parms->virtBottom, !parms->keepratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool fortext) const
|
bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag, va_list tags, DrawParms *parms, bool fortext) const
|
||||||
{
|
{
|
||||||
INTBOOL boolval;
|
INTBOOL boolval;
|
||||||
int intval;
|
int intval;
|
||||||
bool translationset = false;
|
bool translationset = false;
|
||||||
bool virtBottom;
|
|
||||||
bool fillcolorset = false;
|
bool fillcolorset = false;
|
||||||
|
|
||||||
if (img == NULL || img->UseType == FTexture::TEX_Null)
|
if (!fortext)
|
||||||
{
|
{
|
||||||
va_end(tags);
|
if (img == NULL || img->UseType == FTexture::TEX_Null)
|
||||||
return false;
|
{
|
||||||
|
va_end(tags);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do some sanity checks on the coordinates.
|
// Do some sanity checks on the coordinates.
|
||||||
|
@ -351,21 +447,17 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtBottom = false;
|
parms->fortext = fortext;
|
||||||
|
|
||||||
parms->texwidth = img->GetScaledWidthDouble();
|
|
||||||
parms->texheight = img->GetScaledHeightDouble();
|
|
||||||
|
|
||||||
parms->windowleft = 0;
|
parms->windowleft = 0;
|
||||||
parms->windowright = parms->texwidth;
|
parms->windowright = INT_MAX;
|
||||||
parms->dclip = this->GetHeight();
|
parms->dclip = this->GetHeight();
|
||||||
parms->uclip = 0;
|
parms->uclip = 0;
|
||||||
parms->lclip = 0;
|
parms->lclip = 0;
|
||||||
parms->rclip = this->GetWidth();
|
parms->rclip = this->GetWidth();
|
||||||
parms->destwidth = parms->windowright;
|
parms->left = INT_MAX;
|
||||||
parms->destheight = parms->texheight;
|
parms->top = INT_MAX;
|
||||||
parms->top = img->GetScaledTopOffset();
|
parms->destwidth = INT_MAX;
|
||||||
parms->left = img->GetScaledLeftOffset();
|
parms->destheight = INT_MAX;
|
||||||
parms->Alpha = 1.f;
|
parms->Alpha = 1.f;
|
||||||
parms->fillcolor = -1;
|
parms->fillcolor = -1;
|
||||||
parms->remap = NULL;
|
parms->remap = NULL;
|
||||||
|
@ -383,48 +475,50 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
parms->bilinear = false;
|
parms->bilinear = false;
|
||||||
parms->specialcolormap = NULL;
|
parms->specialcolormap = NULL;
|
||||||
parms->colormapstyle = NULL;
|
parms->colormapstyle = NULL;
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->x = x;
|
parms->scalex = parms->scaley = 1;
|
||||||
parms->y = y;
|
parms->cellx = parms->celly = 0;
|
||||||
|
parms->maxstrlen = INT_MAX;
|
||||||
|
parms->virtBottom = false;
|
||||||
|
|
||||||
// Parse the tag list for attributes. (For floating point attributes,
|
// Parse the tag list for attributes. (For floating point attributes,
|
||||||
// consider that the C ABI dictates that all floats be promoted to
|
// consider that the C ABI dictates that all floats be promoted to
|
||||||
// doubles when passed as function arguments.)
|
// doubles when passed as function arguments.)
|
||||||
while (tag != TAG_DONE)
|
while (tag != TAG_DONE)
|
||||||
{
|
{
|
||||||
va_list *more_p;
|
|
||||||
DWORD data;
|
DWORD data;
|
||||||
|
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case TAG_IGNORE:
|
|
||||||
default:
|
default:
|
||||||
data = va_arg(tags, DWORD);
|
data = va_arg(tags, DWORD);
|
||||||
break;
|
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;
|
|
||||||
|
|
||||||
case DTA_DestWidth:
|
case DTA_DestWidth:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->destwidth = va_arg(tags, int);
|
parms->destwidth = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_DestWidthF:
|
case DTA_DestWidthF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->destwidth = va_arg(tags, double);
|
parms->destwidth = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_DestHeight:
|
case DTA_DestHeight:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->destheight = va_arg(tags, int);
|
parms->destheight = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_DestHeightF:
|
case DTA_DestHeightF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->destheight = va_arg(tags, double);
|
parms->destheight = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -432,10 +526,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
parms->x = (parms->x - 160.0) * CleanXfac + (Width * 0.5);
|
parms->scalex = 1;
|
||||||
parms->y = (parms->y - 100.0) * CleanYfac + (Height * 0.5);
|
parms->scaley = 1;
|
||||||
parms->destwidth = parms->texwidth * CleanXfac;
|
parms->cleanmode = tag;
|
||||||
parms->destheight = parms->texheight * CleanYfac;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -443,8 +536,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
parms->destwidth = parms->texwidth * CleanXfac;
|
parms->scalex = CleanXfac;
|
||||||
parms->destheight = parms->texheight * CleanYfac;
|
parms->scaley = CleanYfac;
|
||||||
|
parms->cleanmode = tag;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -452,8 +546,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
parms->destwidth = parms->texwidth * CleanXfac_1;
|
parms->scalex = CleanXfac_1;
|
||||||
parms->destheight = parms->texheight * CleanYfac_1;
|
parms->scaley = CleanYfac_1;
|
||||||
|
parms->cleanmode = tag;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -461,6 +556,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
|
parms->scalex = 1;
|
||||||
|
parms->scaley = 1;
|
||||||
parms->virtWidth = 320;
|
parms->virtWidth = 320;
|
||||||
parms->virtHeight = 200;
|
parms->virtHeight = 200;
|
||||||
}
|
}
|
||||||
|
@ -470,56 +568,37 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
|
parms->scalex = 1;
|
||||||
|
parms->scaley = 1;
|
||||||
parms->virtWidth = 320;
|
parms->virtWidth = 320;
|
||||||
parms->virtHeight = 200;
|
parms->virtHeight = 200;
|
||||||
}
|
}
|
||||||
virtBottom = true;
|
parms->virtBottom = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_HUDRules:
|
case DTA_HUDRules:
|
||||||
{
|
intval = va_arg(tags, int);
|
||||||
bool xright = parms->x < 0;
|
parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules;
|
||||||
bool ybot = parms->y < 0;
|
|
||||||
intval = va_arg(tags, int);
|
|
||||||
|
|
||||||
if (hud_scale)
|
|
||||||
{
|
|
||||||
parms->x *= CleanXfac;
|
|
||||||
if (intval == HUD_HorizCenter)
|
|
||||||
parms->x += Width * 0.5;
|
|
||||||
else if (xright)
|
|
||||||
parms->x = Width + parms->x;
|
|
||||||
parms->y *= CleanYfac;
|
|
||||||
if (ybot)
|
|
||||||
parms->y = Height + parms->y;
|
|
||||||
parms->destwidth = parms->texwidth * CleanXfac;
|
|
||||||
parms->destheight = parms->texheight * CleanYfac;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (intval == HUD_HorizCenter)
|
|
||||||
parms->x += Width * 0.5;
|
|
||||||
else if (xright)
|
|
||||||
parms->x = Width + parms->x;
|
|
||||||
if (ybot)
|
|
||||||
parms->y = Height + parms->y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_VirtualWidth:
|
case DTA_VirtualWidth:
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->virtWidth = va_arg(tags, int);
|
parms->virtWidth = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_VirtualWidthF:
|
case DTA_VirtualWidthF:
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->virtWidth = va_arg(tags, double);
|
parms->virtWidth = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_VirtualHeight:
|
case DTA_VirtualHeight:
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->virtHeight = va_arg(tags, int);
|
parms->virtHeight = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_VirtualHeightF:
|
case DTA_VirtualHeightF:
|
||||||
|
parms->cleanmode = DTA_Base;
|
||||||
parms->virtHeight = va_arg(tags, double);
|
parms->virtHeight = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -527,7 +606,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
boolval = va_arg(tags, INTBOOL);
|
boolval = va_arg(tags, INTBOOL);
|
||||||
if (boolval)
|
if (boolval)
|
||||||
{
|
{
|
||||||
parms->x = parms->y = 0;
|
assert(fortext == false);
|
||||||
|
if (img == NULL) return false;
|
||||||
|
parms->cleanmode = DTA_Fullscreen;
|
||||||
parms->virtWidth = img->GetScaledWidthDouble();
|
parms->virtWidth = img->GetScaledWidthDouble();
|
||||||
parms->virtHeight = img->GetScaledHeightDouble();
|
parms->virtHeight = img->GetScaledHeightDouble();
|
||||||
}
|
}
|
||||||
|
@ -567,50 +648,70 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_TopOffset:
|
case DTA_TopOffset:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->top = va_arg(tags, int);
|
parms->top = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_TopOffsetF:
|
case DTA_TopOffsetF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->top = va_arg(tags, double);
|
parms->top = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_LeftOffset:
|
case DTA_LeftOffset:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->left = va_arg(tags, int);
|
parms->left = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_LeftOffsetF:
|
case DTA_LeftOffsetF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->left = va_arg(tags, double);
|
parms->left = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_CenterOffset:
|
case DTA_CenterOffset:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
if (va_arg(tags, int))
|
if (va_arg(tags, int))
|
||||||
{
|
{
|
||||||
parms->left = parms->texwidth * 0.5;
|
parms->left = img->GetScaledWidthDouble() * 0.5;
|
||||||
parms->top = parms->texheight * 0.5;
|
parms->top = img->GetScaledHeightDouble() * 0.5;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_CenterBottomOffset:
|
case DTA_CenterBottomOffset:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
if (va_arg(tags, int))
|
if (va_arg(tags, int))
|
||||||
{
|
{
|
||||||
parms->left = parms->texwidth * 0.5;
|
parms->left = img->GetScaledWidthDouble() * 0.5;
|
||||||
parms->top = parms->texheight;
|
parms->top = img->GetScaledHeightDouble();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_WindowLeft:
|
case DTA_WindowLeft:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->windowleft = va_arg(tags, int);
|
parms->windowleft = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_WindowLeftF:
|
case DTA_WindowLeftF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->windowleft = va_arg(tags, double);
|
parms->windowleft = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_WindowRight:
|
case DTA_WindowRight:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->windowright = va_arg(tags, int);
|
parms->windowright = va_arg(tags, int);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DTA_WindowRightF:
|
case DTA_WindowRightF:
|
||||||
|
assert(fortext == false);
|
||||||
|
if (fortext) return false;
|
||||||
parms->windowright = va_arg(tags, double);
|
parms->windowright = va_arg(tags, double);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -692,6 +793,19 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
case DTA_ColormapStyle:
|
case DTA_ColormapStyle:
|
||||||
parms->colormapstyle = va_arg(tags, FColormapStyle *);
|
parms->colormapstyle = va_arg(tags, FColormapStyle *);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTA_TextLen:
|
||||||
|
parms->maxstrlen = va_arg(tags, int);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_CellX:
|
||||||
|
parms->cellx = va_arg(tags, int);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DTA_CellY:
|
||||||
|
parms->celly = va_arg(tags, int);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
tag = va_arg(tags, DWORD);
|
tag = va_arg(tags, DWORD);
|
||||||
}
|
}
|
||||||
|
@ -702,15 +816,14 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parms->virtWidth != Width || parms->virtHeight != Height)
|
if (img != NULL)
|
||||||
{
|
{
|
||||||
VirtualToRealCoords(parms->x, parms->y, parms->destwidth, parms->destheight,
|
SetTextureParms(parms, img, x, y);
|
||||||
parms->virtWidth, parms->virtHeight, virtBottom, !parms->keepratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parms->destwidth <= 0 || parms->destheight <= 0)
|
if (parms->destwidth <= 0 || parms->destheight <= 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parms->remap != NULL)
|
if (parms->remap != NULL)
|
||||||
|
|
185
src/v_text.cpp
185
src/v_text.cpp
|
@ -52,7 +52,7 @@
|
||||||
//
|
//
|
||||||
// Write a single character using the given font
|
// 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)
|
if (font == NULL)
|
||||||
return;
|
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)))
|
if (NULL != (pic = font->GetChar (character, &dummy)))
|
||||||
{
|
{
|
||||||
const FRemapTable *range = font->GetColorTranslation ((EColorRange)normalcolor);
|
DrawParms parms;
|
||||||
va_list taglist;
|
va_list tags;
|
||||||
va_start (taglist, character);
|
va_start(tags, tag_first);
|
||||||
DrawTexture (pic, x, y, DTA_Translation, range, TAG_MORE, &taglist);
|
bool res = ParseDrawTextureTags(pic, x, y, tag_first, tags, &parms, false);
|
||||||
va_end (taglist);
|
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
|
// 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;
|
INTBOOL boolval;
|
||||||
va_list tags;
|
|
||||||
uint32 tag;
|
uint32 tag;
|
||||||
|
|
||||||
int maxstrlen = INT_MAX;
|
int w;
|
||||||
int w, maxwidth;
|
|
||||||
const BYTE *ch;
|
const BYTE *ch;
|
||||||
int c;
|
int c;
|
||||||
int cx;
|
int cx;
|
||||||
int cy;
|
int cy;
|
||||||
int boldcolor;
|
int boldcolor;
|
||||||
const FRemapTable *range;
|
FRemapTable *range;
|
||||||
int height;
|
|
||||||
int forcedwidth = 0;
|
|
||||||
int scalex, scaley;
|
|
||||||
int kerning;
|
int kerning;
|
||||||
FTexture *pic;
|
FTexture *pic;
|
||||||
|
DrawParms parms;
|
||||||
|
|
||||||
|
va_list tags;
|
||||||
|
|
||||||
if (font == NULL || string == NULL)
|
if (font == NULL || string == NULL)
|
||||||
return;
|
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)
|
if (normalcolor >= NumTextColors)
|
||||||
normalcolor = CR_UNTRANSLATED;
|
normalcolor = CR_UNTRANSLATED;
|
||||||
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
|
boldcolor = normalcolor ? normalcolor - 1 : NumTextColors - 1;
|
||||||
|
|
||||||
range = font->GetColorTranslation ((EColorRange)normalcolor);
|
range = font->GetColorTranslation ((EColorRange)normalcolor);
|
||||||
height = font->GetHeight () + 1;
|
|
||||||
kerning = font->GetDefaultKerning ();
|
kerning = font->GetDefaultKerning ();
|
||||||
|
|
||||||
ch = (const BYTE *)string;
|
ch = (const BYTE *)string;
|
||||||
cx = x;
|
cx = x;
|
||||||
cy = y;
|
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++;
|
c = *ch++;
|
||||||
if (!c)
|
if (!c)
|
||||||
|
@ -225,53 +149,26 @@ void DCanvas::DrawTextV(FFont *font, int normalcolor, int x, int y, const char *
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
{
|
{
|
||||||
cx = x;
|
cx = x;
|
||||||
cy += height;
|
cy += parms.celly;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != (pic = font->GetChar (c, &w)))
|
if (NULL != (pic = font->GetChar (c, &w)))
|
||||||
{
|
{
|
||||||
#ifndef NO_VA_COPY
|
parms.remap = range;
|
||||||
va_copy(tags, taglist);
|
SetTextureParms(&parms, pic, cx, cy);
|
||||||
#else
|
if (parms.cellx)
|
||||||
tags = taglist;
|
|
||||||
#endif
|
|
||||||
if (forcedwidth)
|
|
||||||
{
|
{
|
||||||
w = forcedwidth;
|
w = parms.cellx;
|
||||||
DrawTexture (pic, cx, cy,
|
parms.destwidth = parms.cellx;
|
||||||
DTA_Translation, range,
|
parms.destheight = parms.celly;
|
||||||
DTA_DestWidth, forcedwidth,
|
|
||||||
DTA_DestHeight, height,
|
|
||||||
TAG_MORE, &tags);
|
|
||||||
}
|
}
|
||||||
else
|
DrawTextureParms(pic, parms);
|
||||||
{
|
|
||||||
DrawTexture (pic, cx, cy,
|
|
||||||
DTA_Translation, range,
|
|
||||||
TAG_MORE, &tags);
|
|
||||||
}
|
|
||||||
va_end (tags);
|
|
||||||
}
|
}
|
||||||
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
|
// Find string width using this font
|
||||||
|
|
|
@ -63,8 +63,6 @@ class FTexture;
|
||||||
|
|
||||||
#define TAG_DONE (0) /* Used to indicate the end of the Tag list */
|
#define TAG_DONE (0) /* Used to indicate the end of the Tag list */
|
||||||
#define TAG_END (0) /* Ditto */
|
#define TAG_END (0) /* Ditto */
|
||||||
#define TAG_IGNORE (1) /* Ignore this Tag */
|
|
||||||
#define TAG_MORE (2) /* Ends this list and continues with the */
|
|
||||||
/* list pointed to in ti_Data */
|
/* list pointed to in ti_Data */
|
||||||
|
|
||||||
#define TAG_USER ((DWORD)(1u<<30))
|
#define TAG_USER ((DWORD)(1u<<30))
|
||||||
|
@ -102,6 +100,7 @@ enum
|
||||||
DTA_ClipRight, // don't draw anything at or to the right of this column (on dest, not source)
|
DTA_ClipRight, // don't draw anything at or to the right of this column (on dest, not source)
|
||||||
DTA_Masked, // true(default)=use masks from texture, false=ignore masks
|
DTA_Masked, // true(default)=use masks from texture, false=ignore masks
|
||||||
DTA_HUDRules, // use fullscreen HUD rules to position and size textures
|
DTA_HUDRules, // use fullscreen HUD rules to position and size textures
|
||||||
|
DTA_HUDRulesC, // only used internally for marking HUD_HorizCenter
|
||||||
DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3
|
DTA_KeepRatio, // doesn't adjust screen size for DTA_Virtual* if the aspect ratio is not 4:3
|
||||||
DTA_RenderStyle, // same as render style for actors
|
DTA_RenderStyle, // same as render style for actors
|
||||||
DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software
|
DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software
|
||||||
|
@ -149,6 +148,7 @@ struct DrawParms
|
||||||
double virtHeight;
|
double virtHeight;
|
||||||
double windowleft;
|
double windowleft;
|
||||||
double windowright;
|
double windowright;
|
||||||
|
int cleanmode;
|
||||||
int dclip;
|
int dclip;
|
||||||
int uclip;
|
int uclip;
|
||||||
int lclip;
|
int lclip;
|
||||||
|
@ -170,6 +170,11 @@ struct DrawParms
|
||||||
FRenderStyle style;
|
FRenderStyle style;
|
||||||
struct FSpecialColormap *specialcolormap;
|
struct FSpecialColormap *specialcolormap;
|
||||||
struct FColormapStyle *colormapstyle;
|
struct FColormapStyle *colormapstyle;
|
||||||
|
int scalex, scaley;
|
||||||
|
int cellx, celly;
|
||||||
|
int maxstrlen;
|
||||||
|
bool fortext;
|
||||||
|
bool virtBottom;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -241,6 +246,7 @@ public:
|
||||||
// Text drawing functions -----------------------------------------------
|
// Text drawing functions -----------------------------------------------
|
||||||
|
|
||||||
// 2D Texture drawing
|
// 2D Texture drawing
|
||||||
|
bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const;
|
||||||
void STACK_ARGS DrawTexture (FTexture *img, double x, double y, int tags, ...);
|
void STACK_ARGS DrawTexture (FTexture *img, double x, double y, int tags, ...);
|
||||||
void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
|
void FillBorder (FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays
|
||||||
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const;
|
void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||||
|
@ -249,13 +255,12 @@ public:
|
||||||
void VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
void VirtualToRealCoordsFixed(fixed_t &x, fixed_t &y, fixed_t &w, fixed_t &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||||
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
void VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
|
||||||
|
|
||||||
// 2D Text drawing
|
#ifdef DrawText
|
||||||
void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...);
|
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
|
||||||
#ifndef DrawText // See WinUser.h for the definition of DrawText as a macro
|
|
||||||
void STACK_ARGS DrawTextA (FFont *font, int normalcolor, int x, int y, const char *string, ...);
|
|
||||||
#endif
|
#endif
|
||||||
void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, va_list tags);
|
// 2D Text drawing
|
||||||
void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...);
|
void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, int tag_first, ...);
|
||||||
|
void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, int tag_first, ...);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BYTE *Buffer;
|
BYTE *Buffer;
|
||||||
|
|
|
@ -2805,10 +2805,11 @@ void D3DFB::DrawTextureParms (FTexture *img, DrawParms &parms)
|
||||||
}
|
}
|
||||||
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
||||||
{
|
{
|
||||||
|
double wi = MIN(parms.windowright, parms.texwidth);
|
||||||
x0 += parms.windowleft * xscale;
|
x0 += parms.windowleft * xscale;
|
||||||
u0 = float(u0 + parms.windowleft * uscale);
|
u0 = float(u0 + parms.windowleft * uscale);
|
||||||
x1 -= (parms.texwidth - parms.windowright) * xscale;
|
x1 -= (parms.texwidth - wi) * xscale;
|
||||||
u1 = float(u1 - (parms.texwidth - parms.windowright) * uscale);
|
u1 = float(u1 - (parms.texwidth - wi) * uscale);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
Loading…
Reference in a new issue