Skip to content

Commit 85ee5e4

Browse files
authored
Fix strokes with inside/outside alignment not being selectable when above other layers (#4207)
1 parent d5c67ee commit 85ee5e4

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

node-graph/libraries/rendering/src/renderer.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster};
2222
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
2323
use graphic_types::vector_types::subpath::Subpath;
2424
use graphic_types::vector_types::vector::click_target::{ClickTarget, FreePoint};
25-
use graphic_types::vector_types::vector::style::{Fill, PaintOrder, RenderMode, Stroke, StrokeAlign};
25+
use graphic_types::vector_types::vector::style::{Fill, PaintOrder, RenderMode, StrokeAlign};
2626
use graphic_types::{Artboard, Graphic, Vector};
2727
use kurbo::{Affine, Cap, Join, Shape};
2828
use num_traits::Zero;
@@ -1491,17 +1491,27 @@ impl Render for List<Vector> {
14911491
/// Build one `CompoundPath` (non-zero fill rule, so holes like the inside of an "O" work
14921492
/// correctly) plus one `FreePoint` per disconnected anchor, apply the transform, and append.
14931493
fn extend_targets_from_vector(targets: &mut Vec<ClickTarget>, vector: &Vector, transform: DAffine2) {
1494-
let stroke_width = vector.style.stroke().as_ref().map_or(0., Stroke::effective_width);
14951494
let filled = vector.style.fill() != &Fill::None;
1496-
let subpaths: Vec<Subpath<_>> = vector
1497-
.stroke_bezier_paths()
1498-
.map(|mut subpath| {
1499-
if filled {
1500-
subpath.set_closed(true);
1501-
}
1502-
subpath
1503-
})
1504-
.collect();
1495+
1496+
let mut subpaths: Vec<Subpath<_>> = vector.stroke_bezier_paths().collect();
1497+
let all_subpaths_closed = subpaths.iter().all(|subpath| subpath.closed());
1498+
1499+
// Inside/Outside-aligned strokes reach `weight` from the centerline rather than `weight / 2` per side,
1500+
// so they need double the click inflation. Alignment is only honored by the renderer for fully-closed paths.
1501+
let stroke_width = vector.style.stroke().map_or(0., |stroke| {
1502+
if stroke.align.is_not_centered() && all_subpaths_closed {
1503+
stroke.weight * 2.
1504+
} else {
1505+
stroke.weight
1506+
}
1507+
});
1508+
1509+
if filled {
1510+
for subpath in &mut subpaths {
1511+
subpath.set_closed(true);
1512+
}
1513+
}
1514+
15051515
if !subpaths.is_empty() {
15061516
let mut click_target = ClickTarget::new_with_compound_path(subpaths, stroke_width);
15071517
click_target.apply_transform(transform);

0 commit comments

Comments
 (0)