From fad257ce8277a6a7315f2ce75f612607352e30dc Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Thu, 12 Nov 2026 20:27:27 -0800 Subject: [PATCH 1/2] Drawing tools: the measurement readout shows with the rubber band off Enable Rubber Band now hides only the preview segment in the Pen, the Curvature tool and the Smart Pen. With it off and Measurement Labels on, the three tools still show the D / Angle / dX / dY readout at the pointer while a path is drawn, and the Curvature tool also shows it when going on from the current end of a selected path. With Measurement Labels off, no readout shows either way. The click places the same anchor as before. Docs: docs/mcp.md (penRubberBand, curvatureRubberBand), docs/ui-parity.md, docs/target-app-parity.md. --- crates/tools/src/addons/smart_pen.rs | 11 +++-- crates/tools/src/addons/smart_pen/tests.rs | 29 +++++++++++++ crates/tools/src/draw2/curvature.rs | 40 ++++++++++-------- crates/tools/src/draw2/curvature/tests.rs | 48 ++++++++++++++++++++++ crates/tools/src/pen.rs | 20 +++++---- crates/tools/src/pen/tests.rs | 42 +++++++++++++++++++ docs/mcp.md | 3 +- docs/target-app-parity.md | 1 + docs/ui-parity.md | 2 +- 9 files changed, 164 insertions(+), 32 deletions(-) diff --git a/crates/tools/src/addons/smart_pen.rs b/crates/tools/src/addons/smart_pen.rs index 6a287b9b54..cd72f1dd40 100644 --- a/crates/tools/src/addons/smart_pen.rs +++ b/crates/tools/src/addons/smart_pen.rs @@ -573,12 +573,15 @@ impl Tool for SmartPenTool { fn overlays(&self, cx: &ToolContext) -> Vec { let mut o = vec![]; - if cx.pen_rubber_band - && self.press.is_none() + // The rubber band preference hides only the preview segment; Measurement Labels decides the readout. + if self.press.is_none() && let (Some((id, _, sp)), Some(h)) = (self.active(cx), self.hover) - && let Some(path) = self.rubber_band(sp, h) { - o.push(Overlay::Path { path, color: cx.doc.layer_color(id), width: 1.0, dashed: false }); + if cx.pen_rubber_band + && let Some(path) = self.rubber_band(sp, h) + { + o.push(Overlay::Path { path, color: cx.doc.layer_color(id), width: 1.0, dashed: false }); + } if let Some(last) = sp.anchors.last().map(|a| a.p) && cx.measurement_labels && last.distance(h) > 1e-9 diff --git a/crates/tools/src/addons/smart_pen/tests.rs b/crates/tools/src/addons/smart_pen/tests.rs index a7f792c22f..8bcc907f9d 100644 --- a/crates/tools/src/addons/smart_pen/tests.rs +++ b/crates/tools/src/addons/smart_pen/tests.rs @@ -315,6 +315,35 @@ fn the_rubber_band_shows_the_next_segment_and_ending_the_path() { assert!(t.overlays(&cx).is_empty()); } +/// With Enable Rubber Band for the Pen off, the preview segment is hidden but Measurement Labels +/// still shows the readout from the last anchor to the pointer. +#[test] +fn the_measurement_label_shows_with_the_rubber_band_off() { + let (d, _, s) = doc(line()); + let p = paint(); + let on = plain(&d, &s, &p); + let off = ToolContext { pen_rubber_band: false, ..plain(&d, &s, &p) }; + let (from, to) = (Point::new(200.0, 100.0), Point::new(300.0, 160.0)); + let measure = + |o: &[Overlay]| o.iter().filter_map(|o| if let Overlay::Measure { text, .. } = o { Some(text.clone()) } else { None }).collect::>(); + let band = |o: &[Overlay]| o.iter().any(|o| matches!(o, Overlay::Path { .. })); + let mut t = drawing(&off, from); + t.pointer(&off, &ev(PointerKind::Move, to.x, to.y, NO)); + let o = t.overlays(&off); + assert_eq!(measure(&o), vec![off.segment_measure_label(from, to)], "{o:?}"); + assert!(!band(&o), "{o:?}"); + let o = t.overlays(&on); + assert_eq!(measure(&o), vec![on.segment_measure_label(from, to)], "{o:?}"); + assert!(band(&o), "{o:?}"); + for rubber in [true, false] { + let quiet = ToolContext { pen_rubber_band: rubber, measurement_labels: false, ..plain(&d, &s, &p) }; + assert!(measure(&t.overlays(&quiet)).is_empty()); + } + // Hovering exactly on the last anchor measures no segment. + t.pointer(&off, &ev(PointerKind::Move, from.x, from.y, NO)); + assert!(measure(&t.overlays(&off)).is_empty()); +} + #[test] fn an_alt_drag_away_from_paths_selects_the_points_inside_a_marquee() { let (d, id, s) = doc(SubPath::polyline(&[Point::new(100.0, 100.0), Point::new(200.0, 100.0), Point::new(300.0, 100.0)], false)); diff --git a/crates/tools/src/draw2/curvature.rs b/crates/tools/src/draw2/curvature.rs index c40607ee63..02087d997a 100644 --- a/crates/tools/src/draw2/curvature.rs +++ b/crates/tools/src/draw2/curvature.rs @@ -718,38 +718,44 @@ impl Tool for CurvatureTool { } fn overlays(&self, cx: &ToolContext) -> Vec { let mut o = self.snap.guides().to_vec(); - let band = cx.curvature_rubber_band && self.drag.is_none(); + // The rubber band preference hides only the preview curve; Measurement Labels decides the readout. + let idle = self.drag.is_none(); + let band = cx.curvature_rubber_band; let mut bp = BezPath::new(); if self.active(cx).is_none() { // The curve on from the current end of a selected path: its last segment and the next. - if band + if idle && let (Some(e), Some(h)) = (current_end(cx), self.hover) && let Some(sp) = subpath(cx, e.id, e.si) { - let n = sp.anchors.len(); - let near = if e.start { - sp.anchors.iter().take(2).rev().map(Anchor::reversed).collect() - } else { - sp.anchors.iter().skip(n.saturating_sub(2)).copied().collect() - }; - let mut tail = SubPath::new(near, false); - curvature_extend(&mut tail, false, h, self.how(&e), false); - tail.to_bezpath_into(&mut bp); - o.push(Overlay::Path { path: bp, color: FEEDBACK, width: 1.0, dashed: false }); + if band { + let n = sp.anchors.len(); + let near = if e.start { + sp.anchors.iter().take(2).rev().map(Anchor::reversed).collect() + } else { + sp.anchors.iter().skip(n.saturating_sub(2)).copied().collect() + }; + let mut tail = SubPath::new(near, false); + curvature_extend(&mut tail, false, h, self.how(&e), false); + tail.to_bezpath_into(&mut bp); + o.push(Overlay::Path { path: bp, color: FEEDBACK, width: 1.0, dashed: false }); + } if cx.measurement_labels && e.p.distance(h) > 1e-9 { o.push(Overlay::Measure { p: h + Vec2::new(cx.tol(12.0), cx.tol(12.0)), text: cx.segment_measure_label(e.p, h) }); } } return o; } - if band + if idle && !self.closed && let Some(h) = self.hover { - let mut pts = self.pts.clone(); - pts.push((h, false)); - curvature_spline(&pts, false).to_bezpath_into(&mut bp); - o.push(Overlay::Path { path: bp, color: FEEDBACK, width: 1.0, dashed: false }); + if band { + let mut pts = self.pts.clone(); + pts.push((h, false)); + curvature_spline(&pts, false).to_bezpath_into(&mut bp); + o.push(Overlay::Path { path: bp, color: FEEDBACK, width: 1.0, dashed: false }); + } if let Some((from, _)) = self.pts.last() && cx.measurement_labels && from.distance(h) > 1e-9 diff --git a/crates/tools/src/draw2/curvature/tests.rs b/crates/tools/src/draw2/curvature/tests.rs index f21deec016..50ef2281d1 100644 --- a/crates/tools/src/draw2/curvature/tests.rs +++ b/crates/tools/src/draw2/curvature/tests.rs @@ -539,3 +539,51 @@ fn clicks_go_on_from_a_current_end_and_the_other_end_closes() { let a = press(&mut t, &quiet(&d, &s, &p), -50.0, 150.0, false); assert!(matches!(edit_op(&a[0]), Some(("extend", v)) if v["end"] == "start" && v["from"] == "keep"), "{a:?}"); } + +/// With Enable Rubber Band for the Curvature tool off, the preview curve is hidden but +/// Measurement Labels still shows the readout, both while drawing a path and going on from the +/// current end of a selected one. +#[test] +fn the_measurement_label_shows_with_the_rubber_band_off() { + let p = paint(); + let measure = + |o: &[Overlay]| o.iter().filter_map(|o| if let Overlay::Measure { text, .. } = o { Some(text.clone()) } else { None }).collect::>(); + let band = |o: &[Overlay]| o.iter().any(|o| matches!(o, Overlay::Path { .. })); + let to = pt(650.0, 60.0); + // Going on from the current end of a selected path. + let (d, id) = doc_with(wave()); + let s = selected(id, Some(4)); + let on = quiet(&d, &s, &p); + let off = ToolContext { curvature_rubber_band: false, ..quiet(&d, &s, &p) }; + let mut t = CurvatureTool::default(); + t.pointer(&off, &PointerEvent::new(PointerKind::Move, to.x, to.y)); + let from = pt(450.0, 60.0); + let o = t.overlays(&off); + assert_eq!(measure(&o), vec![off.segment_measure_label(from, to)], "{o:?}"); + assert!(!band(&o), "{o:?}"); + let o = t.overlays(&on); + assert_eq!(measure(&o), vec![on.segment_measure_label(from, to)], "{o:?}"); + assert!(band(&o), "{o:?}"); + // A path being drawn. + let (d, id) = doc_with(SubPath::polyline(&[pt(100.0, 100.0), pt(200.0, 150.0)], false)); + let s = selected(id, None); + let on = quiet(&d, &s, &p); + let off = ToolContext { curvature_rubber_band: false, ..quiet(&d, &s, &p) }; + let mut t = CurvatureTool { id: Some(id), pts: vec![(pt(100.0, 100.0), false), (pt(200.0, 150.0), false)], ..CurvatureTool::default() }; + assert!(t.active(&off).is_some()); + t.pointer(&off, &PointerEvent::new(PointerKind::Move, to.x, to.y)); + let from = pt(200.0, 150.0); + let o = t.overlays(&off); + assert_eq!(measure(&o), vec![off.segment_measure_label(from, to)], "{o:?}"); + assert!(!band(&o), "{o:?}"); + let o = t.overlays(&on); + assert_eq!(measure(&o), vec![on.segment_measure_label(from, to)], "{o:?}"); + assert!(band(&o), "{o:?}"); + for rubber in [true, false] { + let unlabeled = ToolContext { curvature_rubber_band: rubber, measurement_labels: false, ..quiet(&d, &s, &p) }; + assert!(measure(&t.overlays(&unlabeled)).is_empty()); + } + // Hovering exactly on the last point measures no segment. + t.pointer(&off, &PointerEvent::new(PointerKind::Move, from.x, from.y)); + assert!(measure(&t.overlays(&off)).is_empty()); +} diff --git a/crates/tools/src/pen.rs b/crates/tools/src/pen.rs index 0b625f2813..a0ab57ae87 100644 --- a/crates/tools/src/pen.rs +++ b/crates/tools/src/pen.rs @@ -495,19 +495,21 @@ impl Tool for PenTool { return t.overlays(cx); } let mut o = vec![]; - if cx.pen_rubber_band - && self.drag.is_none() + // The rubber band preference hides only the preview segment; Measurement Labels decides the readout. + if self.drag.is_none() && self.handle.is_none() && let (Some((id, _, _, last, out)), Some(h)) = (self.active(cx), self.hover) { - let mut bp = BezPath::new(); - bp.move_to(last); - if out.distance(last) > 1e-9 { - bp.quad_to(out, h); - } else { - bp.line_to(h); + if cx.pen_rubber_band { + let mut bp = BezPath::new(); + bp.move_to(last); + if out.distance(last) > 1e-9 { + bp.quad_to(out, h); + } else { + bp.line_to(h); + } + o.push(Overlay::Path { path: bp, color: cx.doc.layer_color(id), width: 1.0, dashed: false }); } - o.push(Overlay::Path { path: bp, color: cx.doc.layer_color(id), width: 1.0, dashed: false }); if cx.measurement_labels && last.distance(h) > 1e-9 { o.push(Overlay::Measure { p: h + Vec2::new(cx.tol(12.0), cx.tol(12.0)), text: cx.segment_measure_label(last, h) }); } diff --git a/crates/tools/src/pen/tests.rs b/crates/tools/src/pen/tests.rs index 478589fe9e..32c91318e6 100644 --- a/crates/tools/src/pen/tests.rs +++ b/crates/tools/src/pen/tests.rs @@ -773,6 +773,48 @@ fn anchors_snap_to_smart_guides() { assert_eq!(a[1], Action::Preview("path.create".into(), json!({"anchors": [{"x": 100.0, "y": 100.0}]}))); } +/// With Enable Rubber Band off, the preview segment is hidden but Measurement Labels still shows +/// the D / Angle / dX / dY readout at the snapped point before the next click. +#[test] +fn measurement_label_shows_with_the_rubber_band_off() { + let (d, id, s) = drawing(vectorcraft_geom::SubPath::polyline(&[Point::new(10.0, 300.0), Point::new(60.0, 300.0)], false)); + let p = paint(); + let on = cx(&d, &s, &p); + let off = ToolContext { pen_rubber_band: false, ..cx(&d, &s, &p) }; + let from = Point::new(60.0, 300.0); + let to = Point::new(150.0, 318.0); + let measure = + |o: &[Overlay]| o.iter().filter_map(|o| if let Overlay::Measure { text, .. } = o { Some(text.clone()) } else { None }).collect::>(); + let preview = |o: &[Overlay]| { + o.iter().any(|o| matches!(o, Overlay::Path { path, .. } if path.elements().first().and_then(|e| e.end_point()) == Some(from))) + }; + let mut t = PenTool { drawing: true, ..PenTool::default() }; + t.pointer(&off, &PointerEvent::new(PointerKind::Move, 152.0, 318.0)); + let o = t.overlays(&off); + assert_eq!(measure(&o), vec![off.segment_measure_label(from, to)], "{o:?}"); + assert!(!preview(&o), "{o:?}"); + // The rubber band on still shows both. + let o = t.overlays(&on); + assert_eq!(measure(&o), vec![on.segment_measure_label(from, to)], "{o:?}"); + assert!(preview(&o), "{o:?}"); + // Measurement Labels off shows no readout either way. + for band in [true, false] { + let quiet = ToolContext { pen_rubber_band: band, measurement_labels: false, ..cx(&d, &s, &p) }; + assert!(measure(&t.overlays(&quiet)).is_empty()); + } + // The click places the same anchor as with the rubber band on. + let a = click(&mut t, &off, 152.0, 318.0, Mods::default()); + assert_eq!(a[1], Action::Preview("path.appendAnchor".into(), json!({"id": id.0, "x": 150.0, "y": 318.0, "subpath": 0}))); + // Hovering exactly on the last anchor measures no segment. + let mut t = PenTool { drawing: true, ..PenTool::default() }; + t.pointer(&off, &PointerEvent::new(PointerKind::Move, 60.0, 300.0)); + assert!(measure(&t.overlays(&off)).is_empty()); + // With no path being drawn there is nothing to measure from. + let mut t = PenTool::default(); + t.pointer(&off, &PointerEvent::new(PointerKind::Move, 152.0, 318.0)); + assert!(measure(&t.overlays(&off)).is_empty()); +} + #[test] fn alt_over_a_shown_handle_or_an_anchor_converts() { // The middle anchor is smooth: handles at (150, 100) and (250, 100) round (200, 100). diff --git a/docs/mcp.md b/docs/mcp.md index 53a792d5a6..f4e699620d 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -5389,7 +5389,8 @@ The Selection & Anchor Display and General preferences apply to `pointer_gesture scales it too; off (the default) it stays where it is. `artboard.duplicate`, `artboard.copy` and `artboard.cut` copy or cut locked and hidden art only with it on. A `lockedAndHidden` param on any of these commands takes its place. - `penRubberBand`, `curvatureRubberBand` (on by default): off, the Pen and Curvature tools draw no preview segment to - the pointer. + the pointer. With either off, the Pen, the Smart Pen (`penRubberBand`) and the Curvature tool (`curvatureRubberBand`) + still show the D / Angle / dX / dY readout at the pointer while `measurementLabels` is on. - `showHandlesMultipleAnchors` (on by default): off, Direct Selection (and the Anchor Point tool, and the Pen with Alt) shows and drags direction handles only while a single anchor is selected. On, the handles of the direct-selected anchors, or of every anchor of a path selected as a whole, show and drag. `handleStyle` (`solid`, `hollow`, `large`) draws their ends (desktop app). diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 9ed2e6e180..55d21c00c1 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -892,6 +892,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur - Four brightness themes, persistent preferences. - **Snapping quick access (#6164):** Control bar › Snapping includes Snap to Glyph (`view.snapToGlyph`) and Alignment Guides (`prefs.set`, `alignmentGuides`). The headless pointer/accessibility test `the_control_bar_snapping_menu_shares_glyph_and_alignment_settings` covers both commands, independent state, checked states after reopening, and all eight menu rows within a 1200 × 400-point window. Floating-panel parity remains unverified; scores and estimates unchanged. - **Measure tools and Snap to Glyph:** with Snap to Glyph, Smart Guides and Alignment Guides on, and Snap to Grid and Snap to Pixel off, both ends of a Measure or Measure & Inspect drag land within the snapping tolerance on the guides of live type that the Character panel's options allow, except Anchor Point, and a Shift-drag's end slides along its 45° step to them. The guide shows during the drag. This is VectorCraft's own rule (`Targets::for_measure`, `xform::measure::tests::its_ends_land_on_glyph_guides_with_snap_to_glyph`); scores and estimates unchanged. + - **Drawing readout without the rubber band:** with Enable Rubber Band for the Pen or Curvature tool off and Measurement Labels on, the Pen, the Smart Pen and the Curvature tool hide the preview segment but still show the D / Angle / dX / dY readout at the snapped pointer before the next click, and the Curvature tool also shows it when going on from the current end of a selected path. Measurement Labels show distance and placement while drawing ([the help page](https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/smart-guides-options.html)), and the rubber band preference turns off the path preview ([the help page](https://helpx.adobe.com/illustrator/desktop/draw-shapes-and-paths/draw-shapes/preview-paths-drawn.html)). Showing the readout with the rubber band off is VectorCraft's own rule (`pen::tests::measurement_label_shows_with_the_rubber_band_off`, and `the_measurement_label_shows_with_the_rubber_band_off` in `draw2::curvature::tests` and `addons::smart_pen::tests`); scores and estimates unchanged. - Preferences that act (#394, in part): Show Tool Tips, Double Click To Isolate, Zoom with Mouse Wheel (the wheel zooms about the pointer, Shift-wheel scrolls up and down, Cmd/Ctrl-wheel sideways; Alt/Option-wheel and a trackpad pinch zoom about the pointer either way), Use Precise Cursors; Selection & Anchor Display › Tolerance (objects, anchors and handles), Object Selection by Path Only, Command Click to Select Objects Behind (cycling down the stack), Zoom to Selection, anchor Size, Highlight anchors on mouse over; Type › Number of Recent Fonts (up to 15); Guides & Grid › guide and grid Color and Style (lines or dots) and Grids In Back. Then Snap to Point (its distance, for moves, drawn points and reference points), Move Locked and Hidden Artwork with Artboard, Enable Rubber Band for the Pen and Curvature tools, Handles style, Show handles when multiple anchors are selected, Hide Corner Widget for angles greater than; General › Transform Pattern Tiles (the transforms' and dialogs' Transform Patterns, Align and Distribute, art moved or duplicated with an artboard, and objects moved whole with direct-selected anchors) and Select Same Tint %; Type › Size/Leading, Tracking and Baseline Shift increments (`type.step`, Cmd+Shift+. and Cmd+Shift+, for the size, the Type tool's Alt+arrows), Enable Missing Glyph Protection and Fill New Type Objects With Placeholder Text. Then Smart Guides › Color, Alignment Guides, Anchor/Path Labels, Measurement Labels, Transform Tools, Object Highlighting (with Smart Guides on) and Snapping Tolerance (4 px by default, for every smart guide snap), then Construction Guides and their Angles (#506: a drawn point near a line at one of those angles through the point it leaves from lands on it). Then Type › Type Object Selection by Path Only (type is picked on the baseline of any of its lines, area type's frame or the path of type on a path, no longer anywhere in its bounds; the Type tools and the Eyedropper still take a click among the characters). Then General › Anti-aliased Artwork (off, the canvas draws the art with hard edges). Then Guides & Grid › Show Pixel Grid (Above 600% Zoom), a line at every document pixel over the art in Pixel Preview, turning with a rotated view as the document grid now does too. Then General › Show The Home Screen When No Documents Are Open (off, closing the last document leaves an empty window; the Home button still opens the screen). Then Units › Numbers Without Units Are Points (on by default: a number typed with no unit into a field in picas is read in points, a typed unit still wins; dimmed unless a unit is Picas). Then User Interface › Auto-Collapse Iconic Panels (off by default: on, a click away from a panel popped out of the icon column puts it away). Then Performance › Animated Zoom (on, with GPU Performance, which it needs and which dims it when off: the Zoom tool dragged sideways zooms about the press, right in and left out, and held still zooms on, Alt out; off, a drag zooms to the area dragged across, now drawn as a marquee), User Interface › Large Tabs (taller document tabs) and Scale Cursor Proportional to UI (off, the tool cursors keep their size whatever the UI Scaling), and File Handling › Display Bitmaps as Anti-aliased Images in Pixel Preview (off by default: Pixel Preview draws images with each pixel taking its nearest image pixel). Type › Auto Size New Area Type works too (new area type gets Auto Size). They reach agents too (`prefs.set`, then `pointer_gesture` or `press_key`; `ui.wheel` on the control channel). Then Smart Guides › Spacing Guides (moves space the selection evenly with its row or column, see Drawing aids). Then Hyphenation › Exceptions (comma-separated words that never break, or break only at their hyphens; `prefs.set` and restore push them into the hyphenator, #394). Then Type › Show Font Names in English (off, font menus label a family by its native-language name when the font has one; documents still use the English family, #394). Then General › Display Print Size at 100% Zoom (off by default: View › Actual Size is one document point per screen point; on, one document inch fills 96 screen points, an inch at the reference density display scaling is set against; `view.actualSize` / `prefs.set`, #394). Then Guides & Grid › Gridline every and Subdivisions (changing either sets the grid of every open document; new and opened documents take that grid too, except a native file and the native document an SVG, PDF, `.ai` or EPS file carries, which open with the grid they were saved with; `file.new`, `document.open`, `file.newFromTemplate`, `file.revert`, #394). Then Appearance of Black › On Screen (Display All Blacks Accurately by default: pure CMYK black shows through the CMYK profile, a dark grey; Display All Blacks as Rich Black shows it on the canvas as RGB black, also in CMYK documents drawn by ink planes, while rich blacks, black tints and images show as before; `RenderOptions::rich_black`, #394). Then Appearance of Black › Printing / Exporting (Output All Blacks Accurately by default; Output All Blacks as Rich Black draws pure CMYK black as RGB black in RGB raster exports and Print as Bitmap; CMYK ink exports and the document stay unchanged; `prefs.blackOutput` / `richBlack`, #394). Then Units › Identify Objects By (Object Name by default: Layers, Variables and Layer Options show and edit free names; XML ID shows and edits AI-style XML ids, `_` for a space and `_xHH_` escapes, and `layer.setProps` / rename refuse invalid ids; the document still stores the object name, #394). Then Type › Highlight Alternate Glyphs (off by default: on, pink behind OpenType substitutions on screen — ligatures, contextual forms; Document Setup's Highlight Substituted Glyphs stays separate; `prefs.set`, #394). About 14 stored options still do nothing yet (the rest of #394: Open Documents As Tabs, Real-time Drawing and Editing, GPU Performance beyond Animated Zoom, hyphenation language, scratch disks, the legacy clipboard, Touch Workspace). - Preferences that act (#394, in part): Show Tool Tips, Double Click To Isolate, Zoom with Mouse Wheel (the wheel zooms about the pointer, Shift-wheel scrolls up and down, Cmd/Ctrl-wheel sideways; Alt/Option-wheel and a trackpad pinch zoom about the pointer either way), Use Precise Cursors; Selection & Anchor Display › Tolerance (objects, anchors and handles), Object Selection by Path Only, Command Click to Select Objects Behind (cycling down the stack), Zoom to Selection, anchor Size, Highlight anchors on mouse over; Type › Number of Recent Fonts (up to 15); Guides & Grid › guide and grid Color and Style (lines or dots) and Grids In Back. Then Snap to Point (its distance, for moves, drawn points and reference points), Move Locked and Hidden Artwork with Artboard, Enable Rubber Band for the Pen and Curvature tools, Handles style, Show handles when multiple anchors are selected, Hide Corner Widget for angles greater than; General › Transform Pattern Tiles (the transforms' and dialogs' Transform Patterns, Align and Distribute, art moved or duplicated with an artboard, and objects moved whole with direct-selected anchors) and Select Same Tint %; Type › Size/Leading, Tracking and Baseline Shift increments (`type.step`, Cmd+Shift+. and Cmd+Shift+, for the size, the Type tool's Alt+arrows), Enable Missing Glyph Protection and Fill New Type Objects With Placeholder Text. Then Smart Guides › Color, Alignment Guides, Anchor/Path Labels, Measurement Labels, Transform Tools, Object Highlighting (with Smart Guides on) and Snapping Tolerance (4 px by default, for every smart guide snap), then Construction Guides and their Angles (#506: a drawn point near a line at one of those angles through the point it leaves from lands on it). Then Type › Type Object Selection by Path Only (type is picked on the baseline of any of its lines, area type's frame or the path of type on a path, no longer anywhere in its bounds; the Type tools and the Eyedropper still take a click among the characters). Then General › Anti-aliased Artwork (off, the canvas draws the art with hard edges). Then Guides & Grid › Show Pixel Grid (Above 600% Zoom), a line at every document pixel over the art in Pixel Preview, turning with a rotated view as the document grid now does too. Then General › Show The Home Screen When No Documents Are Open (off, closing the last document leaves an empty window; the Home button still opens the screen). Then Units › Numbers Without Units Are Points (on by default: a number typed with no unit into a field in picas is read in points, a typed unit still wins; dimmed unless a unit is Picas). Then User Interface › Auto-Collapse Iconic Panels (off by default: on, a click away from a panel popped out of the icon column puts it away). Then Performance › Animated Zoom (on, with GPU Performance, which it needs and which dims it when off: the Zoom tool dragged sideways zooms about the press, right in and left out, and held still zooms on, Alt out; off, a drag zooms to the area dragged across, now drawn as a marquee), User Interface › Large Tabs (taller document tabs) and Scale Cursor Proportional to UI (off, the tool cursors keep their size whatever the UI Scaling), and File Handling › Display Bitmaps as Anti-aliased Images in Pixel Preview (off by default: Pixel Preview draws images with each pixel taking its nearest image pixel). Type › Auto Size New Area Type works too (new area type gets Auto Size). They reach agents too (`prefs.set`, then `pointer_gesture` or `press_key`; `ui.wheel` on the control channel). Then Smart Guides › Spacing Guides (moves space the selection evenly with its row or column, see Drawing aids). Then Hyphenation › Exceptions (comma-separated words that never break, or break only at their hyphens; `prefs.set` and restore push them into the hyphenator, #394). Then Type › Show Font Names in English (off, font menus label a family by its native-language name when the font has one; documents still use the English family, #394). Then General › Display Print Size at 100% Zoom (off by default: View › Actual Size is one document point per screen point; on, one document inch fills 96 screen points, an inch at the reference density display scaling is set against; `view.actualSize` / `prefs.set`, #394). Then Guides & Grid › Gridline every and Subdivisions (changing either sets the grid of every open document; new and opened documents take that grid too, except a native file and the native document an SVG, PDF, `.ai` or EPS file carries, which open with the grid they were saved with; `file.new`, `document.open`, `file.newFromTemplate`, `file.revert`, #394). Then Appearance of Black › On Screen (Display All Blacks Accurately by default: pure CMYK black shows through the CMYK profile, a dark grey; Display All Blacks as Rich Black shows it on the canvas as RGB black, also in CMYK documents drawn by ink planes, while rich blacks, black tints and images show as before; `RenderOptions::rich_black`, #394). Then Appearance of Black › Printing / Exporting (Output All Blacks Accurately by default; Output All Blacks as Rich Black draws pure CMYK black as RGB black in RGB raster exports and Print as Bitmap; CMYK ink exports and the document stay unchanged; `prefs.blackOutput` / `richBlack`, #394). Then Units › Identify Objects By (Object Name by default: Layers, Variables and Layer Options show and edit free names; XML ID shows and edits AI-style XML ids, `_` for a space and `_xHH_` escapes, and `layer.setProps` / rename refuse invalid ids; the document still stores the object name, #394). Then Type › Highlight Alternate Glyphs (on by default: pink behind OpenType substitutions on screen — ligatures, contextual forms; Document Setup's Highlight Substituted Glyphs stays separate; `prefs.set`, #394). About 14 stored options still do nothing yet (the rest of #394: Open Documents As Tabs, Real-time Drawing and Editing, GPU Performance beyond Animated Zoom, hyphenation language, scratch disks, the legacy clipboard, Touch Workspace). - The desktop app keeps the Color panel's Show Options or Hide Options between sessions, and `ui.colorPanel` sets its mode and options as its panel menu does. diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 5f10ea4841..bc9e1a3244 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -233,7 +233,7 @@ tools, never checked side by side) isn't captured row by row. | "intersect" label and snapping to path intersections | partial | #1658 (part of #1602): a point drawn with the Pen, the shape tools or the other drawing tools and an anchor dragged with Direct Selection snap to where paths and ruler guides cross; a moved selection's own anchors and the Width tool don't | | Construction guides at preference angles while drawing | done | #506 | | Line extension: the dragged end of a straight segment snaps to the segment's own direction at any angle, past its other end or short of it, with the guide along it | done | #2120; Direct Selection and Curvature, one anchor dragged (with several, the move has no single direction); nearer the horizontal or vertical through the other end, the point lines up with it ("align"), so a nearly level segment can still be straightened | -| Measurement labels while drawing, moving and resizing | done | sizes and offsets; the segment being drawn is labeled with its distance, angle and offsets by the Line Segment tool, and by the Pen, Curvature and Smart Pen tools with Enable Rubber Band on (#2983) | +| Measurement labels while drawing, moving and resizing | done | sizes and offsets; the segment being drawn is labeled with its distance, angle and offsets by the Line Segment tool, and by the Pen, Curvature and Smart Pen tools with Enable Rubber Band on or off (#2983) | | Spacing guides (equal distances) | partial | for moves and bounding-box resizes (#394); not while drawing | | Distance Guides: Alt/Option over another object, or an empty part of an artboard, shows the selection's distances to it (Smart Guides › Invoke Distance Guides) | done | Selection tool hover with Smart Guides on: the gap between facing edges, else the offsets of matching edges, to another object; the left, right, top and bottom distances to the artboard; labelled in the General unit. The selection is measured as a whole. Nothing while moving or nudging, which the public pages don't describe. [Use Distance Guides](https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/use-distance-guides-for-accurate-placement.html), [Smart Guides options](https://helpx.adobe.com/illustrator/desktop/measure-and-align/grids-and-guides/smart-guides-options.html) | | Snapping tolerance preference | done | | From 52da895220b5a5f501320eaa4e722ff620d05e36 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Thu, 12 Nov 2026 21:12:01 -0800 Subject: [PATCH 2/2] Docs: record the drawing readout in the Drawing tools area row The Drawing tools row in docs/target-app-parity.md now names the measurement readout that the Pen, Smart Pen and Curvature tool show with the rubber band off. The score, gaps and hours are unchanged. --- docs/target-app-parity.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 55d21c00c1..0dce10f77f 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -224,7 +224,7 @@ dominate; 3D, graphs and automation are specialist). They sum to 105. Feature de | Area | Weight | Done | Main gaps | One agent (h) | Kind | |---|---:|---:|---|---:|---| | Selection, transform & align tools | 6 | 85% | Direct Selection segment click/Delete corrected (#1278); deletion splits an ordinary contour into selected sibling objects with bounds-fitted gradients kept in place (#3380, deletion only; `crates/engine/tests/it/delete_path_pieces.rs`); open-path anchor Delete keeps gaps; Select › Start Global Edit finds the paths, compound paths and symbol instances of the selected object's shape (Appearance, Size and artboard options) and gives an edit of one to all of them in proportion, as one undo step (#3521), and on a group the groups like it, an edit inside one reaching the same object in the others (#4939), and a Shift-click on a highlighted match leaves it out; the Align panel menu's Align to Glyph Bounds › Point Text and Area Text measure type by its glyphs' ink for Align and Distribute (#4231); remaining: Free Transform/Scale/Reflect along a rotated box, Global Edit of rotated copies, transform nuances (no-op anchor Align history regression-tested, #1180 follow-up) | 4–6 | estimated; Global Edit regression-tested (`crates/engine/src/tests/globaledit.rs`; Quick Action, menu label and Escape in `panels::properties::tests::start_global_edit_quick_action_and_escape`) | -| Drawing tools (Pen, Curvature, Pencil, shapes, Shaper) | 7 | 85% | Shaper construction widget, Pencil/Pen nuances, Blob Brush options, Touch Type, Dimension tool; see [ui-parity.md](ui-parity.md) | 8–13 | estimated; Curvature point display regression-tested (#1236, in part); Polygon/Star exact-size count persistence regression-covered; Live Corners' Relative rounding done (#3091), score unchanged; Copy and Cut with the Pen or Curvature tool take the anchors a Cmd/Ctrl-lent Direct Selection picked (#6123), score and hours unchanged | +| Drawing tools (Pen, Curvature, Pencil, shapes, Shaper) | 7 | 85% | Shaper construction widget, Pencil/Pen nuances, Blob Brush options, Touch Type, Dimension tool; see [ui-parity.md](ui-parity.md) | 8–13 | estimated; Curvature point display regression-tested (#1236, in part); Polygon/Star exact-size count persistence regression-covered; Live Corners' Relative rounding done (#3091), score unchanged; Copy and Cut with the Pen or Curvature tool take the anchors a Cmd/Ctrl-lent Direct Selection picked (#6123), score and hours unchanged; the Pen, Smart Pen and Curvature tool show the measurement readout with the rubber band off (#7043), score, gaps and hours unchanged | | Path operations, Pathfinder, Shape Builder, Live Paint | 5 | 80% | Shape Builder on the reporter's file (#937: art past 4,096 segments is cut by lines again; unconfirmed on the file itself); gap detection shares Live Paint’s finder, with a 72 pt custom cap and the existing options; Live Paint Gap Options | 4–8 | estimated; Shape Builder Gap Detection shares Live Paint’s spatial gap finder and temporary merge bridges (#2526); Custom is capped at 72 pt in the existing options dialog (lowered from 86%: open issues); compound attributes regression-tested (#1197); single-result source names survive SVG export/import (#1293), with [SVG ID semantics](https://www.w3.org/TR/SVG2/struct.html#IDAttribute) and original-shape tests; Simplify component selection and preview regression-tested (#1272); Simplify of a Direct Selection part of a path regression-tested (`tests/simplify_part.rs`); Divide open-cutting-path geometry and appearance regression-tested (#1307); the Shape Builder's edge-source grid is bounded in memory and files a segment once per cell (`planar.rs` test `rect_index_holds_a_bounded_number_of_references`); live compound shapes (Make, Alt-click, member Shape Modes, Release, Expand, saved and exported) regression-tested (#4522); Live Paint Bucket face drags, including narrow faces and one Undo, regression-tested (#6373) | | Colour, swatches, gradients, patterns, mesh, recolor | 7 | 92% | Eyedropper copies effective character dimensions across text transforms (#6404); 30.0's gradient additions are done (dither, perceptual blending, presets); freeform gradients in SVG/PDF, mixed spot/process gradients in SVG, PDF gradients mixing a spot color with RGB or Lab stops, and dithered spot gradient fills and Perceptual spot gradients with RGB or Lab stops other than white or more than 4,096 stops on their curve, which PDF export writes as images in process colors| 4–7 | estimated; Recolor model selection is available through the engine and MCP (#2520), and the dialog's color sliders (HSB, RGB, CMYK, Lab, Tint for a spot color) edit the selected row's new color in its mode, and the Edit tab's Global Adjust sliders (Saturation, Brightness, Temperature, Luminosity, -100% to 100%) change every recolored color at once (lowered from 96%: target moved); unpainted zero-width stroke restoration fixed (#1253), score and hours unchanged; Eyedropper source reads regression-tested (#1251); screen-bounded Recolor Edit chip list (#3416), score and hours unchanged; a point on a gradient mesh's outline locates on its edge on every side (#7006: `mesh_locate_takes_a_point_on_any_side_of_the_outline`, `mesh_add_line_exactly_on_the_edge_needs_no_tolerance`), score and hours unchanged | | Strokes, brushes, width profiles | 5 | 88% | Shift-double-click adjoining adjustment is implemented; brush libraries are done (nine generated libraries including Ink and Wash, Bristle Brushes, Game Trails, Energy Beams and Dry Media, User Defined, Other Library…, Save Brushes); Art brush Overlap and Pattern brush auto corners are done; remaining: pen pressure on macOS, Stylus Wheel, more built-in brush libraries, tilt, bearing and rotation for Art, Pattern and Bristle brushes and on native Wayland and the web | 8–15 | estimated; width-point creation and adjoining adjustment regression-tested; dialog layout reviewed; evidence below; finite-arithmetic follow-up regressions and full CI passed (evidence below) |