Merge pull request #6293 from slafebre/fix/new-art-colorized-image

Follow-up to #6252: a selected colorized image gives new art its fill
This commit is contained in:
BFlat
2026-11-09 17:05:00 +08:00
committed by GitHub
3 changed files with 23 additions and 5 deletions
+5 -3
View File
@@ -217,13 +217,15 @@ impl Session {
/// After a command changed the selection, with New Art Has Basic Appearance on: the fill and
/// stroke proxies and the weight take what the selection shows in them, so new art looks like
/// it. A paint the selected objects don't share (a "?" proxy) stays as it was, and art without
/// paint (a placed image, whose None would make new art invisible) changes nothing. The
/// template is left alone, and without a stroke to show the weight stays too.
/// paint (a placed image that isn't colorized, whose None would make new art invisible) changes
/// nothing. The template is left alone, and without a stroke to show the weight stays too.
pub(crate) fn load_selection_paints(&mut self) {
if !self.prefs.new_art_basic {
return;
}
let has_paint = self.proxy_source(false).is_some_and(|(n, _)| matches!(n.kind, NodeKind::Text(_)) || !n.appearance.items.is_empty());
let has_paint = self
.proxy_source(false)
.is_some_and(|(n, _)| matches!(n.kind, NodeKind::Text(_)) || !n.appearance.items.is_empty() || n.extras().colorize.is_some());
if !has_paint {
return;
}
+16
View File
@@ -173,6 +173,22 @@ fn blend_recolors_a_colorized_gray_image_without_alpha() {
assert_eq!(colorize(&s, middle), Some(Paint::solid(Color::rgb(0.5, 0.5, 0.5))));
}
/// A colorized image shows a fill and no stroke, so selecting it loads them for new art as any
/// object without a stroke does (the weight stays).
#[test]
fn selecting_a_colorized_image_gives_new_art_its_fill_and_no_stroke() {
let mut s = session();
let id = image(&mut s, "gray", gray(false));
s.execute("paint.setFill", &json!({"color": "#336699"})).unwrap();
s.execute("select.none", &json!({})).unwrap();
s.execute("paint.setFill", &json!({"color": "#ff0000"})).unwrap();
s.execute("paint.setStroke", &json!({"color": "#00ff00"})).unwrap();
s.execute("stroke.set", &json!({"weight": 5.0})).unwrap();
s.execute("select.set", &json!({"ids": [id.0]})).unwrap();
assert_eq!(s.paint.fill.color().map(|c| c.to_hex()), Some("#336699".into()));
assert_eq!((s.paint.stroke.clone(), s.paint.stroke_width), (Paint::None, 5.0));
}
#[test]
fn fill_proxy_invert_recolors_a_colorized_gray_image_and_undo_restores_it() {
let mut s = session();
+2 -2
View File
@@ -4199,8 +4199,8 @@ selected) on top of a template. With nothing selected, `stroke.set` / `stroke.se
arrowheads, profile…) and `graphicStyle.apply` (every fill, stroke and effect, opacity, blend mode and the link to the
style; `add: true` stacks it) set that template instead of editing art. With the Appearance panel's New Art Has Basic
Appearance on (the default), a `select.*` command or `layer.target` that changes the selection loads the proxies and
the weight from it: only a paint or weight the selected objects share, and art without paint (a placed image) changes
nothing. With the option off (`appearance.setNewArtBasic {on: false}`, the preference `newArtBasic`) new art takes the
the weight from it: only a paint or weight the selected objects share, and art without paint (a placed image that isn't
colorized) changes nothing. With the option off (`appearance.setNewArtBasic {on: false}`, the preference `newArtBasic`) new art takes the
whole appearance of the last selected object. `appearance.newArt` reports what the next object gets; `paint.default`
resets it.
`appearance.setNewArtBasic` rejects an `on` value that is not a boolean. Omitting `on` toggles the current preference.