Minimal responsive FontSize support#22614
Merged
Merged
Conversation
…the new `RemSize` resource.
Implemented Mul<f32> for FontSize
Member
|
Wondering if this PR supersedes #9524? |
Contributor
Author
Yeah got a bunch of open PRs that I need to clean up. Closed it. |
kfc35
approved these changes
Feb 1, 2026
kfc35
left a comment
Contributor
There was a problem hiding this comment.
Logic looks good to me, just minor comments.
For other reviewers: This change is really not too bad to review!
…Block` and updated them in `TextPipeline::update_buffer`. These will be used by dependents to determine if they should update a text block on changes to the viewport size or rem size respectively.
…ss in viewport and rem size change states.
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
…rate the subtraction.
alice-i-cecile
approved these changes
Feb 2, 2026
alice-i-cecile
left a comment
Member
There was a problem hiding this comment.
Surprisingly straightforward. Very happy about this!
FontSize supportFontSize support
Closed
viridia
pushed a commit
to viridia/bevy
that referenced
this pull request
Feb 3, 2026
# Objective
Add responsive font sizes supporting rem and viewport units to
`bevy_text` with minimal changes to the APIs and systems.
## Solution
Introduce a new `FontSize` enum:
```rust
pub enum FontSize {
/// Font Size in logical pixels.
Px(f32),
/// Font size as a percentage of the viewport width.
Vw(f32),
/// Font size as a percentage of the viewport height.
Vh(f32),
/// Font size as a percentage of the smaller of the viewport width and height.
VMin(f32),
/// Font size as a percentage of the larger of the viewport width and height.
VMax(f32),
/// Font Size relative to the value of the `RemSize` resource.
Rem(f32),
}
```
This replaces the `f32` value of `TextFont`'s `font_size` field.
The viewport variants work the same way as their respective `Val`
counterparts.
`Rem` values are multiplied by the value of the `RemSize` resource
(which newtypes an `f32`).
`FontSize` provides an `eval` method that takes a logical viewport size
and rem base size and returns an `f32` logical font size. The resolved
logical font size is then written into the `Attributes` passed to Cosmic
Text by `TextPipeline::update_buffer`.
Any text implementation using `bevy_text` must now provide viewport and
rem base values when calling `TextPipeline::update_buffer` or
`create_measure`.
`Text2d` uses the size of the primary window to resolve viewport values
(or `Vec2::splat(1000)` if no primary window is found). This is a
deliberate compromise, a single `Text2d` can be rendered to multiple
viewports using `RenderLayers`, so it's difficult to find a rule for
which viewport size should be chosen.
### Change detection
`ComputedTextBlock` has two new fields: `uses_viewport_sizes` and
`uses_rem_sizes`, which are set to true in `TextPipeline::update_buffer`
iff any text section in the block uses viewport or rem font sizes,
respectively.
The `ComputedTextBlock::needs_rerender` method has been modified to take
take two bool parameters:
```rust
pub fn needs_rerender(
&self,
is_viewport_size_changed: bool,
is_rem_size_changed: bool,
) -> bool {
self.needs_rerender
|| (is_viewport_size_changed && self.uses_viewport_sizes)
|| (is_rem_size_changed && self.uses_rem_sizes)
}
```
This ensures that text reupdates will also be scheduled if one of the text section's uses a viewport font size and the local viewport size changed, or if one of the text section's uses a rem font size and the rem size changed.
#### Limitations
There are some limitations because we don't have any sort of font style inheritance yet:
* "rem" units aren't proper rem units, and just based on the value of a resource.
* "em" units are resolved based on inherited font size, so can't be implemented without inheritance support.
#### Notes
* This PR is quite small and not very technical. Reviewers don't need to be especially familiar with `bevy_text`. Most of the changes are to the examples.
* We could consider using `Val` instead of `FontSize`, then we could use `Val`'s constructor functions which would be much nicer, but some variants might not have sensible interpretations in both UI and Text2d contexts. Also we'd have to make `Val` accessible to `bevy_text`.
## Testing
The changes to the text systems are relatively trivial and easy to understand. I already added a minor change to the `text` example to use `Vh` font size for the "hello bevy" text in the bottom right corner. If you change the size of the window, you should see the text change size in response. The text initially flickers before it updates because of some unrelated asset/image changes that mean that font textures aren't ready until the frame after the text update that changes the font size.
Most of the example migrations were automated using regular expressions, and there are bound to be mistakes in those changes. It's infeasible to check every single example thoroughly, but it's early enough in the release cycle that I don't think we should be too worried if a few bugs slip in.
---------
Co-authored-by: Kevin Chen <chen.kevin.f@gmail.com>
gvozdvmozgu
reviewed
Mar 9, 2026
| .map(|window| window.resolution.size()) | ||
| .unwrap_or(Vec2::splat(1000.)); | ||
|
|
||
| let viewport_size_changed = *last_logical_viewport_size == logical_viewport_size; |
There was a problem hiding this comment.
This looks inverted: viewport_size_changed is computed with ==, so it becomes true when the viewport is unchanged and false on the actual resize frame. I think this should be !=, otherwise viewport-based text may rerender unnecessarily and resize updates get delayed by a frame.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Add responsive font sizes supporting rem and viewport units to
bevy_textwith minimal changes to the APIs and systems.Solution
Introduce a new
FontSizeenum:This replaces the
f32value ofTextFont'sfont_sizefield.The viewport variants work the same way as their respective
Valcounterparts.Remvalues are multiplied by the value of theRemSizeresource (which newtypes anf32).FontSizeprovides anevalmethod that takes a logical viewport size and rem base size and returns anf32logical font size. The resolved logical font size is then written into theAttributespassed to Cosmic Text byTextPipeline::update_buffer.Any text implementation using
bevy_textmust now provide viewport and rem base values when callingTextPipeline::update_bufferorcreate_measure.Text2duses the size of the primary window to resolve viewport values (orVec2::splat(1000)if no primary window is found). This is a deliberate compromise, a singleText2dcan be rendered to multiple viewports usingRenderLayers, so it's difficult to find a rule for which viewport size should be chosen.Change detection
ComputedTextBlockhas two new fields:uses_viewport_sizesanduses_rem_sizes, which are set to true inTextPipeline::update_bufferiff any text section in the block uses viewport or rem font sizes, respectively.The
ComputedTextBlock::needs_rerendermethod has been modified to take take two bool parameters:This ensures that text reupdates will also be scheduled if one of the text section's uses a viewport font size and the local viewport size changed, or if one of the text section's uses a rem font size and the rem size changed.
Limitations
There are some limitations because we don't have any sort of font style inheritance yet:
Notes
This PR is quite small and not very technical. Reviewers don't need to be especially familiar with
bevy_text. Most of the changes are to the examples.We could consider using
Valinstead ofFontSize, then we could useVal's constructor functions which would be much nicer, but some variants might not have sensible interpretations in both UI and Text2d contexts. Also we'd have to makeValaccessible tobevy_text.Testing
The changes to the text systems are relatively trivial and easy to understand. I already added a minor change to the
textexample to useVhfont size for the "hello bevy" text in the bottom right corner. If you change the size of the window, you should see the text change size in response. The text initially flickers before it updates because of some unrelated asset/image changes that mean that font textures aren't ready until the frame after the text update that changes the font size.Most of the example migrations were automated using regular expressions, and there are bound to be mistakes in those changes. It's infeasible to check every single example thoroughly, but it's early enough in the release cycle that I don't think we should be too worried if a few bugs slip in.