Fix text alignment for unbounded text (#17270)

Fixes #16783

Works around a `cosmic-text` bug or limitation by triggering a re-layout
with the calculated width from the first layout run. See linked issue.

Credit to @ickshonpe for the clever solution.

This has a significant performance impact only on unbounded text that
are not `JustifyText::Left`, which is still a bit of a bummer because
text2d performance in 0.15.1 is already not great. But this seems better
than alignment not working.

||many_text2d nfc re|many_text2d nfc re center|
|-|-|-|
|unbounded-layout-no-fix|3.06|3.10|
|unbounded-layout-fix|3.05  -0.2%|2.71 🟥 -12.5%|

I added a centered text to the `text2d` example.

`cargo run --example text2d`

We should look at other text examples and stress tests. I haven't tested
as thoroughly as I would like, so help testing that this doesn't break
something in UI would be appreciated.
This commit is contained in:
Rob Parrett 2025-01-10 21:45:32 -08:00 committed by François Mockers
parent 835f572e2a
commit fcc6b4ddff
2 changed files with 10 additions and 1 deletions

View File

@ -193,6 +193,14 @@ impl TextPipeline {
}
buffer.shape_until_scroll(font_system, false);
// Workaround for alignment not working for unbounded text.
// See https://github.com/pop-os/cosmic-text/issues/343
if bounds.width.is_none() && justify != JustifyText::Left {
let dimensions = buffer_dimensions(buffer);
// `set_size` causes a re-layout to occur.
buffer.set_size(font_system, Some(dimensions.x), bounds.height);
}
// Recover the spans buffer.
spans.clear();
self.spans_buffer = spans

View File

@ -111,10 +111,11 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
// Demonstrate font smoothing off
commands.spawn((
Text2d::new("FontSmoothing::None"),
Text2d::new("This text has\nFontSmoothing::None\nAnd JustifyText::Center"),
slightly_smaller_text_font
.clone()
.with_font_smoothing(FontSmoothing::None),
TextLayout::new_with_justify(JustifyText::Center),
Transform::from_translation(Vec3::new(-400.0, -250.0, 0.0)),
));