Improve text transforms (#1487)

This commit is contained in:
0HyperCube
2023-12-04 14:57:44 -08:00
committed by GitHub
parent d2450b4d61
commit f8b9c5db6d
9 changed files with 37 additions and 26 deletions
+11 -5
View File
@@ -230,19 +230,25 @@ impl DocumentMetadata {
} }
pub fn transform_to_viewport(&self, layer: LayerNodeIdentifier) -> DAffine2 { pub fn transform_to_viewport(&self, layer: LayerNodeIdentifier) -> DAffine2 {
self.upstream_transforms layer
.get(&layer.to_node()) .ancestors(self)
.filter_map(|layer| self.upstream_transforms.get(&layer.to_node()))
.copied() .copied()
.map(|(footprint, transform)| footprint.transform * transform) .map(|(footprint, transform)| footprint.transform * transform)
.unwrap_or(DAffine2::IDENTITY) .next()
.unwrap_or(self.document_to_viewport)
} }
pub fn upstream_transform(&self, node_id: NodeId) -> DAffine2 { pub fn upstream_transform(&self, node_id: NodeId) -> DAffine2 {
self.upstream_transforms.get(&node_id).copied().map(|(_, transform)| transform).unwrap_or(DAffine2::IDENTITY) self.upstream_transforms.get(&node_id).copied().map(|(_, transform)| transform).unwrap_or(DAffine2::IDENTITY)
} }
pub fn downstream_transform_to_viewport(&self, node_id: NodeId) -> DAffine2 { pub fn downstream_transform_to_viewport(&self, layer: LayerNodeIdentifier) -> DAffine2 {
self.upstream_transforms.get(&node_id).copied().map(|(footprint, _)| footprint.transform).unwrap_or(DAffine2::IDENTITY) self.upstream_transforms
.get(&layer.to_node())
.copied()
.map(|(footprint, _)| footprint.transform)
.unwrap_or_else(|| self.transform_to_viewport(layer))
} }
} }
@@ -437,11 +437,6 @@ impl<'a> ModifyInputsContext<'a> {
} }
fn vector_modify(&mut self, modification: VectorDataModification) { fn vector_modify(&mut self, modification: VectorDataModification) {
// TODO: Allow modifying a graph with a "Text" node.
if self.network.nodes.values().any(|node| node.name == "Text") {
return;
}
let [mut old_bounds_min, mut old_bounds_max] = [DVec2::ZERO, DVec2::ONE]; let [mut old_bounds_min, mut old_bounds_max] = [DVec2::ZERO, DVec2::ONE];
let [mut new_bounds_min, mut new_bounds_max] = [DVec2::ZERO, DVec2::ONE]; let [mut new_bounds_min, mut new_bounds_max] = [DVec2::ZERO, DVec2::ONE];
let mut empty = false; let mut empty = false;
@@ -576,7 +571,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
skip_rerender, skip_rerender,
} => { } => {
let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), &document.document_network); let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), &document.document_network);
let parent_transform = document.metadata.downstream_transform_to_viewport(layer_identifier.to_node()); let parent_transform = document.metadata.downstream_transform_to_viewport(layer_identifier);
let bounds = LayerBounds::new(document, &layer); let bounds = LayerBounds::new(document, &layer);
if let Some(mut modify_inputs) = ModifyInputsContext::new_layer(&layer, document, node_graph, responses) { if let Some(mut modify_inputs) = ModifyInputsContext::new_layer(&layer, document, node_graph, responses) {
modify_inputs.transform_change(transform, transform_in, parent_transform, bounds, skip_rerender); modify_inputs.transform_change(transform, transform_in, parent_transform, bounds, skip_rerender);
@@ -589,7 +584,7 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
skip_rerender, skip_rerender,
} => { } => {
let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), &document.document_network); let layer_identifier = LayerNodeIdentifier::new(*layer.last().unwrap(), &document.document_network);
let parent_transform = document.metadata.downstream_transform_to_viewport(layer_identifier.to_node()); let parent_transform = document.metadata.downstream_transform_to_viewport(layer_identifier);
let current_transform = Some(document.metadata.transform_to_viewport(layer_identifier)); let current_transform = Some(document.metadata.transform_to_viewport(layer_identifier));
let bounds = LayerBounds::new(document, &layer); let bounds = LayerBounds::new(document, &layer);
@@ -368,7 +368,7 @@ impl<'a> Selected<'a> {
fn transform_layer(document: &Document, layer: LayerNodeIdentifier, original_transform: Option<&DAffine2>, transformation: DAffine2, responses: &mut VecDeque<Message>) { fn transform_layer(document: &Document, layer: LayerNodeIdentifier, original_transform: Option<&DAffine2>, transformation: DAffine2, responses: &mut VecDeque<Message>) {
let Some(&original_transform) = original_transform else { return }; let Some(&original_transform) = original_transform else { return };
let to = document.metadata.downstream_transform_to_viewport(layer.to_node()); let to = document.metadata.downstream_transform_to_viewport(layer);
let new = to.inverse() * transformation * to * original_transform; let new = to.inverse() * transformation * to * original_transform;
responses.add(GraphOperationMessage::TransformSet { responses.add(GraphOperationMessage::TransformSet {
layer: layer.to_path(), layer: layer.to_path(),
@@ -192,8 +192,6 @@ impl Fsm for FreehandToolFsmState {
document, global_tool_data, input, .. document, global_tool_data, input, ..
} = tool_action_data; } = tool_action_data;
let transform = document.metadata().document_to_viewport;
let ToolMessage::Freehand(event) = event else { let ToolMessage::Freehand(event) = event else {
return self; return self;
}; };
@@ -202,6 +200,8 @@ impl Fsm for FreehandToolFsmState {
responses.add(DocumentMessage::StartTransaction); responses.add(DocumentMessage::StartTransaction);
responses.add(DocumentMessage::DeselectAllLayers); responses.add(DocumentMessage::DeselectAllLayers);
let parent = document.new_layer_parent();
let transform = document.metadata().transform_to_viewport(parent);
let pos = transform.inverse().transform_point2(input.mouse.position); let pos = transform.inverse().transform_point2(input.mouse.position);
tool_data.dragged = false; tool_data.dragged = false;
@@ -211,7 +211,7 @@ impl Fsm for FreehandToolFsmState {
let subpath = bezier_rs::Subpath::from_anchors([pos], false); let subpath = bezier_rs::Subpath::from_anchors([pos], false);
let layer = graph_modification_utils::new_vector_layer(vec![subpath], generate_uuid(), document.new_layer_parent(), responses); let layer = graph_modification_utils::new_vector_layer(vec![subpath], generate_uuid(), parent, responses);
tool_data.layer = Some(layer); tool_data.layer = Some(layer);
responses.add(GraphOperationMessage::FillSet { responses.add(GraphOperationMessage::FillSet {
@@ -227,10 +227,11 @@ impl Fsm for FreehandToolFsmState {
FreehandToolFsmState::Drawing FreehandToolFsmState::Drawing
} }
(FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => { (FreehandToolFsmState::Drawing, FreehandToolMessage::PointerMove) => {
let pos = transform.inverse().transform_point2(input.mouse.position); if let Some(layer) = tool_data.layer.clone() {
let transform = document.metadata().transform_to_viewport(layer);
let pos = transform.inverse().transform_point2(input.mouse.position);
if tool_data.last_point != pos { if tool_data.last_point != pos {
if let Some(layer) = tool_data.layer.clone() {
let manipulator_group = ManipulatorGroup::new_anchor(pos); let manipulator_group = ManipulatorGroup::new_anchor(pos);
let modification = VectorDataModification::AddEndManipulatorGroup { subpath_index: 0, manipulator_group }; let modification = VectorDataModification::AddEndManipulatorGroup { subpath_index: 0, manipulator_group };
responses.add(GraphOperationMessage::Vector { layer: layer.to_path(), modification }); responses.add(GraphOperationMessage::Vector { layer: layer.to_path(), modification });
@@ -245,7 +245,7 @@ impl PenToolData {
responses.add(DocumentMessage::DeselectAllLayers); responses.add(DocumentMessage::DeselectAllLayers);
// Get the position and set properties // Get the position and set properties
let transform = document.metadata().document_to_viewport * document.metadata().transform_to_viewport(parent); let transform = document.metadata().transform_to_viewport(parent);
let snapped_position = self.snap_manager.snap_position(responses, document, input.mouse.position); let snapped_position = self.snap_manager.snap_position(responses, document, input.mouse.position);
let start_position = transform.inverse().transform_point2(snapped_position); let start_position = transform.inverse().transform_point2(snapped_position);
self.weight = line_weight; self.weight = line_weight;
@@ -203,8 +203,6 @@ impl Fsm for SplineToolFsmState {
.. ..
} = tool_action_data; } = tool_action_data;
let transform = document.metadata().document_to_viewport;
let ToolMessage::Spline(event) = event else { let ToolMessage::Spline(event) = event else {
return self; return self;
}; };
@@ -217,6 +215,9 @@ impl Fsm for SplineToolFsmState {
responses.add(DocumentMessage::StartTransaction); responses.add(DocumentMessage::StartTransaction);
responses.add(DocumentMessage::DeselectAllLayers); responses.add(DocumentMessage::DeselectAllLayers);
let parent = document.new_layer_parent();
let transform = document.metadata().transform_to_viewport(parent);
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true); tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, None, render_data), true, true);
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]); tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position); let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
@@ -228,7 +229,7 @@ impl Fsm for SplineToolFsmState {
tool_data.weight = tool_options.line_weight; tool_data.weight = tool_options.line_weight;
let layer = graph_modification_utils::new_vector_layer(vec![], generate_uuid(), document.new_layer_parent(), responses); let layer = graph_modification_utils::new_vector_layer(vec![], generate_uuid(), parent, responses);
responses.add(GraphOperationMessage::FillSet { responses.add(GraphOperationMessage::FillSet {
layer: layer.to_path(), layer: layer.to_path(),
@@ -244,7 +245,11 @@ impl Fsm for SplineToolFsmState {
SplineToolFsmState::Drawing SplineToolFsmState::Drawing
} }
(SplineToolFsmState::Drawing, SplineToolMessage::DragStop) => { (SplineToolFsmState::Drawing, SplineToolMessage::DragStop) => {
let Some(layer) = tool_data.layer else {
return SplineToolFsmState::Ready;
};
let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position); let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
let transform = document.metadata().transform_to_viewport(layer);
let pos = transform.inverse().transform_point2(snapped_position); let pos = transform.inverse().transform_point2(snapped_position);
if let Some(last_pos) = tool_data.points.last() { if let Some(last_pos) = tool_data.points.last() {
@@ -259,7 +264,11 @@ impl Fsm for SplineToolFsmState {
SplineToolFsmState::Drawing SplineToolFsmState::Drawing
} }
(SplineToolFsmState::Drawing, SplineToolMessage::PointerMove) => { (SplineToolFsmState::Drawing, SplineToolMessage::PointerMove) => {
let Some(layer) = tool_data.layer else {
return SplineToolFsmState::Ready;
};
let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position); let snapped_position = tool_data.snap_manager.snap_position(responses, document, input.mouse.position);
let transform = document.metadata().transform_to_viewport(layer);
let pos = transform.inverse().transform_point2(snapped_position); let pos = transform.inverse().transform_point2(snapped_position);
tool_data.next_point = pos; tool_data.next_point = pos;
@@ -294,7 +294,7 @@ impl TextToolData {
text: String::new(), text: String::new(),
font: editing_text.font.clone(), font: editing_text.font.clone(),
size: editing_text.font_size, size: editing_text.font_size,
parent: LayerNodeIdentifier::ROOT, parent: document.new_layer_parent(),
insert_index: -1, insert_index: -1,
}); });
responses.add(GraphOperationMessage::FillSet { responses.add(GraphOperationMessage::FillSet {
@@ -395,7 +395,7 @@ impl GraphicElementRendered for Artboard {
} }
} }
fn add_click_targets(&self, click_targets: &mut Vec<ClickTarget>) { fn add_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
let subpath = Subpath::new_rect(self.location.as_dvec2(), self.location.as_dvec2() + self.dimensions.as_dvec2()); let subpath = Subpath::new_rect(DVec2::ZERO, self.dimensions.as_dvec2());
click_targets.push(ClickTarget { stroke_width: 0., subpath }); click_targets.push(ClickTarget { stroke_width: 0., subpath });
} }
} }
+1 -1
View File
@@ -127,7 +127,7 @@ impl TransformMut for VectorData {
impl Transform for Artboard { impl Transform for Artboard {
fn transform(&self) -> DAffine2 { fn transform(&self) -> DAffine2 {
DAffine2::IDENTITY DAffine2::from_translation(self.location.as_dvec2())
} }
fn local_pivot(&self, pivot: DVec2) -> DVec2 { fn local_pivot(&self, pivot: DVec2) -> DVec2 {
self.location.as_dvec2() + self.dimensions.as_dvec2() * pivot self.location.as_dvec2() + self.dimensions.as_dvec2() * pivot