Merge remote-tracking branch 'origin/main' into feat/glyph-alternates

This commit is contained in:
Taha-Mahmoodi
2026-11-12 16:38:46 +04:30
7 changed files with 64 additions and 7 deletions
+20
View File
@@ -56,6 +56,26 @@ fn set(app: &mut VectorcraftApp, key: &str, v: serde_json::Value) {
crate::dialogs::set_field(app.ui.dialog.as_mut().unwrap(), key.into(), v);
}
/// Properties' Quick Actions and the Control bar offer Remove Background for a selected image, and
/// the Control bar's button removes it at once (no dialog) with the defaults, as one step.
#[test]
fn properties_and_the_control_bar_remove_the_background_at_once() {
use crate::tests_removeanchors::{at, click_control, control_frame, has, properties_frame};
let mut app = app();
let steps = |app: &VectorcraftApp| app.session.doc().unwrap().history.undo.len();
let n = steps(&app);
assert!(has(&properties_frame(&mut app, 280.0), "Remove Background"), "Properties offers it");
let ctx = egui::Context::default();
crate::theme::install_fonts(&ctx);
let bar = control_frame(&mut app, &ctx, vec![]);
click_control(&mut app, &ctx, at(&bar, "Remove Background"));
assert!(app.ui.dialog.is_none(), "it runs at once");
assert_eq!(steps(&app), n + 1, "one undo step");
// The defaults (tolerance and softness 10): the white goes, the near-white ring fades.
let [corner, ring, block] = alphas(&app);
assert!(corner == 0 && ring > 0 && ring < 255 && block == 255, "{:?}", alphas(&app));
}
/// Object › Plug-ins › Image Tools › Remove Background… opens the command dialog on Edge Color
/// with Preview off. With Preview on the canvas shows the result for the values in the dialog,
/// each change worked out again from the image as it was; Cancel puts the image back with no step
+4 -2
View File
@@ -96,11 +96,13 @@ pub(super) fn task_bar(app: &mut VectorcraftApp, ui: &mut Ui, xf: &Xf) {
} else {
// Edit Path: the Direct Selection tool, to edit the path's anchors.
let edit_path = || (tl!("Edit Path"), "dc-direct", "tool.select", json!({"tool": "directSelection"}));
// As in the reference app, an image offers Image Trace and Crop Image, and traced art offers
// Expand (<https://community.adobe.com/announcements-651/contextual-task-bar-in-illustrator-2025-quick-actions-when-you-need-them-1546580>).
// As in the reference app, an image offers Image Trace, Crop Image and Remove Background, and
// traced art offers Expand (<https://community.adobe.com/announcements-651/contextual-task-bar-in-illustrator-2025-quick-actions-when-you-need-them-1546580>,
// <https://community.adobe.com/announcements-651/ai-powered-image-editing-features-in-illustrator-1624061>).
if n == 1 && is_image {
items.push((tl!("Image Trace"), "image", TASK_BAR_IMAGE_TRACE, none()));
items.push((tl!("Crop Image"), "dc-pf-crop", "ui.cropImage", none()));
items.push((tl!("Remove Background"), "eraser", crate::addons::image::REMOVE_BACKGROUND, none()));
}
// Direct-selected anchors take the place of a path's Offset Path and Simplify. For them the bar
// offers Remove, Connect, Cut and Convert to corner or smooth, as the reference app does
+27
View File
@@ -9353,6 +9353,33 @@ fn the_task_bar_traces_an_image_then_expands_the_trace() {
assert_eq!(images, 0, "only the traced paths are kept");
}
/// For a selected image the Contextual Task Bar offers Remove Background, which clears the
/// background in the image's pixels at once (no dialog) with the command's defaults.
#[test]
fn the_task_bar_removes_a_selected_images_background() {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
let img =
image::RgbaImage::from_fn(20, 20, |x, y| image::Rgba(if (6..14).contains(&x) && (6..14).contains(&y) { [200, 0, 0, 255] } else { [255; 4] }));
let mut png = vec![];
img.write_to(&mut std::io::Cursor::new(&mut png), image::ImageFormat::Png).unwrap();
let data = vectorcraft_format::base64_encode(&png);
app.run("file.place", json!({"name": "dot.png", "dataBase64": data, "link": false, "at": [200, 150]})).unwrap();
app.select_tool("selection");
let ctx = egui::Context::default();
let labels = task_bar_labels(&mut app, &ctx);
let at = labels.iter().find(|(t, _)| t == "Remove Background").map(|(_, r)| r.center()).expect("Remove Background is offered");
let button = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: Default::default() };
frame(&mut app, &ctx, vec![egui::Event::PointerMoved(at)]);
frame(&mut app, &ctx, vec![button(true)]);
frame(&mut app, &ctx, vec![button(false)]);
assert!(app.ui.dialog.is_none(), "it runs at once");
let st = app.session.active().unwrap();
let Some(NodeKind::Image(im)) = st.selection.objects.first().and_then(|id| st.doc.node(*id)).map(|n| &n.kind) else { panic!("an image") };
let px = image::load_from_memory(&st.doc.images[&im.key].bytes).unwrap().to_rgba8();
assert_eq!((px.get_pixel(0, 0).0[3], px.get_pixel(10, 10).0[3]), (0, 255), "the white background is cleared, the red dot kept");
}
/// The labels the Contextual Task Bar draws in a headless frame (after one to lay it out), with
/// their rects; none while it isn't shown. The SVG loaders are installed so the icons draw as
/// images instead of egui's ⚠ placeholder, which the label list would otherwise pick up.
+3
View File
@@ -159,6 +159,9 @@ pub fn show(app: &mut VectorcraftApp, ui: &mut Ui) {
crate::panels::image_trace::trace_button(app, ui, ui.available_width());
actions.push((tl!("Crop Image"), "ui.cropImage"));
actions.push((tl!("Mask"), "object.maskImage"));
// Remove Background at once with its defaults, as the reference app's Quick Actions do
// (<https://community.adobe.com/announcements-651/ai-powered-image-editing-features-in-illustrator-1624061>).
actions.push((tl!("Remove Background"), crate::addons::image::REMOVE_BACKGROUND));
}
// Object › Path's Offset Path and Simplify take paths: type alone could only fail, and offsets
// live through the Appearance panel's Effect › Path › Offset Path (#2238).
+7 -3
View File
@@ -577,8 +577,8 @@ pub fn image_summary(i: &Value) -> (String, String) {
}
/// The Control bar for the one selected image: Linked File or Embedded, its file name, colour mode
/// and effective resolution, Embed or Unembed, Edit Original (a linked file), Image Trace, Mask and
/// Crop Image. Whether one image is selected.
/// and effective resolution, Embed or Unembed, Edit Original (a linked file), Image Trace, Mask,
/// Crop Image and Remove Background. Whether one image is selected.
pub fn control_bar_details(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool {
let Some(i) = selected_image_info(app) else { return false };
let (name, details) = image_summary(i);
@@ -595,7 +595,11 @@ pub fn control_bar_details(app: &mut VectorcraftApp, ui: &mut egui::Ui) -> bool
ui.separator();
link_buttons(app, ui, id, linked, &name, None);
crate::panels::image_trace::trace_button(app, ui, crate::panels::image_trace::TRACE_BUTTON_W);
for (label, cmd, w) in [(tl!("Mask"), "object.maskImage", 52.0), (tl!("Crop Image"), "ui.cropImage", 84.0)] {
for (label, cmd, w) in [
(tl!("Mask"), "object.maskImage", 52.0),
(tl!("Crop Image"), "ui.cropImage", 84.0),
(tl!("Remove Background"), crate::addons::image::REMOVE_BACKGROUND, 128.0),
] {
if widgets::flat_button(ui, label, w).clicked() {
crate::menus::invoke(app, cmd, json!({}));
}
+1 -1
View File
@@ -2000,7 +2000,7 @@ A VectorCraft addition (it replaces a script some users ran), so no area score m
## Image Tools add-on: Remove Background (2026-11-11)
A VectorCraft addition, so no area score moves. Object › Plug-ins › Image Tools › Remove Background… (`addon.image.removeBackground`) makes the background of the selected images transparent in their own pixels, in the app with no service or model. The background is the most common edge color (nothing is cleared when the edges hold at least as many clear pixels as pixels of that color), the average of the corners that are not clear, or picked colors. Contiguous (on by default) clears it only where it reaches in from an edge; off, it is cleared everywhere. Tolerance and Softness (0 to 100, 10 by default, VectorCraft's own values) set how near a color is cleared and the band over which pixels fade out, measured as RGB distance or, with Match set to Each Channel, as the largest difference on one channel. The run is one undo step, and none is recorded when no pixel changes. The image stays an image: a PNG with alpha at its own bit depth, gray or color as it was, with its color profile and resolution, and a linked image is embedded. CMYK images, linked images that show their preview, images that would need more than the decode allowance and results with no pixel left are refused. The dialog's Preview works as Release Type on a Path's does; its preview steps decode an image once, and the decoded pixels are released when the dialog closes. Tests: `cmd::addons::image::tests` in `vectorcraft-engine` (edge, corner and picked colors, contiguous on and off, a second run, tolerance and softness by distance and by channel, 16-bit and gray images, the color profile and resolution kept, an image read at another size, linked images, refusals and bad params, and decoded pixels reused across preview steps and released at OK and Cancel), `addons::image::tests::remove_background_previews_cancels_and_runs_on_ok` in `vectorcraft-ui-egui` and `command_sweep`. Commands: `docs/mcp.md` › Image Tools add-on.
A VectorCraft addition, so no area score moves. Object › Plug-ins › Image Tools › Remove Background… (`addon.image.removeBackground`) makes the background of the selected images transparent in their own pixels, in the app with no service or model. The background is the most common edge color (nothing is cleared when the edges hold at least as many clear pixels as pixels of that color), the average of the corners that are not clear, or picked colors. Contiguous (on by default) clears it only where it reaches in from an edge; off, it is cleared everywhere. Tolerance and Softness (0 to 100, 10 by default, VectorCraft's own values) set how near a color is cleared and the band over which pixels fade out, measured as RGB distance or, with Match set to Each Channel, as the largest difference on one channel. The run is one undo step, and none is recorded when no pixel changes. The image stays an image: a PNG with alpha at its own bit depth, gray or color as it was, with its color profile and resolution, and a linked image is embedded. CMYK images, linked images that show their preview, images that would need more than the decode allowance and results with no pixel left are refused. The dialog's Preview works as Release Type on a Path's does; its preview steps decode an image once, and the decoded pixels are released when the dialog closes. Tests: `cmd::addons::image::tests` in `vectorcraft-engine` (edge, corner and picked colors, contiguous on and off, a second run, tolerance and softness by distance and by channel, 16-bit and gray images, the color profile and resolution kept, an image read at another size, linked images, refusals and bad params, and decoded pixels reused across preview steps and released at OK and Cancel), `addons::image::tests::remove_background_previews_cancels_and_runs_on_ok` in `vectorcraft-ui-egui` and `command_sweep`. Commands: `docs/mcp.md` › Image Tools add-on. Since 2026-11-12 a selected image also offers Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar, where the reference app offers it (<https://community.adobe.com/announcements-651/ai-powered-image-editing-features-in-illustrator-1624061>); a click runs it at once with the defaults, as one undo step (tests `canvas::tests::the_task_bar_removes_a_selected_images_background` and `addons::image::tests::properties_and_the_control_bar_remove_the_background_at_once`).
## Color Effects add-on: Find Nearest Swatch (2026-11-01)
+2 -1
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-12 · **Change:** minor (Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #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)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-12 · **Change:** minor (Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar; previously minor: Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #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)
>
> Vector Halftone preview update (2026-11-10): temporary dot selection marks are hidden, and the bounding box stays available (#6369).
>
@@ -520,6 +520,7 @@ before release (#6373). [Paint faces and edges](https://helpx.adobe.com/illustra
| Date | Change | Summary |
|---|---|---|
| 2026-11-12 | minor | Remove Background for a selected image in the Contextual Task Bar, Properties › Quick Actions and the Control bar, which runs at once with its defaults. Scores and estimates unchanged. |
| 2026-11-12 | minor | Live Paint Bucket fills faces crossed in one drag (#6373). Scores and estimates unchanged. |
| 2026-11-11 | minor | Ruler origin: the corner drag snaps as a drawn point does, onto the art's and the artboards' anchors, centres, edges and paths, and with Snap to Point along the ruler guides; scores and estimates unchanged |
| 2026-11-11 | minor | Eyedropper copies effective character dimensions between transformed text objects (#6404); scores and estimates unchanged. |