Open bdach opened 4 years ago
I began to doubt all of the above, but I figured out a way to capture a better screenshot that seems to confirm my reasoning:
Note the following:
DrawSizePreservingFillContainer
and makes device pixels correspond to "framework pixels" below in the hierarchy.If it's always a constant ratio, we can fix this by applying a scaleAdjust
to the font/texture store. This can be done on a per project basis, or at the framework level if we decide that is more correct.
It is different between each font, e.g. for the "torus" font:
so the ratio to apply with scaleAdjust
will be 100f / 1.2f
(100f
default scale adjust divided by effective text height / em square
), different from "Open Sans" which will have a scaleAdjust
of 100f / 1.36f
instead.
but that means it can still be done by separating each font family to its font store and calculate the required scale adjustment for them, in an organized way, and potentially move it to a method here in framework.
Though after doing so, all the sprite texts in osu!lazer may need to be revisited as currently the scale adjustment makes things look very off, but is to be expected:
Recently osu!-side there have been multiple contributions that aimed to bring visuals as close to web as possible. An issue raised during that period was that the numerically-identical font size looked smaller in the game than in web.
Right now,
SpriteText
& co. work in a way such that a height of 16 will yield a text sprite of the size of precisely 16. While that's what seems reasonable, it's actually not what CSS does:At this point I'll quickly defer to this article explaining how CSS
font-size
works. Especially relevant is this picture:which shows that for a font:
the effective text height in pixels of a 100px line is actually 164px.
To see how this relates to how framework handles text, I used the existing
SpriteText
test scene, Open Sans and FontForge. The metrics for Open Sans are:That means that:
The measurements in-game seem to indicate that currently the framework is sizing the entire line (ascender to descender) when size is supplied, instead of sizing the em-square:
126 * 52.4% comes down to just over 66 pixels. Measurement is imprecise due to antialiasing. I've only checked this one font, but seems too much of a coincidence if that turned out to be a fluke.
Font size supplied in game was 92, but measured 126 due to an ancestor
DrawSizePreservingFillContainer
. After adjustment the entireSpriteText
should have 126 / 73.4% = ~171 height.Now, the bad news is, as far as I can see font spacing info comes opaquely through bmfont, and all the dimensions above are font-specific, therefore we'd most likely have to modify bmfont to supply us this info, as it doesn't seem to be there. There is a
base
attribute in thecommon
tag, but seems to be the ascender-to-baseline measurement, so not what we want here.It's also not entirely clear what should be done with the ascender and descender sizings. They should be taken into account somehow. The "easiest" way I can see out of this is to make bmfont spit out the numbers needed to make the necessary adjustment (namely, the em-square and ascender + descender heights) and apply sizing adjustment game-side.
I'm aware of the scope and amount of work this could take, and for how little gain it would be. It would probably be nice to have this corrected (as this is probably the more correct, and expected in the eye of consumers, behaviour), but there's way more other important issues to deal with, therefore opening as proposal.
(Also painfully aware this could end up being a big breaking change.)