Skip to content
43 changes: 41 additions & 2 deletions api/rs/slint/tests/partial_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl WindowAdapter for SkiaTestWindow {
#[derive(Default)]
struct SkiaTestSoftwareBuffer {
pixels: RefCell<Option<SharedPixelBuffer<slint::Rgba8Pixel>>>,
last_dirty_region: RefCell<Option<i_slint_core::item_rendering::DirtyRegion>>,
last_dirty_region: RefCell<Option<i_slint_core::partial_renderer::DirtyRegion>>,
}

impl i_slint_renderer_skia::software_surface::RenderBuffer for SkiaTestSoftwareBuffer {
Expand All @@ -153,7 +153,7 @@ impl i_slint_renderer_skia::software_surface::RenderBuffer for SkiaTestSoftwareB
u8,
&mut [u8],
) -> Result<
Option<i_slint_core::item_rendering::DirtyRegion>,
Option<i_slint_core::partial_renderer::DirtyRegion>,
i_slint_core::platform::PlatformError,
>,
) -> Result<(), i_slint_core::platform::PlatformError> {
Expand Down Expand Up @@ -681,3 +681,42 @@ fn text_alignment() {
Some(slint::LogicalPosition { x: 10., y: 10. })
);
}

#[test]
fn nowrap_text_change_doesnt_change_height() {
slint::slint! {
export component Ui inherits Window {
in property <string> first-text: "First text";
out property <length> first-label-width: first-label.width;
out property <length> first-label-height: first-label.height;
background: black;
VerticalLayout {
first-label := Text {
text: root.first-text;
}
Text {
text: "Second text";
}
}
}
}

slint::platform::set_platform(Box::new(TestPlatform)).ok();
let ui = Ui::new().unwrap();
let window = WINDOW.with(|x| x.clone());
window.set_size(slint::PhysicalSize::new(180, 260));
ui.show().unwrap();
assert!(window.draw_if_needed(|renderer| {
do_test_render_region(renderer, 0, 0, 180, 260);
}));
assert!(!window.draw_if_needed(|_| { unreachable!() }));
ui.set_first_text("Hello World longer".into());

let expected_width = ui.get_first_label_width().ceil() as _;
let expected_height = ui.get_first_label_height().ceil() as _;

assert!(window.draw_if_needed(|renderer| {
do_test_render_region(renderer, 0, 0, expected_width, expected_height);
}));
assert!(!window.draw_if_needed(|_| { unreachable!() }));
}
3 changes: 2 additions & 1 deletion internal/backends/linuxkms/renderer/skia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use std::sync::Arc;
use crate::display::RenderingRotation;
use crate::drmoutput::DrmOutput;
use i_slint_core::api::{PhysicalSize as PhysicalWindowSize, Window};
use i_slint_core::item_rendering::{DirtyRegion, ItemRenderer};
use i_slint_core::item_rendering::ItemRenderer;
use i_slint_core::partial_renderer::DirtyRegion;
use i_slint_core::platform::PlatformError;
use i_slint_renderer_skia::SkiaRendererExt;
use i_slint_renderer_skia::{skia_safe, SkiaRenderer, SkiaSharedContext};
Expand Down
58 changes: 0 additions & 58 deletions internal/core/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
Graphics Abstractions.

This module contains the abstractions and convenience types used for rendering.

The run-time library also makes use of [RenderingCache] to store the rendering primitives
created by the backend in a type-erased manner.
*/
extern crate alloc;
use crate::api::PlatformError;
Expand Down Expand Up @@ -83,61 +80,6 @@ impl<T> CachedGraphicsData<T> {
}
}

/// The RenderingCache, in combination with CachedGraphicsData, allows back ends to store data that's either
/// intensive to compute or has bad CPU locality. Back ends typically keep a RenderingCache instance and use
/// the item's cached_rendering_data() integer as index in the vec_arena::Arena.
///
/// This is used only for the [`crate::item_rendering::PartialRenderingCache`]
pub struct RenderingCache<T> {
slab: slab::Slab<CachedGraphicsData<T>>,
generation: usize,
}

impl<T> Default for RenderingCache<T> {
fn default() -> Self {
Self { slab: Default::default(), generation: 1 }
}
}

impl<T> RenderingCache<T> {
/// Returns the generation of the cache. The generation starts at 1 and is increased
/// whenever the cache is cleared, for example when the GL context is lost.
pub fn generation(&self) -> usize {
self.generation
}

/// Retrieves a mutable reference to the cached graphics data at index.
pub fn get_mut(&mut self, index: usize) -> Option<&mut CachedGraphicsData<T>> {
self.slab.get_mut(index)
}

/// Returns true if a cache entry exists for the given index.
pub fn contains(&self, index: usize) -> bool {
self.slab.contains(index)
}

/// Inserts data into the cache and returns the index for retrieval later.
pub fn insert(&mut self, data: CachedGraphicsData<T>) -> usize {
self.slab.insert(data)
}

/// Retrieves an immutable reference to the cached graphics data at index.
pub fn get(&self, index: usize) -> Option<&CachedGraphicsData<T>> {
self.slab.get(index)
}

/// Removes the cached graphics data at the given index.
pub fn remove(&mut self, index: usize) -> CachedGraphicsData<T> {
self.slab.remove(index)
}

/// Removes all entries from the cache and increases the cache's generation count, so
/// that stale index access can be avoided.
pub fn clear(&mut self) {
self.slab.clear();
self.generation += 1;
}
}
/// FontRequest collects all the developer-configurable properties for fonts, such as family, weight, etc.
/// It is submitted as a request to the platform font system (i.e. CoreText on macOS) and in exchange the
/// backend returns a `Box<dyn Font>`.
Expand Down
Loading
Loading