Skip to content

Commit e517ef1

Browse files
committed
Fix incorrect bounding text for Text(Input) when element is bigger than intrinsic text size
The Text element may be given a size that exceeds its intrinsic size, however we returned the intrinsic size. The broke partial rendering when for example text was aligned within the bigger geometry: Text { text: "Ok"; horizontal-alignment: right; x: 0px; y: 0px; width: 100px; height: 50px; } This would return a bounding rect with an origin of (0, 0) and a width of maybe 20px, while the text is being rendered centered in the 100px wide geometry. That in turn meant that if that area with the text was marked as dirty, due to some overlap or for example linuxkms mouse cursor, then the Text element wasn't re-rendered because the bounding rect doesn't intersect with the clip. One option would be to teach the renderers text_size() about alignment, but it turns out that this is the only place where this is needed. So instead, fix this by using bounding_rect() to cover only the case it was originally introduced for - text exceeding the geometry - and otherwise return the geometry.
1 parent 481b298 commit e517ef1

File tree

2 files changed

+63
-10
lines changed

2 files changed

+63
-10
lines changed

api/rs/slint/tests/partial_renderer.rs

+51
Original file line numberDiff line numberDiff line change
@@ -627,3 +627,54 @@ fn shadow_redraw_beyond_geometry() {
627627
Some(slint::LogicalPosition { x: old_shadow_x, y: old_shadow_y })
628628
);
629629
}
630+
631+
#[test]
632+
fn text_alignment() {
633+
slint::slint! {
634+
export component Ui inherits Window {
635+
in property <color> c: green;
636+
Text {
637+
x: 10px;
638+
y: 10px;
639+
width: 200px;
640+
height: 50px;
641+
text: "Ok";
642+
color: c;
643+
}
644+
}
645+
}
646+
647+
slint::platform::set_platform(Box::new(TestPlatform)).ok();
648+
649+
let window = SKIA_WINDOW.with(|w| w.clone());
650+
NEXT_WINDOW_CHOICE.with(|choice| {
651+
*choice.borrow_mut() = Some(window.clone());
652+
});
653+
let ui = Ui::new().unwrap();
654+
window.set_size(slint::PhysicalSize::new(250, 250).into());
655+
ui.show().unwrap();
656+
657+
assert!(window.draw_if_needed());
658+
assert_eq!(
659+
window.last_dirty_region_bounding_box_size(),
660+
Some(slint::LogicalSize { width: 250., height: 250. })
661+
);
662+
assert_eq!(
663+
window.last_dirty_region_bounding_box_origin(),
664+
Some(slint::LogicalPosition { x: 0., y: 0. })
665+
);
666+
667+
assert!(!window.draw_if_needed());
668+
669+
ui.set_c(slint::Color::from_rgb_u8(45, 12, 13));
670+
671+
assert!(window.draw_if_needed());
672+
assert_eq!(
673+
window.last_dirty_region_bounding_box_size(),
674+
Some(slint::LogicalSize { width: 200., height: 50. })
675+
);
676+
assert_eq!(
677+
window.last_dirty_region_bounding_box_origin(),
678+
Some(slint::LogicalPosition { x: 10., y: 10. })
679+
);
680+
}

internal/core/item_rendering.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -340,16 +340,18 @@ pub trait RenderText {
340340
let font_request = self.font_request(window_inner);
341341
let scale_factor = crate::lengths::ScaleFactor::new(window_inner.scale_factor());
342342
let max_width = geometry.size.width_length();
343-
geometry.size = window_adapter
344-
.renderer()
345-
.text_size(
346-
font_request.clone(),
347-
text_string.as_str(),
348-
Some(max_width.cast()),
349-
scale_factor,
350-
self.wrap(),
351-
)
352-
.cast();
343+
geometry.size = geometry.size.max(
344+
window_adapter
345+
.renderer()
346+
.text_size(
347+
font_request.clone(),
348+
text_string.as_str(),
349+
Some(max_width.cast()),
350+
scale_factor,
351+
self.wrap(),
352+
)
353+
.cast(),
354+
);
353355
geometry
354356
}
355357
}

0 commit comments

Comments
 (0)