This commit is contained in:
Christoph Oelckers 2016-04-09 20:48:54 +02:00
commit fde1f28d71
4 changed files with 250 additions and 234 deletions

View file

@ -112,7 +112,9 @@ void STACK_ARGS DCanvas::DrawTexture (FTexture *img, double x, double y, int tag
va_start(tags, tags_first);
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;
}
@ -249,10 +251,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
{
double wi = MIN(parms.windowright, parms.texwidth);
double xscale = parms.destwidth / parms.texwidth;
x0 += parms.windowleft * xscale;
frac += FLOAT2FIXED(parms.windowleft);
x2 -= (parms.texwidth - parms.windowright) * xscale;
x2 -= (parms.texwidth - wi) * xscale;
}
if (x0 < parms.lclip)
{
@ -330,18 +333,111 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
#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
{
INTBOOL boolval;
int intval;
bool translationset = false;
bool virtBottom;
bool fillcolorset = false;
if (img == NULL || img->UseType == FTexture::TEX_Null)
if (!fortext)
{
va_end(tags);
return false;
if (img == NULL || img->UseType == FTexture::TEX_Null)
{
va_end(tags);
return false;
}
}
// Do some sanity checks on the coordinates.
@ -351,21 +447,17 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
return false;
}
virtBottom = false;
parms->texwidth = img->GetScaledWidthDouble();
parms->texheight = img->GetScaledHeightDouble();
parms->fortext = fortext;
parms->windowleft = 0;
parms->windowright = parms->texwidth;
parms->windowright = INT_MAX;
parms->dclip = this->GetHeight();
parms->uclip = 0;
parms->lclip = 0;
parms->rclip = this->GetWidth();
parms->destwidth = parms->windowright;
parms->destheight = parms->texheight;
parms->top = img->GetScaledTopOffset();
parms->left = img->GetScaledLeftOffset();
parms->left = INT_MAX;
parms->top = INT_MAX;
parms->destwidth = INT_MAX;
parms->destheight = INT_MAX;
parms->Alpha = 1.f;
parms->fillcolor = -1;
parms->remap = NULL;
@ -383,48 +475,50 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
parms->bilinear = false;
parms->specialcolormap = NULL;
parms->colormapstyle = NULL;
parms->x = x;
parms->y = y;
parms->cleanmode = DTA_Base;
parms->scalex = parms->scaley = 1;
parms->cellx = parms->celly = 0;
parms->maxstrlen = INT_MAX;
parms->virtBottom = false;
// Parse the tag list for attributes. (For floating point attributes,
// consider that the C ABI dictates that all floats be promoted to
// doubles when passed as function arguments.)
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;
case DTA_DestWidth:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destwidth = va_arg(tags, int);
break;
case DTA_DestWidthF:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destwidth = va_arg(tags, double);
break;
case DTA_DestHeight:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destheight = va_arg(tags, int);
break;
case DTA_DestHeightF:
assert(fortext == false);
if (fortext) return false;
parms->cleanmode = DTA_Base;
parms->destheight = va_arg(tags, double);
break;
@ -432,10 +526,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
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;
parms->scalex = 1;
parms->scaley = 1;
parms->cleanmode = tag;
}
break;
@ -443,8 +536,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->destwidth = parms->texwidth * CleanXfac;
parms->destheight = parms->texheight * CleanYfac;
parms->scalex = CleanXfac;
parms->scaley = CleanYfac;
parms->cleanmode = tag;
}
break;
@ -452,8 +546,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->destwidth = parms->texwidth * CleanXfac_1;
parms->destheight = parms->texheight * CleanYfac_1;
parms->scalex = CleanXfac_1;
parms->scaley = CleanYfac_1;
parms->cleanmode = tag;
}
break;
@ -461,6 +556,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->cleanmode = DTA_Base;
parms->scalex = 1;
parms->scaley = 1;
parms->virtWidth = 320;
parms->virtHeight = 200;
}
@ -470,56 +568,37 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->cleanmode = DTA_Base;
parms->scalex = 1;
parms->scaley = 1;
parms->virtWidth = 320;
parms->virtHeight = 200;
}
virtBottom = true;
parms->virtBottom = true;
break;
case DTA_HUDRules:
{
bool xright = parms->x < 0;
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;
}
}
intval = va_arg(tags, int);
parms->cleanmode = intval == HUD_HorizCenter ? DTA_HUDRulesC : DTA_HUDRules;
break;
case DTA_VirtualWidth:
parms->cleanmode = DTA_Base;
parms->virtWidth = va_arg(tags, int);
break;
case DTA_VirtualWidthF:
parms->cleanmode = DTA_Base;
parms->virtWidth = va_arg(tags, double);
break;
case DTA_VirtualHeight:
parms->cleanmode = DTA_Base;
parms->virtHeight = va_arg(tags, int);
break;
case DTA_VirtualHeightF:
parms->cleanmode = DTA_Base;
parms->virtHeight = va_arg(tags, double);
break;
@ -527,7 +606,9 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
boolval = va_arg(tags, INTBOOL);
if (boolval)
{
parms->x = parms->y = 0;
assert(fortext == false);
if (img == NULL) return false;
parms->cleanmode = DTA_Fullscreen;
parms->virtWidth = img->GetScaledWidthDouble();
parms->virtHeight = img->GetScaledHeightDouble();
}
@ -567,50 +648,70 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
break;
case DTA_TopOffset:
assert(fortext == false);
if (fortext) return false;
parms->top = va_arg(tags, int);
break;
case DTA_TopOffsetF:
assert(fortext == false);
if (fortext) return false;
parms->top = va_arg(tags, double);
break;
case DTA_LeftOffset:
assert(fortext == false);
if (fortext) return false;
parms->left = va_arg(tags, int);
break;
case DTA_LeftOffsetF:
assert(fortext == false);
if (fortext) return false;
parms->left = va_arg(tags, double);
break;
case DTA_CenterOffset:
assert(fortext == false);
if (fortext) return false;
if (va_arg(tags, int))
{
parms->left = parms->texwidth * 0.5;
parms->top = parms->texheight * 0.5;
parms->left = img->GetScaledWidthDouble() * 0.5;
parms->top = img->GetScaledHeightDouble() * 0.5;
}
break;
case DTA_CenterBottomOffset:
assert(fortext == false);
if (fortext) return false;
if (va_arg(tags, int))
{
parms->left = parms->texwidth * 0.5;
parms->top = parms->texheight;
parms->left = img->GetScaledWidthDouble() * 0.5;
parms->top = img->GetScaledHeightDouble();
}
break;
case DTA_WindowLeft:
assert(fortext == false);
if (fortext) return false;
parms->windowleft = va_arg(tags, int);
break;
case DTA_WindowLeftF:
assert(fortext == false);
if (fortext) return false;
parms->windowleft = va_arg(tags, double);
break;
case DTA_WindowRight:
assert(fortext == false);
if (fortext) return false;
parms->windowright = va_arg(tags, int);
break;
case DTA_WindowRightF:
assert(fortext == false);
if (fortext) return false;
parms->windowright = va_arg(tags, double);
break;
@ -692,6 +793,19 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
case DTA_ColormapStyle:
parms->colormapstyle = va_arg(tags, FColormapStyle *);
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);
}
@ -702,15 +816,14 @@ bool DCanvas::ParseDrawTextureTags (FTexture *img, double x, double y, DWORD tag
return false;
}
if (parms->virtWidth != Width || parms->virtHeight != Height)
if (img != NULL)
{
VirtualToRealCoords(parms->x, parms->y, parms->destwidth, parms->destheight,
parms->virtWidth, parms->virtHeight, virtBottom, !parms->keepratio);
}
SetTextureParms(parms, img, x, y);
if (parms->destwidth <= 0 || parms->destheight <= 0)
{
return false;
if (parms->destwidth <= 0 || parms->destheight <= 0)
{
return false;
}
}
if (parms->remap != NULL)

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

