bevy/examples/2d
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
..
2d_shapes.rs Utilise new method for 2d circle example. (#15022) 2024-09-03 00:36:22 +00:00
2d_viewport_to_world.rs Return Results from Camera's world/viewport conversion methods (#14989) 2024-09-03 19:45:15 +00:00
bloom_2d.rs Rename rendering components for improved consistency and clarity (#15035) 2024-09-10 01:11:46 +00:00
bounding_2d.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
custom_gltf_vertex_attribute.rs Highlight dependency on shader files in examples (#13824) 2024-06-12 14:16:01 +00:00
mesh2d.rs Fix some doc warnings (#12961) 2024-04-14 15:23:44 +00:00
mesh2d_alpha_mode.rs Add AlphaMask2d phase (#14724) 2024-08-15 14:10:37 +00:00
mesh2d_arcs.rs Use Isometry in bevy_gizmos wherever we can (#14676) 2024-08-28 01:37:19 +00:00
mesh2d_manual.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
mesh2d_vertex_color_texture.rs Fix some doc warnings (#12961) 2024-04-14 15:23:44 +00:00
move_sprite.rs Schedule-First: the new and improved add_systems (#8079) 2023-03-18 01:45:34 +00:00
pixel_grid_snap.rs Broaden "Check for bevy_internal imports" CI Task (#15333) 2024-09-20 17:08:37 +00:00
rotation.rs Fix floating point math (#15239) 2024-09-16 23:28:12 +00:00
sprite.rs Update color and naming for consistency (#10367) 2023-11-04 02:09:23 +00:00
sprite_animation.rs Updates default Text font size to 24px (#13603) 2024-05-31 16:41:27 +00:00
sprite_flipping.rs Update color and naming for consistency (#10367) 2023-11-04 02:09:23 +00:00
sprite_sheet.rs Deprecate SpriteSheetBundle and AtlasImageBundle (#12218) 2024-03-03 20:11:15 +00:00
sprite_slice.rs Have EntityCommands methods consume self for easier chaining (#14897) 2024-08-26 18:24:59 +00:00
sprite_tile.rs Optional ImageScaleMode (#11780) 2024-02-09 20:36:32 +00:00
text2d.rs Add the ability to control font smoothing (#15368) 2024-09-23 17:28:25 +00:00
texture_atlas.rs Fixing text sizes for examples (#15190) 2024-09-16 23:14:37 +00:00
transparency_2d.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
wireframe_2d.rs Consistency between Wireframe2d and Wireframe (#14720) 2024-08-13 18:57:47 +00:00