From 1e21154e4d99d5dc2d06f0026348c949bd8f032e Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Mon, 9 Nov 2026 04:19:25 +0700 Subject: [PATCH] Symbols: symbol.instance.setAppearance refuses a fill or stroke an object does not draw Squashed from #6232 onto main. --- crates/effects/src/lib.rs | 4 +- crates/effects/src/reshape.rs | 8 +- crates/engine/src/cmd/brushsym.rs | 2 +- crates/engine/src/cmd/brushsym/dynamic.rs | 60 ++++ crates/engine/src/tests/dynamic_symbols.rs | 309 +++++++++++++++++++++ crates/ui-egui/src/i18n/bg.tsv | 10 + crates/ui-egui/src/i18n/bs.tsv | 10 + crates/ui-egui/src/i18n/ca.tsv | 10 + crates/ui-egui/src/i18n/cs.tsv | 10 + crates/ui-egui/src/i18n/da.tsv | 10 + crates/ui-egui/src/i18n/de.tsv | 10 + crates/ui-egui/src/i18n/el.tsv | 10 + crates/ui-egui/src/i18n/es.tsv | 10 + crates/ui-egui/src/i18n/fi.tsv | 10 + crates/ui-egui/src/i18n/fr.tsv | 10 + crates/ui-egui/src/i18n/hi.tsv | 10 + crates/ui-egui/src/i18n/hu.tsv | 10 + crates/ui-egui/src/i18n/id.tsv | 10 + crates/ui-egui/src/i18n/it.tsv | 10 + crates/ui-egui/src/i18n/ja.tsv | 10 + crates/ui-egui/src/i18n/ka.tsv | 10 + crates/ui-egui/src/i18n/ko.tsv | 10 + crates/ui-egui/src/i18n/nl.tsv | 10 + crates/ui-egui/src/i18n/pl.tsv | 10 + crates/ui-egui/src/i18n/pt-br.tsv | 10 + crates/ui-egui/src/i18n/ru.tsv | 10 + crates/ui-egui/src/i18n/sv.tsv | 10 + crates/ui-egui/src/i18n/tr.tsv | 10 + crates/ui-egui/src/i18n/uk.tsv | 10 + crates/ui-egui/src/i18n/vi.tsv | 10 + crates/ui-egui/src/i18n/zh-hans.tsv | 10 + crates/ui-egui/src/i18n/zh-hant.tsv | 10 + docs/mcp.md | 11 +- docs/target-app-parity.md | 3 +- 34 files changed, 659 insertions(+), 8 deletions(-) diff --git a/crates/effects/src/lib.rs b/crates/effects/src/lib.rs index 7bba3e8dd..84c83d2e7 100644 --- a/crates/effects/src/lib.rs +++ b/crates/effects/src/lib.rs @@ -80,8 +80,8 @@ pub use marks::{CROP_MARKS, crop_marks_art, has_crop_marks}; pub use pixel::{PIXEL_EFFECTS, PixelFx, PixelSpace}; pub use raster::{RASTERIZE, RasterFx, Rasterize, color_param, outset, raster_effects}; pub use reshape::{ - SYMBOL_ART_MAX_NODES, expand_outlined, has_gradient_copies, has_item_geometry, has_transform_art, has_transform_copies, has_transform_options, - image_paint, needs_outline, outline_art, outline_text, reshape, + SYMBOL_ART_MAX_NODES, expand_outlined, gives_image_shape, has_gradient_copies, has_item_geometry, has_transform_art, has_transform_copies, + has_transform_options, image_paint, needs_outline, outline_art, outline_text, reshape, }; pub use revolve::{REVOLVE, has_revolve, revolve_art, revolve_options, validate_revolve}; pub use solids::{ diff --git a/crates/effects/src/reshape.rs b/crates/effects/src/reshape.rs index 85f2849d9..7fabc0490 100644 --- a/crates/effects/src/reshape.rs +++ b/crates/effects/src/reshape.rs @@ -133,7 +133,13 @@ fn gives_shape(e: &Effect) -> bool { /// Does `item`, a fill or stroke of an image, paint something: does it paint and carry an effect /// that gives it a shape ([`gives_shape`])? fn shapes_image(item: &AppearanceItem) -> bool { - crate::paints(item) && item.effects().iter().any(gives_shape) + crate::paints(item) && gives_image_shape(item.effects()) +} + +/// Do `effects`, those of an image's fill or stroke, give that fill or stroke a shape to paint +/// ([`gives_shape`])? +pub fn gives_image_shape(effects: &[Effect]) -> bool { + effects.iter().any(gives_shape) } /// The fills and strokes of `items` (an image's own) that paint something ([`shapes_image`]), each diff --git a/crates/engine/src/cmd/brushsym.rs b/crates/engine/src/cmd/brushsym.rs index 5dcb82136..53f373a3b 100644 --- a/crates/engine/src/cmd/brushsym.rs +++ b/crates/engine/src/cmd/brushsym.rs @@ -263,7 +263,7 @@ pub fn specs() -> Vec { "Symbol Instance Appearance", [], None, - "{id?|ids?: [one id] (default: the one selected object), path: [i…] (the object in the symbol's art: child indices in paint order from the art's root down through its groups; [] the root), fill?: \"#rrggbb\"|{…paint params of paint.setFill: color, none, swatch, tint, gradient, keepModel}|null (null: the symbol's own again), stroke?: as fill, opacity?: 0..100|null, blend?: name|null} change the appearance of one object of a dynamic symbol instance's art, for that instance only: it stays linked, so editing the symbol reshapes it and keeps the change; refused for a static symbol or a path naming no object → {id, overrides: how many objects the instance changes}", + "{id?|ids?: [one id] (default: the one selected object), path: [i…] (the object in the symbol's art: child indices in paint order from the art's root down through its groups; [] the root), fill?: \"#rrggbb\"|{…paint params of paint.setFill: color, none, swatch, tint, gradient, keepModel}|null (null: the symbol's own again), stroke?: as fill, opacity?: 0..100|null, blend?: name|null} change the appearance of one object of a dynamic symbol instance's art, for that instance only: it stays linked, so editing the symbol reshapes it and keeps the change; refused for a static symbol, a path naming no object, or a fill or stroke other than null for an object that does not draw it (a guide, blend, envelope, Repeat, Intertwine group, gradient mesh or placed document; a symbol instance's stroke, and its fill unless a solid color or none, which stains its art; an image's fill or stroke without a Convert to Shape or Outline Object effect), with nothing of the call applied; opacity, blend and null are taken for every object → {id, overrides: how many objects the instance changes}", has_selection, symbol_instance_set_appearance ), diff --git a/crates/engine/src/cmd/brushsym/dynamic.rs b/crates/engine/src/cmd/brushsym/dynamic.rs index 6197e57be..89c7c3c52 100644 --- a/crates/engine/src/cmd/brushsym/dynamic.rs +++ b/crates/engine/src/cmd/brushsym/dynamic.rs @@ -129,6 +129,64 @@ fn path_param(p: &Value, art: &Node, cmd: &str) -> Result> { Ok(path) } +/// The refusal of `key` (`fill` or `stroke`) for `n`, an object of a dynamic symbol's art, when `n` +/// does not draw that paint of its own; `None` when it does. Paths (not guides), +/// compound paths, type, groups and layers draw them; a symbol instance draws its fill as a stain +/// on its art ([`solid_fill_check`]) and no stroke; an image draws one only when that fill or +/// stroke has a Convert to Shape or Outline Object effect. +fn paint_refusal(n: &Node, key: &str, cmd: &str) -> Option { + Some(match &n.kind { + NodeKind::Path { guide: true, .. } => bad(cmd, format!("{key} cannot be set on a guide")), + NodeKind::Path { .. } | NodeKind::Compound { .. } | NodeKind::Text(_) | NodeKind::Group { .. } | NodeKind::Layer { .. } => return None, + NodeKind::Image(_) => { + let effects = if key == "fill" { n.appearance.fill().map(|f| &f.effects) } else { n.appearance.stroke().map(|s| &s.effects) }; + if effects.is_some_and(|e| vectorcraft_render::effects::gives_image_shape(e)) { + return None; + } + bad(cmd, format!("{key} cannot be set on an image without a Convert to Shape or Outline Object effect on it")) + } + NodeKind::SymbolInstance { .. } if key == "fill" => return None, + NodeKind::SymbolInstance { .. } => bad(cmd, "stroke cannot be set on a symbol instance"), + NodeKind::Blend { .. } => bad(cmd, format!("{key} cannot be set on a blend")), + NodeKind::Envelope { .. } => bad(cmd, format!("{key} cannot be set on an envelope")), + NodeKind::Mesh(_) => bad(cmd, format!("{key} cannot be set on a gradient mesh")), + NodeKind::Repeat(_) => bad(cmd, format!("{key} cannot be set on a Repeat")), + NodeKind::PlacedDocument(_) => bad(cmd, format!("{key} cannot be set on a placed document")), + NodeKind::Intertwine { .. } => bad(cmd, format!("{key} cannot be set on an Intertwine group")), + }) +} + +/// Refuse a `fill` or `stroke` other than null that the object at `path` of `art` does not draw +/// ([`paint_refusal`]); null, which takes a change back, is taken for every object. +fn check_paint_kinds(p: &Value, art: &Node, path: &[u32], cmd: &str) -> Result<()> { + let Some(n) = symbol_overrides::part(art, path) else { return Ok(()) }; + for key in ["fill", "stroke"] { + if p.get(key).is_some_and(|v| !v.is_null()) + && let Some(e) = paint_refusal(n, key, cmd) + { + return Err(e); + } + } + Ok(()) +} + +/// Refuse `fill`, the paint `p` asks for the object at `path` of `art`, when that object is a +/// symbol instance and `fill` is a gradient or a pattern: an instance stains its art with a solid +/// fill only, so such a fill draws nothing. +fn solid_fill_check(p: &Value, art: &Node, path: &[u32], fill: Option<&vectorcraft_color::Paint>, cmd: &str) -> Result<()> { + let asked = p.get("fill").is_some_and(|v| !v.is_null()); + let is_instance = symbol_overrides::part(art, path).is_some_and(|n| matches!(n.kind, NodeKind::SymbolInstance { .. })); + let draws_nothing = |f: &vectorcraft_color::Paint| match f { + vectorcraft_color::Paint::Gradient(_) => true, + vectorcraft_color::Paint::Pattern { .. } => true, + vectorcraft_color::Paint::None | vectorcraft_color::Paint::Solid { .. } => false, + }; + if asked && is_instance && fill.is_some_and(draws_nothing) { + return Err(bad(cmd, "fill on a symbol instance must be a solid color or none")); + } + Ok(()) +} + /// `fill` or `stroke` of `p` for override `o`: absent leaves it, null clears it, a colour string or /// an object of `paint.setFill`'s paint params sets it. fn paint_change(s: &Session, p: &Value, key: &str, cmd: &str) -> Result>> { @@ -170,9 +228,11 @@ pub(super) fn symbol_instance_set_appearance(s: &mut Session, p: &Value) -> Resu } let (id, art) = dynamic_instance(s, p, C)?; let path = path_param(p, &art, C)?; + check_paint_kinds(p, &art, &path, C)?; let d = &s.doc()?.doc; let old = d.node(id).and_then(|n| n.extras().symbol_overrides.iter().find(|o| o.path == path).cloned()); let new = changed(s, p, old.unwrap_or_else(|| SymbolOverride { path: path.clone(), ..Default::default() }), C)?; + solid_fill_check(p, &art, &path, new.fill.as_ref(), C)?; let count = edit_part(s, id, &path, "Symbol Instance Appearance", |o| *o = new)?; Ok(json!({ "id": id.0, "overrides": count })) } diff --git a/crates/engine/src/tests/dynamic_symbols.rs b/crates/engine/src/tests/dynamic_symbols.rs index 9ec00cd24..b946f7192 100644 --- a/crates/engine/src/tests/dynamic_symbols.rs +++ b/crates/engine/src/tests/dynamic_symbols.rs @@ -4,6 +4,7 @@ //! Fill or Stroke changes it. use serde_json::{Value, json}; +use vectorcraft_color::{Color, Paint}; use vectorcraft_doc::{Node, NodeKind}; use vectorcraft_geom::Rect; use vectorcraft_tools::{Mods, PointerEvent, PointerKind}; @@ -107,6 +108,314 @@ fn static_symbols_and_bad_targets_are_refused() { assert_eq!(overrides(&s, inst), 0); } +fn undo_len(s: &Session) -> usize { + s.doc().unwrap().history.undo.len() +} + +/// The frontmost object of the active layer. +fn top(s: &Session) -> NodeId { + let d = &s.doc().unwrap().doc; + d.node(d.default_layer().unwrap()).unwrap().children().unwrap().last().unwrap().id +} + +/// Every pixel of the page. +fn page(s: &Session) -> Vec<[u8; 4]> { + let r = vectorcraft_render::Renderer::new().render_region(&s.doc().unwrap().doc, Rect::new(0.0, 0.0, 200.0, 100.0), 1.0, true); + (0..r.height).flat_map(|y| (0..r.width).map(move |x| (x, y))).map(|(x, y)| r.pixel(x, y)).collect() +} + +/// A dynamic symbol "Art" of the frontmost object, made in place: its instance. +fn art_of_top(s: &mut Session) -> NodeId { + let t = top(s); + id(&s.execute("symbol.new", &json!({"name": "Art", "ids": [t.0], "type": "dynamic"})).unwrap()) +} + +/// Put a red fill and stroke on the root of instance `inst`'s art directly, past the command. +fn paint_root_red(s: &mut Session, inst: NodeId) { + let red = Paint::solid(Color::rgb(1.0, 0.0, 0.0)); + s.edit("paint", |d, _| { + let o = vectorcraft_doc::symbol_overrides::SymbolOverride { path: vec![], fill: Some(red.clone()), stroke: Some(red), ..Default::default() }; + d.node_mut(inst).ok_or(EngineError::NoNode(inst))?.extras_mut().symbol_overrides.push(o); + Ok(()) + }) + .unwrap(); +} + +/// A 30×30 red image placed with its frame from (50, 20) to (80, 50). +fn place_image(s: &mut Session) { + let png = crate::tests_links::png(30, 30, [255, 0, 0]); + let data = vectorcraft_format::base64_encode(&png); + s.execute("file.place", &json!({"name": "red.png", "dataBase64": data, "at": [65, 35], "link": false})).unwrap(); +} + +fn select_top(s: &mut Session, n: usize) { + let d = &s.doc().unwrap().doc; + let kids = d.node(d.default_layer().unwrap()).unwrap().children().unwrap(); + let ids: Vec = kids[kids.len() - n..].iter().map(|c| c.id.0).collect(); + s.execute("select.set", &json!({ "ids": ids })).unwrap(); +} + +#[test] +fn objects_that_draw_no_fill_or_stroke_of_their_own_refuse_one() { + let folder = crate::tests_links::Folder::new("dynamic-symbol-kinds"); + let source = folder.file("placed.vectorcraft"); + let mut doc = vectorcraft_doc::Document::new(40.0, 40.0); + let layer = doc.layers[0].id; + let look = vectorcraft_doc::Appearance::basic(Paint::solid(Color::rgb(0.0, 0.0, 1.0)), Paint::None, 0.0); + let rect = vectorcraft_doc::Node::path(doc.alloc_id(), vectorcraft_geom::shapes::rectangle(Rect::new(0.0, 0.0, 40.0, 40.0)), look); + doc.insert(Some(layer), 0, rect).unwrap(); + crate::tests_links::write(&source, &vectorcraft_format::save_file(&doc)); + type Make = Box; + let cases: Vec<(&str, &str, Make)> = vec![ + ( + "guide", + "a guide", + Box::new(|s| { + square(s, 10.0); + select_top(s, 1); + s.execute("view.guides.make", &json!({})).unwrap(); + }), + ), + ( + "blend", + "a blend", + Box::new(|s| { + let (a, b) = (square(s, 10.0), square(s, 60.0)); + s.execute("object.blend.make", &json!({"ids": [a.0, b.0], "steps": 1})).unwrap(); + }), + ), + ( + "envelope", + "an envelope", + Box::new(|s| { + square(s, 10.0); + select_top(s, 1); + s.execute("object.envelope.makeWithWarp", &json!({"style": "arch", "bend": 50})).unwrap(); + }), + ), + ("radial Repeat", "a Repeat", Box::new(|s| repeat(s, "object.repeat.radial"))), + ("grid Repeat", "a Repeat", Box::new(|s| repeat(s, "object.repeat.grid"))), + ("mirror Repeat", "a Repeat", Box::new(|s| repeat(s, "object.repeat.mirror"))), + ( + "Intertwine", + "an Intertwine group", + Box::new(|s| { + square(s, 10.0); + square(s, 30.0); + select_top(s, 2); + s.execute("object.intertwine.make", &json!({})).unwrap(); + }), + ), + ( + "gradient mesh", + "a gradient mesh", + Box::new(|s| { + let r = square(s, 10.0); + s.execute("object.mesh.create", &json!({"ids": [r.0], "rows": 1, "cols": 1})).unwrap(); + }), + ), + ("image", "an image", Box::new(place_image)), + ( + "placed document", + "a placed document", + Box::new(move |s| { + let r = s.execute("file.place", &json!({"path": source, "at": [40, 40]})).unwrap(); + assert_eq!(r["linked"], true, "{r}"); + }), + ), + ]; + // Every case runs, and the failure lists each object that fails. + let mut failures = Vec::new(); + for (label, kind, make) in cases { + let mut s = session(); + make(&mut s); + let inst = art_of_top(&mut s); + if let Err(why) = refuses_own_paint(&mut s, inst, kind) { + failures.push(format!("{label}: {why}")); + } + } + assert!(failures.is_empty(), "{}", failures.join("\n")); +} + +/// Check that the root of instance `inst`'s art, an object of `kind` that draws no fill or stroke +/// of its own, refuses both, takes null, opacity and blend, and draws no stored fill or stroke. +fn refuses_own_paint(s: &mut Session, inst: NodeId, kind: &str) -> std::result::Result<(), String> { + let set = |s: &mut Session, p: &Value| s.execute("symbol.instance.setAppearance", p); + let undo = undo_len(s); + for key in ["fill", "stroke"] { + for paint in [json!("#ff0000"), json!({"none": true})] { + // With a valid opacity too: nothing of the call is applied. + let p = json!({"id": inst.0, "path": [], key: paint, "opacity": 50}); + match set(s, &p) { + Ok(_) => return Err(format!("{p} was taken")), + Err(e) if !e.to_string().contains(&format!("{key} cannot be set on {kind}")) => return Err(format!("{p}: {e}")), + Err(_) => {} + } + } + } + if (overrides(s, inst), undo_len(s)) != (0, undo) { + return Err("a refused call changed the instance or added an undo step".into()); + } + // Null (taking a change back), opacity and blend are taken. + let clear = json!({"id": inst.0, "path": [], "fill": null, "stroke": null}); + for p in [clear, json!({"id": inst.0, "path": [], "opacity": 50, "blend": "multiply"})] { + set(s, &p).map_err(|e| format!("{p}: {e}"))?; + } + if overrides(s, inst) != 1 { + return Err("opacity and blend were not stored".into()); + } + // The renderer draws no fill or stroke of the object's own: a stored one changes nothing. + let before = page(s); + paint_root_red(s, inst); + if page(s) != before { + return Err("a stored fill and stroke changed the canvas".into()); + } + Ok(()) +} + +fn repeat(s: &mut Session, cmd: &str) { + square(s, 10.0); + select_top(s, 1); + s.execute(cmd, &json!({})).unwrap(); +} + +#[test] +fn a_symbol_instance_in_the_art_takes_a_fill_that_stains_it_and_no_stroke() { + let mut s = session(); + pair(&mut s, "static"); + let inst = art_of_top(&mut s); + let undo = undo_len(&s); + let e = s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "stroke": "#ff0000"})).unwrap_err().to_string(); + assert!(e.contains("stroke cannot be set on a symbol instance"), "{e}"); + assert_eq!((overrides(&s, inst), undo_len(&s)), (0, undo)); + // A stroke stored past the command draws nothing. + let before = page(&s); + let red = Paint::solid(Color::rgb(1.0, 0.0, 0.0)); + s.edit("paint", |d, _| { + let o = vectorcraft_doc::symbol_overrides::SymbolOverride { path: vec![], stroke: Some(red), ..Default::default() }; + d.node_mut(inst).ok_or(EngineError::NoNode(inst))?.extras_mut().symbol_overrides.push(o); + Ok(()) + }) + .unwrap(); + assert!(page(&s) == before, "a stroke on a symbol instance draws nothing"); + // The fill stains the nested instance's art. + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "fill": "#ff0000"})).unwrap(); + assert_eq!(pixel(&s, 30, 30), RED, "the fill stains the art"); +} + +#[test] +fn a_symbol_instance_in_the_art_refuses_a_gradient_fill() { + let mut s = session(); + pair(&mut s, "static"); + let inst = art_of_top(&mut s); + let undo = undo_len(&s); + let gradient = json!({"stops": [{"offset": 0, "color": "#ff0000"}, {"offset": 1, "color": "#00ff00"}]}); + let p = json!({"id": inst.0, "path": [], "fill": {"gradient": gradient}, "opacity": 50}); + let e = s.execute("symbol.instance.setAppearance", &p).unwrap_err().to_string(); + assert!(e.contains("fill on a symbol instance must be a solid color or none"), "{e}"); + assert_eq!((overrides(&s, inst), undo_len(&s)), (0, undo), "nothing changes and no undo step"); + // A gradient fill stored past the command draws nothing. + let before = page(&s); + let paint = Paint::Gradient(Box::new(vectorcraft_color::GradientPaint::new(vectorcraft_color::Gradient::default()))); + s.edit("paint", |d, _| { + let o = vectorcraft_doc::symbol_overrides::SymbolOverride { path: vec![], fill: Some(paint), ..Default::default() }; + d.node_mut(inst).ok_or(EngineError::NoNode(inst))?.extras_mut().symbol_overrides.push(o); + Ok(()) + }) + .unwrap(); + assert!(page(&s) == before, "a gradient fill on a symbol instance draws nothing"); + // A solid fill and none are taken. + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "fill": {"none": true}})).unwrap(); + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "fill": "#ff0000"})).unwrap(); + assert_eq!(pixel(&s, 30, 30), RED); +} + +#[test] +fn a_symbol_instance_in_the_art_refuses_a_pattern_fill() { + let mut s = session(); + let tile = id(&s.execute("shape.rectangle", &json!({"x": 150, "y": 60, "width": 10, "height": 10})).unwrap()); + s.execute("object.pattern.make", &json!({"ids": [tile.0], "name": "Dots", "edit": false})).unwrap(); + pair(&mut s, "static"); + let inst = art_of_top(&mut s); + let undo = undo_len(&s); + let p = json!({"id": inst.0, "path": [], "fill": {"swatch": "Dots"}, "opacity": 50}); + let e = s.execute("symbol.instance.setAppearance", &p).unwrap_err().to_string(); + assert!(e.contains("fill on a symbol instance must be a solid color or none"), "{e}"); + assert_eq!((overrides(&s, inst), undo_len(&s)), (0, undo), "nothing changes and no undo step"); + // The pattern draws on a path. + let probe = square(&mut s, 110.0); + let before = page(&s); + s.execute("paint.setFill", &json!({"ids": [probe.0], "swatch": "Dots"})).unwrap(); + assert!(page(&s) != before, "the pattern draws on a path"); + // A pattern fill stored on the nested instance past the command draws nothing. + let before = page(&s); + let paint = s.doc().unwrap().doc.swatch("Dots").unwrap().paint.clone(); + assert!(matches!(paint, Paint::Pattern { .. }), "{paint:?}"); + s.edit("paint", |d, _| { + let o = vectorcraft_doc::symbol_overrides::SymbolOverride { path: vec![], fill: Some(paint), ..Default::default() }; + d.node_mut(inst).ok_or(EngineError::NoNode(inst))?.extras_mut().symbol_overrides.push(o); + Ok(()) + }) + .unwrap(); + assert!(page(&s) == before, "a pattern fill on a symbol instance draws nothing"); +} + +#[test] +fn null_takes_back_an_old_change_an_object_does_not_draw() { + let mut s = session(); + let (a, b) = (square(&mut s, 10.0), square(&mut s, 60.0)); + s.execute("object.blend.make", &json!({"ids": [a.0, b.0], "steps": 1})).unwrap(); + let inst = art_of_top(&mut s); + // A change stored before the command refused one, as an older document may hold. + paint_root_red(&mut s, inst); + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "fill": null})).unwrap(); + assert!(node(&s, inst).extras().symbol_overrides[0].fill.is_none()); + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "stroke": null})).unwrap(); + assert_eq!(overrides(&s, inst), 0); +} + +#[test] +fn paths_type_groups_and_shaped_image_paint_take_a_fill_and_stroke() { + let set = |s: &mut Session, inst: NodeId, path: Value| { + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": path, "fill": "#ff0000", "stroke": "#ff0000"})).unwrap() + }; + // A group's own fill paints over its members. + let mut s = session(); + let inst = pair(&mut s, "dynamic"); + assert_eq!(set(&mut s, inst, json!([]))["overrides"], 1); + assert_eq!(pixel(&s, 30, 30), RED, "the group's own fill"); + // A compound path, type and a clipping path. + let mut s = session(); + let (a, b) = (square(&mut s, 10.0), square(&mut s, 60.0)); + s.execute("object.compoundPath.make", &json!({"ids": [a.0, b.0]})).unwrap(); + let inst = art_of_top(&mut s); + set(&mut s, inst, json!([])); + assert_eq!(pixel(&s, 30, 30), RED, "the compound path"); + let mut s = session(); + s.execute("text.create", &json!({"x": 10, "y": 40, "text": "Hi"})).unwrap(); + let inst = art_of_top(&mut s); + set(&mut s, inst, json!([])); + let mut s = session(); + let (a, b) = (square(&mut s, 10.0), square(&mut s, 20.0)); + s.execute("object.clippingMask.make", &json!({"ids": [a.0, b.0]})).unwrap(); + let inst = art_of_top(&mut s); + assert!(matches!(&node(&s, inst).kind, NodeKind::SymbolInstance { .. })); + set(&mut s, inst, json!([0])); + set(&mut s, inst, json!([])); + // An image whose fill has Convert to Shape: the fill paints 9 pt past its frame. + let mut s = session(); + place_image(&mut s); + s.execute("appearance.addFill", &json!({})).unwrap(); + s.execute("paint.setFill", &json!({"color": "#00ff00", "item": 0})).unwrap(); + s.execute("effect.apply", &json!({"effect": "convertToShape.rectangle", "item": 0})).unwrap(); + assert_eq!(pixel(&s, 44, 35), [0, 255, 0, 255]); + let inst = art_of_top(&mut s); + let e = s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "stroke": "#ff0000"})).unwrap_err().to_string(); + assert!(e.contains("stroke cannot be set on an image without a Convert to Shape or Outline Object effect on it"), "{e}"); + s.execute("symbol.instance.setAppearance", &json!({"id": inst.0, "path": [], "fill": "#ff0000"})).unwrap(); + assert_eq!(pixel(&s, 44, 35), RED, "the shaped fill takes the instance's color"); +} + #[test] fn redefining_the_symbol_keeps_the_changes_whose_objects_remain() { let mut s = session(); diff --git a/crates/ui-egui/src/i18n/bg.tsv b/crates/ui-egui/src/i18n/bg.tsv index 6da0c90d6..db56ce309 100644 --- a/crates/ui-egui/src/i18n/bg.tsv +++ b/crates/ui-egui/src/i18n/bg.tsv @@ -6266,6 +6266,16 @@ breakText Glyphs Глифи @msg path must be a list of child indices path трябва да е списък с индекси на дъщерни обекти @msg no object at path {shown} in the symbol's art в графиката на символа няма обект на пътя {shown} @msg give fill, stroke, opacity and/or blend задайте fill, stroke, opacity и/или blend +@msg {key} cannot be set on a guide {key} не може да се задава за водач +@msg {key} cannot be set on a blend {key} не може да се задава за преливане +@msg {key} cannot be set on an envelope {key} не може да се задава за плик +@msg {key} cannot be set on a gradient mesh {key} не може да се задава за мрежа с градиент +@msg {key} cannot be set on a Repeat {key} не може да се задава за повтаряне +@msg {key} cannot be set on a placed document {key} не може да се задава за вмъкнат документ +@msg {key} cannot be set on an Intertwine group {key} не може да се задава за група с преплитане +@msg stroke cannot be set on a symbol instance stroke не може да се задава за екземпляр на символ +@msg fill on a symbol instance must be a solid color or none fill на екземпляр на символ трябва да е плътен цвят или none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} не може да се задава за изображение без ефект „Конвертиране в фигура“ или „Преобразуване на обекта в контур“ @msg pass newName, registration, exportType, nineSlice and/or type задайте newName, registration, exportType, nineSlice и/или type Text Flow Поток на текста By Rows По редове diff --git a/crates/ui-egui/src/i18n/bs.tsv b/crates/ui-egui/src/i18n/bs.tsv index b7f8c6ed8..820737059 100644 --- a/crates/ui-egui/src/i18n/bs.tsv +++ b/crates/ui-egui/src/i18n/bs.tsv @@ -6315,6 +6315,16 @@ shape Open Otvoren @msg path must be a list of child indices path mora biti lista indeksa podređenih objekata @msg no object at path {shown} in the symbol's art nema objekta na putanji {shown} u grafici simbola @msg give fill, stroke, opacity and/or blend navedite fill, stroke, opacity i/ili blend +@msg {key} cannot be set on a guide {key} se ne može postaviti na vodilicu +@msg {key} cannot be set on a blend {key} se ne može postaviti na stapanje +@msg {key} cannot be set on an envelope {key} se ne može postaviti na omotnicu +@msg {key} cannot be set on a gradient mesh {key} se ne može postaviti na gradijentnu mrežu +@msg {key} cannot be set on a Repeat {key} se ne može postaviti na ponavljanje +@msg {key} cannot be set on a placed document {key} se ne može postaviti na postavljeni dokument +@msg {key} cannot be set on an Intertwine group {key} se ne može postaviti na Intertwine grupu +@msg stroke cannot be set on a symbol instance stroke se ne može postaviti na instancu simbola +@msg fill on a symbol instance must be a solid color or none fill instance simbola mora biti puna boja ili none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} se ne može postaviti na sliku bez efekta „Pretvori u oblik“ ili „Objekat u obrisu“ @msg pass newName, registration, exportType, nineSlice and/or type navedite newName, registration, exportType, nineSlice i/ili type Text Flow Tok teksta By Rows Po redovima diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv index e891476f7..048e034e9 100644 --- a/crates/ui-egui/src/i18n/ca.tsv +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -6431,6 +6431,16 @@ breakText Glyphs Glifs @msg path must be a list of child indices path ha de ser una llista d’índexs de fills @msg no object at path {shown} in the symbol's art no hi ha cap objecte al camí {shown} de l’art del símbol @msg give fill, stroke, opacity and/or blend indiqueu fill, stroke, opacity i/o blend +@msg {key} cannot be set on a guide {key} no es pot definir en una guia +@msg {key} cannot be set on a blend {key} no es pot definir en una fusió +@msg {key} cannot be set on an envelope {key} no es pot definir en un embolcall +@msg {key} cannot be set on a gradient mesh {key} no es pot definir en una malla de degradat +@msg {key} cannot be set on a Repeat {key} no es pot definir en una repetició +@msg {key} cannot be set on a placed document {key} no es pot definir en un document col·locat +@msg {key} cannot be set on an Intertwine group {key} no es pot definir en un grup entrelligat +@msg stroke cannot be set on a symbol instance stroke no es pot definir en una instància de símbol +@msg fill on a symbol instance must be a solid color or none el fill d’una instància de símbol ha de ser un color sòlid o none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} no es pot definir en una imatge sense l’efecte Converteix en forma o Contorneja l’objecte @msg pass newName, registration, exportType, nineSlice and/or type indiqueu newName, registration, exportType, nineSlice i/o type Text Flow Flux del text By Rows Per files diff --git a/crates/ui-egui/src/i18n/cs.tsv b/crates/ui-egui/src/i18n/cs.tsv index 45fe55dd7..bfc7083b7 100644 --- a/crates/ui-egui/src/i18n/cs.tsv +++ b/crates/ui-egui/src/i18n/cs.tsv @@ -6449,6 +6449,16 @@ breakText Glyphs Glyfy @msg path must be a list of child indices path musí být seznam indexů potomků @msg no object at path {shown} in the symbol's art v kresbě symbolu není na cestě {shown} žádný objekt @msg give fill, stroke, opacity and/or blend zadejte fill, stroke, opacity a/nebo blend +@msg {key} cannot be set on a guide {key} nelze nastavit u vodítka +@msg {key} cannot be set on a blend {key} nelze nastavit u prolnutí +@msg {key} cannot be set on an envelope {key} nelze nastavit u obálky +@msg {key} cannot be set on a gradient mesh {key} nelze nastavit u přechodové sítě +@msg {key} cannot be set on a Repeat {key} nelze nastavit u opakování +@msg {key} cannot be set on a placed document {key} nelze nastavit u umístěného dokumentu +@msg {key} cannot be set on an Intertwine group {key} nelze nastavit u propletené skupiny +@msg stroke cannot be set on a symbol instance stroke nelze nastavit u instance symbolu +@msg fill on a symbol instance must be a solid color or none fill instance symbolu musí být plná barva nebo none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} nelze nastavit u obrazu bez efektu Převést na tvar nebo Převést objekt na obrys @msg pass newName, registration, exportType, nineSlice and/or type zadejte newName, registration, exportType, nineSlice a/nebo type Text Flow Tok textu By Rows Po řádcích diff --git a/crates/ui-egui/src/i18n/da.tsv b/crates/ui-egui/src/i18n/da.tsv index 9cdd8e5c6..2d15c2b63 100644 --- a/crates/ui-egui/src/i18n/da.tsv +++ b/crates/ui-egui/src/i18n/da.tsv @@ -6280,6 +6280,16 @@ breakText Glyphs Glyffer @msg path must be a list of child indices path skal være en liste over underordnede indekser @msg no object at path {shown} in the symbol's art intet objekt ved stien {shown} i symbolets grafik @msg give fill, stroke, opacity and/or blend angiv fill, stroke, opacity og/eller blend +@msg {key} cannot be set on a guide {key} kan ikke angives for en hjælpelinje +@msg {key} cannot be set on a blend {key} kan ikke angives for en blanding +@msg {key} cannot be set on an envelope {key} kan ikke angives for en kuvert +@msg {key} cannot be set on a gradient mesh {key} kan ikke angives for et gradientnet +@msg {key} cannot be set on a Repeat {key} kan ikke angives for en gentagelse +@msg {key} cannot be set on a placed document {key} kan ikke angives for et placeret dokument +@msg {key} cannot be set on an Intertwine group {key} kan ikke angives for en sammenflettet gruppe +@msg stroke cannot be set on a symbol instance stroke kan ikke angives for en symbolforekomst +@msg fill on a symbol instance must be a solid color or none fill på en symbolforekomst skal være en ensfarvet farve eller none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} kan ikke angives for et billede uden effekten Konvertér til form eller Objekt til kontur @msg pass newName, registration, exportType, nineSlice and/or type angiv newName, registration, exportType, nineSlice og/eller type Text Flow Tekstflow By Rows Efter rækker diff --git a/crates/ui-egui/src/i18n/de.tsv b/crates/ui-egui/src/i18n/de.tsv index f485f5c44..309dce8a7 100644 --- a/crates/ui-egui/src/i18n/de.tsv +++ b/crates/ui-egui/src/i18n/de.tsv @@ -6035,6 +6035,16 @@ breakText Glyphs Glyphen @msg path must be a list of child indices path muss eine Liste von Kindindizes sein @msg no object at path {shown} in the symbol's art kein Objekt am Pfad {shown} in der Grafik des Symbols @msg give fill, stroke, opacity and/or blend geben Sie fill, stroke, opacity und/oder blend an +@msg {key} cannot be set on a guide {key} kann nicht für eine Hilfslinie gesetzt werden +@msg {key} cannot be set on a blend {key} kann nicht für eine Angleichung gesetzt werden +@msg {key} cannot be set on an envelope {key} kann nicht für eine Verzerrungshülle gesetzt werden +@msg {key} cannot be set on a gradient mesh {key} kann nicht für ein Verlaufsgitter gesetzt werden +@msg {key} cannot be set on a Repeat {key} kann nicht für eine Wiederholung gesetzt werden +@msg {key} cannot be set on a placed document {key} kann nicht für ein platziertes Dokument gesetzt werden +@msg {key} cannot be set on an Intertwine group {key} kann nicht für eine Verflechten-Gruppe gesetzt werden +@msg stroke cannot be set on a symbol instance stroke kann nicht für eine Symbolinstanz gesetzt werden +@msg fill on a symbol instance must be a solid color or none fill einer Symbolinstanz muss eine Vollfarbe oder none sein +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} kann nicht für ein Bild ohne den Effekt „In Form umwandeln“ oder „Objekt in Pfade umwandeln“ gesetzt werden @msg pass newName, registration, exportType, nineSlice and/or type geben Sie newName, registration, exportType, nineSlice und/oder type an Text Flow Textfluss By Rows Nach Zeilen diff --git a/crates/ui-egui/src/i18n/el.tsv b/crates/ui-egui/src/i18n/el.tsv index e7880f10b..40bd8f2c9 100644 --- a/crates/ui-egui/src/i18n/el.tsv +++ b/crates/ui-egui/src/i18n/el.tsv @@ -6401,6 +6401,16 @@ breakText Glyphs Γλύφοι @msg path must be a list of child indices το path πρέπει να είναι λίστα δεικτών θυγατρικών αντικειμένων @msg no object at path {shown} in the symbol's art δεν υπάρχει αντικείμενο στη διαδρομή {shown} στο γραφικό του συμβόλου @msg give fill, stroke, opacity and/or blend δώστε fill, stroke, opacity ή/και blend +@msg {key} cannot be set on a guide το {key} δεν μπορεί να οριστεί σε οδηγό +@msg {key} cannot be set on a blend το {key} δεν μπορεί να οριστεί σε ανάμειξη +@msg {key} cannot be set on an envelope το {key} δεν μπορεί να οριστεί σε περίβλημα +@msg {key} cannot be set on a gradient mesh το {key} δεν μπορεί να οριστεί σε πλέγμα ντεγκραντέ +@msg {key} cannot be set on a Repeat το {key} δεν μπορεί να οριστεί σε επανάληψη +@msg {key} cannot be set on a placed document το {key} δεν μπορεί να οριστεί σε τοποθετημένο έγγραφο +@msg {key} cannot be set on an Intertwine group το {key} δεν μπορεί να οριστεί σε ομάδα διαπλοκής +@msg stroke cannot be set on a symbol instance το stroke δεν μπορεί να οριστεί σε στιγμιότυπο συμβόλου +@msg fill on a symbol instance must be a solid color or none το fill ενός στιγμιότυπου συμβόλου πρέπει να είναι συμπαγές χρώμα ή none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it το {key} δεν μπορεί να οριστεί σε εικόνα χωρίς το εφέ «Μετατροπή σε σχήμα» ή «Μετατροπή αντικειμένου σε περιγράμματα» @msg pass newName, registration, exportType, nineSlice and/or type δώστε newName, registration, exportType, nineSlice ή/και type Text Flow Ροή κειμένου By Rows Κατά γραμμές diff --git a/crates/ui-egui/src/i18n/es.tsv b/crates/ui-egui/src/i18n/es.tsv index a5f9f5d82..6c5ac8015 100644 --- a/crates/ui-egui/src/i18n/es.tsv +++ b/crates/ui-egui/src/i18n/es.tsv @@ -6391,6 +6391,16 @@ breakText Glyphs Glifos @msg path must be a list of child indices path debe ser una lista de índices de hijos @msg no object at path {shown} in the symbol's art no hay ningún objeto en la ruta {shown} del arte del símbolo @msg give fill, stroke, opacity and/or blend indique fill, stroke, opacity y/o blend +@msg {key} cannot be set on a guide {key} no se puede definir en una guía +@msg {key} cannot be set on a blend {key} no se puede definir en una fusión +@msg {key} cannot be set on an envelope {key} no se puede definir en una envolvente +@msg {key} cannot be set on a gradient mesh {key} no se puede definir en una malla de degradado +@msg {key} cannot be set on a Repeat {key} no se puede definir en una repetición +@msg {key} cannot be set on a placed document {key} no se puede definir en un documento colocado +@msg {key} cannot be set on an Intertwine group {key} no se puede definir en un grupo entrelazado +@msg stroke cannot be set on a symbol instance stroke no se puede definir en una instancia de símbolo +@msg fill on a symbol instance must be a solid color or none el fill de una instancia de símbolo debe ser un color sólido o none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} no se puede definir en una imagen sin el efecto Convertir en forma o Contornear objeto @msg pass newName, registration, exportType, nineSlice and/or type indique newName, registration, exportType, nineSlice y/o type Text Flow Flujo de texto By Rows Por filas diff --git a/crates/ui-egui/src/i18n/fi.tsv b/crates/ui-egui/src/i18n/fi.tsv index c9c0d9198..f563bfcb8 100644 --- a/crates/ui-egui/src/i18n/fi.tsv +++ b/crates/ui-egui/src/i18n/fi.tsv @@ -6479,6 +6479,16 @@ breakText Glyphs Merkit @msg path must be a list of child indices path-arvon on oltava luettelo alikohteiden indeksejä @msg no object at path {shown} in the symbol's art symbolin kuvituksessa ei ole objektia polussa {shown} @msg give fill, stroke, opacity and/or blend anna fill, stroke, opacity ja/tai blend +@msg {key} cannot be set on a guide {key}-arvoa ei voi asettaa apuviivalle +@msg {key} cannot be set on a blend {key}-arvoa ei voi asettaa sulautukselle +@msg {key} cannot be set on an envelope {key}-arvoa ei voi asettaa kuorelle +@msg {key} cannot be set on a gradient mesh {key}-arvoa ei voi asettaa liukuväriverkolle +@msg {key} cannot be set on a Repeat {key}-arvoa ei voi asettaa toistolle +@msg {key} cannot be set on a placed document {key}-arvoa ei voi asettaa sijoitetulle dokumentille +@msg {key} cannot be set on an Intertwine group {key}-arvoa ei voi asettaa lomitetulle ryhmälle +@msg stroke cannot be set on a symbol instance stroke-arvoa ei voi asettaa symbolin ilmentymälle +@msg fill on a symbol instance must be a solid color or none symbolin ilmentymän fill-arvon on oltava tasainen väri tai none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key}-arvoa ei voi asettaa kuvalle, jolla ei ole tehostetta Muunna muodoksi tai Muunna objekti ääriviivoiksi @msg pass newName, registration, exportType, nineSlice and/or type anna newName, registration, exportType, nineSlice ja/tai type Text Flow Tekstin kulku By Rows Riveittäin diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index 3b9190e59..01d2695be 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -6444,6 +6444,16 @@ breakText Glyphs Glyphes @msg path must be a list of child indices path doit être une liste d'indices d'enfants @msg no object at path {shown} in the symbol's art aucun objet au chemin {shown} dans l'illustration du symbole @msg give fill, stroke, opacity and/or blend indiquez fill, stroke, opacity et/ou blend +@msg {key} cannot be set on a guide {key} ne peut pas être défini sur un repère +@msg {key} cannot be set on a blend {key} ne peut pas être défini sur un dégradé de formes +@msg {key} cannot be set on an envelope {key} ne peut pas être défini sur une enveloppe +@msg {key} cannot be set on a gradient mesh {key} ne peut pas être défini sur un filet de dégradé +@msg {key} cannot be set on a Repeat {key} ne peut pas être défini sur une répétition +@msg {key} cannot be set on a placed document {key} ne peut pas être défini sur un document importé +@msg {key} cannot be set on an Intertwine group {key} ne peut pas être défini sur un groupe entrelacé +@msg stroke cannot be set on a symbol instance stroke ne peut pas être défini sur une instance de symbole +@msg fill on a symbol instance must be a solid color or none le fill d’une instance de symbole doit être une couleur unie ou none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} ne peut pas être défini sur une image sans l’effet Convertir en forme ou Vectoriser l’objet @msg pass newName, registration, exportType, nineSlice and/or type indiquez newName, registration, exportType, nineSlice et/ou type Text Flow Flux du texte By Rows Par lignes diff --git a/crates/ui-egui/src/i18n/hi.tsv b/crates/ui-egui/src/i18n/hi.tsv index 5db92a70e..7fb1484c4 100644 --- a/crates/ui-egui/src/i18n/hi.tsv +++ b/crates/ui-egui/src/i18n/hi.tsv @@ -6294,6 +6294,16 @@ @msg give dataBase64 dataBase64 दें @msg give either at (a click) or area (a path drawn around the overlaps) या तो (एक क्लिक) या क्षेत्र (ओवरलैप के चारों ओर खींचा गया एक पाथ) देना @msg give fill, stroke, opacity and/or blend भरने, स्ट्रोक, अपारदर्शिता और/या मिश्रण देते हैं +@msg {key} cannot be set on a guide गाइड पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on a blend ब्लेंड पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on an envelope एन्वेलप पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on a gradient mesh ग्रेडिएंट मेश पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on a Repeat रिपीट पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on a placed document प्लेस्ड डॉक्यूमेंट पर {key} सेट नहीं किया जा सकता +@msg {key} cannot be set on an Intertwine group इंटरट्वाइन समूह पर {key} सेट नहीं किया जा सकता +@msg stroke cannot be set on a symbol instance सिंबल इंस्टेंस पर stroke सेट नहीं किया जा सकता +@msg fill on a symbol instance must be a solid color or none सिंबल इंस्टेंस का fill ठोस रंग या none होना चाहिए +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it शेप में बदलें या रूपरेखा ऑब्जेक्ट इफ़ेक्ट के बिना इमेज पर {key} सेट नहीं किया जा सकता @msg give formats or a preset, not both फ़ॉर्मैट या एक पूर्व निर्धारित देना, दोनों ही नहीं @msg give horizontal or vertical क्षैतिज या ऊर्ध्वाधर देना @msg give newName or delete newName या delete दें diff --git a/crates/ui-egui/src/i18n/hu.tsv b/crates/ui-egui/src/i18n/hu.tsv index 83c7f8fa8..4034d962d 100644 --- a/crates/ui-egui/src/i18n/hu.tsv +++ b/crates/ui-egui/src/i18n/hu.tsv @@ -6433,6 +6433,16 @@ breakText Glyphs Glifák @msg path must be a list of child indices a path gyermekindexek listája kell legyen @msg no object at path {shown} in the symbol's art a szimbólum grafikájában nincs objektum a(z) {shown} útvonalon @msg give fill, stroke, opacity and/or blend adja meg a fill, stroke, opacity és/vagy blend értékét +@msg {key} cannot be set on a guide a {key} nem állítható be segédvonalon +@msg {key} cannot be set on a blend a {key} nem állítható be összemosáson +@msg {key} cannot be set on an envelope a {key} nem állítható be burkolón +@msg {key} cannot be set on a gradient mesh a {key} nem állítható be színátmenetes hálón +@msg {key} cannot be set on a Repeat a {key} nem állítható be ismétlésen +@msg {key} cannot be set on a placed document a {key} nem állítható be elhelyezett dokumentumon +@msg {key} cannot be set on an Intertwine group a {key} nem állítható be összefonási csoporton +@msg stroke cannot be set on a symbol instance a stroke nem állítható be szimbólumpéldányon +@msg fill on a symbol instance must be a solid color or none a szimbólumpéldány fill értéke csak egyszínű szín vagy none lehet +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it a {key} nem állítható be olyan képen, amelyen nincs Átalakítás alakzattá vagy Objektum útvonallá alakítása effektus @msg pass newName, registration, exportType, nineSlice and/or type adja meg a newName, registration, exportType, nineSlice és/vagy type értékét Text Flow Szövegfolyás By Rows Soronként diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index 213d9584a..cc322cb6c 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -6280,6 +6280,16 @@ breakText Glyphs Glif @msg path must be a list of child indices path harus berupa daftar indeks anak @msg no object at path {shown} in the symbol's art tidak ada objek di jalur {shown} dalam karya seni simbol @msg give fill, stroke, opacity and/or blend berikan fill, stroke, opacity dan/atau blend +@msg {key} cannot be set on a guide {key} tidak dapat diatur pada panduan +@msg {key} cannot be set on a blend {key} tidak dapat diatur pada blend +@msg {key} cannot be set on an envelope {key} tidak dapat diatur pada amplop +@msg {key} cannot be set on a gradient mesh {key} tidak dapat diatur pada mesh gradien +@msg {key} cannot be set on a Repeat {key} tidak dapat diatur pada perulangan +@msg {key} cannot be set on a placed document {key} tidak dapat diatur pada dokumen yang ditempatkan +@msg {key} cannot be set on an Intertwine group {key} tidak dapat diatur pada grup jalinan +@msg stroke cannot be set on a symbol instance stroke tidak dapat diatur pada instans simbol +@msg fill on a symbol instance must be a solid color or none fill pada instans simbol harus berupa warna solid atau none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} tidak dapat diatur pada gambar tanpa efek Konversi ke bentuk atau Kerangka objek @msg pass newName, registration, exportType, nineSlice and/or type berikan newName, registration, exportType, nineSlice dan/atau type Text Flow Alur teks By Rows Per baris diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index ba04b872e..470224ce3 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -6069,6 +6069,16 @@ breakText Glyphs Glifi @msg path must be a list of child indices path deve essere un elenco di indici figlio @msg no object at path {shown} in the symbol's art nessun oggetto al percorso {shown} nella grafica del simbolo @msg give fill, stroke, opacity and/or blend specifica fill, stroke, opacity e/o blend +@msg {key} cannot be set on a guide {key} non può essere impostato su una guida +@msg {key} cannot be set on a blend {key} non può essere impostato su una fusione +@msg {key} cannot be set on an envelope {key} non può essere impostato su un involucro +@msg {key} cannot be set on a gradient mesh {key} non può essere impostato su una trama sfumatura +@msg {key} cannot be set on a Repeat {key} non può essere impostato su una ripetizione +@msg {key} cannot be set on a placed document {key} non può essere impostato su un documento inserito +@msg {key} cannot be set on an Intertwine group {key} non può essere impostato su un gruppo intrecciato +@msg stroke cannot be set on a symbol instance stroke non può essere impostato su un’istanza di simbolo +@msg fill on a symbol instance must be a solid color or none il fill di un’istanza di simbolo deve essere un colore pieno o none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} non può essere impostato su un’immagine senza l’effetto Converti in forma o Contorna oggetto @msg pass newName, registration, exportType, nineSlice and/or type specifica newName, registration, exportType, nineSlice e/o type Text Flow Flusso del testo By Rows Per righe diff --git a/crates/ui-egui/src/i18n/ja.tsv b/crates/ui-egui/src/i18n/ja.tsv index 24b36257f..2041ea41a 100644 --- a/crates/ui-egui/src/i18n/ja.tsv +++ b/crates/ui-egui/src/i18n/ja.tsv @@ -6134,6 +6134,16 @@ breakText Glyphs 字形 @msg path must be a list of child indices path は子のインデックスのリストにしてください @msg no object at path {shown} in the symbol's art シンボルのアートのパス {shown} にオブジェクトがありません @msg give fill, stroke, opacity and/or blend fill、stroke、opacity、blend のいずれかを指定してください +@msg {key} cannot be set on a guide ガイドには {key} を設定できません +@msg {key} cannot be set on a blend ブレンドには {key} を設定できません +@msg {key} cannot be set on an envelope エンベロープには {key} を設定できません +@msg {key} cannot be set on a gradient mesh グラデーションメッシュには {key} を設定できません +@msg {key} cannot be set on a Repeat リピートには {key} を設定できません +@msg {key} cannot be set on a placed document 配置したドキュメントには {key} を設定できません +@msg {key} cannot be set on an Intertwine group 織り交ぜグループには {key} を設定できません +@msg stroke cannot be set on a symbol instance シンボルインスタンスには stroke を設定できません +@msg fill on a symbol instance must be a solid color or none シンボルインスタンスの fill は単色または none にしてください +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it 「シェイプに変換」または「オブジェクトのアウトライン」効果のない画像には {key} を設定できません @msg pass newName, registration, exportType, nineSlice and/or type newName、registration、exportType、nineSlice、type のいずれかを指定してください Text Flow テキストの流れ By Rows 行方向 diff --git a/crates/ui-egui/src/i18n/ka.tsv b/crates/ui-egui/src/i18n/ka.tsv index 4b329f368..ec39a4fe4 100644 --- a/crates/ui-egui/src/i18n/ka.tsv +++ b/crates/ui-egui/src/i18n/ka.tsv @@ -6447,6 +6447,16 @@ breakText Glyphs გლიფები @msg path must be a list of child indices path უნდა იყოს შვილობილი ინდექსების სია @msg no object at path {shown} in the symbol's art სიმბოლოს გრაფიკაში გზაზე {shown} ობიექტი არ არის @msg give fill, stroke, opacity and/or blend მიუთითეთ fill, stroke, opacity და/ან blend +@msg {key} cannot be set on a guide {key} ვერ დაყენდება დამხმარე ხაზზე +@msg {key} cannot be set on a blend {key} ვერ დაყენდება გადასვლაზე +@msg {key} cannot be set on an envelope {key} ვერ დაყენდება გარსზე +@msg {key} cannot be set on a gradient mesh {key} ვერ დაყენდება გრადიენტულ ბადეზე +@msg {key} cannot be set on a Repeat {key} ვერ დაყენდება გამეორებაზე +@msg {key} cannot be set on a placed document {key} ვერ დაყენდება განთავსებულ დოკუმენტზე +@msg {key} cannot be set on an Intertwine group {key} ვერ დაყენდება გადახლართვის ჯგუფზე +@msg stroke cannot be set on a symbol instance stroke ვერ დაყენდება სიმბოლოს ეგზემპლარზე +@msg fill on a symbol instance must be a solid color or none სიმბოლოს ეგზემპლარის fill უნდა იყოს ერთფეროვანი ფერი ან none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} ვერ დაყენდება გამოსახულებაზე „ფიგურად გარდაქმნის“ ან „ობიექტის კონტურებად გარდაქმნის“ ეფექტის გარეშე @msg pass newName, registration, exportType, nineSlice and/or type მიუთითეთ newName, registration, exportType, nineSlice და/ან type Text Flow ტექსტის დინება By Rows სტრიქონების მიხედვით diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 856c8ba89..c49988f5e 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -6030,6 +6030,16 @@ breakText Glyphs 글리프 @msg path must be a list of child indices path는 자식 인덱스 목록이어야 합니다 @msg no object at path {shown} in the symbol's art 심볼 아트의 경로 {shown}에 개체가 없습니다 @msg give fill, stroke, opacity and/or blend fill, stroke, opacity 및/또는 blend를 지정하세요 +@msg {key} cannot be set on a guide 안내선에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on a blend 블렌드에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on an envelope 엔벨로프에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on a gradient mesh 그레이디언트 메시에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on a Repeat 반복에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on a placed document 가져온 문서에는 {key}을(를) 설정할 수 없습니다 +@msg {key} cannot be set on an Intertwine group 교차 그룹에는 {key}을(를) 설정할 수 없습니다 +@msg stroke cannot be set on a symbol instance 심볼 인스턴스에는 stroke를 설정할 수 없습니다 +@msg fill on a symbol instance must be a solid color or none 심볼 인스턴스의 fill은 단색 또는 none이어야 합니다 +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it 모양으로 변환 또는 개체 윤곽선화 효과가 없는 이미지에는 {key}을(를) 설정할 수 없습니다 @msg pass newName, registration, exportType, nineSlice and/or type newName, registration, exportType, nineSlice 및/또는 type을 지정하세요 Text Flow 텍스트 흐름 By Rows 행 방향 diff --git a/crates/ui-egui/src/i18n/nl.tsv b/crates/ui-egui/src/i18n/nl.tsv index 46ba3105e..38252fd32 100644 --- a/crates/ui-egui/src/i18n/nl.tsv +++ b/crates/ui-egui/src/i18n/nl.tsv @@ -6326,6 +6326,16 @@ breakText Glyphs Glyphs @msg path must be a list of child indices path moet een lijst met onderliggende indexen zijn @msg no object at path {shown} in the symbol's art geen object op pad {shown} in de illustratie van het symbool @msg give fill, stroke, opacity and/or blend geef fill, stroke, opacity en/of blend op +@msg {key} cannot be set on a guide {key} kan niet worden ingesteld op een hulplijn +@msg {key} cannot be set on a blend {key} kan niet worden ingesteld op een vermenging +@msg {key} cannot be set on an envelope {key} kan niet worden ingesteld op een envelop +@msg {key} cannot be set on a gradient mesh {key} kan niet worden ingesteld op een verloopraster +@msg {key} cannot be set on a Repeat {key} kan niet worden ingesteld op een herhaling +@msg {key} cannot be set on a placed document {key} kan niet worden ingesteld op een geplaatst document +@msg {key} cannot be set on an Intertwine group {key} kan niet worden ingesteld op een verstrengelde groep +@msg stroke cannot be set on a symbol instance stroke kan niet worden ingesteld op een symboolinstantie +@msg fill on a symbol instance must be a solid color or none fill van een symboolinstantie moet een egale kleur of none zijn +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} kan niet worden ingesteld op een afbeelding zonder het effect Converteren naar vorm of Object omtrekken @msg pass newName, registration, exportType, nineSlice and/or type geef newName, registration, exportType, nineSlice en/of type op Text Flow Tekstdoorloop By Rows Per rij diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 270e7a356..ddeded23a 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -6304,6 +6304,16 @@ breakText Glyphs Glify @msg path must be a list of child indices path musi być listą indeksów elementów podrzędnych @msg no object at path {shown} in the symbol's art brak obiektu w ścieżce {shown} w grafice symbolu @msg give fill, stroke, opacity and/or blend podaj fill, stroke, opacity i/lub blend +@msg {key} cannot be set on a guide nie można ustawić {key} dla linii pomocniczej +@msg {key} cannot be set on a blend nie można ustawić {key} dla przejścia +@msg {key} cannot be set on an envelope nie można ustawić {key} dla koperty +@msg {key} cannot be set on a gradient mesh nie można ustawić {key} dla siatki gradientowej +@msg {key} cannot be set on a Repeat nie można ustawić {key} dla powtórzenia +@msg {key} cannot be set on a placed document nie można ustawić {key} dla umieszczonego dokumentu +@msg {key} cannot be set on an Intertwine group nie można ustawić {key} dla grupy przeplatania +@msg stroke cannot be set on a symbol instance nie można ustawić stroke dla wystąpienia symbolu +@msg fill on a symbol instance must be a solid color or none fill wystąpienia symbolu musi być jednolitym kolorem lub none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it nie można ustawić {key} dla obrazu bez efektu Konwertuj na kształt lub Kontur obiektu @msg pass newName, registration, exportType, nineSlice and/or type podaj newName, registration, exportType, nineSlice i/lub type Text Flow Przepływ tekstu By Rows Wierszami diff --git a/crates/ui-egui/src/i18n/pt-br.tsv b/crates/ui-egui/src/i18n/pt-br.tsv index 0827c88e5..70006dd0e 100644 --- a/crates/ui-egui/src/i18n/pt-br.tsv +++ b/crates/ui-egui/src/i18n/pt-br.tsv @@ -6367,6 +6367,16 @@ breakText Glyphs Glifos @msg path must be a list of child indices path deve ser uma lista de índices de filhos @msg no object at path {shown} in the symbol's art nenhum objeto no caminho {shown} na arte do símbolo @msg give fill, stroke, opacity and/or blend informe fill, stroke, opacity e/ou blend +@msg {key} cannot be set on a guide {key} não pode ser definido em uma guia +@msg {key} cannot be set on a blend {key} não pode ser definido em uma mesclagem +@msg {key} cannot be set on an envelope {key} não pode ser definido em um envelope +@msg {key} cannot be set on a gradient mesh {key} não pode ser definido em uma malha de gradiente +@msg {key} cannot be set on a Repeat {key} não pode ser definido em uma repetição +@msg {key} cannot be set on a placed document {key} não pode ser definido em um documento colocado +@msg {key} cannot be set on an Intertwine group {key} não pode ser definido em um grupo entrelaçado +@msg stroke cannot be set on a symbol instance stroke não pode ser definido em uma instância de símbolo +@msg fill on a symbol instance must be a solid color or none o fill de uma instância de símbolo deve ser uma cor sólida ou none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} não pode ser definido em uma imagem sem o efeito Converter em Forma ou Contornar Objeto @msg pass newName, registration, exportType, nineSlice and/or type informe newName, registration, exportType, nineSlice e/ou type # Strings the sibling catalogs translate that pt-BR did not yet cover (translated 2026-10-31). on the canvas to create one na tela para criar um diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 8deafd1d5..86839abb5 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -6426,6 +6426,16 @@ breakText Glyphs Глифы @msg path must be a list of child indices path должен быть списком индексов дочерних объектов @msg no object at path {shown} in the symbol's art в графике символа нет объекта по пути {shown} @msg give fill, stroke, opacity and/or blend укажите fill, stroke, opacity и/или blend +@msg {key} cannot be set on a guide {key} нельзя задать для направляющей +@msg {key} cannot be set on a blend {key} нельзя задать для перехода +@msg {key} cannot be set on an envelope {key} нельзя задать для оболочки +@msg {key} cannot be set on a gradient mesh {key} нельзя задать для градиентной сетки +@msg {key} cannot be set on a Repeat {key} нельзя задать для повторения +@msg {key} cannot be set on a placed document {key} нельзя задать для помещенного документа +@msg {key} cannot be set on an Intertwine group {key} нельзя задать для группы переплетения +@msg stroke cannot be set on a symbol instance stroke нельзя задать для экземпляра символа +@msg fill on a symbol instance must be a solid color or none fill экземпляра символа должен быть сплошным цветом или none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} нельзя задать для изображения без эффекта «Преобразовать в фигуру» или «Обвести объект» @msg pass newName, registration, exportType, nineSlice and/or type укажите newName, registration, exportType, nineSlice и/или type Text Flow Поток текста By Rows По строкам diff --git a/crates/ui-egui/src/i18n/sv.tsv b/crates/ui-egui/src/i18n/sv.tsv index 578feef9c..a2f701c56 100644 --- a/crates/ui-egui/src/i18n/sv.tsv +++ b/crates/ui-egui/src/i18n/sv.tsv @@ -6501,6 +6501,16 @@ breakText Glyphs Glyfer @msg path must be a list of child indices path måste vara en lista med underordnade index @msg no object at path {shown} in the symbol's art inget objekt vid sökvägen {shown} i symbolens bild @msg give fill, stroke, opacity and/or blend ange fill, stroke, opacity och/eller blend +@msg {key} cannot be set on a guide {key} kan inte anges för en stödlinje +@msg {key} cannot be set on a blend {key} kan inte anges för en blandning +@msg {key} cannot be set on an envelope {key} kan inte anges för ett kuvert +@msg {key} cannot be set on a gradient mesh {key} kan inte anges för ett gradientnät +@msg {key} cannot be set on a Repeat {key} kan inte anges för en upprepning +@msg {key} cannot be set on a placed document {key} kan inte anges för ett placerat dokument +@msg {key} cannot be set on an Intertwine group {key} kan inte anges för en sammanflätad grupp +@msg stroke cannot be set on a symbol instance stroke kan inte anges för en symbolinstans +@msg fill on a symbol instance must be a solid color or none fill för en symbolinstans måste vara en enfärgad färg eller none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} kan inte anges för en bild utan effekten Konvertera till form eller Konvertera objekt till konturer @msg pass newName, registration, exportType, nineSlice and/or type ange newName, registration, exportType, nineSlice och/eller type Text Flow Textflöde By Rows Radvis diff --git a/crates/ui-egui/src/i18n/tr.tsv b/crates/ui-egui/src/i18n/tr.tsv index 6931e8489..1ed96a44c 100644 --- a/crates/ui-egui/src/i18n/tr.tsv +++ b/crates/ui-egui/src/i18n/tr.tsv @@ -6406,6 +6406,16 @@ breakText Glyphs Glifler @msg path must be a list of child indices path alt öğe dizinlerinden oluşan bir liste olmalıdır @msg no object at path {shown} in the symbol's art sembolün çiziminde {shown} yolunda nesne yok @msg give fill, stroke, opacity and/or blend fill, stroke, opacity ve/veya blend verin +@msg {key} cannot be set on a guide {key} bir kılavuzda ayarlanamaz +@msg {key} cannot be set on a blend {key} bir karışımda ayarlanamaz +@msg {key} cannot be set on an envelope {key} bir zarfta ayarlanamaz +@msg {key} cannot be set on a gradient mesh {key} bir degrade örgüde ayarlanamaz +@msg {key} cannot be set on a Repeat {key} bir tekrarda ayarlanamaz +@msg {key} cannot be set on a placed document {key} yerleştirilmiş bir belgede ayarlanamaz +@msg {key} cannot be set on an Intertwine group {key} bir iç içe geçirme grubunda ayarlanamaz +@msg stroke cannot be set on a symbol instance stroke bir sembol örneğinde ayarlanamaz +@msg fill on a symbol instance must be a solid color or none bir sembol örneğinin fill değeri düz renk veya none olmalıdır +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key}, Şekle Dönüştür veya Anahat Nesnesi efekti olmayan bir görüntüde ayarlanamaz @msg pass newName, registration, exportType, nineSlice and/or type newName, registration, exportType, nineSlice ve/veya type verin Text Flow Metin Akışı By Rows Satırlara Göre diff --git a/crates/ui-egui/src/i18n/uk.tsv b/crates/ui-egui/src/i18n/uk.tsv index 89189e12f..cfe40daff 100644 --- a/crates/ui-egui/src/i18n/uk.tsv +++ b/crates/ui-egui/src/i18n/uk.tsv @@ -6049,6 +6049,16 @@ breakText Glyphs Гліфи @msg path must be a list of child indices path має бути списком індексів дочірніх об’єктів @msg no object at path {shown} in the symbol's art у графіці символу немає об’єкта за шляхом {shown} @msg give fill, stroke, opacity and/or blend вкажіть fill, stroke, opacity та/або blend +@msg {key} cannot be set on a guide {key} не можна задати для напрямної +@msg {key} cannot be set on a blend {key} не можна задати для переходу +@msg {key} cannot be set on an envelope {key} не можна задати для оболонки +@msg {key} cannot be set on a gradient mesh {key} не можна задати для градієнтної сітки +@msg {key} cannot be set on a Repeat {key} не можна задати для повторення +@msg {key} cannot be set on a placed document {key} не можна задати для розміщеного документа +@msg {key} cannot be set on an Intertwine group {key} не можна задати для групи переплетення +@msg stroke cannot be set on a symbol instance stroke не можна задати для екземпляра символу +@msg fill on a symbol instance must be a solid color or none fill екземпляра символу має бути суцільним кольором або none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it {key} не можна задати для зображення без ефекту «Перетворити на фігуру» або «Обвести об’єкт» @msg pass newName, registration, exportType, nineSlice and/or type вкажіть newName, registration, exportType, nineSlice та/або type Text Flow Потік тексту By Rows За рядками diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index a58087cd1..a59521044 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -6050,6 +6050,16 @@ breakText Glyphs Glyph @msg path must be a list of child indices path phải là danh sách chỉ số con @msg no object at path {shown} in the symbol's art không có đối tượng tại đường dẫn {shown} trong hình của ký hiệu @msg give fill, stroke, opacity and/or blend hãy cung cấp fill, stroke, opacity và/hoặc blend +@msg {key} cannot be set on a guide không thể đặt {key} cho đường căn +@msg {key} cannot be set on a blend không thể đặt {key} cho hòa trộn +@msg {key} cannot be set on an envelope không thể đặt {key} cho envelope +@msg {key} cannot be set on a gradient mesh không thể đặt {key} cho lưới chuyển sắc +@msg {key} cannot be set on a Repeat không thể đặt {key} cho lặp lại +@msg {key} cannot be set on a placed document không thể đặt {key} cho tài liệu đã đặt +@msg {key} cannot be set on an Intertwine group không thể đặt {key} cho nhóm đan xen +@msg stroke cannot be set on a symbol instance không thể đặt stroke cho thực thể ký hiệu +@msg fill on a symbol instance must be a solid color or none fill của thực thể ký hiệu phải là màu đặc hoặc none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it không thể đặt {key} cho hình ảnh không có hiệu ứng Chuyển thành hình dạng hoặc Đường bao đối tượng @msg pass newName, registration, exportType, nineSlice and/or type hãy cung cấp newName, registration, exportType, nineSlice và/hoặc type Text Flow Luồng văn bản By Rows Theo hàng diff --git a/crates/ui-egui/src/i18n/zh-hans.tsv b/crates/ui-egui/src/i18n/zh-hans.tsv index ef0711e48..5cde122a9 100644 --- a/crates/ui-egui/src/i18n/zh-hans.tsv +++ b/crates/ui-egui/src/i18n/zh-hans.tsv @@ -6290,6 +6290,16 @@ breakText Glyphs 字形 @msg path must be a list of child indices path 必须是子项索引列表 @msg no object at path {shown} in the symbol's art 符号图稿中路径 {shown} 处没有对象 @msg give fill, stroke, opacity and/or blend 请提供 fill、stroke、opacity 和/或 blend +@msg {key} cannot be set on a guide 无法为参考线设置 {key} +@msg {key} cannot be set on a blend 无法为混合设置 {key} +@msg {key} cannot be set on an envelope 无法为封套设置 {key} +@msg {key} cannot be set on a gradient mesh 无法为渐变网格设置 {key} +@msg {key} cannot be set on a Repeat 无法为重复设置 {key} +@msg {key} cannot be set on a placed document 无法为置入的文档设置 {key} +@msg {key} cannot be set on an Intertwine group 无法为交织编组设置 {key} +@msg stroke cannot be set on a symbol instance 无法为符号实例设置 stroke +@msg fill on a symbol instance must be a solid color or none 符号实例的 fill 必须是纯色或 none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it 无法为没有“转换为形状”或“轮廓化对象”效果的图像设置 {key} @msg pass newName, registration, exportType, nineSlice and/or type 请提供 newName、registration、exportType、nineSlice 和/或 type Text Flow 文本流向 By Rows 按行 diff --git a/crates/ui-egui/src/i18n/zh-hant.tsv b/crates/ui-egui/src/i18n/zh-hant.tsv index 733008a65..d61ffb375 100644 --- a/crates/ui-egui/src/i18n/zh-hant.tsv +++ b/crates/ui-egui/src/i18n/zh-hant.tsv @@ -6087,6 +6087,16 @@ breakText Glyphs 字符 @msg path must be a list of child indices path 必須是子項索引清單 @msg no object at path {shown} in the symbol's art 符號圖稿中路徑 {shown} 處沒有物件 @msg give fill, stroke, opacity and/or blend 請提供 fill、stroke、opacity 和/或 blend +@msg {key} cannot be set on a guide 無法為參考線設定 {key} +@msg {key} cannot be set on a blend 無法為漸變設定 {key} +@msg {key} cannot be set on an envelope 無法為封套設定 {key} +@msg {key} cannot be set on a gradient mesh 無法為漸層網格設定 {key} +@msg {key} cannot be set on a Repeat 無法為重複設定 {key} +@msg {key} cannot be set on a placed document 無法為置入的文件設定 {key} +@msg {key} cannot be set on an Intertwine group 無法為交織群組設定 {key} +@msg stroke cannot be set on a symbol instance 無法為符號範例設定 stroke +@msg fill on a symbol instance must be a solid color or none 符號範例的 fill 必須是純色或 none +@msg {key} cannot be set on an image without a Convert to Shape or Outline Object effect on it 無法為沒有「轉換為形狀」或「外框物件」效果的影像設定 {key} @msg pass newName, registration, exportType, nineSlice and/or type 請提供 newName、registration、exportType、nineSlice 和/或 type Text Flow 文字流向 By Rows 依列 diff --git a/docs/mcp.md b/docs/mcp.md index 6bff1f368..69deb6502 100644 --- a/docs/mcp.md +++ b/docs/mcp.md @@ -1797,9 +1797,14 @@ already walks Image Trace. Short agent entry points: art for itself only and stays linked. `symbol.instance.setAppearance {id?, path, fill?, stroke?, opacity?, blend?}` names the object by `path`, child indices in paint order from the art's root down through its groups (`[]` is the root; `[1, 0]` is the first object of the art's second member when that member is a group). `fill` and `stroke` take - a colour string or the paint params of `paint.setFill` (`color`, `none`, `swatch`, `tint`, `gradient`), `opacity` is - 0..100 and `blend` a blend mode name; `null` gives one back to the symbol. It is refused for a static symbol and for - a path that names no object. On the canvas (VectorCraft's own rule), a Direct Selection click on an instance of a + a colour string or the paint params of `paint.setFill` (`color`, `none`, `swatch`, `tint`, `gradient`). Paths, + compound paths, type, groups and layers take both. A symbol instance takes a solid color or `none` as its fill, + which stains its art, and no gradient or pattern fill and no stroke. An image takes a fill or stroke only when that + fill or stroke has a Convert to Shape or Outline Object effect. A guide, blend, envelope, Repeat, Intertwine group, + gradient mesh or placed document takes neither. A refused fill or stroke (VectorCraft's own rule) gives an error + that names the key and the object, and nothing of the call is applied; `opacity`, `blend` and `null` are taken for + every object, so a stored change can be taken back. `opacity` is 0..100 and `blend` a blend mode name; `null` gives + one back to the symbol. It is refused for a static symbol and for a path that names no object. On the canvas (VectorCraft's own rule), a Direct Selection click on an instance of a dynamic symbol selects the path, compound path or type object of its art under the pointer and outlines it (`symbol.instance.selectPart {id, path}`; Alt or Shift selects the instance whole). While it is selected, `paint.setFill` and `paint.setStroke` with a solid color or none, `paint.invert` and `paint.complement` on a solid diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index adc5f473a..4f8072436 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -738,6 +738,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur - **Symbol libraries** ([public source](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/create-or-import-symbol-libraries.html)): Window › Symbol Libraries and the Symbols panel's Symbol Libraries Menu open each library in a library panel of its own, as swatch and graphic style libraries do. The built-in library, Basic Shapes, is original art generated in code (`crates/engine/src/cmd/symbollib.rs`). A click on a symbol adds it to the document's Symbols as one undo step, with its Symbol Options (size, registration, export type, 9-slice guides) and every resource it uses (the symbols it nests, patterns, swatches, brushes, graphic styles, images), and makes it the current symbol; a symbol the document already has is not added again and another symbol of the same name keeps its name, the library's comes in numbered. Thumbnails, in the library panels and the Symbols panel, draw a symbol with the symbols it nests and the patterns and images it uses. Dragging a library symbol onto the canvas also places an instance there, in the same step ([placing from a library](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/create-and-place-symbols.html)). Save Symbols (the library menu) and Save Symbol Library… (the Symbols panel menu) write the document's symbols as a `.vectorcraft` document holding only them, into the user library folder (listed under User Defined) or a file; Other Library… reads the symbols of any document VectorCraft opens; a file it can't read is an error and opens no panel. Tests: `crates/engine/src/tests/symbollib.rs`, `crates/ui-egui/src/panels/tests_symbol_libraries.rs`, `panels::symbols::tests::thumbnails_show_the_symbols_a_symbol_nests`, `canvas::tests::a_library_symbol_dropped_on_the_canvas_is_added_and_placed_there_in_one_step`. - **9-slice scaling** ([public source](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/maintain-proportions-while-scaling-symbols.html)): a scaled instance of a symbol with Enable Guides for 9-Slice Scaling on stays an instance and keeps the parts of its art outside the guides at their size. New guides sit a quarter of the symbol's width and height in from each edge ([reference](https://help.adobe.com/archive/en/illustrator/cs6/illustrator_reference.pdf), Use 9-slice scaling section); saved guides keep their values. The rest is VectorCraft's own rule: the corners keep both sizes, the top and bottom edges stretch in width, the left and right edges in height and the center in both; an instance smaller than its two outer cells on an axis shrinks them in proportion and leaves the center empty; the cells are sized along the symbol's axes before the instance's rotation, shear or reflection. A path with solid paint that crosses a guide is cut there and stays one path, its stroke at its weight with Scale Strokes & Effects on or off; type, images, live objects and gradient or pattern paint that cross a guide are drawn in each cell they reach, clipped to it, except those that draw symbol art (a nested instance, type with an inline graphic, a placed document, a brushed stroke, or a pattern whose tile draws one of these), which are placed by the cell their center is in; an object in one cell is placed by that cell and stays as it is. The canvas, bounds, the Eyedropper, Break Link to Symbol and the PDF, EPS, DXF, EMF/WMF and SVG exports place the art the same way; SVG writes such an instance as its placed art instead of a ``, and DXF and WMF, which do not clip, cut every path that crosses a guide and place other such objects by the cell their center is in. Tests: `symbol_nine_slice::tests` in `crates/doc`, `crates/engine/src/tests/symbol_nine_slice.rs`, `a_scaled_nine_slice_instance_keeps_its_corners` (PDF), `a_scaled_nine_slice_instance_is_written_as_the_canvas_draws_it` (SVG), `a_scaled_nine_slice_instance_is_sampled_as_it_is_drawn` (Eyedropper). - **Symbol editing mode** ([Edit symbols](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/edit-symbols.html), [Symbols panel options](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/symbols-panel-options.html)): a double-click on a symbol instance, the Control bar's Edit Symbol button, a double-click on a symbol in the Symbols panel and the panel menu's Edit Symbol (`symbol.edit`) open the symbol's art on a temporary isolated layer, where the instance shows it (from the panel: centered on the active artboard, or in the view in a document without artboards), with the rest of the document dimmed. Each edit there changes every instance at once; the instances keep their own transforms and stay linked (Break Link to Symbol still expands one), and a dynamic symbol's instances keep their appearance changes to the objects the art still has. Escape, the isolation bar's back button, the Control bar's Exit Symbol Editing Mode and a double-click outside the art leave the mode (`symbol.exitEditing`); leaving without an edit adds no undo step. Saving leaves the editing layer out. Tests: `crates/engine/src/tests/symboledit.rs`, `select::tests::a_double_click_on_a_symbol_instance_edits_its_symbol`, `panels::symbols::tests::edit_symbol_from_the_panel_centers_the_art_on_the_active_artboard_or_the_view`. + - **Dynamic symbol appearance follows what an object draws** (VectorCraft's own rule): `symbol.instance.setAppearance` refuses a fill or stroke for an object of the art that does not draw it (a guide, blend, envelope, Repeat, Intertwine group, gradient mesh or placed document; a nested symbol instance's stroke, and its fill unless a solid color or none, which stains its art; an image's fill or stroke without a Convert to Shape or Outline Object effect) with an error that names the key and the object, and the call changes nothing. Opacity, blend and `null`, which takes a stored change back, are taken for every object. Tests: `crates/engine/src/tests/dynamic_symbols.rs`. - Symbol editing mode keeps every instance in step: instances of a dynamic symbol inside other symbols' art, pattern tiles, graph designs, stored brushes and opacity masks keep their appearance changes on the objects an edit reorders and drop the changes to objects it deletes. The view does not draw the instance the edit was entered from. Area type in the symbol's art takes the text wrap that moving a wrap object gives it. Editing another symbol at a place that fails keeps the current edit open, and only the editing layer or art on it can be isolated. Tests: `crates/engine/src/tests/symboledit.rs`, `isolation::symbol_editing_does_not_draw_the_instance_it_was_entered_from`, `panels::symbols::tests::double_clicking_a_symbol_in_the_panel_edits_it_in_either_view`, `the_panel_menus_edit_symbol_edits_the_instances_symbol_or_the_panels`, `the_control_bars_edit_symbol_edits_the_selected_instances_symbol`, `chrome::tests::the_control_bar_exits_symbol_editing_mode`. - **Dynamic symbol instances on the canvas** ([Symbols, archived copy](https://web.archive.org/web/20240206075757/https://helpx.adobe.com/illustrator/using/symbols.html)): each instance of a dynamic symbol can have an appearance of its own while it shares the symbol's shape. The rest of this entry is VectorCraft's own rules. A Direct Selection click on an instance of a dynamic symbol selects the path, compound path or type object of the symbol's art under the pointer and outlines it (`symbol.instance.selectPart`); the Swatches and Color panels, the Control bar, the Eyedropper and the other fill and stroke controls then change that object's solid color fill or stroke for this instance only, each as one undo step, and the symbol's art and its other instances stay as they were. Alt or Shift picks the instance whole. A gradient or pattern for the object, an Eyedropper source that is not a path, compound path or type, a click on any other object of the art (a group, image, blend or nested instance) and the commands that change the selected objects (opacity, moving, Delete, Group, Hide, Lock, Arrange, Expand, the gradient commands, the Appearance panel's rows and others) are refused with a status message. Copy, Export Selection, Fit to Selection, Liquify, Isolate, Add to Library and Save Selection use the whole instance (`docs/mcp.md`), and another selection tool selects the instance whole again. Tests: `crates/engine/src/tests/dynamic_symbols.rs`, `direct::tests::a_click_on_a_dynamic_instance_picks_the_object_under_the_pointer`. - **9-slice guides on the canvas** ([public source](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/maintain-proportions-while-scaling-symbols.html)): while a symbol with Enable Guides for 9-Slice Scaling on is edited in symbol editing mode, the canvas draws its two horizontal and two vertical guides as dotted lines across its art, with any tool and with ruler guides hidden. With the Selection tool the pointer near a guide shows the Move cursor, and dragging the guide moves it (`symbol.options`'s `nineSliceGuides`) as one undo step; Escape during the drag puts it back. VectorCraft's own rules: a guide within 4 screen pixels takes the press before the art and the bounding box; it stays within the art's box (guides outside the art are not supported yet) and stops short of the opposite guide; the drag does not snap. Tests: `nineslice::tests`, `symbol_nine_slice::tests::the_edited_symbols_guides_cross_its_art_where_the_editing_layer_shows_it`, `a_moved_guide_stays_in_the_art_and_short_of_the_opposite_guide`, `canvas::tests::the_edited_symbols_nine_slice_guides_are_drawn_and_dragged_on_the_canvas`. @@ -1791,7 +1792,7 @@ A VectorCraft addition, not a feature of the reference app, so no area score mov ## Dynamic symbols (2026-11-01) -Symbols area (#4938), from the public symbol documentation ([create and place symbols](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/create-and-place-symbols.html), [edit symbols](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/edit-symbols.html)). Symbol Options has Symbol Type (Dynamic Symbol / Static Symbol; the dialog's default is Dynamic, `symbol.new`'s `type` defaults to static so scripts behave as before). An instance of a dynamic symbol keeps its own fill, stroke, opacity and blend for any object of the symbol's art, named by a child-index path (`symbol.instance.setAppearance`), and stays an instance: the canvas, SVG, PDF, EPS, legacy `.ai`, EMF/WMF and DXF writers, effects and Expand draw the art with those changes. Redefining the symbol reshapes every instance and keeps each change whose object the new art still has; Break Link bakes the changes into the art; Edit Symbol expands the symbol's own art; Reset (`symbol.instance.reset`: the Properties panel's Quick Actions and the Symbols panel menu) and making the symbol static drop them, and Replace Symbol drops them when it gives the instance a different symbol. The type is stored on the symbol and the changes on the instance in the native format, both left out when unset, so documents without them save byte for byte as before. Remaining: on-canvas editing beyond a solid fill and stroke on a path, compound path or type object inside a dynamic instance; reading and writing the type and changes in `.ai` files. Evidence: `crates/engine/src/tests/dynamic_symbols.rs`, `crates/doc/src/symbol_overrides.rs` tests. Score unchanged at 87% (estimated); hours 5–9 → 4–8. +Symbols area (#4938), from the public symbol documentation ([create and place symbols](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/create-and-place-symbols.html), [edit symbols](https://helpx.adobe.com/illustrator/desktop/manage-objects/traces-mockups-symbols/edit-symbols.html)). Symbol Options has Symbol Type (Dynamic Symbol / Static Symbol; the dialog's default is Dynamic, `symbol.new`'s `type` defaults to static so scripts behave as before). An instance of a dynamic symbol keeps its own opacity and blend for any object of the symbol's art, and its own fill and stroke for an object that draws them, named by a child-index path (`symbol.instance.setAppearance`), and stays an instance: the canvas, SVG, PDF, EPS, legacy `.ai`, EMF/WMF and DXF writers, effects and Expand draw the art with those changes. Redefining the symbol reshapes every instance and keeps each change whose object the new art still has; Break Link bakes the changes into the art; Edit Symbol expands the symbol's own art; Reset (`symbol.instance.reset`: the Properties panel's Quick Actions and the Symbols panel menu) and making the symbol static drop them, and Replace Symbol drops them when it gives the instance a different symbol. The type is stored on the symbol and the changes on the instance in the native format, both left out when unset, so documents without them save byte for byte as before. Remaining: on-canvas editing beyond a solid fill and stroke on a path, compound path or type object inside a dynamic instance; reading and writing the type and changes in `.ai` files. Evidence: `crates/engine/src/tests/dynamic_symbols.rs`, `crates/doc/src/symbol_overrides.rs` tests. Score unchanged at 87% (estimated); hours 5–9 → 4–8. ## Document Tools add-on: Export All Open Documents (2026-11-01)