Align TextBuilder
characters by their baselines during addition/removal
#4774
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Previously characters were implicitly aligned using their
YOffset
s, and that works when only one font is used, but not when more than one font gets used inside oneSpriteText
/TextBuilder
.This PR aims to resolve the "multiple fonts" case by offsetting their
DrawRectangle
s based on the difference between theBaseline
of the new character and the previous characters.I've worked on this initially so that font-mixed sprite texts with #3271 don't look badly misaligned (as I noticed after implementing #3271), but apparently, there are already alignment improvements osu!-side with this PR alone (although slightly unnoticable):
Before:
After:
(notice
(TV Size)
aligned correctly with the other glyphs)I have added in-depth test coverage in
TextBuilderTest
which had the perfect setup for having so, with all possible scenarios I can think of.Along with test coverage, I've also added a benchmark including the regular "no baseline adjustment" cases, and "one baseline adjustment every 10 characters" case, and the results seem reasonable.
I can see this being further optimised by offseting new characters to negative
X/Y
s rather than offsetting all the other previous characters in the line, but that might be a bit complicated to deal with in theSpriteText_DrawNode
(especially given thatTextBuilder
can have multiple lines), therefore I've went with the simplest way of for looping all characters in the line for now.