Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace the font renderer with one without the issues of anti-aliasing/hinting/subpixel/baseline #2404

Closed
dasifefe opened this issue Jun 27, 2021 · 12 comments
Labels
A-Rendering Drawing game state to the screen A-Text Rendering and layout for characters C-Bug An unexpected or incorrect behavior

Comments

@dasifefe
Copy link

Bevy version

Bevy 0.5.0.

What you did

Comparison between the font rendered by Bevy (ab_glyph) and Firefox (with subpixel disabled and subpixel enabled).

What you expected to happen

The font rendered with anti-aliasing in Bevy should be as rendered as close as possible as in Firefox (readable in small sizes, sharp, and correct positioning of glyphs).

What actually happened

Issue 1: aliasing

Font in Bevy is "bulkier". It is possible to notice that the anti-aliasing in Bevy generates a pixel with higher lightness than in the other implementations, that it is possible to notice single pixels without zooming-in (look at the letter e, for example).

The line on the top is Bevy, the line in the middle is Firefox with subpixel disabled, and the line bellow is Firefox with subpixel enabled:
f
f2

The values indicated are the values of LCh lightness (using the color picker from GIMP). The lightness of the anti-alias in the Bevy implementation is 3-5 times than in the other implementations.

Issue 2: vertical positioning

Another issue is the positioning of the glyphs on the baseline. In Bevy, with certain fonts at certain font sizes, the glyphs will be rendered on the incorrect vertical position:

image

It only happens with certain sizes, but not others. The examples above (showing the aliasing issues) are rendered in the correct vertical position, but not at size 15.

Possible issue 3: sizing

The size defined in TextStyle does not match the size in other implementations. On the first image (showing the aliasing issues), for example, I had to use the size 14.5 to match the font size 12 in Firefox.

Additional information

I did this experiment using the font "Fredoka One" on Google Fonts for comparison.

Proposal

Replace the Bevy implementation with one of two existing solutions: fontdue or swash. It seems that these two libraries are the best options for font rendering in pure Rust. We should evaluate which features that both have or don't have that are important for Bevy.

@dasifefe dasifefe added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jun 27, 2021
@MinerSebas
Copy link
Contributor

Could you also test Bevy with its subpixel_glyph_atlas Feature enabled?

@mockersf
Copy link
Member

Issue 2: vertical positioning

Good ol' wavy text... #283, #725, #765

@mockersf mockersf added A-Rendering Drawing game state to the screen and removed S-Needs-Triage This issue needs to be labelled labels Jun 27, 2021
@alice-i-cecile
Copy link
Member

I noticed 1 and 2 while working on my Sudoku game, and strongly support this proposal. Clean text rendering is important and basically impossible to fix as an end user.

@dasifefe
Copy link
Author

Could you also test Bevy with its subpixel_glyph_atlas Feature enabled?

I will give a try.

Akoriam (on Discord showed that the first issue might be solved by applying (2.2) gamma correction in the font renderer and the aliasing of Bevy will look like the anti-aliasing of non-subpixel anti-aliasing of Firefox. What remains to determine if it is worth switching to fontdue or swash to 1) solve the bug with vertical positioning or to 2) have the features of those libraries (fontdue/swash) in Bevy.

@kirawi
Copy link

kirawi commented Oct 2, 2021

Swash would also allow shaping.

@BiosElement
Copy link

Has there been any further discussion on this? I'm struggling with some fuzzy font rendering which appears to be caused by aliasing as well. Certainly prepared to attempt to contribute a fix, but wondering if anyone else has better ideas.

@alice-i-cecile
Copy link
Member

Has there been any further discussion on this?

Not a great deal, but it seems clear that our current font rendering solution is inadequate. IMO, opening up a draft PR with a
backend swap and showing the before / after results would help us come to a concrete decision sooner.

@djeedai
Copy link
Contributor

djeedai commented Aug 2, 2022

I think the vertical positioning is a Bevy bug, not an ab_glyph one.

I've tried replicating the built-in text rendering of Bevy using a different TextPipeline<T>, and after several hours of debugging I found that it returns the glyph position PositionedGlyph relative to the bounding box of the text section, and not relative to the baseline. Moreover the position is the one of the center of the glyph quad. This is 1) very surprising, and cost me hours because it's not documented, 2) arguable, because the text origin should be on the baseline, so the returned position is not the text origin (in typography terminology) and I suspect prevent doing more complex text positioning like baseline alignement, 3) increase the chance we get sub-pixel positioning wrong by messing with the position ab_glyph calculated for us.

I strongly suspect the bug is in that transformation code Bevy operates to convert the glyph position. The screenshot really looks like some bug I had while trying to figure out positioning and simplified some code temporarily to make it easier to debug.

@kirawi
Copy link

kirawi commented Dec 3, 2022

A few weeks ago https://github.com/pop-os/cosmic-text was released.

@alice-i-cecile
Copy link
Member

Yep I'm in favor of exploring a migration to this.

@kirawi
Copy link

kirawi commented Dec 5, 2022

I'm interested in playing around with it, though it probably wouldn't it be good enough for a PR. Would a migration be too difficult for someone unfamiliar with the codebase?

@nicoburns nicoburns added the A-Text Rendering and layout for characters label May 16, 2024
@rparrett
Copy link
Contributor

Bevy now uses swash by way of cosmic-text.

As far as I can tell, all three issues enumerated in the description are now resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen A-Text Rendering and layout for characters C-Bug An unexpected or incorrect behavior
Projects
None yet
Development

No branches or pull requests

9 participants