[Solved] HUDFONT_DOOM vs SMALLFONT: monospacing discrepancy

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Player701
 
 
Posts: 1640
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

[Solved] HUDFONT_DOOM vs SMALLFONT: monospacing discrepancy

Post by Player701 »

I'm not sure if this is a bug, so I'm posting this question here instead.

I've been implementing a custom HUD in ZScript and noticed a discrepancy between how monospaced strings are drawn in HUDFONT_DOOM (aka DoomStatusBar.mHUDFont) and SMALLFONT. I'm creating a HUDFont instance for SMALLFONT in the same way mHUDFont is initialized in DoomStatusBar:

Code: Select all

Font fnt = "SMALLFONT";
mHUDFont = HUDFont.Create(fnt, fnt.GetCharWidth("0"), true, 1, 1);
The problem is: characters in HUDFONT_DOOM are centered, but in SMALLFONT they are left-aligned. This is very noticeable when drawing numbers that have "1" in them, as this character is less wide than the other digits and leaves a lot of empty space to the right of it, which doesn't look great at all:



To confirm this, I wrote some debugging code which draws colored rectangles under my strings. The height of these rectangles is calculated by calling GetHeight on the corresponding font, while the width is calculated by multiplying the character width by the number of characters. Here is an example with all digits from HUDFONT_DOOM and SMALLFONT. It is very easy to see that the big "1" is centered in its box, while the small "1" is hugging the left side of it.

(disregard the red rectangles, the green ones are the ones you need)



The question is: is it possible to change this behavior for SMALLFONT? SBARINFO seems to center characters, so I think it should be possible, but due to the lack of comprehensive documenation, I haven't found out how to do it. Maybe one of the developers could answer?

Also, please note that I do want monospacing to align all the digits perfectly above each other (as on the first picture), so not using it is out of the question.
Last edited by Player701 on Fri Oct 19, 2018 8:33 am, edited 1 time in total.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49073
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: HUDFONT_DOOM vs SMALLFONT: monospacing discrepancy

Post by Graf Zahl »

Of course this cannot be changed. It'd break a lot of stuff depending on this behavior. Unless I am misunderstanding something the alignment is a property of the character graphics.
User avatar
Player701
 
 
Posts: 1640
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: HUDFONT_DOOM vs SMALLFONT: monospacing discrepancy

Post by Player701 »

Graf Zahl wrote:Of course this cannot be changed. It'd break a lot of stuff depending on this behavior. Unless I am misunderstanding something the alignment is a property of the character graphics.
I see. But how does SBARINFO do it, then? Back when I used SBARINFO to draw these numbers, the digits seemed to be centered. I just checked it again with an old version of my mod and it looks much better:



Note that there is much less space between "1" and "8" here than on the previous picture.
User avatar
Player701
 
 
Posts: 1640
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: HUDFONT_DOOM vs SMALLFONT: monospacing discrepancy

Post by Player701 »

I have managed to implement a ZScript function which emulates SBARINFO monospacing, at least for my needs. Now the numbers look exactly (pixel to pixel!) the same as before.

This is the code of the drawing function, in case someone runs into an issue similar to mine and needs a solution:

Code: Select all

private void DrawStringForceMonospace(HUDFont hudFont, string what, vector2 where, int color, int spacingChar)
{
    int spacingWidth = hudFont.mFont.GetCharWidth(spacingChar);
    int len = what.Length();
    
    double x = where.x + spacingWidth;
    double y = where.y;
    
    for (int i = 0; i < len; i++)
    {
        int charWidth = hudFont.mFont.GetCharWidth(what.CharCodeAt(i));        
        double realX = x - (spacingWidth - charWidth) / 2.0;

        DrawString(hudFont, what.CharAt(i), (realX, y), BaseStatusBar.DI_TEXT_ALIGN_RIGHT, color);
        
        x += spacingWidth;
    }
}
Also attaching a standalone (no need to edit scripts, add MAPINFO etc.) example which demonstrates the function's usage and output (warp to any map to see).
Attachments
ForceMonospace.wad
(1.28 KiB) Downloaded 26 times
User avatar
NightFright
Spotlight Team
Posts: 1343
Joined: Fri May 02, 2008 12:29 pm
Location: Germany

Re: [Solved] HUDFONT_DOOM vs SMALLFONT: monospacing discrepa

Post by NightFright »

Man, where have you been all my life? I was running into the exact same issue when making a level stats counter with a custom font derived from indexfont_doom (the one used for the ammo counter overview) and having forced gaps in the colon and "1" chars since they were only 2px wide instead of 4 like the others.

If this script can solve this problem, you'll be my personal hero! I'd be glad if I were able to make the gaps disappear for chars with less width than others, and an sbarinfo solution would be fine. I would need a proportional font instead of a monospaced one, I guess. If that makes any sense at all.
User avatar
Player701
 
 
Posts: 1640
Joined: Wed May 13, 2009 3:15 am
Graphics Processor: nVidia with Vulkan support
Contact:

Re: [Solved] HUDFONT_DOOM vs SMALLFONT: monospacing discrepa

Post by Player701 »

I haven't tested it with INDEXFONT_DOOM, but there is a chance it may work fine with that font too. For my needs (and that is drawing numbers in SMALLFONT) it does exactly what I want, and I'm content with that.

Also, one correction to the above code: "BaseStatusBar." qualifier in "DI_TEXT_ALIGN_RIGHT" is not necessary if the code is being called from a class which descends from BaseStatusBar. I'm using these functions in separate classes (otherwise my status bar class would get too bloated and unreadable), so I needed that and forgot to remove it when rewriting the code to make a standalone example.
Post Reply

Return to “Scripting”