From e01077a67452ef585d69066fb771f9a67c7b1786 Mon Sep 17 00:00:00 2001 From: theironchef <6278036+theironchef@users.noreply.github.com> Date: Tue, 6 Oct 2026 19:44:20 -0700 Subject: [PATCH] Fix #250: an area-type frame dragged with the Type tools is the dragged rectangle The Type tool passed `y + 12` to `text.create` for a dragged frame, and `text.create` puts the frame's top-left at (x, y), so every frame landed 12 pt below the marquee the user dragged. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/tests_textedit.rs | 17 +++++++++++++++++ crates/tools/src/text.rs | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/tests_textedit.rs b/crates/engine/src/tests_textedit.rs index 0462cfd8..2285a1b5 100644 --- a/crates/engine/src/tests_textedit.rs +++ b/crates/engine/src/tests_textedit.rs @@ -328,6 +328,23 @@ fn select_all_and_cut_like_ui() { assert_eq!(obj(&s, id).plain_text(), "abc defabc def"); } +#[test] +fn a_frame_dragged_with_the_type_tools_is_the_dragged_rectangle() { + for tool in ["type", "verticalType"] { + let mut s = session(); + let v = ViewInfo::default(); + s.select_tool(tool, v).unwrap(); + for (k, x, y) in [(PointerKind::Down, 100.0, 100.0), (PointerKind::Drag, 300.0, 180.0), (PointerKind::Up, 300.0, 180.0)] { + s.pointer(&PointerEvent::new(k, x, y), v).unwrap(); + } + let t = obj(&s, s.doc().unwrap().selection.objects[0]); + let TextKind::Area { frame } = &t.kind else { panic!("{tool}: not area type") }; + let b = frame.bounds().unwrap(); + let (a, z) = (t.xf * Point::new(b.x0, b.y0), t.xf * Point::new(b.x1, b.y1)); + assert!((a - Point::new(100.0, 100.0)).hypot() < 1e-9 && (z - Point::new(300.0, 180.0)).hypot() < 1e-9, "{tool}: {a:?} {z:?}"); + } +} + #[test] fn area_type_from_a_circle_keeps_glyphs_inside() { let mut s = session(); diff --git a/crates/tools/src/text.rs b/crates/tools/src/text.rs index a152b388..66523d72 100644 --- a/crates/tools/src/text.rs +++ b/crates/tools/src/text.rs @@ -264,7 +264,7 @@ impl TypeTool { } let area = drag.map(|d| Rect::from_points(start, d)).filter(|r| r.width() > cx.tol(6.0) && r.height() > cx.tol(6.0)); let mut params = match area { - Some(r) => json!({"x": r.x0, "y": r.y0 + 12.0, "text": "", "area": {"width": r.width(), "height": r.height()}}), + Some(r) => json!({"x": r.x0, "y": r.y0, "text": "", "area": {"width": r.width(), "height": r.height()}}), None => json!({"x": start.x, "y": start.y, "text": ""}), }; params["vertical"] = json!(self.vertical);