Fix 'Regular Polygon' and 'Star' shapes incorrectly having cubic handles, not linear (#3606)
Fix shape nodes creating cubic-curved polylines
This commit is contained in:
parent
bd847034f3
commit
1b91198b28
|
|
@ -1844,12 +1844,12 @@ impl NodeNetworkInterface {
|
||||||
|
|
||||||
if *import_index == 0 {
|
if *import_index == 0 {
|
||||||
let remove_import_center = reorder_import_center + DVec2::new(-4., 0.);
|
let remove_import_center = reorder_import_center + DVec2::new(-4., 0.);
|
||||||
let remove_import = ClickTarget::new_with_subpath(Subpath::new_rect(remove_import_center - DVec2::new(8., 8.), remove_import_center + DVec2::new(8., 8.)), 0.);
|
let remove_import = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_import_center - DVec2::new(8., 8.), remove_import_center + DVec2::new(8., 8.)), 0.);
|
||||||
remove_imports_exports.insert_custom_output_port(*import_index, remove_import);
|
remove_imports_exports.insert_custom_output_port(*import_index, remove_import);
|
||||||
} else {
|
} else {
|
||||||
let remove_import_center = reorder_import_center + DVec2::new(-12., 0.);
|
let remove_import_center = reorder_import_center + DVec2::new(-12., 0.);
|
||||||
let reorder_import = ClickTarget::new_with_subpath(Subpath::new_rect(reorder_import_center - DVec2::new(3., 4.), reorder_import_center + DVec2::new(3., 4.)), 0.);
|
let reorder_import = ClickTarget::new_with_subpath(Subpath::new_rectangle(reorder_import_center - DVec2::new(3., 4.), reorder_import_center + DVec2::new(3., 4.)), 0.);
|
||||||
let remove_import = ClickTarget::new_with_subpath(Subpath::new_rect(remove_import_center - DVec2::new(8., 8.), remove_import_center + DVec2::new(8., 8.)), 0.);
|
let remove_import = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_import_center - DVec2::new(8., 8.), remove_import_center + DVec2::new(8., 8.)), 0.);
|
||||||
reorder_imports_exports.insert_custom_output_port(*import_index, reorder_import);
|
reorder_imports_exports.insert_custom_output_port(*import_index, reorder_import);
|
||||||
remove_imports_exports.insert_custom_output_port(*import_index, remove_import);
|
remove_imports_exports.insert_custom_output_port(*import_index, remove_import);
|
||||||
}
|
}
|
||||||
|
|
@ -1864,12 +1864,12 @@ impl NodeNetworkInterface {
|
||||||
|
|
||||||
if *export_index == 0 {
|
if *export_index == 0 {
|
||||||
let remove_export_center = reorder_export_center + DVec2::new(4., 0.);
|
let remove_export_center = reorder_export_center + DVec2::new(4., 0.);
|
||||||
let remove_export = ClickTarget::new_with_subpath(Subpath::new_rect(remove_export_center - DVec2::new(8., 8.), remove_export_center + DVec2::new(8., 8.)), 0.);
|
let remove_export = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_export_center - DVec2::new(8., 8.), remove_export_center + DVec2::new(8., 8.)), 0.);
|
||||||
remove_imports_exports.insert_custom_input_port(*export_index, remove_export);
|
remove_imports_exports.insert_custom_input_port(*export_index, remove_export);
|
||||||
} else {
|
} else {
|
||||||
let remove_export_center = reorder_export_center + DVec2::new(12., 0.);
|
let remove_export_center = reorder_export_center + DVec2::new(12., 0.);
|
||||||
let reorder_export = ClickTarget::new_with_subpath(Subpath::new_rect(reorder_export_center - DVec2::new(3., 4.), reorder_export_center + DVec2::new(3., 4.)), 0.);
|
let reorder_export = ClickTarget::new_with_subpath(Subpath::new_rectangle(reorder_export_center - DVec2::new(3., 4.), reorder_export_center + DVec2::new(3., 4.)), 0.);
|
||||||
let remove_export = ClickTarget::new_with_subpath(Subpath::new_rect(remove_export_center - DVec2::new(8., 8.), remove_export_center + DVec2::new(8., 8.)), 0.);
|
let remove_export = ClickTarget::new_with_subpath(Subpath::new_rectangle(remove_export_center - DVec2::new(8., 8.), remove_export_center + DVec2::new(8., 8.)), 0.);
|
||||||
reorder_imports_exports.insert_custom_input_port(*export_index, reorder_export);
|
reorder_imports_exports.insert_custom_input_port(*export_index, reorder_export);
|
||||||
remove_imports_exports.insert_custom_input_port(*export_index, remove_export);
|
remove_imports_exports.insert_custom_input_port(*export_index, remove_export);
|
||||||
}
|
}
|
||||||
|
|
@ -2482,7 +2482,7 @@ impl NodeNetworkInterface {
|
||||||
let node_click_target_bottom_right = node_click_target_top_left + DVec2::new(width as f64, height as f64);
|
let node_click_target_bottom_right = node_click_target_top_left + DVec2::new(width as f64, height as f64);
|
||||||
|
|
||||||
let radius = 3.;
|
let radius = 3.;
|
||||||
let subpath = Subpath::new_rounded_rect(node_click_target_top_left, node_click_target_bottom_right, [radius; 4]);
|
let subpath = Subpath::new_rounded_rectangle(node_click_target_top_left, node_click_target_bottom_right, [radius; 4]);
|
||||||
let node_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
let node_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
||||||
|
|
||||||
DocumentNodeClickTargets {
|
DocumentNodeClickTargets {
|
||||||
|
|
@ -2507,12 +2507,12 @@ impl NodeNetworkInterface {
|
||||||
|
|
||||||
// Update visibility button click target
|
// Update visibility button click target
|
||||||
let visibility_offset = node_top_left + DVec2::new(width as f64, 24.);
|
let visibility_offset = node_top_left + DVec2::new(width as f64, 24.);
|
||||||
let subpath = Subpath::new_rounded_rect(DVec2::new(-12., -12.) + visibility_offset, DVec2::new(12., 12.) + visibility_offset, [3.; 4]);
|
let subpath = Subpath::new_rounded_rectangle(DVec2::new(-12., -12.) + visibility_offset, DVec2::new(12., 12.) + visibility_offset, [3.; 4]);
|
||||||
let visibility_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
let visibility_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
||||||
|
|
||||||
// Update grip button click target, which is positioned to the left of the left most icon
|
// Update grip button click target, which is positioned to the left of the left most icon
|
||||||
let grip_offset_right_edge = node_top_left + DVec2::new(width as f64 - (GRID_SIZE as f64) / 2., 24.);
|
let grip_offset_right_edge = node_top_left + DVec2::new(width as f64 - (GRID_SIZE as f64) / 2., 24.);
|
||||||
let subpath = Subpath::new_rounded_rect(DVec2::new(-8., -12.) + grip_offset_right_edge, DVec2::new(0., 12.) + grip_offset_right_edge, [0.; 4]);
|
let subpath = Subpath::new_rounded_rectangle(DVec2::new(-8., -12.) + grip_offset_right_edge, DVec2::new(0., 12.) + grip_offset_right_edge, [0.; 4]);
|
||||||
let grip_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
let grip_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
||||||
|
|
||||||
// Create layer click target, which is contains the layer and the chain background
|
// Create layer click target, which is contains the layer and the chain background
|
||||||
|
|
@ -2521,7 +2521,7 @@ impl NodeNetworkInterface {
|
||||||
let node_bottom_right = node_top_left + DVec2::new(width as f64, height as f64);
|
let node_bottom_right = node_top_left + DVec2::new(width as f64, height as f64);
|
||||||
let chain_top_left = node_top_left - DVec2::new((chain_width_grid_spaces * crate::consts::GRID_SIZE) as f64, 0.);
|
let chain_top_left = node_top_left - DVec2::new((chain_width_grid_spaces * crate::consts::GRID_SIZE) as f64, 0.);
|
||||||
let radius = 10.;
|
let radius = 10.;
|
||||||
let subpath = Subpath::new_rounded_rect(chain_top_left, node_bottom_right, [radius; 4]);
|
let subpath = Subpath::new_rounded_rectangle(chain_top_left, node_bottom_right, [radius; 4]);
|
||||||
let node_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
let node_click_target = ClickTarget::new_with_subpath(subpath, 0.);
|
||||||
|
|
||||||
DocumentNodeClickTargets {
|
DocumentNodeClickTargets {
|
||||||
|
|
@ -2747,7 +2747,7 @@ impl NodeNetworkInterface {
|
||||||
});
|
});
|
||||||
|
|
||||||
let bounds = self.all_nodes_bounding_box(network_path).cloned().unwrap_or([DVec2::ZERO, DVec2::ZERO]);
|
let bounds = self.all_nodes_bounding_box(network_path).cloned().unwrap_or([DVec2::ZERO, DVec2::ZERO]);
|
||||||
let rect = Subpath::<PointId>::new_rect(bounds[0], bounds[1]);
|
let rect = Subpath::<PointId>::new_rectangle(bounds[0], bounds[1]);
|
||||||
let all_nodes_bounding_box = rect.to_bezpath().to_svg();
|
let all_nodes_bounding_box = rect.to_bezpath().to_svg();
|
||||||
|
|
||||||
let mut modify_import_export = Vec::new();
|
let mut modify_import_export = Vec::new();
|
||||||
|
|
@ -3008,7 +3008,7 @@ impl NodeNetworkInterface {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let bounding_box_subpath = Subpath::<PointId>::new_rect(bounds[0], bounds[1]);
|
let bounding_box_subpath = Subpath::<PointId>::new_rectangle(bounds[0], bounds[1]);
|
||||||
bounding_box_subpath.bounding_box_with_transform(network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport)
|
bounding_box_subpath.bounding_box_with_transform(network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1081,7 +1081,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||||
log::error!("The old Spline node's input at index 1 is not a TaggedValue::VecDVec2");
|
log::error!("The old Spline node's input at index 1 is not a TaggedValue::VecDVec2");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let vector = Vector::from_subpath(Subpath::from_anchors_linear(points.to_vec(), false));
|
let vector = Vector::from_subpath(Subpath::from_anchors(points.to_vec(), false));
|
||||||
|
|
||||||
// Retrieve the output connectors linked to the "Spline" node's output connector
|
// Retrieve the output connectors linked to the "Spline" node's output connector
|
||||||
let Some(spline_outputs) = document.network_interface.outward_wires(network_path)?.get(&OutputConnector::node(*node_id, 0)).cloned() else {
|
let Some(spline_outputs) = document.network_interface.outward_wires(network_path)?.get(&OutputConnector::node(*node_id, 0)).cloned() else {
|
||||||
|
|
|
||||||
|
|
@ -2155,7 +2155,7 @@ impl ShapeState {
|
||||||
if polygon.len() < 2 {
|
if polygon.len() < 2 {
|
||||||
return (points_inside, segments_inside);
|
return (points_inside, segments_inside);
|
||||||
}
|
}
|
||||||
let polygon: Subpath<PointId> = Subpath::from_anchors_linear(polygon.to_vec(), true);
|
let polygon: Subpath<PointId> = Subpath::from_anchors(polygon.to_vec(), true);
|
||||||
Some(polygon)
|
Some(polygon)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -452,7 +452,7 @@ impl SelectToolData {
|
||||||
if self.lasso_polygon.len() < 2 {
|
if self.lasso_polygon.len() < 2 {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
}
|
}
|
||||||
let polygon = Subpath::from_anchors_linear(self.lasso_polygon.clone(), true);
|
let polygon = Subpath::from_anchors(self.lasso_polygon.clone(), true);
|
||||||
document.intersect_polygon_no_artboards(polygon, viewport).collect()
|
document.intersect_polygon_no_artboards(polygon, viewport).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,7 +460,7 @@ impl SelectToolData {
|
||||||
if self.lasso_polygon.len() < 2 {
|
if self.lasso_polygon.len() < 2 {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let polygon = Subpath::from_anchors_linear(self.lasso_polygon.clone(), true);
|
let polygon = Subpath::from_anchors(self.lasso_polygon.clone(), true);
|
||||||
document.is_layer_fully_inside_polygon(layer, viewport, polygon)
|
document.is_layer_fully_inside_polygon(layer, viewport, polygon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -470,7 +470,7 @@ impl Render for Artboard {
|
||||||
|
|
||||||
fn collect_metadata(&self, metadata: &mut RenderMetadata, mut footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_metadata(&self, metadata: &mut RenderMetadata, mut footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
if let Some(element_id) = element_id {
|
if let Some(element_id) = element_id {
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, self.dimensions.as_dvec2());
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, self.dimensions.as_dvec2());
|
||||||
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
||||||
metadata.upstream_footprints.insert(element_id, footprint);
|
metadata.upstream_footprints.insert(element_id, footprint);
|
||||||
metadata.local_transforms.insert(element_id, DAffine2::from_translation(self.location.as_dvec2()));
|
metadata.local_transforms.insert(element_id, DAffine2::from_translation(self.location.as_dvec2()));
|
||||||
|
|
@ -483,7 +483,7 @@ impl Render for Artboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
||||||
let subpath_rectangle = Subpath::new_rect(DVec2::ZERO, self.dimensions.as_dvec2());
|
let subpath_rectangle = Subpath::new_rectangle(DVec2::ZERO, self.dimensions.as_dvec2());
|
||||||
click_targets.push(ClickTarget::new_with_subpath(subpath_rectangle, 0.));
|
click_targets.push(ClickTarget::new_with_subpath(subpath_rectangle, 0.));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1363,7 +1363,7 @@ impl Render for Table<Raster<CPU>> {
|
||||||
|
|
||||||
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
let Some(element_id) = element_id else { return };
|
let Some(element_id) = element_id else { return };
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
|
|
||||||
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
||||||
metadata.upstream_footprints.insert(element_id, footprint);
|
metadata.upstream_footprints.insert(element_id, footprint);
|
||||||
|
|
@ -1374,7 +1374,7 @@ impl Render for Table<Raster<CPU>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
click_targets.push(ClickTarget::new_with_subpath(subpath, 0.));
|
click_targets.push(ClickTarget::new_with_subpath(subpath, 0.));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1423,7 +1423,7 @@ impl Render for Table<Raster<GPU>> {
|
||||||
|
|
||||||
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
let Some(element_id) = element_id else { return };
|
let Some(element_id) = element_id else { return };
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
|
|
||||||
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
metadata.click_targets.insert(element_id, vec![ClickTarget::new_with_subpath(subpath, 0.)]);
|
||||||
metadata.upstream_footprints.insert(element_id, footprint);
|
metadata.upstream_footprints.insert(element_id, footprint);
|
||||||
|
|
@ -1434,7 +1434,7 @@ impl Render for Table<Raster<GPU>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
click_targets.push(ClickTarget::new_with_subpath(subpath, 0.));
|
click_targets.push(ClickTarget::new_with_subpath(subpath, 0.));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,24 +156,19 @@ impl<PointId: Identifier> Subpath<PointId> {
|
||||||
.all(|manipulator_group| manipulator_group.anchor.abs_diff_eq(point, MAX_ABSOLUTE_DIFFERENCE))
|
.all(|manipulator_group| manipulator_group.anchor.abs_diff_eq(point, MAX_ABSOLUTE_DIFFERENCE))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a [Subpath] from an iter of anchor positions.
|
|
||||||
pub fn from_anchors(anchor_positions: impl IntoIterator<Item = DVec2>, closed: bool) -> Self {
|
pub fn from_anchors(anchor_positions: impl IntoIterator<Item = DVec2>, closed: bool) -> Self {
|
||||||
Self::new(anchor_positions.into_iter().map(|anchor| ManipulatorGroup::new_anchor(anchor)).collect(), closed)
|
Self::new(anchor_positions.into_iter().map(|anchor| ManipulatorGroup::new_anchor(anchor)).collect(), closed)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_anchors_linear(anchor_positions: impl IntoIterator<Item = DVec2>, closed: bool) -> Self {
|
|
||||||
Self::new(anchor_positions.into_iter().map(|anchor| ManipulatorGroup::new_anchor_linear(anchor)).collect(), closed)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Constructs a rectangle with `corner1` and `corner2` as the two corners.
|
/// Constructs a rectangle with `corner1` and `corner2` as the two corners.
|
||||||
pub fn new_rect(corner1: DVec2, corner2: DVec2) -> Self {
|
pub fn new_rectangle(corner1: DVec2, corner2: DVec2) -> Self {
|
||||||
Self::from_anchors_linear([corner1, DVec2::new(corner2.x, corner1.y), corner2, DVec2::new(corner1.x, corner2.y)], true)
|
Self::from_anchors([corner1, DVec2::new(corner2.x, corner1.y), corner2, DVec2::new(corner1.x, corner2.y)], true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a rounded rectangle with `corner1` and `corner2` as the two corners and `corner_radii` as the radii of the corners: `[top_left, top_right, bottom_right, bottom_left]`.
|
/// Constructs a rounded rectangle with `corner1` and `corner2` as the two corners and `corner_radii` as the radii of the corners: `[top_left, top_right, bottom_right, bottom_left]`.
|
||||||
pub fn new_rounded_rect(corner1: DVec2, corner2: DVec2, corner_radii: [f64; 4]) -> Self {
|
pub fn new_rounded_rectangle(corner1: DVec2, corner2: DVec2, corner_radii: [f64; 4]) -> Self {
|
||||||
if corner_radii.iter().all(|radii| radii.abs() < f64::EPSILON * 100.) {
|
if corner_radii.iter().all(|radii| radii.abs() < f64::EPSILON * 100.) {
|
||||||
return Self::new_rect(corner1, corner2);
|
return Self::new_rectangle(corner1, corner2);
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::f64::consts::{FRAC_1_SQRT_2, PI};
|
use std::f64::consts::{FRAC_1_SQRT_2, PI};
|
||||||
|
|
@ -185,7 +180,7 @@ impl<PointId: Identifier> Subpath<PointId> {
|
||||||
return vec![ManipulatorGroup::new_anchor(point1), ManipulatorGroup::new_anchor(point2)];
|
return vec![ManipulatorGroup::new_anchor(point1), ManipulatorGroup::new_anchor(point2)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://pomax.github.io/bezierinfo/#circles_cubic
|
// Constant from https://pomax.github.io/bezierinfo/#circles_cubic
|
||||||
const HANDLE_OFFSET_FACTOR: f64 = 0.551784777779014;
|
const HANDLE_OFFSET_FACTOR: f64 = 0.551784777779014;
|
||||||
let handle_offset = radius * HANDLE_OFFSET_FACTOR;
|
let handle_offset = radius * HANDLE_OFFSET_FACTOR;
|
||||||
vec![
|
vec![
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ mod test_centroid {
|
||||||
use super::*;
|
use super::*;
|
||||||
#[test]
|
#[test]
|
||||||
fn centroid_rect() {
|
fn centroid_rect() {
|
||||||
let rect = Subpath::<PointId>::new_rect(DVec2::new(100., 100.), DVec2::new(300., 200.));
|
let rect = Subpath::<PointId>::new_rectangle(DVec2::new(100., 100.), DVec2::new(300., 200.));
|
||||||
let (centre, area) = rect.area_centroid_and_area(Some(1e-3), Some(1e-3)).unwrap();
|
let (centre, area) = rect.area_centroid_and_area(Some(1e-3), Some(1e-3)).unwrap();
|
||||||
assert_eq!(area, 200. * 100.);
|
assert_eq!(area, 200. * 100.);
|
||||||
assert_eq!(centre, DVec2::new(200., 150.))
|
assert_eq!(centre, DVec2::new(200., 150.))
|
||||||
|
|
|
||||||
|
|
@ -55,10 +55,6 @@ impl<PointId: Identifier> ManipulatorGroup<PointId> {
|
||||||
|
|
||||||
/// Construct a new manipulator point with just an anchor position
|
/// Construct a new manipulator point with just an anchor position
|
||||||
pub fn new_anchor(anchor: DVec2) -> Self {
|
pub fn new_anchor(anchor: DVec2) -> Self {
|
||||||
Self::new(anchor, Some(anchor), Some(anchor))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new_anchor_linear(anchor: DVec2) -> Self {
|
|
||||||
Self::new(anchor, None, None)
|
Self::new(anchor, None, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -330,7 +330,7 @@ mod tests {
|
||||||
let mut cache = BoundingBoxCache::default();
|
let mut cache = BoundingBoxCache::default();
|
||||||
|
|
||||||
// Create a simple rectangle subpath for testing
|
// Create a simple rectangle subpath for testing
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
||||||
|
|
||||||
let rotation = PI / 4.0;
|
let rotation = PI / 4.0;
|
||||||
let scale = DVec2::new(2.0, 2.0);
|
let scale = DVec2::new(2.0, 2.0);
|
||||||
|
|
@ -353,7 +353,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bounding_box_cache_ring_buffer_behavior() {
|
fn test_bounding_box_cache_ring_buffer_behavior() {
|
||||||
let mut cache = BoundingBoxCache::default();
|
let mut cache = BoundingBoxCache::default();
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::new(10.0, 10.0));
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::new(10.0, 10.0));
|
||||||
let scale = DVec2::ONE;
|
let scale = DVec2::ONE;
|
||||||
let translation = DVec2::ZERO;
|
let translation = DVec2::ZERO;
|
||||||
|
|
||||||
|
|
@ -378,7 +378,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_click_target_bounding_box_caching() {
|
fn test_click_target_bounding_box_caching() {
|
||||||
// Create a click target with a simple rectangle
|
// Create a click target with a simple rectangle
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
||||||
let click_target = ClickTarget::new_with_subpath(subpath, 1.0);
|
let click_target = ClickTarget::new_with_subpath(subpath, 1.0);
|
||||||
|
|
||||||
let rotation = PI / 6.0;
|
let rotation = PI / 6.0;
|
||||||
|
|
@ -415,7 +415,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_click_target_skew_bypass_cache() {
|
fn test_click_target_skew_bypass_cache() {
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::new(100.0, 50.0));
|
||||||
let click_target = ClickTarget::new_with_subpath(subpath.clone(), 1.0);
|
let click_target = ClickTarget::new_with_subpath(subpath.clone(), 1.0);
|
||||||
|
|
||||||
// Create a transform with skew (non-uniform scaling in different directions)
|
// Create a transform with skew (non-uniform scaling in different directions)
|
||||||
|
|
@ -431,7 +431,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cache_fingerprint_collision_handling() {
|
fn test_cache_fingerprint_collision_handling() {
|
||||||
let mut cache = BoundingBoxCache::default();
|
let mut cache = BoundingBoxCache::default();
|
||||||
let subpath = Subpath::new_rect(DVec2::ZERO, DVec2::new(10.0, 10.0));
|
let subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::new(10.0, 10.0));
|
||||||
let scale = DVec2::ONE;
|
let scale = DVec2::ONE;
|
||||||
let translation = DVec2::ZERO;
|
let translation = DVec2::ZERO;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -654,7 +654,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn modify_new() {
|
fn modify_new() {
|
||||||
let vector: Vector<()> = Vector::from_subpaths([Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE), Subpath::new_rect(DVec2::NEG_ONE, DVec2::ZERO)], false);
|
let vector: Vector<()> = Vector::from_subpaths([Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE), Subpath::new_rectangle(DVec2::NEG_ONE, DVec2::ZERO)], false);
|
||||||
|
|
||||||
let modify = VectorModification::create_from_vector(&vector);
|
let modify = VectorModification::create_from_vector(&vector);
|
||||||
|
|
||||||
|
|
@ -667,7 +667,7 @@ mod tests {
|
||||||
fn modify_existing() {
|
fn modify_existing() {
|
||||||
let subpaths = [
|
let subpaths = [
|
||||||
Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE),
|
Subpath::new_ellipse(DVec2::ZERO, DVec2::ONE),
|
||||||
Subpath::new_rect(DVec2::NEG_ONE, DVec2::ZERO),
|
Subpath::new_rectangle(DVec2::NEG_ONE, DVec2::ZERO),
|
||||||
Subpath::from_beziers(
|
Subpath::from_beziers(
|
||||||
&[
|
&[
|
||||||
PathSeg::Quad(QuadBez::new(Point::new(0., 0.), Point::new(5., 10.), Point::new(10., 0.))),
|
PathSeg::Quad(QuadBez::new(Point::new(0., 0.), Point::new(5., 10.), Point::new(10., 0.))),
|
||||||
|
|
|
||||||
|
|
@ -249,7 +249,7 @@ fn flatten_vector(graphic_table: &Table<Graphic>) -> Table<Vector> {
|
||||||
Graphic::RasterCPU(image) => {
|
Graphic::RasterCPU(image) => {
|
||||||
let make_row = |transform| {
|
let make_row = |transform| {
|
||||||
// Convert the image frame into a rectangular subpath with the image's transform
|
// Convert the image frame into a rectangular subpath with the image's transform
|
||||||
let mut subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let mut subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
subpath.apply_transform(transform);
|
subpath.apply_transform(transform);
|
||||||
|
|
||||||
// Create a vector table row from the rectangular subpath, with a default black fill
|
// Create a vector table row from the rectangular subpath, with a default black fill
|
||||||
|
|
@ -265,7 +265,7 @@ fn flatten_vector(graphic_table: &Table<Graphic>) -> Table<Vector> {
|
||||||
Graphic::RasterGPU(image) => {
|
Graphic::RasterGPU(image) => {
|
||||||
let make_row = |transform| {
|
let make_row = |transform| {
|
||||||
// Convert the image frame into a rectangular subpath with the image's transform
|
// Convert the image frame into a rectangular subpath with the image's transform
|
||||||
let mut subpath = Subpath::new_rect(DVec2::ZERO, DVec2::ONE);
|
let mut subpath = Subpath::new_rectangle(DVec2::ZERO, DVec2::ONE);
|
||||||
subpath.apply_transform(transform);
|
subpath.apply_transform(transform);
|
||||||
|
|
||||||
// Create a vector table row from the rectangular subpath, with a default black fill
|
// Create a vector table row from the rectangular subpath, with a default black fill
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ trait CornerRadius {
|
||||||
impl CornerRadius for f64 {
|
impl CornerRadius for f64 {
|
||||||
fn generate(self, size: DVec2, clamped: bool) -> Table<Vector> {
|
fn generate(self, size: DVec2, clamped: bool) -> Table<Vector> {
|
||||||
let clamped_radius = if clamped { self.clamp(0., size.x.min(size.y).max(0.) / 2.) } else { self };
|
let clamped_radius = if clamped { self.clamp(0., size.x.min(size.y).max(0.) / 2.) } else { self };
|
||||||
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_rounded_rect(size / -2., size / 2., [clamped_radius; 4])))
|
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_rounded_rectangle(size / -2., size / 2., [clamped_radius; 4])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl CornerRadius for [f64; 4] {
|
impl CornerRadius for [f64; 4] {
|
||||||
|
|
@ -34,7 +34,7 @@ impl CornerRadius for [f64; 4] {
|
||||||
} else {
|
} else {
|
||||||
self
|
self
|
||||||
};
|
};
|
||||||
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_rounded_rect(size / -2., size / 2., clamped_radius)))
|
Table::new_from_element(Vector::from_subpath(subpath::Subpath::new_rounded_rectangle(size / -2., size / 2., clamped_radius)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
let positions = [DVec2::new(40., 20.), DVec2::ONE, DVec2::new(-42., 9.), DVec2::new(10., 345.)];
|
let positions = [DVec2::new(40., 20.), DVec2::ONE, DVec2::new(-42., 9.), DVec2::new(10., 345.)];
|
||||||
let points = Table::new_from_element(Vector::from_subpath(Subpath::from_anchors_linear(positions, false)));
|
let points = Table::new_from_element(Vector::from_subpath(Subpath::from_anchors(positions, false)));
|
||||||
let generated = super::instance_on_points(owned, points, &rect, false).await;
|
let generated = super::instance_on_points(owned, points, &rect, false).await;
|
||||||
assert_eq!(generated.len(), positions.len());
|
assert_eq!(generated.len(), positions.len());
|
||||||
for (position, generated_row) in positions.into_iter().zip(generated.iter()) {
|
for (position, generated_row) in positions.into_iter().zip(generated.iter()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue