mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 08:51:25 +00:00
M2.1: avoid discarded path copies during deletion (#3380)
This commit is contained in:
@@ -764,6 +764,10 @@ fn cut(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
/// Remove the geometry copied by a direct-selection Cut, including selected guides in one edit.
|
||||
/// Select every surviving piece while retaining intentional compound-path structure.
|
||||
/// `roots` contains the copied targets: whole-object roots are removed in full, while partial paths
|
||||
/// lose only the copied geometry. An exhausted partial path is removed, along with its compound
|
||||
/// parent if now empty; layers remain. Returns JSON `null` on success, replacing direct-selection
|
||||
/// references with surviving object IDs.
|
||||
fn cut_direct_selection(s: &mut Session, roots: &[NodeId]) -> Result<Value> {
|
||||
let st = s.doc()?;
|
||||
let sel = st.selection.clone();
|
||||
@@ -780,20 +784,22 @@ fn cut_direct_selection(s: &mut Session, roots: &[NodeId]) -> Result<Value> {
|
||||
d.remove(*id)?;
|
||||
continue;
|
||||
}
|
||||
let Some(path) = node.path_data() else {
|
||||
if node.path_data().is_none() {
|
||||
d.remove(*id)?;
|
||||
continue;
|
||||
};
|
||||
}
|
||||
let original = super::path::deletion_source(d, *id)?;
|
||||
|
||||
let seg_refs = sel.segments.get(id);
|
||||
let anchor_refs = sel.anchors.get(id);
|
||||
let mut subpaths = Vec::new();
|
||||
for (si, sp) in path.subpaths.iter().enumerate() {
|
||||
let cuts = super::clipboard::subpath_selected_segments(sp, si, seg_refs, anchor_refs);
|
||||
let owned = std::mem::take(&mut super::path::path_mut(d, *id)?.subpaths);
|
||||
for (si, sp) in owned.into_iter().enumerate() {
|
||||
let cuts = super::clipboard::subpath_selected_segments(&sp, si, seg_refs, anchor_refs);
|
||||
if cuts.is_empty() {
|
||||
subpaths.push(sp.clone());
|
||||
subpaths.push(sp);
|
||||
} else {
|
||||
subpaths.extend(super::path::without_segments(sp.clone(), &cuts));
|
||||
subpaths.extend(super::path::without_segments(sp, &cuts));
|
||||
}
|
||||
}
|
||||
subpaths.retain(|sp| sp.anchors.len() >= 2);
|
||||
@@ -806,7 +812,7 @@ fn cut_direct_selection(s: &mut Session, roots: &[NodeId]) -> Result<Value> {
|
||||
d.remove(p)?;
|
||||
}
|
||||
} else {
|
||||
survivors.extend(super::path::replace_deleted_pieces(d, &mut pieces, *id, subpaths)?);
|
||||
survivors.extend(super::path::replace_deleted_pieces(d, &mut pieces, original, subpaths)?);
|
||||
}
|
||||
}
|
||||
pieces.finish(d)?;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! Path editing commands (used by the Pen and Direct Selection tools and Object → Path).
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::{Document, Node, NodeId, NodeKind, Scaling};
|
||||
@@ -1191,6 +1192,9 @@ fn convert_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
|
||||
/// Delete direct-selected anchors or segments and whole selected objects in one edit.
|
||||
/// Leave surviving pieces selected, splitting ordinary contours into independent sibling objects.
|
||||
/// `p.guides: true` also removes the selected ruler guides in that edit; otherwise guides remain.
|
||||
/// Layers are retained, and an object removed with a selected ancestor is not removed twice.
|
||||
/// Returns JSON `null` on success; selection is replaced by the surviving object IDs.
|
||||
pub(crate) fn delete_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
// `guides: true` (Cut, #3226): the selected ruler guides go in the same undo step.
|
||||
let with_guides = switch_or(p, "guides", false, "path.deleteAnchors")?;
|
||||
@@ -1222,13 +1226,14 @@ pub(crate) fn delete_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
if d.node(*id).is_none() {
|
||||
continue;
|
||||
}
|
||||
let original = deletion_source(d, *id)?;
|
||||
let subpaths: Vec<SubPath> = {
|
||||
let path = d.node(*id).and_then(|n| n.path_data()).ok_or(EngineError::NoNode(*id))?;
|
||||
let path = path_mut(d, *id)?;
|
||||
let subpaths = std::mem::take(&mut path.subpaths);
|
||||
if let Some(refs) = segments.get(id) {
|
||||
// A segment pick cuts its connection, keeping every neighboring cubic.
|
||||
path.subpaths
|
||||
.iter()
|
||||
.cloned()
|
||||
subpaths
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.flat_map(|(si, sp)| {
|
||||
let cuts = refs.iter().filter_map(|&(s, seg)| (s == si).then_some(seg)).collect();
|
||||
@@ -1239,9 +1244,8 @@ pub(crate) fn delete_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
} else {
|
||||
// Remove every selected anchor against the original indexes, keeping surviving
|
||||
// stretches separate rather than joining across deleted anchors.
|
||||
path.subpaths
|
||||
.iter()
|
||||
.cloned()
|
||||
subpaths
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.flat_map(|(si, sp)| {
|
||||
let gone = set.iter().filter_map(|&(s, ai)| (s == si).then_some(ai)).collect();
|
||||
@@ -1255,7 +1259,7 @@ pub(crate) fn delete_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
emptied.put(d, *id, vec![])?;
|
||||
} else {
|
||||
// Every remaining piece is selected whole, so the next Delete removes them.
|
||||
survivors.extend(replace_deleted_pieces(d, &mut emptied, *id, subpaths)?);
|
||||
survivors.extend(replace_deleted_pieces(d, &mut emptied, original, subpaths)?);
|
||||
}
|
||||
}
|
||||
emptied.finish(d)?;
|
||||
@@ -1265,15 +1269,39 @@ pub(crate) fn delete_anchors(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
ok()
|
||||
}
|
||||
|
||||
/// Deletion splits an ordinary contour into sibling objects. Existing multi-subpath paths and
|
||||
/// explicit compound members keep their compound semantics, even when a member has one contour.
|
||||
/// Separate objects retain the gradient placement of the original path.
|
||||
pub(super) fn replace_deleted_pieces(d: &mut Document, beside: &mut Beside, id: NodeId, subpaths: Vec<SubPath>) -> Result<Vec<NodeId>> {
|
||||
let single = d.node(id).and_then(|n| n.path_data()).is_some_and(|p| p.subpaths.len() == 1);
|
||||
/// Retain path `id` from `d` without copying its geometry before deletion takes its subpaths.
|
||||
/// The shared snapshot supplies the original path classification and, only if needed, gradient
|
||||
/// bounds after the working node's geometry has moved. Returns `NoNode` for a missing/non-path ID.
|
||||
pub(super) fn deletion_source(d: &Document, id: NodeId) -> Result<Arc<Node>> {
|
||||
let (parent, index, _) = d.position(id).ok_or(EngineError::NoNode(id))?;
|
||||
// Verify the cached position still names this path before retaining the shared node.
|
||||
d.children(parent)
|
||||
.and_then(|children| children.get(index))
|
||||
.filter(|n| n.id == id && n.path_data().is_some())
|
||||
.cloned()
|
||||
.ok_or(EngineError::NoNode(id))
|
||||
}
|
||||
|
||||
/// Replace the deleted path in `d` with the nonempty surviving runs in `subpaths`.
|
||||
/// `original` must be retained by [`deletion_source`] before taking the working node's geometry.
|
||||
/// An ordinary single-contour source becomes siblings; multi-subpath paths and compound members
|
||||
/// retain their node. Only actual splits pin unplaced gradients to `original`'s bounds; already
|
||||
/// placed gradients and connected remainders retain their placement behavior.
|
||||
///
|
||||
/// Returns the surviving IDs in `subpaths` order (the first keeps the source ID). The original
|
||||
/// node's geometry is updated immediately. Replacements are handed to `beside`, which may defer
|
||||
/// insertion; the caller must finish that [`Beside`] before using new IDs in `d`.
|
||||
/// Missing/invalid paths return an error.
|
||||
pub(super) fn replace_deleted_pieces(d: &mut Document, beside: &mut Beside, original: Arc<Node>, subpaths: Vec<SubPath>) -> Result<Vec<NodeId>> {
|
||||
let id = original.id;
|
||||
let single = original.path_data().is_some_and(|p| p.subpaths.len() == 1);
|
||||
if single && compound_or_self(d, id) == id {
|
||||
// Pin only actual splits: each new object's smaller bounds would otherwise refit its gradients.
|
||||
if subpaths.len() > 1 {
|
||||
d.node_mut(id).ok_or(EngineError::NoNode(id))?.pin_gradients();
|
||||
if subpaths.len() > 1
|
||||
&& original.appearance.has_unplaced_gradient()
|
||||
&& let Some(bounds) = original.geometric_bounds()
|
||||
{
|
||||
d.node_mut(id).ok_or(EngineError::NoNode(id))?.appearance.pin_gradients(bounds);
|
||||
}
|
||||
super::draw2::replace_with_pieces(d, beside, id, subpaths.into_iter().map(PathData::single).collect())
|
||||
} else {
|
||||
|
||||
+2
-4
@@ -1,7 +1,6 @@
|
||||
# Gaps
|
||||
|
||||
> **Last updated:** 2026-11-08 · **Change:** #3380 deletion review follow-up: split survivors keep their original bounds-fitted gradient placement; documentation evidence, geometry assertions and function docs clarified. Existing multi-subpath paths and compound members stay intact. Segment endpoint highlighting remains open. Scores and estimates unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (#3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Indian-language hyphenation review and license allowlist, #4947; opening a slow file shows a progress window, part of #5930; Hindi catalog and contributor loanword preferences; agent wording pass complete; wider native proofreading welcome; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); scores and estimates unchanged; a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window; scores and estimates unchanged; large images in CMYK documents are shrunk before they are separated into ink planes (#4155); scores and estimates unchanged; `.ai` paths with a Calligraphic brush open brushed, with the 6D Art Pen's channels, and Windows reads the pen's tilt and barrel rotation, #372; scores and estimates unchanged; Compound Shapes add-on, beyond Illustrator; scores and estimates unchanged; Contour add-on, beyond Illustrator; scores and estimates unchanged; a slow first frame is waited for instead of restarting without the graphics adapter, and the menu bar no longer waits for the installed fonts' scan; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
@@ -38,8 +37,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-08 | minor | #3380, deletion only: pin bounds-fitted gradients before creating separate survivors; placed gradients and connected remainders retain their behavior. Regression coverage checks linear/radial fill and stroke vectors, rendered survivors and Undo/Redo. Scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380 review follow-up: clarify deletion evidence and survivor selection, consolidate milestone notes, and retain the open endpoint-highlighting work. Behavior, scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380, deletion only: preserve gradient placement and exact surviving geometry; consume owned subpaths with a shared original-node snapshot; consolidate status/evidence and document command/helper contracts. Compound behavior and the existing M2 status entry are retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | #3380 (deletion only): independent surviving path objects; transformed appearance, stacking, selection, cubic handles and Undo/Redo covered by `delete_path_pieces`; compound semantics retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
|
||||
| 2026-11-05 | minor | G15: long open strokes with an undashed width profile are outlined near the view while keeping profile positions on the full path; a 200,000-segment outline took 59.95 ms before and 8.44 ms after in local median runs. Closed and dashed profile strokes remain whole; estimate unchanged. |
|
||||
|
||||
+2
-4
@@ -1,7 +1,6 @@
|
||||
# Roadmap: milestones and what's next
|
||||
|
||||
> **Last updated:** 2026-11-08 · **Change:** #3380 deletion review follow-up: split survivors keep their original bounds-fitted gradient placement; documentation evidence, geometry assertions and function docs clarified. Existing multi-subpath paths and compound members stay intact. Segment endpoint highlighting remains open. Scores and estimates unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (Indian-language hyphenation review and license allowlist, #4947; Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (#3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Indian-language hyphenation review and license allowlist, #4947; Hindi catalog and contributor loanword preferences; full wording review in progress; Effect dialogs: a colour swatch beside a hex colour opens the Color Picker, #5365; shape tools move the selection from its centre point and turn it from the zone outside a box corner, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
@@ -37,8 +36,7 @@ M7 type: Touch Type moves a right-to-left character along its line and up from i
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-08 | minor | #3380, deletion only: pin bounds-fitted gradients before creating separate survivors; placed gradients and connected remainders retain their behavior. Regression coverage checks linear/radial fill and stroke vectors, rendered survivors and Undo/Redo. Scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380 review follow-up: clarify deletion evidence and survivor selection, consolidate milestone notes, and retain the open endpoint-highlighting work. Behavior, scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380, deletion only: preserve gradient placement and exact surviving geometry; consume owned subpaths with a shared original-node snapshot; consolidate status/evidence and document command/helper contracts. Compound behavior and the existing M2 status entry are retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | #3380 (deletion only): independent surviving path objects; transformed appearance, stacking, selection, cubic handles and Undo/Redo covered by `delete_path_pieces`; compound semantics retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
|
||||
| 2026-11-05 | minor | Effect dialogs: a colour swatch beside a hex colour field follows typed values, and a double-click opens the Color Picker over the dialog, whose OK fills the field (#5365); scores and estimates unchanged. |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Parity with Adobe Illustrator
|
||||
|
||||
> **Last updated:** 2026-11-08 · **Change:** #3380 deletion review follow-up: split survivors keep their original bounds-fitted gradient placement; documentation evidence, geometry assertions and function docs clarified. Existing multi-subpath paths and compound members stay intact. Segment endpoint highlighting remains open. Scores and estimates unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-07 · **Change:** minor (the canvas keeps selection outlines and anchors between frames; Indian-language hyphenation review and license allowlist, #4947; Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (#3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; the canvas keeps selection outlines and anchors between frames; Indian-language hyphenation review and license allowlist, #4947; Stroke gradients: an arrowhead aligned to the tip is painted to the corners of its base, #5964; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Hindi catalog and contributor loanword preferences; full wording review in progress; Properties in Edit Artboards: a Transform section with the reference point above the Artboards section, #5219; the Control bar's Stroke: and Opacity: links scrub their fields, #4088; an image zoomed in on is separated, colorized or proofed only where it shows (#4155); a document's first frame renders on the render worker, so opening a heavy file no longer freezes the window, #4155; Control bar Paragraph section with type selected, #5372; translating unchanged type reuses its glyph and character-stroke outlines; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
@@ -32,8 +31,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-08 | minor | #3380, deletion only: pin bounds-fitted gradients before creating separate survivors; placed gradients and connected remainders retain their behavior. Regression coverage checks linear/radial fill and stroke vectors, rendered survivors and Undo/Redo. Scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380 review follow-up: clarify deletion evidence and survivor selection, consolidate milestone notes, and retain the open endpoint-highlighting work. Behavior, scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380, deletion only: preserve gradient placement and exact surviving geometry; consume owned subpaths with a shared original-node snapshot; consolidate status/evidence and document command/helper contracts. Compound behavior and the existing M2 status entry are retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | #3380 (deletion only): independent surviving path objects; transformed appearance, stacking, selection, cubic handles and Undo/Redo covered by `delete_path_pieces`; compound semantics retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | The canvas keeps selection outlines, anchors and handles between frames, so an idle frame with a large selection redraws them as one mesh; scores and estimates unchanged |
|
||||
| 2026-11-07 | minor | Indian-language hyphenation (#4947): eleven MIT-licensed pattern sets, with grapheme and shaping-cluster protection in both composers and existing paragraph limits. Assamese and Sanskrit are selectable; Sanskrit automatic patterns remain pending an allowlisted source. Scores and estimates unchanged. |
|
||||
|
||||
+2
-4
@@ -1,7 +1,6 @@
|
||||
# UI and interaction parity
|
||||
|
||||
> **Last updated:** 2026-11-08 · **Change:** #3380 deletion review follow-up: split survivors keep their original bounds-fitted gradient placement; documentation evidence, geometry assertions and function docs clarified. Existing multi-subpath paths and compound members stay intact. Segment endpoint highlighting remains open. Scores and estimates unchanged.
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-06 · **Change:** minor (Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-08 · **Change:** minor (#3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
|
||||
|
||||
## Feature submission evidence
|
||||
|
||||
@@ -40,8 +39,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-08 | minor | #3380, deletion only: pin bounds-fitted gradients before creating separate survivors; placed gradients and connected remainders retain their behavior. Regression coverage checks linear/radial fill and stroke vectors, rendered survivors and Undo/Redo. Scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380 review follow-up: clarify deletion evidence and survivor selection, consolidate milestone notes, and retain the open endpoint-highlighting work. Behavior, scores and estimates unchanged. |
|
||||
| 2026-11-08 | minor | #3380, deletion only: preserve gradient placement and exact surviving geometry; consume owned subpaths with a shared original-node snapshot; consolidate status/evidence and document command/helper contracts. Compound behavior and the existing M2 status entry are retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-11-07 | minor | #3380 (deletion only): independent surviving path objects; transformed appearance, stacking, selection, cubic handles and Undo/Redo covered by `delete_path_pieces`; compound semantics retained. Endpoint highlighting remains open; scores and estimates unchanged. |
|
||||
| 2026-10-30 | minor | Home screen: welcome, New / Open and Community are centred and the large Discord button uses the theme accent, part of #4684; scores and estimates unchanged (estimated) |
|
||||
| 2026-11-06 | minor | Snap to Grid: a straight segment dragged with Direct Selection lands its anchors on the grid, not the pressed point (#3835); scores and estimates unchanged |
|
||||
|
||||
Reference in New Issue
Block a user