mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 10:58:04 +08:00
Improve click targets to use compound paths so interior negative space is excluded (#4096)
* Add ClickTargetType::CompoundPath variant for fill-rule-aware compound shape hit testing * Generate one compound click target per Vector so glyph holes aren't treated as filled * Fix insidenss logic
This commit is contained in:
@@ -1636,6 +1636,11 @@ impl DocumentMessageHandler {
|
||||
subpath.apply_transform(layer_transform);
|
||||
subpath.is_inside_subpath(&viewport_polygon, None, None)
|
||||
}
|
||||
ClickTargetType::CompoundPath(subpaths) => subpaths.iter().all(|subpath| {
|
||||
let mut subpath = subpath.clone();
|
||||
subpath.apply_transform(layer_transform);
|
||||
subpath.is_inside_subpath(&viewport_polygon, None, None)
|
||||
}),
|
||||
ClickTargetType::FreePoint(point) => {
|
||||
let mut point = *point;
|
||||
point.apply_transform(layer_transform);
|
||||
|
||||
@@ -1035,6 +1035,7 @@ impl OverlayContextInternal {
|
||||
self.manipulator_anchor(transform.transform_point2(point.position), false, None);
|
||||
}
|
||||
ClickTargetType::Subpath(subpath) => subpaths.push(subpath.clone()),
|
||||
ClickTargetType::CompoundPath(compound) => subpaths.extend(compound.iter().cloned()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -986,6 +986,7 @@ impl OverlayContext {
|
||||
self.manipulator_anchor(transform.transform_point2(point.position), false, None);
|
||||
}
|
||||
ClickTargetType::Subpath(subpath) => subpaths.push(subpath.clone()),
|
||||
ClickTargetType::CompoundPath(compound) => subpaths.extend(compound.iter().cloned()),
|
||||
});
|
||||
|
||||
if !subpaths.is_empty() {
|
||||
|
||||
@@ -177,6 +177,10 @@ impl DocumentMetadata {
|
||||
.iter()
|
||||
.filter_map(|click_target| match click_target.target_type() {
|
||||
ClickTargetType::Subpath(subpath) => subpath.loose_bounding_box_with_transform(transform),
|
||||
ClickTargetType::CompoundPath(subpaths) => subpaths
|
||||
.iter()
|
||||
.filter_map(|subpath| subpath.loose_bounding_box_with_transform(transform))
|
||||
.reduce(|[a_min, a_max], [b_min, b_max]| [a_min.min(b_min), a_max.max(b_max)]),
|
||||
ClickTargetType::FreePoint(_) => click_target.bounding_box_with_transform(transform),
|
||||
})
|
||||
.reduce(Quad::combine_bounds)
|
||||
@@ -219,9 +223,10 @@ impl DocumentMetadata {
|
||||
}
|
||||
|
||||
pub fn layer_outline(&self, layer: LayerNodeIdentifier) -> impl Iterator<Item = &subpath::Subpath<PointId>> {
|
||||
self.visual_targets(layer).unwrap_or(&[]).iter().filter_map(|target| match target.target_type() {
|
||||
ClickTargetType::Subpath(subpath) => Some(subpath),
|
||||
_ => None,
|
||||
self.visual_targets(layer).unwrap_or(&[]).iter().flat_map(|target| match target.target_type() {
|
||||
ClickTargetType::Subpath(subpath) => std::slice::from_ref(subpath),
|
||||
ClickTargetType::CompoundPath(subpaths) => subpaths.as_slice(),
|
||||
ClickTargetType::FreePoint(_) => &[],
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user