Page 1 of 1

High-resolution fonts with love.graphics.scale

Posted: Thu Jul 02, 2020 2:14 am
by actually_reb
I'm having trouble finding a good way to make fonts resolution independent. Currently, when drawing my game, I'm calling love.graphics.scale() in order to fit what I'm drawing to the size of the window. The problem with that is drawing text to the screen looks awful when it's upscaled. My current solution is to load in the font to be really big, and then to scale it down inside the print() command. That way, it will still look high resolution when upscaled. However, this causes the opposite of my problem to happen, where text looks good at high resolutions, but absolutely awful at low ones. Is there a one-size-fits-all solution when it comes to drawing text?

Re: High-resolution fonts with love.graphics.scale

Posted: Thu Jul 02, 2020 3:07 pm
by ReFreezed
You're very close to the solution. Instead of always using the same sizes of the fonts during the whole time the game is running you can simply reload the fonts with more appropriate sizes as necessary using the resolution/scale as reference. (I.e. make the fonts a percentage of the window height instead of using a fixed pixel size.)

Re: High-resolution fonts with love.graphics.scale

Posted: Thu Jul 02, 2020 7:07 pm
by actually_reb
The problem with that approach that I had is that changing the size of the font also changes the amount of space the font takes up, not just the resolution. I would have to scale the font down in the drawing call my varying amounts depending on the scale transform used, and I'm not quite sure how to do the math on that.
I recently discovered the DPI scale property, which seems to be what I'm looking for. I'm using code like this to scale the font currently:

Code: Select all

font = love.graphics.setNewFont(14, "normal", 1 * scale)
When scaling up and down smoothly a lot of jitter is introduced, but when just changing window size it looks fine, albeit a little bit inconsistent. I still think there's probably a better way of doing this.

Re: High-resolution fonts with love.graphics.scale

Posted: Thu Jul 02, 2020 8:46 pm
by ReFreezed
The DPI parameter doesn't solve anything in this situation - it just scales the font size on creation and messes up the font hinting when rendering. If you use a high DPI scaling on creation and use a small scale in print() you'll still have bad looking text just like before, and the inverse problem as well.

Code: Select all

-- These result in the same font size, but the former also has the hinting problem.
font = love.graphics.setNewFont(14, "normal", scale)
font = love.graphics.setNewFont(14*scale, "normal", 1)
When drawing the text, using the method I described, just use the font size to determine the scale for print():

Code: Select all

love.graphics.scale(scale)
love.graphics.print("foo", x, y, 0, 14/font.getSize()/scale)
When it comes to jitter caused by changing the font size, just don't change the size if the scale hasn't changed that much over some time.

No solution is going to be perfect here so I guess the answer to your original question is: no, there's no one-size-fits-all solution.

Re: High-resolution fonts with love.graphics.scale

Posted: Fri Jul 03, 2020 1:37 am
by actually_reb

Code: Select all

font = love.graphics.setNewFont(14, "normal", scale)
font = love.graphics.setNewFont(14*scale, "normal", 1)
In my testing, these two commands don't make two fonts of the same size. The second one takes up more space on the screen when you draw it, while changing the DPI increases the resolution without scaling. Changing DPI didn't produce bad looking text at any size for me. Maybe you misunderstand what I want to do, because the formula you gave me draws the font on the screen with the same size independent of the scaling, rather than scaling the font with the the screen. 14/(14 * scale), which simplifies to 1/scale, is what I ended up using for scaling text while increasing DPI, which works ok. It has almost the exact same output as the DPI method, but with less jitter.

Re: High-resolution fonts with love.graphics.scale

Posted: Fri Jul 03, 2020 12:12 pm
by pgimeno
actually_reb wrote: Thu Jul 02, 2020 2:14 amHowever, this causes the opposite of my problem to happen, where text looks good at high resolutions, but absolutely awful at low ones.
Generally, you can't downscale stuff to less than 50% without it looking awful, unless you enable mipmaps. But text doesn't seem to support them.

Re: High-resolution fonts with love.graphics.scale

Posted: Fri Jul 03, 2020 12:17 pm
by ReFreezed
actually_reb wrote: Fri Jul 03, 2020 1:37 am In my testing, these two commands don't make two fonts of the same size.
I meant if you scale them in print() so they have the same size on the screen they will have about the same quality; the actual size used by LÖVE internally will be the same. (See FontDpiHackTest.love in the attached zip file, the description for Font:getDPIScale or look at LÖVE's source code.)

Changing the DPI scale to something higher than your physical screen is will make the font blurrier if the scale is 1 in print() as you're tricking LÖVE into thinking the physical screen resolution is higher than what it actually is.

Now, I am confused what you actually want. I made a test project that doesn't use any DPI hack. Maybe it'll help in some way. (FontScaleTests.love in the attachment.)

Re: High-resolution fonts with love.graphics.scale

Posted: Sun Jul 05, 2020 12:00 am
by actually_reb
Those tests made it a lot more clear actually, thank you! I added in some tests with the DPI method I was using, and the jitter introduced was a lot more clear with your tests than with mine. I'll be use the fourth method that you used in the future.