Skip to content

Pen tool offset - #4616

Open
VimYoung wants to merge 12 commits into
GraphiteEditor:masterfrom
VimYoung:pen-tool-offset
Open

VimYoung wants to merge 12 commits into
GraphiteEditor:masterfrom
VimYoung:pen-tool-offset

Conversation

@VimYoung

@VimYoung VimYoung commented Sep 27, 2026 •

Copy link
Copy Markdown

Description

This PR aims to close #4213. Also clears path to further close #4214.
The solution works by removing buffering_merged_vector parameter from PenToolData and adding a local variable which prompts active recalculation of position in the process of merging after the snap.

TODO

  • Add a proper description for the PR.
  • Add tests for this issue(Following are the ones suggested).
    • Test to ensure change in position doesn't happen.(Original bug for which test is added but doesn't work).
    • Test for different different groups with offsets.
    • Test for artboards with different offsets.
    • Test using different boolean outputs.
    • Test with layers having a path node
  • Remove the comment section( add relevant screencast).

Snapping Before

pen_tool_snap_before.mp4

Snapping After

pen_tool_snap_after.mp4

@Keavon

Keavon commented Oct 4, 2026

Copy link
Copy Markdown
Member

Thank you for your contribution! Please see #4647 for why we've chosen to close this. Your efforts are appreciated even though this didn't ultimately make it through.

@Keavon Keavon closed this Oct 4, 2026
@0HyperCube

Copy link
Copy Markdown
Contributor

@Keavon fixing this bug is extremely important for any 1.0 release. It is fairly easy to encounter and makes the editor look very janky. I'm not sure why you'd close this?

@Keavon

Keavon commented Oct 4, 2026

Copy link
Copy Markdown
Member

You're right @0HyperCube, this one is worth keeping, sorry that it got caught up in the flurry. Reopening.

@Keavon Keavon reopened this Oct 4, 2026
@VimYoung

VimYoung commented Oct 4, 2026 •

Copy link
Copy Markdown
Author

Hey @0HyperCube, i tried implementing the test with translation but I am a bit confused about the behavior. I thought translation for any transform node refereed to it's position from the top left. So when the bug pushes the pen to the left, the translation value will not be the same as it was when the pen stroke was created.

But seems like the translation remains the same even if I am creating a pen with stroke going from right to left from the point of creation of the pen stroke. I thought moving left (2 and 3rd quadrant in the linear space so to say) would place the translation to the top leftmost point of the pen stroke layer in question.

As this is not the case, the test offset_change_on_snap passes for both my branch and the master branch.

Can you look at the test and guide as to how can I capture the left jerk of pen tool in a test which this PR seems to resolve?

@VimYoung
VimYoung marked this pull request as ready for review October 4, 2026 19:21

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file

Reply to a comment to ask cubic a question or push back. It learns from your replies.

Re-trigger cubic

Comment thread editor/src/messages/tool/tool_messages/pen_tool.rs Outdated
Comment thread editor/src/messages/tool/tool_messages/pen_tool.rs
@0HyperCube

Copy link
Copy Markdown
Contributor

With regards to your test @VimYoung, it seems there have been some mistakes in using the pen tool. Your current test does a mouse down on one corner of the rectangle, then drags the mouse to another corner. This has the effect of moving the handle of the first anchor point (try this in the editor GUI). To produce a line, you must click on your start point and then click on your end point. I find it is easier to write a test after doing the setup in the editor a few times.

I have created a sample test to demonstrate how to properly do the set up:

/// Using the path tool to merge layers (by setting the endpoint to an anchor of another layer) should produce only expected anchor positions.
#[tokio::test]
async fn merging_layers_simple() {
	let mut editor = EditorTestUtils::create();
	editor.new_document().await;

	// Draw a rectangle not at the origin (so will end up with a non-identity transform)
	editor.draw_rect(A.x, A.y, C.x, C.y).await;

	// Start the pen somewhere random
	let pen_start = DVec2::new(999., 999.);
	click_pen(&mut editor, pen_start).await;
	// Connect to the top right of the rectangle
	click_pen(&mut editor, B).await;

	// Validate that these anchors are the only ones that exist (TODO: improve code reuse)
	let expected_anchors = [A, B, C, D, pen_start];
	let (layer, vector) = drawn_path(&editor).expect("Expected a drawn path");
	let layer_to_viewport = editor.active_document().metadata().transform_to_viewport(layer);
	let mut viewport_points: Vec<DVec2> = vector.point_domain.positions().iter().map(|&pos| layer_to_viewport.transform_point2(pos)).collect();

	for (expected_index, &expected_position) in expected_anchors.iter().enumerate() {
		let Some(viewport_index) = viewport_points.iter().position(|viewport| viewport.distance_squared(expected_position) < 1e-10) else {
			panic!("The expected anchor index {expected_index} and position {expected_position} was not found in the actual anchors {viewport_points:?}");
		};
		println!("Successfully found expected position {expected_position} (index {expected_index}) in viewport points as index {viewport_index}");
		// Remove so no other one matches
		viewport_points.remove(viewport_index);
	}
	assert!(viewport_points.is_empty(), "Viewport point(s) were not matched: {viewport_points:?}");
}

@VimYoung

VimYoung commented Oct 6, 2026

Copy link
Copy Markdown
Author

Okay, I thoroughly went through you test example and understood the issue with my code. I was under the impression that the mouse movement needs to be reproduced for the test case but seems like the click itself will suffice. Also, I was taking in the transform's anchor only in place of checking all the anchors of the merged layer.

I think I will be able to extrapolate other test cases based on this.

@0HyperCube

Copy link
Copy Markdown
Contributor

The click methods will automatically move the pointer to the position and then issue mouse down and then mouse up events.

The issue with your test was that you did mouse down, mouse move, mouse up. This has the effect of setting the first bézier handle position. The correct order should be mouse down, mouse up, mouse move, mouse down, mouse up which will create a line segment.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread editor/src/messages/tool/tool_messages/pen_tool.rs

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow avoid merging layers with pen tool Pen tool offset when merging

3 participants