mirror of
https://github.com/penpot/penpot.git
synced 2025-07-18 13:07:14 +02:00
🐛 Fix shapes without fills contained in a group with fills
This commit is contained in:
parent
fec7d5cff2
commit
a9702f104d
3 changed files with 32 additions and 5 deletions
|
@ -696,8 +696,10 @@
|
||||||
false)
|
false)
|
||||||
rotation (dm/get-prop shape :rotation)
|
rotation (dm/get-prop shape :rotation)
|
||||||
transform (dm/get-prop shape :transform)
|
transform (dm/get-prop shape :transform)
|
||||||
fills (if (= type :group)
|
|
||||||
[] (dm/get-prop shape :fills))
|
;; Groups from imported SVG's can have their own fills
|
||||||
|
fills (dm/get-prop shape :fills)
|
||||||
|
|
||||||
strokes (if (= type :group)
|
strokes (if (= type :group)
|
||||||
[] (dm/get-prop shape :strokes))
|
[] (dm/get-prop shape :strokes))
|
||||||
children (dm/get-prop shape :shapes)
|
children (dm/get-prop shape :shapes)
|
||||||
|
|
|
@ -19,7 +19,9 @@ use options::RenderOptions;
|
||||||
use surfaces::{SurfaceId, Surfaces};
|
use surfaces::{SurfaceId, Surfaces};
|
||||||
|
|
||||||
use crate::performance;
|
use crate::performance;
|
||||||
use crate::shapes::{modified_children_ids, Corners, Shape, StrokeKind, StructureEntry, Type};
|
use crate::shapes::{
|
||||||
|
modified_children_ids, Corners, Fill, Shape, StrokeKind, StructureEntry, Type,
|
||||||
|
};
|
||||||
use crate::tiles::{self, PendingTiles, TileRect};
|
use crate::tiles::{self, PendingTiles, TileRect};
|
||||||
use crate::uuid::Uuid;
|
use crate::uuid::Uuid;
|
||||||
use crate::view::Viewbox;
|
use crate::view::Viewbox;
|
||||||
|
@ -97,6 +99,11 @@ pub(crate) struct RenderState {
|
||||||
pub tile_viewbox: tiles::TileViewbox,
|
pub tile_viewbox: tiles::TileViewbox,
|
||||||
pub tiles: tiles::TileHashMap,
|
pub tiles: tiles::TileHashMap,
|
||||||
pub pending_tiles: PendingTiles,
|
pub pending_tiles: PendingTiles,
|
||||||
|
// nested_fills maintains a stack of group fills that apply to nested shapes
|
||||||
|
// without their own fill definitions. This is necessary because in SVG, a group's `fill`
|
||||||
|
// can affect its child elements if they don't specify one themselves. If the planned
|
||||||
|
// migration to remove group-level fills is completed, this code should be removed.
|
||||||
|
pub nested_fills: Vec<Vec<Fill>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cache_size(viewbox: Viewbox, scale: f32) -> skia::ISize {
|
pub fn get_cache_size(viewbox: Viewbox, scale: f32) -> skia::ISize {
|
||||||
|
@ -162,6 +169,7 @@ impl RenderState {
|
||||||
1.0,
|
1.0,
|
||||||
),
|
),
|
||||||
pending_tiles: PendingTiles::new_empty(),
|
pending_tiles: PendingTiles::new_empty(),
|
||||||
|
nested_fills: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,9 +443,18 @@ impl RenderState {
|
||||||
s.canvas().concat(&matrix);
|
s.canvas().concat(&matrix);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if shape.fills.is_empty() && matches!(shape.shape_type, Type::Group(_)) {
|
||||||
|
if let Some(fills_to_render) = self.nested_fills.last() {
|
||||||
|
let fills_to_render = fills_to_render.clone();
|
||||||
|
for fill in fills_to_render.iter() {
|
||||||
|
fills::render(self, &shape, fill, antialias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
for fill in shape.fills().rev() {
|
for fill in shape.fills().rev() {
|
||||||
fills::render(self, &shape, fill, antialias);
|
fills::render(self, &shape, fill, antialias);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for stroke in shape.strokes().rev() {
|
for stroke in shape.strokes().rev() {
|
||||||
shadows::render_stroke_drop_shadows(self, &shape, stroke, antialias);
|
shadows::render_stroke_drop_shadows(self, &shape, stroke, antialias);
|
||||||
|
@ -599,6 +616,8 @@ impl RenderState {
|
||||||
// an extra save_layer to keep all the masked group separate from
|
// an extra save_layer to keep all the masked group separate from
|
||||||
// other already drawn elements.
|
// other already drawn elements.
|
||||||
if let Type::Group(group) = element.shape_type {
|
if let Type::Group(group) = element.shape_type {
|
||||||
|
let fills = &element.fills;
|
||||||
|
self.nested_fills.push(fills.to_vec());
|
||||||
if group.masked {
|
if group.masked {
|
||||||
let paint = skia::Paint::default();
|
let paint = skia::Paint::default();
|
||||||
let layer_rec = skia::canvas::SaveLayerRec::default().paint(&paint);
|
let layer_rec = skia::canvas::SaveLayerRec::default().paint(&paint);
|
||||||
|
@ -645,6 +664,9 @@ impl RenderState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Type::Group(group) = element.shape_type {
|
||||||
|
self.nested_fills.pop();
|
||||||
|
}
|
||||||
self.surfaces.canvas(SurfaceId::Current).restore();
|
self.surfaces.canvas(SurfaceId::Current).restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,9 @@ pub fn render(render_state: &mut RenderState, shape: &Shape, fill: &Fill, antial
|
||||||
.surfaces
|
.surfaces
|
||||||
.draw_path_to(SurfaceId::Fills, shape, paint);
|
.draw_path_to(SurfaceId::Fills, shape, paint);
|
||||||
}
|
}
|
||||||
|
(_, Type::Group(_)) => {
|
||||||
|
// Groups can have fills but they propagate them to their children
|
||||||
|
}
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
unreachable!("This shape should not have fills")
|
unreachable!("This shape should not have fills")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue