mirror of
https://github.com/penpot/penpot.git
synced 2025-12-11 22:14:05 +01:00
🐛 Fix bleeding masks
This commit is contained in:
committed by
Belén Albeza
parent
62ec66cd15
commit
8840246425
@@ -1103,9 +1103,7 @@ impl RenderState {
|
||||
if let Some(frame_blur) = Self::frame_clip_layer_blur(element) {
|
||||
let scale = self.get_scale();
|
||||
let sigma = frame_blur.value * scale;
|
||||
if let Some(filter) =
|
||||
skia::image_filters::blur((sigma, sigma), None, None, None)
|
||||
{
|
||||
if let Some(filter) = skia::image_filters::blur((sigma, sigma), None, None, None) {
|
||||
paint.set_image_filter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -885,19 +885,50 @@ impl Shape {
|
||||
scale: f32,
|
||||
) -> Bounds {
|
||||
let mut rect = bounds.to_rect();
|
||||
let include_children = match self.shape_type {
|
||||
Type::Group(_) => true,
|
||||
Type::Frame(_) => !self.clip_content,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if include_children {
|
||||
for child_id in self.children_ids_iter(false) {
|
||||
if let Some(child_shape) = shapes_pool.get(child_id) {
|
||||
let child_extrect = child_shape.calculate_extrect(shapes_pool, scale);
|
||||
rect.join(child_extrect);
|
||||
match self.shape_type {
|
||||
Type::Group(Group { masked: true }) => {
|
||||
let mut mask_rect: Option<math::Rect> = None;
|
||||
let mut content_rect: Option<math::Rect> = None;
|
||||
|
||||
for (index, child_id) in self.children.iter().enumerate() {
|
||||
if let Some(child_shape) = shapes_pool.get(child_id) {
|
||||
let child_extrect = child_shape.calculate_extrect(shapes_pool, scale);
|
||||
|
||||
if index == 0 {
|
||||
mask_rect = Some(child_extrect);
|
||||
} else {
|
||||
match content_rect.as_mut() {
|
||||
Some(r) => r.join(child_extrect),
|
||||
None => content_rect = Some(child_extrect),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match (mask_rect, content_rect) {
|
||||
(Some(mut mask), Some(content)) => {
|
||||
if mask.intersect(&content) {
|
||||
rect.join(mask);
|
||||
}
|
||||
}
|
||||
(Some(mask), None) | (None, Some(mask)) => {
|
||||
rect.join(mask);
|
||||
}
|
||||
(None, None) => {}
|
||||
}
|
||||
}
|
||||
|
||||
Type::Group(_) | Type::Frame(_) if !self.clip_content => {
|
||||
for child_id in self.children_ids_iter(false) {
|
||||
if let Some(child_shape) = shapes_pool.get(child_id) {
|
||||
let child_extrect = child_shape.calculate_extrect(shapes_pool, scale);
|
||||
rect.join(child_extrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Bounds::from_rect(&rect)
|
||||
@@ -1426,6 +1457,7 @@ impl Shape {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::state::ShapesPool;
|
||||
|
||||
fn any_shape() -> Shape {
|
||||
Shape::new(Uuid::nil())
|
||||
@@ -1485,4 +1517,35 @@ mod tests {
|
||||
assert_eq!(shape.selrect().width(), 20.0);
|
||||
assert_eq!(shape.selrect().height(), 20.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn masked_group_extrect_matches_mask_intersection() {
|
||||
let mut pool = ShapesPool::new();
|
||||
pool.initialize(3);
|
||||
|
||||
let group_id = Uuid::new_v4();
|
||||
let mask_id = Uuid::new_v4();
|
||||
let content_id = Uuid::new_v4();
|
||||
|
||||
let group = pool.add_shape(group_id);
|
||||
group.set_shape_type(Type::Group(Group { masked: true }));
|
||||
group.children = vec![mask_id, content_id];
|
||||
|
||||
let mask = pool.add_shape(mask_id);
|
||||
mask.set_shape_type(Type::Rect(Rect::default()));
|
||||
mask.set_selrect(0.0, 0.0, 50.0, 50.0);
|
||||
mask.set_parent(group_id);
|
||||
|
||||
let content = pool.add_shape(content_id);
|
||||
content.set_shape_type(Type::Rect(Rect::default()));
|
||||
content.set_selrect(-10.0, -10.0, 110.0, 110.0);
|
||||
content.set_parent(group_id);
|
||||
|
||||
let extrect = group.calculate_extrect(&pool, 1.0);
|
||||
|
||||
assert_eq!(extrect.left, 0.0);
|
||||
assert_eq!(extrect.top, 0.0);
|
||||
assert_eq!(extrect.right, 50.0);
|
||||
assert_eq!(extrect.bottom, 50.0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user