LiveSplit / LiveSplit

A sleek, highly customizable timer for speedrunners.
https://livesplit.org
MIT License
1.56k stars 744 forks source link

Font Misalignment #1633

Open Jademalo opened 4 years ago

Jademalo commented 4 years ago

For some reason, a variety of fonts are substantially misaligned. They're perfect in the preview in the font selector, but entirely wrong in the actual splits.

image image

image image

As you can see, they seem to be aligned in the sample text box, but Chiaro Std B is substantially too high in the actual splits. Gabriola is another font that has this same issue, but honestly just flicking down the list of fonts shows that they're all over the place in the actual splits window and seem to be totally misaligned.

Any ideas what the cause of this could be, and if not would it be possible to get a text position compensation variable so it can be properly lined up with the other elements?

Thanks

wooferzfg commented 4 years ago

This is where we calculate the positioning: https://github.com/LiveSplit/LiveSplit.Timer/blob/2f5f6cb0bd0cf2f171ca6e97e6140634be770d81/UI/Components/Timer.cs#L170-L184

These values seem to be incorrect (?) for some fonts.

For those fonts specifically, it looks like lowering the font size might help?

Jademalo commented 4 years ago

The problem with lowering the font size is that they're then too small. Unbelievable, I know, lol.

I have a feeling that this is an issue with fonts that have incorrectly set descents, resulting in the middle being calculated totally incorrectly rather than the middle of the core letters.

I wonder if straight up ignoring the descent for the purposes of font alignment might be a better approach.

image

Considering this, if you were to just use the Ascent value to calculate the position then it should result in a consistent baseline across any font. I can't really see a reason that descent needs to be used in this situation either honestly, since the split heights are set independently. Normally the only relevance of descent is in line spacing calculation, to make sure that lines don't overlap.

A consistent baseline for every font should totally fix this issue, as far as I can tell.

https://github.com/LiveSplit/LiveSplit.Timer/blob/2f5f6cb0bd0cf2f171ca6e97e6140634be770d81/UI/Components/Timer.cs#L177

Changing that to var shift = (height - ascent) / 2f; might just straight up fix it entirely

Jademalo commented 4 years ago

Realised that you noticed the wrong thing - Look at the splits text, not the timer. In some fonts it's extremely high compared to the icon, and in other fonts it's correctly in the middle. Ignore the timer being cropped, that was just me testing quickly.

Had a quick poke through the source, and I can't find anything in the actual Splits component that has to do with text sizing or positioning. I'm fairly confident the bug is with descents affecting alignment instead of just line spacing, but I don't know enough to be able to fix it.

wooferzfg commented 4 years ago

Everything besides the timer just uses standard .NET drawing calls. We don't do any custom positioning logic.

Jademalo commented 4 years ago

Hmm, that's extremely weird then. This isn't an issue with any normal text editor, it seems to be something weird with how .NET is handling certain fonts. I've tested both Chiaro Std B and Gabriola in Notepad and Word, and they work as you would expect.

In that case, how difficult would it be to add a text offset tweak? I'd do it myself but I'm not knowledgable enough to actually implement it. I can poke my way around and figure out what's happening, but I'd not be able to actually add anything.