Reuse ClipMask in iced_tiny_skia

This commit is contained in:
Héctor Ramón Jiménez 2023-03-02 00:40:36 +01:00
parent 350427e82c
commit 868f79d22e
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
2 changed files with 32 additions and 16 deletions

View file

@ -25,6 +25,7 @@ impl Backend {
pub fn draw<T: AsRef<str>>( pub fn draw<T: AsRef<str>>(
&mut self, &mut self,
pixels: &mut tiny_skia::PixmapMut<'_>, pixels: &mut tiny_skia::PixmapMut<'_>,
clip_mask: &mut tiny_skia::ClipMask,
primitives: &[Primitive], primitives: &[Primitive],
viewport: &Viewport, viewport: &Viewport,
background_color: Color, background_color: Color,
@ -38,6 +39,7 @@ impl Backend {
self.draw_primitive( self.draw_primitive(
primitive, primitive,
pixels, pixels,
clip_mask,
None, None,
scale_factor, scale_factor,
Vector::ZERO, Vector::ZERO,
@ -63,6 +65,7 @@ impl Backend {
vertical_alignment: alignment::Vertical::Top, vertical_alignment: alignment::Vertical::Top,
}, },
pixels, pixels,
clip_mask,
None, None,
scale_factor, scale_factor,
Vector::ZERO, Vector::ZERO,
@ -76,7 +79,8 @@ impl Backend {
&mut self, &mut self,
primitive: &Primitive, primitive: &Primitive,
pixels: &mut tiny_skia::PixmapMut<'_>, pixels: &mut tiny_skia::PixmapMut<'_>,
clip_mask: Option<&tiny_skia::ClipMask>, clip_mask: &mut tiny_skia::ClipMask,
clip_bounds: Option<Rectangle>,
scale_factor: f32, scale_factor: f32,
translation: Vector, translation: Vector,
) { ) {
@ -95,6 +99,7 @@ impl Backend {
.post_scale(scale_factor, scale_factor); .post_scale(scale_factor, scale_factor);
let path = rounded_rectangle(*bounds, *border_radius); let path = rounded_rectangle(*bounds, *border_radius);
let clip_mask = clip_bounds.map(|_| clip_mask as &_);
pixels.fill_path( pixels.fill_path(
&path, &path,
@ -151,7 +156,7 @@ impl Backend {
*horizontal_alignment, *horizontal_alignment,
*vertical_alignment, *vertical_alignment,
pixels, pixels,
clip_mask, clip_bounds.map(|_| clip_mask as &_),
); );
} }
Primitive::Image { .. } => { Primitive::Image { .. } => {
@ -173,7 +178,7 @@ impl Backend {
transform transform
.post_translate(translation.x, translation.y) .post_translate(translation.x, translation.y)
.post_scale(scale_factor, scale_factor), .post_scale(scale_factor, scale_factor),
clip_mask, clip_bounds.map(|_| clip_mask as &_),
); );
} }
Primitive::Stroke { Primitive::Stroke {
@ -189,7 +194,7 @@ impl Backend {
transform transform
.post_translate(translation.x, translation.y) .post_translate(translation.x, translation.y)
.post_scale(scale_factor, scale_factor), .post_scale(scale_factor, scale_factor),
clip_mask, clip_bounds.map(|_| clip_mask as &_),
); );
} }
Primitive::Group { primitives } => { Primitive::Group { primitives } => {
@ -198,6 +203,7 @@ impl Backend {
primitive, primitive,
pixels, pixels,
clip_mask, clip_mask,
clip_bounds,
scale_factor, scale_factor,
translation, translation,
); );
@ -211,27 +217,37 @@ impl Backend {
content, content,
pixels, pixels,
clip_mask, clip_mask,
clip_bounds,
scale_factor, scale_factor,
translation + *offset, translation + *offset,
); );
} }
Primitive::Clip { bounds, content } => { Primitive::Clip { bounds, content } => {
let bounds = (*bounds + translation) * scale_factor;
adjust_clip_mask(clip_mask, pixels, bounds);
self.draw_primitive( self.draw_primitive(
content, content,
pixels, pixels,
Some(&rectangular_clip_mask( clip_mask,
pixels, Some(bounds),
(*bounds + translation) * scale_factor,
)),
scale_factor, scale_factor,
translation, translation,
); );
if let Some(bounds) = clip_bounds {
adjust_clip_mask(clip_mask, pixels, bounds);
} else {
clip_mask.clear();
}
} }
Primitive::Cache { content } => { Primitive::Cache { content } => {
self.draw_primitive( self.draw_primitive(
content, content,
pixels, pixels,
clip_mask, clip_mask,
clip_bounds,
scale_factor, scale_factor,
translation, translation,
); );
@ -393,12 +409,11 @@ fn arc_to(
} }
} }
fn rectangular_clip_mask( fn adjust_clip_mask(
clip_mask: &mut tiny_skia::ClipMask,
pixels: &tiny_skia::PixmapMut<'_>, pixels: &tiny_skia::PixmapMut<'_>,
bounds: Rectangle, bounds: Rectangle,
) -> tiny_skia::ClipMask { ) {
let mut clip_mask = tiny_skia::ClipMask::new();
let path = { let path = {
let mut builder = tiny_skia::PathBuilder::new(); let mut builder = tiny_skia::PathBuilder::new();
builder.push_rect(bounds.x, bounds.y, bounds.width, bounds.height); builder.push_rect(bounds.x, bounds.y, bounds.width, bounds.height);
@ -415,8 +430,6 @@ fn rectangular_clip_mask(
true, true,
) )
.expect("Set path of clipping area"); .expect("Set path of clipping area");
clip_mask
} }
impl iced_graphics::Backend for Backend { impl iced_graphics::Backend for Backend {

View file

@ -6,6 +6,7 @@ use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
use std::marker::PhantomData; use std::marker::PhantomData;
pub struct Compositor<Theme> { pub struct Compositor<Theme> {
clip_mask: tiny_skia::ClipMask,
_theme: PhantomData<Theme>, _theme: PhantomData<Theme>,
} }
@ -83,9 +84,10 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
} }
pub fn new<Theme>(settings: Settings) -> (Compositor<Theme>, Backend) { pub fn new<Theme>(settings: Settings) -> (Compositor<Theme>, Backend) {
// TODO // TOD
( (
Compositor { Compositor {
clip_mask: tiny_skia::ClipMask::new(),
_theme: PhantomData, _theme: PhantomData,
}, },
Backend::new(settings), Backend::new(settings),
@ -93,7 +95,7 @@ pub fn new<Theme>(settings: Settings) -> (Compositor<Theme>, Backend) {
} }
pub fn present<Theme, T: AsRef<str>>( pub fn present<Theme, T: AsRef<str>>(
_compositor: &mut Compositor<Theme>, compositor: &mut Compositor<Theme>,
backend: &mut Backend, backend: &mut Backend,
surface: &mut Surface, surface: &mut Surface,
primitives: &[Primitive], primitives: &[Primitive],
@ -110,6 +112,7 @@ pub fn present<Theme, T: AsRef<str>>(
physical_size.height, physical_size.height,
) )
.expect("Create pixel map"), .expect("Create pixel map"),
&mut compositor.clip_mask,
primitives, primitives,
viewport, viewport,
background_color, background_color,