fontspec_t, V_GetFontSpecification

Reduces quantity of copypasted code between V_StringWidthScaled and V_DrawStringScaled to far more manageable "this is an inner loop and cannot be abstracted" levels.

Guarantees consistency in handling across existing and future functions.
This commit is contained in:
toaster 2023-07-11 13:00:08 +01:00
parent b69a255fe9
commit fd4c1aeec3

View file

@ -2217,6 +2217,181 @@ static inline fixed_t LSTitleCharacterDim(
return 0;
}
typedef struct
{
fixed_t chw;
fixed_t spacew;
fixed_t lfh;
fixed_t (*dim_fn)(fixed_t,fixed_t,INT32,INT32,fixed_t *);
} fontspec_t;
static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
{
/*
Hardcoded until a better system can be implemented
for determining how fonts space.
*/
// All other properties are guaranteed to be set
result->chw = 0;
const INT32 spacing = ( flags & V_SPACINGMASK );
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
result->spacew = 4;
switch (spacing)
{
case V_MONOSPACE:
result->spacew = 8;
/* FALLTHRU */
case V_OLDSPACING:
result->chw = 8;
break;
case V_6WIDTHSPACE:
result->spacew = 6;
}
break;
case TINY_FONT:
result->spacew = 2;
switch (spacing)
{
case V_MONOSPACE:
result->spacew = 5;
/* FALLTHRU */
case V_OLDSPACING:
result->chw = 5;
break;
// Out of video flags, so we're reusing this for alternate charwidth instead
/*case V_6WIDTHSPACE:
result->spacewidth = 3;*/
}
break;
case LT_FONT:
result->spacew = 12;
break;
case CRED_FONT:
result->spacew = 16;
break;
case KART_FONT:
result->spacew = 3;
switch (spacing)
{
case V_MONOSPACE:
result->spacew = 12;
/* FALLTHRU */
case V_OLDSPACING:
result->chw = 12;
break;
case V_6WIDTHSPACE:
result->spacew = 6;
}
break;
case GM_FONT:
result->spacew = 6;
break;
case FILE_FONT:
result->spacew = 0;
break;
case LSHI_FONT:
case LSLOW_FONT:
result->spacew = 10;
break;
case OPPRF_FONT:
result->spacew = 5;
break;
case PINGF_FONT:
result->spacew = 3;
break;
}
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
case TINY_FONT:
case KART_FONT:
result->lfh = 12;
break;
case LT_FONT:
case CRED_FONT:
case FILE_FONT:
result->lfh = 12;
break;
case GM_FONT:
result->lfh = 32;
break;
case LSHI_FONT:
result->lfh = 56;
break;
case LSLOW_FONT:
result->lfh = 38;
break;
case OPPRF_FONT:
case PINGF_FONT:
result->lfh = 10;
break;
}
switch (fontno)
{
default:
if (result->chw)
result->dim_fn = CenteredCharacterDim;
else
result->dim_fn = VariableCharacterDim;
break;
case KART_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
result->dim_fn = BunchedCharacterDim;
break;
case TINY_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
{
/* Reuse this flag for the alternate bunched-up spacing. */
if (( flags & V_6WIDTHSPACE ))
result->dim_fn = BunchedCharacterDim;
else
result->dim_fn = VariableCharacterDim;
}
break;
case GM_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
result->dim_fn = GamemodeCharacterDim;
break;
case FILE_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
result->dim_fn = FileCharacterDim;
break;
case LSHI_FONT:
case LSLOW_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
result->dim_fn = LSTitleCharacterDim;
break;
case OPPRF_FONT:
case PINGF_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else
result->dim_fn = BunchedCharacterDim;
break;
}
}
void V_DrawStringScaled(
fixed_t x,
fixed_t y,
@ -2228,18 +2403,13 @@ void V_DrawStringScaled(
int fontno,
const char *s)
{
fixed_t chw;
INT32 hchw;/* half-width for centering */
fixed_t spacew;
fixed_t lfh;
INT32 dupx;
fixed_t right;
fixed_t bot;
fixed_t (*dim_fn)(fixed_t,fixed_t,INT32,INT32,fixed_t *);
font_t *font;
boolean uppercase;
@ -2254,7 +2424,6 @@ void V_DrawStringScaled(
fixed_t cxoff, cyoff;
fixed_t cw;
INT32 spacing;
fixed_t left;
int c;
@ -2279,127 +2448,23 @@ void V_DrawStringScaled(
font = &fontv[fontno];
chw = 0;
fontspec_t fontspec;
spacing = ( flags & V_SPACINGMASK );
V_GetFontSpecification(fontno, flags, &fontspec);
/*
Hardcoded until a better system can be implemented
for determining how fonts space.
*/
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
spacew = 4;
switch (spacing)
{
case V_MONOSPACE:
spacew = 8;
/* FALLTHRU */
case V_OLDSPACING:
chw = 8;
break;
case V_6WIDTHSPACE:
spacew = 6;
}
break;
case TINY_FONT:
spacew = 2;
switch (spacing)
{
case V_MONOSPACE:
spacew = 5;
/* FALLTHRU */
case V_OLDSPACING:
chw = 5;
break;
// Out of video flags, so we're reusing this for alternate charwidth instead
/*case V_6WIDTHSPACE:
spacewidth = 3;*/
}
break;
case LT_FONT:
spacew = 12;
break;
case CRED_FONT:
spacew = 16;
break;
case KART_FONT:
spacew = 3;
switch (spacing)
{
case V_MONOSPACE:
spacew = 12;
/* FALLTHRU */
case V_OLDSPACING:
chw = 12;
break;
case V_6WIDTHSPACE:
spacew = 6;
}
break;
case GM_FONT:
spacew = 6;
break;
case FILE_FONT:
spacew = 0;
break;
case LSHI_FONT:
case LSLOW_FONT:
spacew = 10;
break;
case OPPRF_FONT:
spacew = 5;
break;
case PINGF_FONT:
spacew = 3;
break;
}
hchw = fontspec.chw >> 1;
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
case TINY_FONT:
case KART_FONT:
lfh = 12;
break;
case LT_FONT:
case CRED_FONT:
case FILE_FONT:
lfh = 12;
break;
case GM_FONT:
lfh = 32;
break;
case LSHI_FONT:
lfh = 56;
break;
case LSLOW_FONT:
lfh = 38;
break;
case OPPRF_FONT:
case PINGF_FONT:
lfh = 10;
break;
}
hchw = chw >> 1;
chw <<= FRACBITS;
spacew <<= FRACBITS;
lfh <<= FRACBITS;
fontspec.chw <<= FRACBITS;
fontspec.spacew <<= FRACBITS;
fontspec.lfh <<= FRACBITS;
#define Mul( id, scale ) ( id = FixedMul (scale, id) )
Mul (chw, scale);
Mul (spacew, scale);
Mul (lfh, scale);
Mul (fontspec.chw, scale);
Mul (fontspec.spacew, scale);
Mul (fontspec.lfh, scale);
Mul (spacew, spacescale);
Mul (lfh, lfscale);
Mul (fontspec.spacew, spacescale);
Mul (fontspec.lfh, lfscale);
#undef Mul
if (( flags & V_NOSCALESTART ))
@ -2408,9 +2473,9 @@ void V_DrawStringScaled(
hchw *= dupx;
chw *= dupx;
spacew *= dupx;
lfh *= vid.dupy;
fontspec.chw *= dupx;
fontspec.spacew *= dupx;
fontspec.lfh *= vid.dupy;
right = vid.width;
}
@ -2429,60 +2494,6 @@ void V_DrawStringScaled(
right <<= FRACBITS;
bot = vid.height << FRACBITS;
switch (fontno)
{
default:
if (chw)
dim_fn = CenteredCharacterDim;
else
dim_fn = VariableCharacterDim;
break;
case KART_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
case TINY_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
{
/* Reuse this flag for the alternate bunched-up spacing. */
if (( flags & V_6WIDTHSPACE ))
dim_fn = BunchedCharacterDim;
else
dim_fn = VariableCharacterDim;
}
break;
case GM_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = GamemodeCharacterDim;
break;
case FILE_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = FileCharacterDim;
break;
case LSHI_FONT:
case LSLOW_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = LSTitleCharacterDim;
break;
case OPPRF_FONT:
case PINGF_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
}
cx = x;
cy = y;
cyoff = 0;
@ -2492,7 +2503,7 @@ void V_DrawStringScaled(
switch (c)
{
case '\n':
cy += lfh;
cy += fontspec.lfh;
if (cy >= bot)
return;
cx = x;
@ -2544,13 +2555,13 @@ void V_DrawStringScaled(
if (V_CharacterValid(font, c) == true)
{
cw = SHORT (font->font[c]->width) * dupx;
cxoff = (*dim_fn)(scale, chw, hchw, dupx, &cw);
cxoff = (*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
V_DrawFixedPatch(cx + cxoff, cy + cyoff, scale,
flags, font->font[c], colormap);
cx += cw;
}
else
cx += spacew;
cx += fontspec.spacew;
}
}
}
@ -2564,15 +2575,10 @@ fixed_t V_StringScaledWidth(
int fontno,
const char *s)
{
fixed_t chw;
INT32 hchw;/* half-width for centering */
fixed_t spacew;
fixed_t lfh;
INT32 dupx;
fixed_t (*dim_fn)(fixed_t,fixed_t,INT32,INT32,fixed_t *);
font_t *font;
boolean uppercase;
@ -2582,8 +2588,6 @@ fixed_t V_StringScaledWidth(
fixed_t cw;
INT32 spacing;
int c;
fixed_t fullwidth = 0;
@ -2593,124 +2597,22 @@ fixed_t V_StringScaledWidth(
font = &fontv[fontno];
chw = 0;
fontspec_t fontspec;
spacing = ( flags & V_SPACINGMASK );
V_GetFontSpecification(fontno, flags, &fontspec);
/*
Hardcoded until a better system can be implemented
for determining how fonts space.
*/
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
spacew = 4;
switch (spacing)
{
case V_MONOSPACE:
spacew = 8;
/* FALLTHRU */
case V_OLDSPACING:
chw = 8;
break;
case V_6WIDTHSPACE:
spacew = 6;
}
break;
case TINY_FONT:
spacew = 2;
switch (spacing)
{
case V_MONOSPACE:
spacew = 5;
/* FALLTHRU */
case V_OLDSPACING:
chw = 5;
break;
// Out of video flags, so we're reusing this for alternate charwidth instead
/*case V_6WIDTHSPACE:
spacewidth = 3;*/
}
break;
case LT_FONT:
spacew = 12;
break;
case CRED_FONT:
spacew = 16;
break;
case KART_FONT:
spacew = 3;
switch (spacing)
{
case V_MONOSPACE:
spacew = 12;
/* FALLTHRU */
case V_OLDSPACING:
chw = 12;
break;
case V_6WIDTHSPACE:
spacew = 6;
}
break;
case GM_FONT:
case FILE_FONT:
spacew = 0;
break;
case LSHI_FONT:
case LSLOW_FONT:
spacew = 10;
break;
case OPPRF_FONT:
spacew = 5;
break;
case PINGF_FONT:
spacew = 3;
break;
}
hchw = fontspec.chw >> 1;
switch (fontno)
{
default:
case HU_FONT:
case MENU_FONT:
case TINY_FONT:
case KART_FONT:
lfh = 12;
break;
case LT_FONT:
case CRED_FONT:
case FILE_FONT:
lfh = 12;
break;
case GM_FONT:
lfh = 32;
break;
case LSHI_FONT:
lfh = 56;
break;
case LSLOW_FONT:
lfh = 38;
break;
case OPPRF_FONT:
case PINGF_FONT:
lfh = 10;
break;
}
hchw = chw >> 1;
chw <<= FRACBITS;
spacew <<= FRACBITS;
fontspec.chw <<= FRACBITS;
fontspec.spacew <<= FRACBITS;
#define Mul( id, scale ) ( id = FixedMul (scale, id) )
Mul (chw, scale);
Mul (spacew, scale);
Mul (lfh, scale);
Mul (fontspec.chw, scale);
Mul (fontspec.spacew, scale);
Mul (fontspec.lfh, scale);
Mul (spacew, spacescale);
Mul (lfh, lfscale);
Mul (fontspec.spacew, spacescale);
Mul (fontspec.lfh, lfscale);
#undef Mul
if (( flags & V_NOSCALESTART ))
@ -2719,69 +2621,15 @@ fixed_t V_StringScaledWidth(
hchw *= dupx;
chw *= dupx;
spacew *= dupx;
lfh *= vid.dupy;
fontspec.chw *= dupx;
fontspec.spacew *= dupx;
fontspec.lfh *= vid.dupy;
}
else
{
dupx = 1;
}
switch (fontno)
{
default:
if (chw)
dim_fn = CenteredCharacterDim;
else
dim_fn = VariableCharacterDim;
break;
case KART_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
case TINY_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
{
/* Reuse this flag for the alternate bunched-up spacing. */
if (( flags & V_6WIDTHSPACE ))
dim_fn = BunchedCharacterDim;
else
dim_fn = VariableCharacterDim;
}
break;
case GM_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = GamemodeCharacterDim;
break;
case FILE_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = FileCharacterDim;
break;
case LSHI_FONT:
case LSLOW_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = LSTitleCharacterDim;
break;
case OPPRF_FONT:
case PINGF_FONT:
if (chw)
dim_fn = FixedCharacterDim;
else
dim_fn = BunchedCharacterDim;
break;
}
cx = cy = 0;
right = 0;
@ -2790,7 +2638,7 @@ fixed_t V_StringScaledWidth(
switch (c)
{
case '\n':
cy += lfh;
cy += fontspec.lfh;
cx = 0;
break;
default:
@ -2821,11 +2669,11 @@ fixed_t V_StringScaledWidth(
// We need to count the full width to get the rightmost edge of the string though.
right = cx + (cw * scale);
(*dim_fn)(scale, chw, hchw, dupx, &cw);
(*fontspec.dim_fn)(scale, fontspec.chw, hchw, dupx, &cw);
cx += cw;
}
else
cx += spacew;
cx += fontspec.spacew;
}
fullwidth = std::max(right, std::max(cx, fullwidth));