mirror of
https://github.com/penpot/penpot.git
synced 2026-02-09 14:16:35 -05:00
Compare commits
1 Commits
develop
...
superalex-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
880ad8e450 |
@@ -26,7 +26,7 @@ fn draw_stroke_on_rect(
|
||||
// Draw the different kind of strokes for a rect is straightforward, we just need apply a stroke to:
|
||||
// - The same rect if it's a center stroke
|
||||
// - A bigger rect if it's an outer stroke
|
||||
// - A smaller rect if it's an outer stroke
|
||||
// - A smaller rect if it's an inner stroke
|
||||
let stroke_rect = stroke.aligned_rect(rect, scale);
|
||||
let mut paint = stroke.to_paint(selrect, svg_attrs, antialias);
|
||||
|
||||
@@ -34,14 +34,75 @@ fn draw_stroke_on_rect(
|
||||
let filter = compose_filters(blur, shadow);
|
||||
paint.set_image_filter(filter);
|
||||
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let radii = stroke.outer_corners(radii);
|
||||
let rrect = RRect::new_rect_radii(stroke_rect, &radii);
|
||||
canvas.draw_rrect(rrect, &paint);
|
||||
// For inner/outer strokes, we need clipping to prevent stroke pattern
|
||||
// (like dotted circles) from appearing in wrong areas
|
||||
match stroke.kind {
|
||||
StrokeKind::Inner => {
|
||||
// Inner: clip to original rect to hide parts outside boundary
|
||||
canvas.save();
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let rrect = RRect::new_rect_radii(*rect, radii);
|
||||
canvas.clip_rrect(rrect, skia::ClipOp::Intersect, antialias);
|
||||
}
|
||||
None => {
|
||||
canvas.clip_rect(*rect, skia::ClipOp::Intersect, antialias);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the stroke
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let radii = stroke.outer_corners(radii);
|
||||
let rrect = RRect::new_rect_radii(stroke_rect, &radii);
|
||||
canvas.draw_rrect(rrect, &paint);
|
||||
}
|
||||
None => {
|
||||
canvas.draw_rect(stroke_rect, &paint);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
None => {
|
||||
canvas.draw_rect(stroke_rect, &paint);
|
||||
StrokeKind::Outer => {
|
||||
// Outer: clip to exclude original rect to hide parts inside boundary
|
||||
canvas.save();
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let rrect = RRect::new_rect_radii(*rect, radii);
|
||||
canvas.clip_rrect(rrect, skia::ClipOp::Difference, antialias);
|
||||
}
|
||||
None => {
|
||||
canvas.clip_rect(*rect, skia::ClipOp::Difference, antialias);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the stroke
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let radii = stroke.outer_corners(radii);
|
||||
let rrect = RRect::new_rect_radii(stroke_rect, &radii);
|
||||
canvas.draw_rrect(rrect, &paint);
|
||||
}
|
||||
None => {
|
||||
canvas.draw_rect(stroke_rect, &paint);
|
||||
}
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
StrokeKind::Center => {
|
||||
// Center strokes don't need clipping
|
||||
match corners {
|
||||
Some(radii) => {
|
||||
let radii = stroke.outer_corners(radii);
|
||||
let rrect = RRect::new_rect_radii(stroke_rect, &radii);
|
||||
canvas.draw_rrect(rrect, &paint);
|
||||
}
|
||||
None => {
|
||||
canvas.draw_rect(stroke_rect, &paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +123,7 @@ fn draw_stroke_on_circle(
|
||||
// Draw the different kind of strokes for an oval is straightforward, we just need apply a stroke to:
|
||||
// - The same oval if it's a center stroke
|
||||
// - A bigger oval if it's an outer stroke
|
||||
// - A smaller oval if it's an outer stroke
|
||||
// - A smaller oval if it's an inner stroke
|
||||
let stroke_rect = stroke.aligned_rect(rect, scale);
|
||||
let mut paint = stroke.to_paint(selrect, svg_attrs, antialias);
|
||||
|
||||
@@ -70,7 +131,28 @@ fn draw_stroke_on_circle(
|
||||
let filter = compose_filters(blur, shadow);
|
||||
paint.set_image_filter(filter);
|
||||
|
||||
canvas.draw_oval(stroke_rect, &paint);
|
||||
// For inner/outer strokes, we need clipping to prevent stroke pattern
|
||||
// (like dotted circles) from appearing in wrong areas
|
||||
match stroke.kind {
|
||||
StrokeKind::Inner => {
|
||||
// Inner: clip to original rect to hide parts outside boundary
|
||||
canvas.save();
|
||||
canvas.clip_rect(*rect, skia::ClipOp::Intersect, antialias);
|
||||
canvas.draw_oval(stroke_rect, &paint);
|
||||
canvas.restore();
|
||||
}
|
||||
StrokeKind::Outer => {
|
||||
// Outer: clip to exclude original rect to hide parts inside boundary
|
||||
canvas.save();
|
||||
canvas.clip_rect(*rect, skia::ClipOp::Difference, antialias);
|
||||
canvas.draw_oval(stroke_rect, &paint);
|
||||
canvas.restore();
|
||||
}
|
||||
StrokeKind::Center => {
|
||||
// Center strokes don't need clipping
|
||||
canvas.draw_oval(stroke_rect, &paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn draw_outer_stroke_path(
|
||||
|
||||
@@ -128,20 +128,26 @@ impl Stroke {
|
||||
}
|
||||
|
||||
pub fn outer_rect(&self, rect: &Rect) -> Rect {
|
||||
match self.kind {
|
||||
StrokeKind::Inner => Rect::from_xywh(
|
||||
rect.left + (self.width / 2.),
|
||||
rect.top + (self.width / 2.),
|
||||
rect.width() - self.width,
|
||||
rect.height() - self.width,
|
||||
),
|
||||
StrokeKind::Center => Rect::from_xywh(rect.left, rect.top, rect.width(), rect.height()),
|
||||
StrokeKind::Outer => Rect::from_xywh(
|
||||
rect.left - (self.width / 2.),
|
||||
rect.top - (self.width / 2.),
|
||||
rect.width() + self.width,
|
||||
rect.height() + self.width,
|
||||
),
|
||||
match (self.kind, self.style) {
|
||||
(StrokeKind::Inner, StrokeStyle::Dotted) | (StrokeKind::Outer, StrokeStyle::Dotted) => {
|
||||
// Boundary so circles center on it and semicircles match after clipping
|
||||
*rect
|
||||
}
|
||||
_ => match self.kind {
|
||||
StrokeKind::Inner => Rect::from_xywh(
|
||||
rect.left + (self.width / 2.),
|
||||
rect.top + (self.width / 2.),
|
||||
rect.width() - self.width,
|
||||
rect.height() - self.width,
|
||||
),
|
||||
StrokeKind::Center => Rect::from_xywh(rect.left, rect.top, rect.width(), rect.height()),
|
||||
StrokeKind::Outer => Rect::from_xywh(
|
||||
rect.left - (self.width / 2.),
|
||||
rect.top - (self.width / 2.),
|
||||
rect.width() + self.width,
|
||||
rect.height() + self.width,
|
||||
),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +161,13 @@ impl Stroke {
|
||||
}
|
||||
|
||||
pub fn outer_corners(&self, corners: &Corners) -> Corners {
|
||||
if matches!(self.style, StrokeStyle::Dotted)
|
||||
&& matches!(self.kind, StrokeKind::Inner | StrokeKind::Outer)
|
||||
{
|
||||
// Path at boundary so no corner offset
|
||||
return *corners;
|
||||
}
|
||||
|
||||
let offset = match self.kind {
|
||||
StrokeKind::Center => 0.0,
|
||||
StrokeKind::Inner => -self.width / 2.0,
|
||||
|
||||
Reference in New Issue
Block a user