View file

@ -63,8 +63,6 @@ class FTexture;
#define TAG_DONE (0) /* Used to indicate the end of the Tag list */
#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 */
#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_Masked, // true(default)=use masks from texture, false=ignore masks
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_RenderStyle, // same as render style for actors
DTA_ColorOverlay, // DWORD: ARGB to overlay on top of image; limited to black for software
@ -149,6 +148,7 @@ struct DrawParms
double virtHeight;
double windowleft;
double windowright;
int cleanmode;
int dclip;
int uclip;
int lclip;
@ -170,6 +170,11 @@ struct DrawParms
FRenderStyle style;
struct FSpecialColormap *specialcolormap;
struct FColormapStyle *colormapstyle;
int scalex, scaley;
int cellx, celly;
int maxstrlen;
bool fortext;
bool virtBottom;
};
//
@ -241,6 +246,7 @@ public:
// Text drawing functions -----------------------------------------------
// 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 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;
@ -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 VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, int vwidth, int vheight, bool vbottom=false, bool handleaspect=true) const;
// 2D Text drawing
void STACK_ARGS DrawText (FFont *font, int normalcolor, int x, int y, const char *string, ...);
#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, ...);
#ifdef DrawText
#undef DrawText // See WinUser.h for the definition of DrawText as a macro
#endif
void DrawTextV (FFont *font, int normalcolor, int x, int y, const char *string, va_list tags);
void STACK_ARGS DrawChar (FFont *font, int normalcolor, int x, int y, BYTE character, ...);
// 2D Text drawing
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:
BYTE *Buffer;

View file

@ -2805,10 +2805,11 @@ void D3DFB::DrawTextureParms (FTexture *img, DrawParms &parms)
}
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
{
double wi = MIN(parms.windowright, parms.texwidth);
x0 += parms.windowleft * xscale;
u0 = float(u0 + parms.windowleft * uscale);
x1 -= (parms.texwidth - parms.windowright) * xscale;
u1 = float(u1 - (parms.texwidth - parms.windowright) * uscale);
x1 -= (parms.texwidth - wi) * xscale;
u1 = float(u1 - (parms.texwidth - wi) * uscale);
}
#if 0