Merge pull request #4699 from storytold/feat/addon-color-select

Add-ons: Color Effects — select by color kind (spot colors, color effects, RGB, CMYK and grayscale images)
This commit is contained in:
BFlat
2026-10-30 19:02:12 +07:00
committed by GitHub
31 changed files with 404 additions and 16 deletions
+83 -12
View File
@@ -1,28 +1,99 @@
//! Color Effects (`addon.color.*`), a built-in add-on: its live effects (Exposure, Desaturate and
//! Invert Colors, in Effect › Color Effects) are the effects crate's; here, Apply as Filter writes
//! any colour adjustment into the colours themselves. Its panel and its submenu, Object › Plug-ins ›
//! Color Effects, are the UI's.
//! any colour adjustment into the colours themselves, and Select by Color Kind selects the objects
//! that use spot colours, carry a live colour adjustment, or are images of a colour model. Its panel
//! and its submenu, Object › Plug-ins › Color Effects, are the UI's.
#[cfg(test)]
mod tests;
use serde_json::{Value, json};
use vectorcraft_doc::{Document, Node, NodeId, NodeKind};
use vectorcraft_render::effects;
use super::super::colorcmds::recolor;
use super::super::{CommandSpec, bad, checked_ids_or_selection, cmd, has_selection, text_param};
use super::super::select::walk_selectable;
use super::super::{CommandSpec, bad, checked_ids_or_selection, cmd, has_doc, has_selection, text_param};
use crate::{Result, Session};
/// The kinds Select by Color Kind selects (`addon.color.select`).
pub const SELECT_KINDS: [&str; 5] = ["spotColors", "colorEffects", "rgbImages", "cmykImages", "grayImages"];
pub fn specs() -> Vec<CommandSpec> {
vec![cmd!(
"addon.color.filter",
"Apply as Filter",
["Object", "Plug-ins", "Color Effects"],
None,
"{effect: a colour adjustment's effect id (adjust.brightnessContrast, adjust.curves, adjust.hueSaturation, adjust.levels, adjust.shiftToColor, adjust.temperatureTint, addon.color.exposure, addon.color.desaturate or addon.color.invert), params?: {…} (as effect.apply; missing keys take the dialog defaults), fill?: true, stroke?: true, includeImages?: true, includePatterns?: true, ids?: [id…] (default: the selection)} recolour the objects and everything inside them as the live effect would draw them, but in their colours, as edit.colors.invert does (fills, strokes, type, gradient meshes, embedded images and pattern tiles), as one undo step; their effects stay → {changed}",
has_selection,
filter
)]
vec![
cmd!(
"addon.color.select",
"Select by Color Kind",
["Object", "Plug-ins", "Color Effects"],
None,
"{kind: \"spotColors\" (objects painted with a spot colour swatch, solid or in a gradient's stops) | \"colorEffects\" (objects carrying a visible colour adjustment effect, on themselves or on a fill or stroke) | \"rgbImages\" | \"cmykImages\" | \"grayImages\" (embedded or linked images whose pixels are RGB, CMYK, or grayscale or 1-bit)} select those objects among the ones Select All reaches, inside groups too; locked and hidden ones are left out → {count}",
has_doc,
select
),
cmd!(
"addon.color.filter",
"Apply as Filter",
["Object", "Plug-ins", "Color Effects"],
None,
"{effect: a colour adjustment's effect id (adjust.brightnessContrast, adjust.curves, adjust.hueSaturation, adjust.levels, adjust.shiftToColor, adjust.temperatureTint, addon.color.exposure, addon.color.desaturate or addon.color.invert), params?: {…} (as effect.apply; missing keys take the dialog defaults), fill?: true, stroke?: true, includeImages?: true, includePatterns?: true, ids?: [id…] (default: the selection)} recolour the objects and everything inside them as the live effect would draw them, but in their colours, as edit.colors.invert does (fills, strokes, type, gradient meshes, embedded images and pattern tiles), as one undo step; their effects stay → {changed}",
has_selection,
filter
),
]
}
fn select(s: &mut Session, p: &Value) -> Result<Value> {
const C: &str = "addon.color.select";
let kind = text_param(p, "kind", C)?.ok_or_else(|| bad(C, "missing `kind`"))?;
if !SELECT_KINDS.contains(&kind) {
return Err(bad(C, "`kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages"));
}
let st = s.doc()?;
let mut ids: Vec<NodeId> = vec![];
walk_selectable(&st.doc, st.isolation, |n| {
if is_of_kind(&st.doc, n, kind) {
ids.push(n.id);
// An object taken whole: what is inside it isn't taken again.
return false;
}
true
});
s.select(|_, sel| sel.set(ids))?;
Ok(json!({ "count": s.doc()?.selection.objects.len() }))
}
/// Is `n` an object of Select by Color Kind's `kind`? Containers count for colour effects only:
/// for the other kinds, the objects inside them are looked at one by one.
fn is_of_kind(d: &Document, n: &Node, kind: &str) -> bool {
match kind {
"colorEffects" => effects::has_adjustment(n),
"spotColors" if !n.is_container() => {
let mut spot = false;
vectorcraft_doc::swatches::node_colors(n, &mut |_, swatch| {
spot |= swatch.is_some_and(|name| d.swatch(name).is_some_and(|w| w.spot));
});
spot
}
_ => {
let NodeKind::Image(img) = &n.kind else { return false };
let Some(blob) = d.images.get(&img.key) else { return false };
let model = if blob.is_cmyk() {
"cmykImages"
} else if is_gray(&blob.bytes) {
"grayImages"
} else {
"rgbImages"
};
model == kind
}
}
}
/// Are the encoded image `bytes` grayscale or 1-bit? Reads only the header.
fn is_gray(bytes: &[u8]) -> bool {
use image::ImageDecoder as _;
let decoder = image::ImageReader::new(std::io::Cursor::new(bytes)).with_guessed_format().ok().and_then(|r| r.into_decoder().ok());
decoder.is_some_and(|d| matches!(d.color_type(), image::ColorType::L8 | image::ColorType::La8 | image::ColorType::L16 | image::ColorType::La16))
}
fn filter(s: &mut Session, p: &Value) -> Result<Value> {
@@ -87,3 +87,70 @@ fn bad_requests_are_refused() {
s.execute("select.none", &json!({})).unwrap();
assert!(s.execute("addon.color.filter", &json!({"effect": "addon.color.invert"})).is_err(), "nothing selected");
}
/// An embedded image object of `blob`, selected.
fn image(s: &mut Session, key: &str, blob: vectorcraft_doc::ImageBlob, x: f64) -> NodeId {
s.edit("Place", |d, sel| {
d.images.insert(key.into(), blob);
let id = d.alloc_id();
let im = vectorcraft_doc::ImageObject {
key: key.into(),
width: 4,
height: 4,
xf: vectorcraft_geom::Affine::translate((x, 0.0)) * vectorcraft_geom::Affine::scale(10.0),
link: None,
placement: Default::default(),
pixels: None,
};
d.insert(d.default_layer(), 0, vectorcraft_doc::Node::new(id, vectorcraft_doc::NodeKind::Image(Box::new(im))))?;
sel.set([id]);
Ok(id)
})
.unwrap()
}
fn png(img: image::DynamicImage) -> vectorcraft_doc::ImageBlob {
let mut bytes = vec![];
img.write_to(&mut std::io::Cursor::new(&mut bytes), image::ImageFormat::Png).unwrap();
vectorcraft_doc::ImageBlob::png(bytes)
}
fn selected(s: &Session) -> Vec<NodeId> {
s.doc().unwrap().selection.objects.clone()
}
#[test]
fn select_by_color_kind_finds_spot_colours_effects_and_image_models() {
let (mut s, plain) = red_rect();
// A spot colour, inside a group: the path is taken, not the group.
s.execute("swatch.new", &json!({"name": "Gold", "color": {"model": "cmyk", "c": 0.0, "m": 0.2, "y": 0.8, "k": 0.1}, "spot": true})).unwrap();
let spot = NodeId(s.execute("shape.rectangle", &json!({"x": 100, "y": 20, "width": 30, "height": 30})).unwrap()["id"].as_u64().unwrap());
s.execute("paint.setFill", &json!({"swatch": "Gold"})).unwrap();
s.execute("object.group", &json!({})).unwrap();
// A live colour adjustment.
let adjusted = NodeId(s.execute("shape.rectangle", &json!({"x": 140, "y": 20, "width": 30, "height": 30})).unwrap()["id"].as_u64().unwrap());
// Its own colour: setting the spot fill made it the default for new art too.
s.execute("paint.setFill", &json!({"color": "#00ff00"})).unwrap();
s.execute("effect.apply", &json!({"effect": "addon.color.invert"})).unwrap();
let rgb = image(&mut s, "rgb", png(image::DynamicImage::ImageRgb8(image::RgbImage::new(4, 4))), 0.0);
let gray = image(&mut s, "gray", png(image::DynamicImage::ImageLuma8(image::GrayImage::new(4, 4))), 50.0);
let inks = vectorcraft_doc::cmyk::Inks::new(4, 4, vec![0; 64]).unwrap();
let cmyk = image(&mut s, "cmyk", vectorcraft_doc::ImageBlob::cmyk_tiff(&inks).unwrap(), 100.0);
for (kind, ids) in [
("spotColors", vec![spot]),
("colorEffects", vec![adjusted]),
("rgbImages", vec![rgb]),
("grayImages", vec![gray]),
("cmykImages", vec![cmyk]),
] {
let v = s.execute("addon.color.select", &json!({"kind": kind})).unwrap();
assert_eq!((selected(&s), v["count"].clone()), (ids.clone(), json!(ids.len())), "{kind}");
}
// Locked objects are left out; none found selects nothing.
s.execute("select.set", &json!({"ids": [spot.0]})).unwrap();
s.execute("object.lock", &json!({})).unwrap();
assert_eq!(s.execute("addon.color.select", &json!({"kind": "spotColors"})).unwrap()["count"], 0);
assert!(!selected(&s).contains(&plain));
assert!(s.execute("addon.color.select", &json!({"kind": "pantone"})).is_err());
assert!(s.execute("addon.color.select", &json!({})).is_err());
}
+14
View File
@@ -75,6 +75,20 @@ pub fn menu() -> Vec<Item> {
Item::Cmd("Exposure…", "effect.dialog", json!({ "effect": "addon.color.exposure" })),
Item::Cmd("Desaturate", "effect.apply", json!({ "effect": "addon.color.desaturate" })),
Item::Cmd("Invert Colors", "effect.apply", json!({ "effect": "addon.color.invert" })),
Item::Sep,
Item::Sub(
"Select by Color Kind",
[
("Objects with Spot Colors", "spotColors"),
("Objects with Color Effects", "colorEffects"),
("RGB Images", "rgbImages"),
("CMYK Images", "cmykImages"),
("Grayscale Images", "grayImages"),
]
.into_iter()
.map(|(label, kind)| Item::Cmd(label, "addon.color.select", json!({ "kind": kind })))
.collect(),
),
]
}
+9
View File
@@ -5709,3 +5709,12 @@ anchor Points: Точки:
@msg `segment` must be "straight" or "curved" `segment` трябва да е "straight" или "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` трябва да е "free", "keepAngles" или "symmetric"
@msg `{key}` must be [x, y] `{key}` трябва да е [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Избиране по вид цвят
Objects with Spot Colors Обекти с плакатни цветове
Objects with Color Effects Обекти с цветови ефекти
RGB Images RGB изображения
CMYK Images CMYK изображения
Grayscale Images Изображения в нюанси на сивото
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` трябва да е spotColors, colorEffects, rgbImages, cmykImages или grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5810,3 +5810,12 @@ anchor Points: Punts:
@msg `segment` must be "straight" or "curved" `segment` ha de ser "straight" o "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` ha de ser "free", "keepAngles" o "symmetric"
@msg `{key}` must be [x, y] `{key}` ha de ser [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Selecciona per tipus de color
Objects with Spot Colors Objectes amb colors directes
Objects with Color Effects Objectes amb efectes de color
RGB Images Imatges RGB
CMYK Images Imatges CMYK
Grayscale Images Imatges en escala de grisos
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` ha de ser spotColors, colorEffects, rgbImages, cmykImages o grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5819,3 +5819,12 @@ anchor Points: Body:
@msg `segment` must be "straight" or "curved" `segment` musí být "straight" nebo "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` musí být "free", "keepAngles" nebo "symmetric"
@msg `{key}` must be [x, y] `{key}` musí být [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Vybrat podle druhu barvy
Objects with Spot Colors Objekty s přímými barvami
Objects with Color Effects Objekty s barevnými efekty
RGB Images Obrazy RGB
CMYK Images Obrazy CMYK
Grayscale Images Obrazy ve stupních šedi
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` musí být spotColors, colorEffects, rgbImages, cmykImages nebo grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5724,3 +5724,12 @@ anchor Points: Punkter:
@msg `segment` must be "straight" or "curved" `segment` skal være "straight" eller "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` skal være "free", "keepAngles" eller "symmetric"
@msg `{key}` must be [x, y] `{key}` skal være [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Markér efter farvetype
Objects with Spot Colors Objekter med spotfarver
Objects with Color Effects Objekter med farveeffekter
RGB Images RGB-billeder
CMYK Images CMYK-billeder
Grayscale Images Gråtonebilleder
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` skal være spotColors, colorEffects, rgbImages, cmykImages eller grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5402,3 +5402,12 @@ anchor Points: Punkte:
@msg `segment` must be "straight" or "curved" `segment` muss "straight" oder "curved" sein
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` muss "free", "keepAngles" oder "symmetric" sein
@msg `{key}` must be [x, y] `{key}` muss [x, y] sein
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Nach Farbart auswählen
Objects with Spot Colors Objekte mit Volltonfarben
Objects with Color Effects Objekte mit Farbeffekten
RGB Images RGB-Bilder
CMYK Images CMYK-Bilder
Grayscale Images Graustufenbilder
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` muss spotColors, colorEffects, rgbImages, cmykImages oder grayImages sein
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5771,3 +5771,12 @@ anchor Points: Σημεία:
@msg `segment` must be "straight" or "curved" Το `segment` πρέπει να είναι "straight" ή "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" Το `mode` πρέπει να είναι "free", "keepAngles" ή "symmetric"
@msg `{key}` must be [x, y] Το `{key}` πρέπει να είναι [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Επιλογή κατά είδος χρώματος
Objects with Spot Colors Αντικείμενα με χρώματα spot
Objects with Color Effects Αντικείμενα με εφέ χρώματος
RGB Images Εικόνες RGB
CMYK Images Εικόνες CMYK
Grayscale Images Εικόνες σε κλίμακα του γκρι
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages Το `kind` πρέπει να είναι spotColors, colorEffects, rgbImages, cmykImages ή grayImages
Can't render this file because it contains an unexpected character in line 164 and column 5.
+9
View File
@@ -5762,3 +5762,12 @@ anchor Points: Puntos:
@msg `segment` must be "straight" or "curved" `segment` debe ser "straight" o "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` debe ser "free", "keepAngles" o "symmetric"
@msg `{key}` must be [x, y] `{key}` debe ser [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Seleccionar por tipo de color
Objects with Spot Colors Objetos con tintas planas
Objects with Color Effects Objetos con efectos de color
RGB Images Imágenes RGB
CMYK Images Imágenes CMYK
Grayscale Images Imágenes en escala de grises
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` debe ser spotColors, colorEffects, rgbImages, cmykImages o grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5850,3 +5850,12 @@ anchor Points: Pisteet:
@msg `segment` must be "straight" or "curved" `segment` on oltava "straight" tai "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` on oltava "free", "keepAngles" tai "symmetric"
@msg `{key}` must be [x, y] `{key}` on oltava [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Valitse värityypin mukaan
Objects with Spot Colors Objektit, joissa on spottivärejä
Objects with Color Effects Objektit, joissa on väritehosteita
RGB Images RGB-kuvat
CMYK Images CMYK-kuvat
Grayscale Images Harmaasävykuvat
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` on oltava spotColors, colorEffects, rgbImages, cmykImages tai grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5818,3 +5818,12 @@ anchor Points: Points :
@msg `segment` must be "straight" or "curved" `segment` doit être "straight" ou "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` doit être "free", "keepAngles" ou "symmetric"
@msg `{key}` must be [x, y] `{key}` doit être [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Sélectionner par type de couleur
Objects with Spot Colors Objets avec tons directs
Objects with Color Effects Objets avec effets de couleur
RGB Images Images RVB
CMYK Images Images CMJN
Grayscale Images Images en niveaux de gris
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` doit être spotColors, colorEffects, rgbImages, cmykImages ou grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5806,3 +5806,12 @@ anchor Points: Pontok:
@msg `segment` must be "straight" or "curved" `segment`: "straight" vagy "curved" kell
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode`: "free", "keepAngles" vagy "symmetric" kell
@msg `{key}` must be [x, y] `{key}`: [x, y] kell
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Kijelölés színtípus szerint
Objects with Spot Colors Direkt színeket használó objektumok
Objects with Color Effects Színeffektusos objektumok
RGB Images RGB-képek
CMYK Images CMYK-képek
Grayscale Images Szürkeárnyalatos képek
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages A `kind` értéke spotColors, colorEffects, rgbImages, cmykImages vagy grayImages lehet
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5724,3 +5724,12 @@ anchor Points: Titik:
@msg `segment` must be "straight" or "curved" `segment` harus "straight" atau "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` harus "free", "keepAngles" atau "symmetric"
@msg `{key}` must be [x, y] `{key}` harus [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Pilih menurut Jenis Warna
Objects with Spot Colors Objek dengan Warna Spot
Objects with Color Effects Objek dengan Efek Warna
RGB Images Gambar RGB
CMYK Images Gambar CMYK
Grayscale Images Gambar Skala Abu-abu
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` harus spotColors, colorEffects, rgbImages, cmykImages, atau grayImages
Can't render this file because it contains an unexpected character in line 2169 and column 5.
+9
View File
@@ -5436,3 +5436,12 @@ anchor Points: Punti:
@msg `segment` must be "straight" or "curved" `segment` deve essere "straight" o "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` deve essere "free", "keepAngles" o "symmetric"
@msg `{key}` must be [x, y] `{key}` deve essere [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Seleziona per tipo di colore
Objects with Spot Colors Oggetti con colori spot
Objects with Color Effects Oggetti con effetti colore
RGB Images Immagini RGB
CMYK Images Immagini CMYK
Grayscale Images Immagini in scala di grigi
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` deve essere spotColors, colorEffects, rgbImages, cmykImages o grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5505,3 +5505,12 @@ anchor Points: ポイント:
@msg `segment` must be "straight" or "curved" `segment` には "straight" または "curved" を指定してください
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` には "free"、"keepAngles" または "symmetric" を指定してください
@msg `{key}` must be [x, y] `{key}` には [x, y] を指定してください
# Color Effects add-on: Select by Color Kind.
Select by Color Kind カラーの種類で選択
Objects with Spot Colors 特色を使用したオブジェクト
Objects with Color Effects カラー効果のあるオブジェクト
RGB Images RGB 画像
CMYK Images CMYK 画像
Grayscale Images グレースケール画像
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` は spotColors、colorEffects、rgbImages、cmykImages、grayImages のいずれかにしてください
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5809,3 +5809,12 @@ anchor Points: წერტილები:
@msg `segment` must be "straight" or "curved" `segment` უნდა იყოს "straight" ან "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` უნდა იყოს "free", "keepAngles" ან "symmetric"
@msg `{key}` must be [x, y] `{key}` უნდა იყოს [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind ფერის სახეობით არჩევა
Objects with Spot Colors ობიექტები სპოტ-ფერებით
Objects with Color Effects ობიექტები ფერის ეფექტებით
RGB Images RGB გამოსახულებები
CMYK Images CMYK გამოსახულებები
Grayscale Images ნაცრისფერის გრადაციის გამოსახულებები
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` უნდა იყოს spotColors, colorEffects, rgbImages, cmykImages ან grayImages
Can't render this file because it is too large.
+9
View File
@@ -5399,3 +5399,12 @@ anchor Points: 포인트:
@msg `segment` must be "straight" or "curved" `segment`는 "straight" 또는 "curved"여야 합니다
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode`는 "free", "keepAngles" 또는 "symmetric"이어야 합니다
@msg `{key}` must be [x, y] `{key}`은(는) [x, y]여야 합니다
# Color Effects add-on: Select by Color Kind.
Select by Color Kind 색상 종류로 선택
Objects with Spot Colors 별색을 사용한 개체
Objects with Color Effects 색상 효과가 있는 개체
RGB Images RGB 이미지
CMYK Images CMYK 이미지
Grayscale Images 회색 음영 이미지
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind`는 spotColors, colorEffects, rgbImages, cmykImages 또는 grayImages여야 합니다
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5768,3 +5768,12 @@ anchor Points: Punten:
@msg `segment` must be "straight" or "curved" `segment` moet "straight" of "curved" zijn
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` moet "free", "keepAngles" of "symmetric" zijn
@msg `{key}` must be [x, y] `{key}` moet [x, y] zijn
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Selecteren op kleursoort
Objects with Spot Colors Objecten met steunkleuren
Objects with Color Effects Objecten met kleureffecten
RGB Images RGB-afbeeldingen
CMYK Images CMYK-afbeeldingen
Grayscale Images Grijswaardenafbeeldingen
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` moet spotColors, colorEffects, rgbImages, cmykImages of grayImages zijn
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5674,3 +5674,12 @@ anchor Points: Punkty:
@msg `segment` must be "straight" or "curved" `segment` musi mieć wartość "straight" lub "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` musi mieć wartość "free", "keepAngles" lub "symmetric"
@msg `{key}` must be [x, y] `{key}` musi mieć postać [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Zaznacz według rodzaju koloru
Objects with Spot Colors Obiekty z kolorami dodatkowymi
Objects with Color Effects Obiekty z efektami koloru
RGB Images Obrazy RGB
CMYK Images Obrazy CMYK
Grayscale Images Obrazy w skali szarości
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` musi mieć wartość spotColors, colorEffects, rgbImages, cmykImages lub grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5737,3 +5737,12 @@ anchor Points: Pontos:
@msg `segment` must be "straight" or "curved" `segment` deve ser "straight" ou "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` deve ser "free", "keepAngles" ou "symmetric"
@msg `{key}` must be [x, y] `{key}` deve ser [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Selecionar por tipo de cor
Objects with Spot Colors Objetos com cores spot
Objects with Color Effects Objetos com efeitos de cor
RGB Images Imagens RGB
CMYK Images Imagens CMYK
Grayscale Images Imagens em escala de cinza
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` deve ser spotColors, colorEffects, rgbImages, cmykImages ou grayImages
Can't render this file because it contains an unexpected character in line 6 and column 47.
+9
View File
@@ -5797,3 +5797,12 @@ anchor Points: Точки:
@msg `segment` must be "straight" or "curved" `segment` должно быть "straight" или "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` должно быть "free", "keepAngles" или "symmetric"
@msg `{key}` must be [x, y] `{key}` должно быть [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Выделить по типу цвета
Objects with Spot Colors Объекты с плашечными цветами
Objects with Color Effects Объекты с цветовыми эффектами
RGB Images Изображения RGB
CMYK Images Изображения CMYK
Grayscale Images Изображения в оттенках серого
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` должен быть spotColors, colorEffects, rgbImages, cmykImages или grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5843,3 +5843,12 @@ anchor Points: Punkter:
@msg `segment` must be "straight" or "curved" `segment` måste vara "straight" eller "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` måste vara "free", "keepAngles" eller "symmetric"
@msg `{key}` must be [x, y] `{key}` måste vara [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Markera efter färgtyp
Objects with Spot Colors Objekt med dekorfärger
Objects with Color Effects Objekt med färgeffekter
RGB Images RGB-bilder
CMYK Images CMYK-bilder
Grayscale Images Gråskalebilder
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` måste vara spotColors, colorEffects, rgbImages, cmykImages eller grayImages
Can't render this file because it contains an unexpected character in line 5 and column 25.
+9
View File
@@ -5777,3 +5777,12 @@ anchor Points: Noktalar:
@msg `segment` must be "straight" or "curved" `segment` "straight" veya "curved" olmalıdır
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` "free", "keepAngles" veya "symmetric" olmalıdır
@msg `{key}` must be [x, y] `{key}` [x, y] olmalıdır
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Renk Türüne Göre Seç
Objects with Spot Colors Spot Renkli Nesneler
Objects with Color Effects Renk Efektli Nesneler
RGB Images RGB Görüntüler
CMYK Images CMYK Görüntüler
Grayscale Images Gri Tonlamalı Görüntüler
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` değeri spotColors, colorEffects, rgbImages, cmykImages veya grayImages olmalıdır
Can't render this file because it contains an unexpected character in line 5 and column 25.
+9
View File
@@ -5416,3 +5416,12 @@ anchor Points: Точки:
@msg `segment` must be "straight" or "curved" `segment` має бути "straight" або "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` має бути "free", "keepAngles" або "symmetric"
@msg `{key}` must be [x, y] `{key}` має бути [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Виділити за типом кольору
Objects with Spot Colors Об’єкти з плашковими кольорами
Objects with Color Effects Об’єкти з колірними ефектами
RGB Images Зображення RGB
CMYK Images Зображення CMYK
Grayscale Images Зображення у відтінках сірого
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` має бути spotColors, colorEffects, rgbImages, cmykImages або grayImages
Can't render this file because it contains an unexpected character in line 178 and column 5.
+9
View File
@@ -5418,3 +5418,12 @@ anchor Points: Điểm:
@msg `segment` must be "straight" or "curved" `segment` phải là "straight" hoặc "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` phải là "free", "keepAngles" hoặc "symmetric"
@msg `{key}` must be [x, y] `{key}` phải là [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind Chọn theo loại màu
Objects with Spot Colors Đối tượng có màu pha
Objects with Color Effects Đối tượng có hiệu ứng màu
RGB Images Ảnh RGB
CMYK Images Ảnh CMYK
Grayscale Images Ảnh thang độ xám
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` phải là spotColors, colorEffects, rgbImages, cmykImages hoặc grayImages
Can't render this file because it contains an unexpected character in line 200 and column 5.
+9
View File
@@ -5659,3 +5659,12 @@ anchor Points: 点:
@msg `segment` must be "straight" or "curved" `segment` 必须是 "straight" 或 "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` 必须是 "free"、"keepAngles" 或 "symmetric"
@msg `{key}` must be [x, y] `{key}` 必须是 [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind 按颜色类型选择
Objects with Spot Colors 使用专色的对象
Objects with Color Effects 带颜色效果的对象
RGB Images RGB 图像
CMYK Images CMYK 图像
Grayscale Images 灰度图像
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` 必须是 spotColors、colorEffects、rgbImages、cmykImages 或 grayImages
Can't render this file because it contains an unexpected character in line 2 and column 73.
+9
View File
@@ -5455,3 +5455,12 @@ anchor Points: 點:
@msg `segment` must be "straight" or "curved" `segment` 必須是 "straight" 或 "curved"
@msg `mode` must be "free", "keepAngles" or "symmetric" `mode` 必須是 "free"、"keepAngles" 或 "symmetric"
@msg `{key}` must be [x, y] `{key}` 必須是 [x, y]
# Color Effects add-on: Select by Color Kind.
Select by Color Kind 依顏色類型選取
Objects with Spot Colors 使用特別色的物件
Objects with Color Effects 帶有顏色效果的物件
RGB Images RGB 影像
CMYK Images CMYK 影像
Grayscale Images 灰階影像
@msg `kind` must be spotColors, colorEffects, rgbImages, cmykImages or grayImages `kind` 必須是 spotColors、colorEffects、rgbImages、cmykImages 或 grayImages
Can't render this file because it contains an unexpected character in line 6 and column 47.
+7
View File
@@ -5854,3 +5854,10 @@ undo step. Missing `params` take the effect's dialog defaults; the objects' own
The panel picks an adjustment (Brightness/Contrast, Hue/Saturation, Levels, Temperature/Tint, Exposure, Desaturate or
Invert Colors), sets its values, and then Add as Effect (`effect.apply`) or Apply as Filter (`addon.color.filter`).
`addon.color.select {kind}` (Object › Plug-ins › Color Effects › Select by Color Kind) selects, among the objects Select
All reaches and the objects inside groups (locked and hidden ones left out), those of one kind: `spotColors` (painted
with a spot colour swatch, solid or in a gradient's stops), `colorEffects` (carrying a visible colour adjustment effect,
on the object or on one of its fills or strokes; a group carrying one is selected whole), `rgbImages`, `cmykImages` or
`grayImages` (images whose pixels are RGB, CMYK, or grayscale or 1-bit, read from the image's header). It returns the
`count` selected.
+5 -2
View File
@@ -1,6 +1,6 @@
# Parity with Adobe Illustrator
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Gradient stop popover: an eyedropper samples the stop's colour from the art (#4681); scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Color Effects add-on: Select by Color Kind; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x; public release notes through 30.7, August 2026)
## Feature submission evidence
@@ -1259,11 +1259,14 @@ to the colours themselves through the Edit Colors pass. Object › Plug-ins ›
Tests: `addons::color` in `vectorcraft-effects` (exposure in stops, desaturate keeps lightness, invert twice is
identity), `cmd::addons::color::tests` in `vectorcraft-engine` (drawn live without changing the colours; a filter as one
undo step, with any adjustment and its params; bad requests refused) and `addons::color::tests` in
`vectorcraft-ui-egui` (the menus and the panel). Commands: `docs/mcp.md` › Color Effects add-on.
`vectorcraft-ui-egui` (the menus and the panel). Select by Color Kind (`addon.color.select`) selects the objects that use
spot colours, carry a colour adjustment, or are RGB, CMYK or grayscale images
(`select_by_color_kind_finds_spot_colours_effects_and_image_models`). Commands: `docs/mcp.md` › Color Effects add-on.
## Revision history
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | Color Effects add-on: Select by Color Kind; scores and estimates unchanged |
| 2026-10-30 | minor | Gradient stop popover: an eyedropper samples the stop's colour from the art (#4681); scores and estimates unchanged |
| 2026-10-30 | minor | Full Screen and Presentation Mode fill the screen (#4365); scores and estimates unchanged |
| 2026-10-30 | minor | Place: a photo's EXIF orientation turns it upright (#4284); scores and estimates unchanged |
+3 -2
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (View › Hide Artboards hides their edges and shows the canvas as paper (#4038); scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-30 · **Change:** minor (Color Effects add-on: Select by Color Kind; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
## Feature submission evidence
@@ -326,7 +326,7 @@ next unit in the order a right-click on a ruler lists them, from Feet back to Po
| Smart Pen add-on (VectorCraft addition): Object › Plug-ins › Smart Pen selects the Smart Pen Tool, which the All Tools drawer lists under its own heading but neither toolbar shows as shipped (no shortcut), and opens the Smart Pen panel (next segment straight or curved; Remove Points Keep Shape, Make Smooth, Make Corner, Retract Handles, Close or Join). The tool draws (click: straight or curved segment, a curve after a straight one tangent; drag: smooth anchor, Alt breaks the handle, Shift 45°, Space moves it; Tab switches a segment; rubber band; close, join, continue) and edits without switching tools (click selects a point, drag moves it, Alt-click removes it keeping the shape, Shift+Alt-click deletes it, double-click toggles smooth/corner; handle drags with Shift and Alt; segment drags reshape, Alt-click adds a point) | done | `addon.pen.*`, `crates/tools/src/addons/smart_pen.rs`, `crates/ui-egui/src/addons/pen.rs` and their tests; not an Illustrator feature, so it is not scored |
| Path Precision Tools add-on (VectorCraft addition): Object › Plug-ins › Path Precision Tools selects its three tools (Anchor Eraser Brush, Extend Path, Measure & Inspect), which the All Tools drawer lists under their own heading but neither toolbar shows as shipped, opens the Anchor Inspector panel (the selected anchor's X/Y and handle lengths and angles as fields; Make Smooth, Make Corner, Equalize Handles, Remove Points Keep Shape, Add Points, the three ways to close) and runs Add Points at / Split at Crossings; a double-click on the brush or Extend Path tool opens its options | done | `addon.pathtools.*`, `crates/tools/src/addons/`, `crates/ui-egui/src/addons/pathtools.rs` and their tests; not an Illustrator feature, so it is not scored |
| Artwork Cleanup add-on (VectorCraft addition): Object › Plug-ins › Artwork Cleanup opens its panel, which checks the selection or the document for 16 kinds of issue, lists them with counts, and shows or fixes the picked rows or all of them, each fix one undo step; Simplify Anchors (Keep Shape), Rejoin Path Pieces and Deep Ungroup open their options first | done | `addon.cleanup.*`, `crates/ui-egui/src/addons/cleanup.rs` and its tests; not an Illustrator feature, so it is not scored |
| Color Effects add-on (VectorCraft addition): live Exposure, Desaturate and Invert Colors in Effect › Color Effects and Object › Plug-ins › Color Effects; its panel picks a colour adjustment and its values and adds it as a live effect or applies it as a filter, into the colours, as one undo step | done | `addon.color.*`, `crates/ui-egui/src/addons/color.rs` and its tests; not an Illustrator feature, so it is not scored |
| Color Effects add-on (VectorCraft addition): live Exposure, Desaturate and Invert Colors in Effect › Color Effects and Object › Plug-ins › Color Effects; its panel picks a colour adjustment and its values and adds it as a live effect or applies it as a filter, into the colours, as one undo step; Select by Color Kind selects the objects that use spot colours, carry colour effects, or are RGB, CMYK or grayscale images | done | `addon.color.*`, `crates/ui-egui/src/addons/color.rs` and its tests; not an Illustrator feature, so it is not scored |
## Look and feel
@@ -367,6 +367,7 @@ separate. Scores and hours unchanged. [Behavior and command details](development
| Date | Change | Summary |
|---|---|---|
| 2026-10-30 | minor | Color Effects add-on: Select by Color Kind; scores and estimates unchanged |
| 2026-10-30 | minor | View › Hide Artboards hides their edges and shows the canvas as paper (#4038); scores and estimates unchanged |
| 2026-10-30 | minor | Contextual task bar: stays up through a click on another object, hides only for a drag (#4681); scores and estimates unchanged |
| 2026-10-30 | minor | Draw Inside marks the corners of the object it draws into (#4319); scores and estimates unchanged |