Create V_CenteredTitleCardStringOffset

- V_TitleCardStringWidth no longer has the special case
  for punctuation, moved to this function instead.
- Handles both leading and trailing punctuation, and even
  spaces.

toaster-assisted, thank-you-toaster
This commit is contained in:
James R 2023-08-27 15:06:51 -07:00
parent 79699f47d5
commit 2e748636d7
3 changed files with 112 additions and 32 deletions

View file

@ -1902,7 +1902,7 @@ static void HU_DrawTitlecardCEcho(size_t num)
while (*echoptr != '\0')
{
INT32 w;
INT32 ofs;
INT32 timer = (INT32)(elapsed - timeroffset);
if (timer <= 0)
@ -1915,8 +1915,8 @@ static void HU_DrawTitlecardCEcho(size_t num)
*line = '\0';
w = V_TitleCardStringWidth(echoptr, p4);
V_DrawTitleCardString(x -w/2, y, echoptr, 0, false, timer, TICRATE*4, p4);
ofs = V_CenteredTitleCardStringOffset(echoptr, p4);
V_DrawTitleCardString(x - ofs, y, echoptr, 0, false, timer, TICRATE*4, p4);
y += p4 ? 18 : 32;

View file

@ -1852,9 +1852,8 @@ void V_DrawChatCharacter(INT32 x, INT32 y, INT32 c, boolean lowercase, UINT8 *co
);
}
// V_TitleCardStringWidth
// Get the string's width using the titlecard font.
INT32 V_TitleCardStringWidth(const char *str, boolean p4)
template <bool Centered>
static INT32 Internal_TitleCardStringOffset(const char *str, boolean p4)
{
int bg_font = GTOL_FONT;
int fg_font = GTFN_FONT;
@ -1870,45 +1869,123 @@ INT32 V_TitleCardStringWidth(const char *str, boolean p4)
char c;
patch_t *pp;
for (;;ch++)
// Returns true if it reached the end, false if interrupted.
auto scan = [&](auto keep_going)
{
if (!*ch)
break;
if (*ch == '\n')
for (;;ch++)
{
xoffs = 0;
continue;
if (*ch == '\n')
{
xoffs = 0;
return false;
}
if (!keep_going(*ch))
{
break;
}
c = *ch;
c = toupper(c);
c -= LT_FONTSTART;
// check if character exists, if not, it's a space.
if (c < 0 || c >= LT_FONTSIZE || !fontv[bg_font].font[(INT32)c])
{
xoffs += p4 ? 5 : 10;
continue;
}
pp = fontv[fg_font].font[(INT32)c];
xoffs += pp->width - (p4 ? 3 : 5);
}
// For the sake of centering, don't count punctuation.
return true;
};
do
{
// For the sake of centering, don't count spaces or
// punctuation at each end of a line.
// TODO: This should ideally be more sophisticated:
// - Only apply on the ends of each line.
// - Check patch width directly for monospace or
// punctuation that isn't necessarily thin.
// - Apply to all string drawing.
if (ispunct(*ch))
// - Apply to all centered string drawing.
if constexpr (Centered)
{
continue;
// Count leading fluff
if (!scan([](int c) { return c && !isalnum(c); }))
{
continue;
}
if (!*ch)
{
// ALL fluff, so center it normally.
break;
}
// xoffs gets halved later, which centers the
// string. If we don't want leading fluff to push
// everything to the right, its full width needs
// to be subtracted, so it's doubled here to
// cancel out the division.
xoffs *= 2;
INT32 trim = -1;
bool reached_end = scan(
[&trim, &xoffs](int c)
{
if (isalnum(c))
{
trim = -1;
}
else if (trim < 0)
{
trim = xoffs;
}
return c;
}
);
// Discount trailing fluff
if (reached_end && trim >= 0)
{
xoffs = trim;
}
}
c = *ch;
c = toupper(c);
c -= LT_FONTSTART;
// check if character exists, if not, it's a space.
if (c < 0 || c >= LT_FONTSIZE || !fontv[bg_font].font[(INT32)c])
else
{
xoffs += p4 ? 5 : 10;
continue;
scan([](int c) { return c; });
}
pp = fontv[fg_font].font[(INT32)c];
xoffs += pp->width - (p4 ? 3 : 5);
}
while (*(ch++));
return xoffs;
if constexpr (Centered)
{
return xoffs / 2;
}
else
{
return xoffs;
}
}
// V_TitleCardStringWidth
// Get the string's width using the titlecard font.
INT32 V_TitleCardStringWidth(const char *str, boolean p4)
{
return Internal_TitleCardStringOffset<false>(str, p4);
}
// V_CenteredTitleCardStringOffset
// Subtract this offset from an X coordinate to center the string around that point.
INT32 V_CenteredTitleCardStringOffset(const char *str, boolean p4)
{
return Internal_TitleCardStringOffset<true>(str, p4);
}
// V_DrawTitleCardScreen.

View file

@ -352,6 +352,9 @@ void V_DrawTitleCardString(INT32 x, INT32 y, const char *str, INT32 flags, boole
// returns thr width of a string drawn using the above function.
INT32 V_TitleCardStringWidth(const char *str, boolean p4);
// offset that can be subtracted to center align.
INT32 V_CenteredTitleCardStringOffset(const char *str, boolean p4);
// Draw tall nums, used for menu, HUD, intermission
void V_DrawTallNum(INT32 x, INT32 y, INT32 flags, INT32 num);
void V_DrawPaddedTallNum(INT32 x, INT32 y, INT32 flags, INT32 num, INT32 digits);