bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
36.4k stars 3.59k forks source link

`cosmic_text` font fallback causes inconsistent text rendering results #16354

Open TurtIeSocks opened 1 week ago

TurtIeSocks commented 1 week ago

Bevy version

Bevy: Latest main Cargo: cargo 1.82.0 (8f40fc59f 2024-08-21) OS: Windows 11

`AdapterInfo { name: "NVIDIA GeForce RTX 4090", vendor: 4318, device: 9860, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "566.03", backend: Vulkan }`

What you did

I discovered this issue while working on an i18n crate for Bevy that loads dynamic fonts based on the selected locale.

I put together a minimal reproduction repo here: https://github.com/TurtIeSocks/bevy_font_bug

What went wrong

While working on this crate I noticed that if a font wasn't using the dynamic font component, it was still able to successfully render characters from the fonts that I had used in other text components, even though the component in question was only using the default font included with Bevy. After putting together the minimal reproduction repo and taking a closer look at the debug logs, it seems that cosmic_text is caching fonts to use as a fallback when the given font does not have support for the necessary characters.

Expectation

Texts should (?) render with the font that is (or isn't) provided,

What Happened

Texts are automatically selecting previously used fonts as fallbacks.

Additional information

These logs are taken from the minimal reproduction repo linked above:

Logs from first render (when the font was not cached)

2024-11-11T17:18:24.216542Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI'
2024-11-11T17:18:24.216621Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Emoji'
2024-11-11T17:18:24.218546Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI'
2024-11-11T17:18:24.218683Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Emoji'
2024-11-11T17:18:24.218804Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Symbol'
2024-11-11T17:18:24.218902Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Historic'
2024-11-11T17:18:24.219010Z DEBUG cosmic_text::font::fallback: Failed to find any fallback for [Han] locale 'en-US': '界'

Logs from the second render

2024-11-11T17:18:25.221886Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI'
2024-11-11T17:18:25.221966Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Emoji'
2024-11-11T17:18:25.222059Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Symbol'
2024-11-11T17:18:25.222179Z DEBUG cosmic_text::font::fallback: failed to find family 'Segoe UI Historic'
2024-11-11T17:18:25.222333Z DEBUG cosmic_text::font::fallback: Failed to find preset fallback for [Han] locale 'en-US', used 'Noto Sans JP': '界'

Thoughts

I like the idea of having font fallbacks, especially for i18n purposes, but I think the undocumented behavior may just lead to confusion more than anything else. And as the logs mentioned, it says "Failed to find preset fallback", so I assume we can customize this in some way, which could be a desirable public API that could be added.

Couple of thoughts on this: