bevyengine / bevyengine/bevy

Problems with `Font`s as `Asset`s

Open
#22,415 0 comments 0 reactions 0 assignees View on GitHub
A-Assets A-Text C-Bug C-Feature P-High S-Needs-Design
Dominant language
Rust
Stars
48.2k
Forks
4.8k
Avg merge
3d 22h
Merged PRs (30d)
161

Description

## The problems with `Font`s as `Asset`s

1. When a `Font`’s asset handles are dropped, the font data isn’t deleted because Cosmic Text clones the `Arc` holding the font data and stores it in its `FontDb`. Once a font is added to the database, it can’t be removed. The only way to remove fonts is to create a new `FontDb` instance without the font you want to remove. Creating a new database changes all font `ID`s, which requires regenerating all font atlases, text data, and layouts. This is all very expensive and probably not something that should happen automatically.

2. If a font handle is dropped and its font asset is unloaded, its old `FontDb` entry isn't overwritten. Instead, if you reload the same font again later, a new entry for the font data is added to cosmic text's `FontDb`, alongside the old one.

3. Font's are normally static data, there isn't a lot of need for applications to load and unload them dynamically.

4. `Font` assets can contain multiple faces, but the handle can only be used to reference one of them.

5. Font texture atlases are created per font instance and aren't disposed of automatically. Naively animating the `FontSize` for a `Text` entity can create easily create hundreds of texture atlases that persist and accumulate.

## Some naive suggestions

* Load fonts once during `App` creation.

* Remove (the non-working) support for unloading fonts.

* Load fonts using `Asset`s but hide the handle. Add an extension method on `Commands` like:
```
commands.load_font("fonts/FiraSans-Bold.ttf");
```
Internally load the font data using an asset loader. Once the font data is loaded, automatically add it to Cosmic Text's database and then drop the handle.

* Manage and dispose of font atlases using an LRU buffer.

* Only allow fonts to be referenced by name string or by a generic font family enum.

* Add a helper function/system that constructs a new a `FontDb` instance from a filtered set of fonts, replaces the existing database, and regenerates all the associated text data.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.