From 28c8bb47fb1577272a0db08ff28d928eb215f00f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 11 Apr 2019 00:14:53 +0200 Subject: [PATCH] - added generic font support for intermission text screen. --- src/intermission/intermission.cpp | 87 ++++++++++++++++++++++--------- src/intermission/intermission.h | 5 ++ src/rendering/2d/v_drawtext.cpp | 9 ++++ 3 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index e681a6ce4..33587f712 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -253,17 +253,34 @@ void DIntermissionScreenText::Init(FIntermissionAction *desc, bool first) if (mText[0] == '$') mText = GStrings(&mText[1]); mTextSpeed = static_cast(desc)->mTextSpeed; mTextX = static_cast(desc)->mTextX; - bool usesDefault = mTextX < 0; + usesDefault = mTextX < 0; if (mTextX < 0) mTextX =gameinfo.TextScreenX; mTextY = static_cast(desc)->mTextY; if (mTextY < 0) mTextY =gameinfo.TextScreenY; - // If the text is too wide, center it so that it works better on widescreen displays. - // On 4:3 it'd still be cut off, though. - int width = SmallFont->StringWidth(mText); - if (usesDefault && mTextX + width > 320 - mTextX) + if (!generic_ui) { - mTextX = (320 - width) / 2; + // Todo: Split too long texts + + // If the text is too wide, center it so that it works better on widescreen displays. + // On 4:3 it'd still be cut off, though. + int width = SmallFont->StringWidth(mText); + if (usesDefault && mTextX + width > 320 - mTextX) + { + mTextX = (320 - width) / 2; + } + } + else + { + // Todo: Split too long texts + + mTextX *= 2; + mTextY *= 2; + int width = NewSmallFont->StringWidth(mText); + if (usesDefault && mTextX + width > 640 - mTextX) + { + mTextX = (640 - width) / 2; + } } @@ -298,45 +315,59 @@ void DIntermissionScreenText::Drawer () int c; const FRemapTable *range; const uint8_t *ch = (const uint8_t*)mText.GetChars(); - const int kerning = SmallFont->GetDefaultKerning(); // Count number of rows in this text. Since it does not word-wrap, we just count // line feed characters. int numrows; + auto font = generic_ui ? NewSmallFont : SmallFont; + auto fontscale = generic_ui ? MIN(screen->GetWidth()/640, screen->GetHeight()/400) : CleanXfac; + int cleanwidth = screen->GetWidth() / fontscale; + int cleanheight = screen->GetHeight() / fontscale; + int refwidth = generic_ui ? 640 : 320; + int refheight = generic_ui ? 400 : 200; + const int kerning = font->GetDefaultKerning(); for (numrows = 1, c = 0; ch[c] != '\0'; ++c) { numrows += (ch[c] == '\n'); } - int rowheight = SmallFont->GetHeight() * CleanYfac; - int rowpadding = (gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1) * CleanYfac; + int rowheight = font->GetHeight() * fontscale; + int rowpadding = (generic_ui? 2 : ((gameinfo.gametype & (GAME_DoomStrifeChex) ? 3 : -1))) * fontscale; - int cx = (mTextX - 160)*CleanXfac + screen->GetWidth() / 2; - int cy = (mTextY - 100)*CleanYfac + screen->GetHeight() / 2; + int cx = (mTextX - refwidth/2) * fontscale + screen->GetWidth() / 2; + int cy = (mTextY - refheight/2) * fontscale + screen->GetHeight() / 2; cx = MAX(0, cx); int startx = cx; - // Does this text fall off the end of the screen? If so, try to eliminate some margins first. - while (rowpadding > 0 && cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight()) + if (usesDefault) { - rowpadding--; - } - // If it's still off the bottom, try to center it vertically. - if (cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight()) - { - cy = (screen->GetHeight() - (numrows * (rowheight + rowpadding) - rowpadding)) / 2; - // If it's off the top now, you're screwed. It's too tall to fit. - if (cy < 0) + int allheight; + while ((allheight = numrows * (rowheight + rowpadding)), allheight > screen->GetHeight() && rowpadding > 0) { - cy = 0; + rowpadding--; } + allheight = numrows * (rowheight + rowpadding); + if (screen->GetHeight() - cy - allheight < cy) + { + cy = (screen->GetHeight() - allheight) / 2; + if (cy < 0) cy = 0; + } + } + else + { + // Does this text fall off the end of the screen? If so, try to eliminate some margins first. + while (rowpadding > 0 && cy + numrows * (rowheight + rowpadding) - rowpadding > screen->GetHeight()) + { + rowpadding--; + } + // If it's still off the bottom, you are screwed if the origin is fixed. } rowheight += rowpadding; // draw some of the text onto the screen count = (mTicker - mTextDelay) / mTextSpeed; - range = SmallFont->GetColorTranslation (mTextColor); + range = font->GetColorTranslation (mTextColor); for ( ; count > 0 ; count-- ) { @@ -350,13 +381,17 @@ void DIntermissionScreenText::Drawer () continue; } - pic = SmallFont->GetChar (c, mTextColor, &w); + pic = font->GetChar (c, mTextColor, &w); w += kerning; - w *= CleanXfac; + w *= fontscale; if (cx + w > SCREENWIDTH) continue; - screen->DrawChar(SmallFont, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE); + if (generic_ui) + screen->DrawChar(font, mTextColor, cx/fontscale, cy/fontscale, c, DTA_KeepRatio, true, DTA_VirtualWidth, cleanwidth, DTA_VirtualHeight, cleanheight, TAG_DONE); + else + screen->DrawChar(font, mTextColor, cx, cy, c, DTA_CleanNoMove, true, TAG_DONE); + cx += w; } } diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 4f776a1dc..3c28434cc 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -8,6 +8,7 @@ #include "s_sound.h" #include "v_font.h" #include "g_game.h" +#include "v_text.h" struct event_t; @@ -214,6 +215,10 @@ class DIntermissionScreenText : public DIntermissionScreen int mTextDelay; int mTextLen; EColorRange mTextColor; + bool usesDefault; + + void MeasureText(bool posisfixed); + FString RemoveLineFeeds(const char *text); public: diff --git a/src/rendering/2d/v_drawtext.cpp b/src/rendering/2d/v_drawtext.cpp index 066a46d04..2d1996a4b 100644 --- a/src/rendering/2d/v_drawtext.cpp +++ b/src/rendering/2d/v_drawtext.cpp @@ -181,6 +181,10 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i int dummy; bool redirected; + // Workaround until this can be automated. + if (font == NewSmallFont && normalcolor == CR_UNTRANSLATED) + normalcolor = C_GetDefaultFontColor(); + if (NULL != (pic = font->GetChar (character, normalcolor, &dummy, &redirected))) { DrawParms parms; @@ -211,6 +215,11 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in int dummy; bool redirected; + // Workaround until this can be automated. + if (font == NewSmallFont && normalcolor == CR_UNTRANSLATED) + normalcolor = C_GetDefaultFontColor(); + + if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected))) { DrawParms parms;