bevy/examples/ui
Marco Buono 8e3db957c5
Add the ability to control font smoothing (#15368)
# Objective

- Fixes #10720
- Adds the ability to control font smoothing of rendered text

## Solution

- Introduce the `FontSmoothing` enum, with two possible variants
(`FontSmoothing::None` and `FontSmoothing::AntiAliased`):
- This is based on `-webkit-font-smoothing`, in line with our practice
of adopting CSS-like properties/names for UI;
- I could have gone instead for the [`font-smooth`
property](https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth)
that's also supported by browsers, but didn't since it's also
non-standard, has an uglier name, and doesn't allow controlling the type
of antialias applied.
- Having an enum instead of e.g. a boolean, leaves the path open for
adding `FontSmoothing::SubpixelAntiAliased` in the future, without a
breaking change;
- Add all the necessary plumbing to get the `FontSmoothing` information
to where we rasterize the glyphs and store them in the atlas;
- Change the font atlas key to also take into account the smoothing
setting, not only font and font size;
- Since COSMIC Text [doesn't support controlling font
smoothing](https://github.com/pop-os/cosmic-text/issues/279), we roll
out our own threshold-based “implementation”:
- This has the downside of **looking ugly for “regular” vector fonts**
⚠️, since it doesn't properly take the hinting information into account
like a proper implementation on the rasterizer side would.
- However, **for fonts that have been specifically authored to be pixel
fonts, (a common use case in games!) this is not as big of a problem**,
since all lines are vertical/horizontal, and close to the final pixel
boundaries (as long as the font is used at a multiple of the size
originally intended by the author)
- Once COSMIC exposes this functionality, we can switch to using it
directly, and get better results;
- Use a nearest neighbor sampler for atlases with font smoothing
disabled, so that you can scale the text via transform and still get the
pixelated look;
- Add a convenience method to `Text` for setting the font smoothing;
- Add a demonstration of using the `FontSmoothing` property to the
`text2d` example.

## Testing

- Did you test these changes? If so, how?
  - Yes. Via the `text2d`example, and also in my game.
- Are there any parts that need more testing?
- I'd like help from someone for testing this on devices/OSs with
fractional scaling (Android/Windows)
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
- Both via the `text2d` example and also by using it directly on your
projects.
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test?
  - macOS

---

## Showcase

```rust
commands.spawn(Text2dBundle {
    text: Text::from_section("Hello, World!", default())
        .with_font_smoothing(FontSmoothing::None),
    ..default()
});
```
![Screenshot 2024-09-22 at 12 33
39](https://github.com/user-attachments/assets/93e19672-b8c0-4cba-a8a3-4525fe2ae1cb)

<img width="740" alt="image"
src="https://github.com/user-attachments/assets/b881b02c-4e43-410b-902f-6985c25140fc">

## Migration Guide

- `Text` now contains a `font_smoothing: FontSmoothing` property, make
sure to include it or add `..default()` when using the struct directly;
- `FontSizeKey` has been renamed to `FontAtlasKey`, and now also
contains the `FontSmoothing` setting;
- The following methods now take an extra `font_smoothing:
FontSmoothing` argument:
  - `FontAtlas::new()`
  - `FontAtlasSet::add_glyph_to_atlas()`
  - `FontAtlasSet::get_glyph_atlas_info()`
  - `FontAtlasSet::get_outlined_glyph_texture()`
2024-09-23 17:28:25 +00:00
..
borders.rs Rename push children to add children (#15196) 2024-09-16 23:16:04 +00:00
button.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
display_and_visibility.rs fix remaining issues with background color in examples (#14115) 2024-07-03 01:13:55 +00:00
flex_layout.rs Omit font size where it closely matches the default in examples (#13952) 2024-06-20 21:01:28 +00:00
font_atlas_debug.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
grid.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
overflow_debug.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
overflow.rs Updates default Text font size to 24px (#13603) 2024-05-31 16:41:27 +00:00
relative_cursor_position.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
render_ui_to_texture.rs Broaden "Check for bevy_internal imports" CI Task (#15333) 2024-09-20 17:08:37 +00:00
scroll.rs UI Scrolling (#15291) 2024-09-23 17:17:58 +00:00
size_constraints.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
text_debug.rs Rename push children to add children (#15196) 2024-09-16 23:16:04 +00:00
text_wrap_debug.rs Add the ability to control font smoothing (#15368) 2024-09-23 17:28:25 +00:00
text.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
transparency_ui.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
ui_material.rs Add a border to the UI material example (#15120) 2024-09-09 16:34:24 +00:00
ui_scaling.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
ui_texture_atlas_slice.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
ui_texture_atlas.rs Make default behavior for BackgroundColor and BorderColor more intuitive (#14017) 2024-06-25 21:50:41 +00:00
ui_texture_slice_flip_and_tile.rs fix imports in example ui_texture_slice_flip_and_tile (#15064) 2024-09-06 06:00:43 +00:00
ui_texture_slice.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
ui.rs UI Scrolling (#15291) 2024-09-23 17:17:58 +00:00
viewport_debug.rs Fix green colors becoming darker in various examples (#12328) 2024-03-05 23:42:03 +00:00
window_fallthrough.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
z_index.rs Fix green colors becoming darker in various examples (#12328) 2024-03-05 23:42:03 +00:00