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.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants