bevy icon indicating copy to clipboard operation
bevy copied to clipboard

add `FontRef` and `DefaultFont`

Open IceSentry opened this issue 3 years ago • 3 comments
trafficstars

Objective

Creating a TextStyle requires an Handle<Font> which means you either need to pass the text_style around or pass an asset_server everywhere. This makes declaring reusable ui components harder than necessary.

It should be possible to not need to pass around anything and create it where we want it and let bevy take care of loading the font.

Solution

  • Introduce a new FontRef inspired by the ShaderRef from the new Material
    • A default font that can be configured globally with the new DefaultFont resource
    • A string path to a font can be automatically converted to a FontRef and the new bevy_text::load_font() system will take care of loading the font asset and converting the path to an Handle<Font>.
    • Keep support for manually loading fonts and convert the Handle to a FontRef::Handle

Changelog

This section is optional. If this was a trivial fix, or has no externally-visible impact, you can delete this section.

  • Added FontRef and DefaultFont
  • TextStyle now uses FontRef instead of Handle<Font>

Migration Guide

// 0.8
commands.spawn_bundle(TextBundle::from_section(
    "hello bevy!",
    TextStyle {
        font: asset_server.load("fonts/FiraSans-Bold.ttf"),
		..default()
    },
));

// 0.9
commands.spawn_bundle(TextBundle::from_section(
    "hello bevy!",
    TextStyle {
        font: "fonts/FiraSans-Bold.ttf".into(),
		..default()
    },
));

Notes

I updated all the examples using fonts, but I only used the new DefaultFont on the game_menu example.

Closes #5515

IceSentry avatar Aug 02 '22 03:08 IceSentry

If the DefaultFont resource has not been set, would it make sense to pick the first font available in Assets<Font> and only fail if there isn't one?

mockersf avatar Aug 02 '22 07:08 mockersf

That could work, but this new api encourages people to just use "path/to/font.ttf".into() everywhere which would mean it's very possible a font won't be loaded by the time it reaches a FontRef::Default.

Even if it did, it would be a bit weird how order dependent it would become. Like you change the order of a ui widget and now suddenly all the text in your app looks different.

IceSentry avatar Aug 02 '22 13:08 IceSentry

I don't mind doing it as a fallback, but personally I'd rather get an error if it's not set. Eventually, once we ship an editor we'll be able to ship a font and initialize the resource with a default value, but right now it feels less error prone to not do that. Eventually we could also load the system font, but that should be done in a separate PR.

IceSentry avatar Aug 02 '22 13:08 IceSentry

Alright, I implemented the fallback to the first font on default, but as I expected if the fonts are added in the same system it doesn't work because the font isn't added to the assets store yet.

I also fixed a bug where text wouldn't load on startup in desktop_app mode.

IceSentry avatar Aug 06 '22 03:08 IceSentry

I added a short description to the migration guide. I'm not sure what would be needed in the changelog section.

IceSentry avatar Aug 29 '22 02:08 IceSentry

I closed this PR because the solution in https://github.com/bevyengine/bevy/pull/8445 solves this in a much nicer way.

IceSentry avatar Apr 20 '23 17:04 IceSentry