bevy/crates
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
..
bevy_a11y Reflected traits for resources and components: bevy_a11y (#15192) 2024-09-14 01:43:16 +00:00
bevy_animation Allow animation clips to animate arbitrary properties. (#15282) 2024-09-23 17:14:12 +00:00
bevy_app Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_asset bevy_reflect: Add ReflectRef/ReflectMut/ReflectOwned convenience casting methods (#15235) 2024-09-23 16:50:46 +00:00
bevy_audio Reflect derived traits on all components and resources: bevy_audio (#15211) 2024-09-15 14:24:00 +00:00
bevy_color Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
bevy_core Unify crate-level preludes (#15080) 2024-09-08 17:10:57 +00:00
bevy_core_pipeline Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_derive Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_dev_tools Added HeadlessPlugins (#15203) (#15260) 2024-09-19 16:44:43 +00:00
bevy_diagnostic Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_dylib Generate links to definition in source code pages on docs.rs and dev-docs.bevyengine.org (#12965) 2024-07-29 23:10:16 +00:00
bevy_ecs Allow animation clips to animate arbitrary properties. (#15282) 2024-09-23 17:14:12 +00:00
bevy_encase_derive Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_gilrs Update gilrs requirement from 0.10.1 to 0.11.0 (#15245) 2024-09-16 23:34:04 +00:00
bevy_gizmos Reduce runtime panics through SystemParam validation (#15276) 2024-09-23 16:54:21 +00:00
bevy_gltf Allow animation clips to animate arbitrary properties. (#15282) 2024-09-23 17:14:12 +00:00
bevy_hierarchy move ShortName to bevy_reflect (#15340) 2024-09-21 20:52:46 +00:00
bevy_input Use of deprecated function in example for ButtonInput (#15221) 2024-09-15 15:22:39 +00:00
bevy_internal Spirv passthrough main (adopted, part deux) (#15352) 2024-09-22 14:51:14 +00:00
bevy_log Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_macro_utils Generate links to definition in source code pages on docs.rs and dev-docs.bevyengine.org (#12965) 2024-07-29 23:10:16 +00:00
bevy_math Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
bevy_mikktspace Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_pbr Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_picking Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_ptr Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_reflect Reflect for TextureFormat (#15355) 2024-09-23 17:26:12 +00:00
bevy_render Reduce runtime panics through SystemParam validation (#15276) 2024-09-23 16:54:21 +00:00
bevy_scene Rename push children to add children (#15196) 2024-09-16 23:16:04 +00:00
bevy_sprite feature gate picking backends (#15369) 2024-09-22 19:35:15 +00:00
bevy_state Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_tasks Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_text Add the ability to control font smoothing (#15368) 2024-09-23 17:28:25 +00:00
bevy_time Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_transform Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_ui Add the ability to control font smoothing (#15368) 2024-09-23 17:28:25 +00:00
bevy_utils move ShortName to bevy_reflect (#15340) 2024-09-21 20:52:46 +00:00
bevy_window Allow to expect (adopted) (#15301) 2024-09-20 19:16:42 +00:00
bevy_winit Remove ReceivedCharacter (#15126) 2024-09-10 00:22:06 +00:00