Skip to content

Conversation

@ickshonpe
Copy link
Contributor

@ickshonpe ickshonpe commented Dec 5, 2025

Objective

Add font weight support.

Solution

  • New FontWeight struct that newtypes a u16.
  • New font: FontWeight field on TextFont.
  • The weight attribute for the cosmic text buffer is set in TextPipeline during text updates.
  • Added a new font asset, MonSans-VariableFont.ttf. This needs a variable font for testing.

Doesn't support lighter and bolder as that would require text style inheritance, which we don't support yet.

I added stretch and slant as well, but split them off from this PR. Swash only has limited variable-font support and there's no way to demonstrate that they work without other changes.

Testing

Added a basic example:
cargo run --example font_weights

Showcase

font_weights

@ickshonpe ickshonpe changed the title Font weights Font weight support Dec 5, 2025
@ickshonpe ickshonpe added A-Text Rendering and layout for characters C-Feature A new feature, making something new possible M-Release-Note Work that should be called out in the blog due to impact D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes labels Dec 5, 2025
Copy link
Member

@ThierryBerger ThierryBerger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! But the noto font should probably be removed indeed ; Is there any reason not to use fira font ? or another one already present ?

section_info.5 = (metrics.underline_offset * scalar).round();
}
if let Some((id, _)) = self.map_handle_to_font_id.get(&section_info.0)
&& let Some(font) = font_system.get_font(*id, cosmic_text::Weight(section_info.6))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let chain 🎉 👍

@ickshonpe
Copy link
Contributor Author

Looks good! But the noto font should probably be removed indeed ; Is there any reason not to use fira font ? or another one already present ?

All the fonts we include atm are static, so they won't show any changes.

@ickshonpe
Copy link
Contributor Author

Maybe there is some light weight minimalistic variable font we can include instead, I'll have a look.

Copy link
Member

@ThierryBerger ThierryBerger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving ; if font size is a problem we may:

  • look into bringing a smaller font, maybe inter being 875kb (~half noto?)
  • or choose a more "powerful"/"featureful" font to anticipate further needs (but I doubt that makes sense, anticipating unclear goals is usually a no-no)

But it quickly gets into bikeshed territory, and assets management is a wild topic which I wouldn't want to block on here.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Dec 10, 2025

Switched to MonaSans variable font. It's only 384kb, which seems reasonable. If the extra size is a problem, we could remove the static EBGaramond font.

@viridia
Copy link
Contributor

viridia commented Dec 10, 2025

So if I understand correctly, this new font weight attribute only affects variable fonts, it has no affect on non-variable fonts? If so, this should be made clear in the documentation.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Dec 10, 2025

So if I understand correctly, this new font weight attribute only affects variable fonts, it has no affect on non-variable fonts? If so, this should be made clear in the documentation.

Sort of. To use this with static fonts, you need to load multiple fonts with different weights, so that it can choose the one with the nearest font-weight.

@viridia
Copy link
Contributor

viridia commented Dec 10, 2025

To use this with static fonts, you need to load multiple fonts with different weights, so that it can choose the one with the nearest font-weight.

How does that work? Because we are still assigning a font handle to each individual text span, how can it choose between different handles?

I mean, obviously this is how we want it to work, but it's not clear that this PR works that way now.

In any case, my point stands: if there are limitations then they should be called out in the docs.

@alice-i-cecile alice-i-cecile added the S-Needs-Review Needs reviewer attention (from anyone!) to move forward label Dec 15, 2025
Copy link
Contributor

@pablo-lua pablo-lua left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool feature, of course will only work with variables fonts (Because those are the only type of fonts that have multiple weights), but it works well, I tested with other font here, and even comes with some simplifying in the code, LGTM

@pablo-lua
Copy link
Contributor

pablo-lua commented Dec 16, 2025

To use this with static fonts, you need to load multiple fonts with different weights, so that it can choose the one with the nearest font-weight.

How does that work? Because we are still assigning a font handle to each individual text span, how can it choose between different handles?

I mean, obviously this is how we want it to work, but it's not clear that this PR works that way now.

In any case, my point stands: if there are limitations then they should be called out in the docs.

IIUC, we just rely on cosmic text to work behind the scenes and take the right gliphs. Because of this, comes with the limitation of just working with a font with variable weights on the same file (kinda rare, but not so much), but it'll not do any magic like looking for the file of a bold font in assets, in case of a not variable kind of ttf, sadly.
So this limitation in fact exists

@pablo-lua pablo-lua added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it and removed S-Needs-Review Needs reviewer attention (from anyone!) to move forward labels Dec 16, 2025
@alice-i-cecile
Copy link
Member

@ickshonpe can you please resolve merge conflicts?

Copy link
Member

@alice-i-cecile alice-i-cecile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very useful, surprisingly easy, as we delegate all the hard bits.

@ickshonpe
Copy link
Contributor Author

ickshonpe commented Dec 16, 2025

@alice-i-cecile Should be good now, assuming it passes CI.

@alice-i-cecile alice-i-cecile added this pull request to the merge queue Dec 16, 2025
Merged via the queue into bevyengine:main with commit b4e74de Dec 16, 2025
40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Text Rendering and layout for characters C-Feature A new feature, making something new possible D-Modest A "normal" level of difficulty; suitable for simple features or challenging fixes M-Release-Note Work that should be called out in the blog due to impact S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants