mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
Merge pull request #2686 from storytold/fix/2441-group-select-compound-part
Part of #2441: Group Selection picks and moves one path of a compound path; i18n and docs for the sixth batch
This commit is contained in:
+2
-2
@@ -9,7 +9,7 @@
|
||||
|
||||
**Stage: alpha** · next: beta, ~13 points (ready for real work ~62% → ~75%, and reliable `.ai` exchange) and ~170–270 h away
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-17 · **Change:** minor (about 115 community PRs of 2026-10-17: image-decode overflow guards, opaque floating panels, MCP export cancel and progress, editable Illustrator EPS import, scoped `doc_inspect`, Dutch, Danish and Indonesian, Simplified Chinese messages, screen-reader names; headline numbers unchanged; about 160 community PRs of 2026-10-15/16: PDF import crash fixes, Dimension tool, legacy `.ai` save, Intertwine, web pen input, Image Trace fixes, `.ai`/EPS/PDF import fidelity, Bulgarian, Greek, Swedish and Finnish catalogs; headline numbers unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-17 · **Change:** minor (about 145 community PRs of 2026-10-17: image-decode overflow guards, opaque floating panels, MCP export cancel and progress, editable Illustrator EPS import, scoped `doc_inspect`, Dutch, Danish and Indonesian, Simplified Chinese messages, screen-reader names; headline numbers unchanged; about 160 community PRs of 2026-10-15/16: PDF import crash fixes, Dimension tool, legacy `.ai` save, Intertwine, web pen input, Image Trace fixes, `.ai`/EPS/PDF import fidelity, Bulgarian, Greek, Swedish and Finnish catalogs; headline numbers unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
VectorCraft is a clean-room, open-source, pure-Rust reimplementation of the Adobe Illustrator workflow. It runs
|
||||
on macOS, Windows, Linux, FreeBSD and the web (WASM), and agents can drive all of it over MCP, the CLI and a JSON
|
||||
@@ -134,7 +134,7 @@ Ranked; detail in [docs/roadmap.md](docs/roadmap.md) and [docs/gaps.md](docs/gap
|
||||
|
||||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-17 | About 115 community PRs landed in five batches, each through the full gate, plus our fixes on top. Crashes and hostile input: an image's RGBA size is checked from its header before decoding, without overflowing, in the renderer, sampling, recoloring and Crop Image (#2442, #2468, #2407), PDF Add Around and huge art are clamped (#2440), graph axis labels past i64, `+` in hex colours and XML ids are handled (#2610, #2470, #2447), Document Raster Effects resolutions open in range (#2579), Batch names stay in their folder (#2504). Regressions: floating panel groups are opaque again while the docked card keeps its rounded corners (#2499), the Wayland pointer returns over panels (#2502). New: MCP cancels long exports, answers while one runs and reports progress (#2546), `doc_inspect` takes ids, kind and paging (#2543), raster export of a page rectangle (#2511), `text.create` returns bounds (#2478), PDF presets and ICC profiles persist (#2547), screen-reader names for widgets (#2611), Expand on Intertwine (#2622, fixes #2540), Duplicate/Copy/Cut of several artboards (#2567), print presets by name (#2607), TSV data sets (#2608), planar TIFF (#2598), Alt-click a swatch onto a gradient stop (#2623), Shift-click ranges in Links, Graphic Styles and Libraries (#2612, #2613, #2618), Space+Shift rotates the view (#2601), Presentation Mode keys (#2583), Small Caps and super/subscript buttons (#2508). Fidelity: editable vector art from Illustrator EPS (#2571), `.ai` Drop Shadow Darkness (#2513), overprint preview with Darken (#2514), Generic CMYK black round-trips (#2503), PNG sRGB chunk (#2519), kerning at a caret (#2518), tab widths in justified area type (#2487), Transform copies keep their own gradients (#2486), smooth Zig Zag (#2475), Live Corners round up to their neighbours (#2484), kerning across style runs (#2554), SVG letter spacing on justified lines (#2574), Dimension tool snapping (#2482), gradient chips (#2495), Transform panel flips and percentages (#2400, #2404). Later the same day: PostScript `.ps` and `.epsf` files open (#2461), EPS images with CCITTFax compression draw (#2445), Illustrator 3 EPS without layers (#2436), `.ai` type opacity and blend modes (#2420), envelope meshes and compound holes in `.ai` (#2410, #2444), CMYK image soft masks in PDF export (#2448), Show Transparency Grid saved with the document (#2488), Save Selection in the Layers panel menu (#2483), Character and Paragraph Reset Panel (#2479, #2438), Cmd/Ctrl+Shift double-click releases a guide (#2467), Shift+Enter keeps a field active (#2431), Shift keeps reshaped handles perpendicular (#2425), emptied type keeps its style (#2464), Smart Blur radius (#2443), freeform gradients recolour (#2397), mesh slivers (#2456), Recolor wheel handles in CMYK (#2454), and six Image Trace fixes (#2387, #2584, #2586–#2589). Fifth batch: Optical Margin Alignment (#2563), Window › Blend panel (#2573), graph column designs (#2406), Live Paint Gap Options (#2424), the SVG Interactivity panel (#2437), RTF placed as area type (#2524), the Touch Type tool (#2469), pattern fills expand into clipped tiles (#2616), Save and Export ask before replacing a file an added extension names (#2619), the Artboard tool's Control bar and Contextual Task Bar (#2559, #2556), Alt-click New Artboard for its options (#2496), Shift-click in Brushes (#2562), the Move dialog remembers the last move (#2542), PDF export uses the document's assigned profiles (#2536), Printer Setup opens the selected printer's preferences on Windows (#2577). Languages: Dutch, Danish and Indonesian complete (#2393), Simplified Chinese status and error messages (#2578), translated file filters and presets (#2590). Headline numbers unchanged (estimated). |
|
||||
| 2026-10-17 | About 145 community PRs landed in six batches, each through the full gate, plus our fixes on top. Crashes and hostile input: an image's RGBA size is checked from its header before decoding, without overflowing, in the renderer, sampling, recoloring and Crop Image (#2442, #2468, #2407), PDF Add Around and huge art are clamped (#2440), graph axis labels past i64, `+` in hex colours and XML ids are handled (#2610, #2470, #2447), Document Raster Effects resolutions open in range (#2579), Batch names stay in their folder (#2504). Regressions: floating panel groups are opaque again while the docked card keeps its rounded corners (#2499), the Wayland pointer returns over panels (#2502). New: MCP cancels long exports, answers while one runs and reports progress (#2546), `doc_inspect` takes ids, kind and paging (#2543), raster export of a page rectangle (#2511), `text.create` returns bounds (#2478), PDF presets and ICC profiles persist (#2547), screen-reader names for widgets (#2611), Expand on Intertwine (#2622, fixes #2540), Duplicate/Copy/Cut of several artboards (#2567), print presets by name (#2607), TSV data sets (#2608), planar TIFF (#2598), Alt-click a swatch onto a gradient stop (#2623), Shift-click ranges in Links, Graphic Styles and Libraries (#2612, #2613, #2618), Space+Shift rotates the view (#2601), Presentation Mode keys (#2583), Small Caps and super/subscript buttons (#2508). Fidelity: editable vector art from Illustrator EPS (#2571), `.ai` Drop Shadow Darkness (#2513), overprint preview with Darken (#2514), Generic CMYK black round-trips (#2503), PNG sRGB chunk (#2519), kerning at a caret (#2518), tab widths in justified area type (#2487), Transform copies keep their own gradients (#2486), smooth Zig Zag (#2475), Live Corners round up to their neighbours (#2484), kerning across style runs (#2554), SVG letter spacing on justified lines (#2574), Dimension tool snapping (#2482), gradient chips (#2495), Transform panel flips and percentages (#2400, #2404). Later the same day: PostScript `.ps` and `.epsf` files open (#2461), EPS images with CCITTFax compression draw (#2445), Illustrator 3 EPS without layers (#2436), `.ai` type opacity and blend modes (#2420), envelope meshes and compound holes in `.ai` (#2410, #2444), CMYK image soft masks in PDF export (#2448), Show Transparency Grid saved with the document (#2488), Save Selection in the Layers panel menu (#2483), Character and Paragraph Reset Panel (#2479, #2438), Cmd/Ctrl+Shift double-click releases a guide (#2467), Shift+Enter keeps a field active (#2431), Shift keeps reshaped handles perpendicular (#2425), emptied type keeps its style (#2464), Smart Blur radius (#2443), freeform gradients recolour (#2397), mesh slivers (#2456), Recolor wheel handles in CMYK (#2454), and six Image Trace fixes (#2387, #2584, #2586–#2589). Fifth batch: Optical Margin Alignment (#2563), Window › Blend panel (#2573), graph column designs (#2406), Live Paint Gap Options (#2424), the SVG Interactivity panel (#2437), RTF placed as area type (#2524), the Touch Type tool (#2469), pattern fills expand into clipped tiles (#2616), Save and Export ask before replacing a file an added extension names (#2619), the Artboard tool's Control bar and Contextual Task Bar (#2559, #2556), Alt-click New Artboard for its options (#2496), Shift-click in Brushes (#2562), the Move dialog remembers the last move (#2542), PDF export uses the document's assigned profiles (#2536), Printer Setup opens the selected printer's preferences on Windows (#2577). Sixth batch: Effect › Artistic › Cutout, Neon Glow and Poster Edges (#2453), View › Rulers › Change to Global / Artboard Rulers (#2416), Symbol Options 9-slice guides (#2512), Create Gradient Mesh on an embedded image (#2538), Rotate View cursors and the Mac trackpad rotation gesture (#2594, #2644), choice parameters as dropdowns in the inline effect editor (#2582), Group Selection picks and moves one path of a compound path (part of #2441), Shift-click ranges in the Artboards panel (#2626), Lock Variables (#2631), a layer dropped under the last row goes to the bottom (#2632), and robustness work: huge selections draw bounded overlays (#2635, #2645, part of #2460), values out of range in presets and files are clamped (#2656), whole-number checks for counts (#2638, #2659), exports warn about overset type (#2628), symbol instances measured by their art (#2614), colour-managed Eyedropper in CMYK documents (#2664). Languages: Dutch, Danish and Indonesian complete (#2393), Simplified Chinese status and error messages (#2578), translated file filters and presets (#2590). Headline numbers unchanged (estimated). |
|
||||
| 2026-10-16 | Symbol Options › Export Type (Graphic or Movie Clip, default Movie Clip) with Registration; `symbol.options` / `symbol.list` (G5).
|
||||
| 2026-10-15 | Cursors: 36 more tool states get cursors of their own. Node editing follows the public manual (Direct Selection's anchor squares, Reshape Segment, Group Selection's plus, the arrow hollow on a snap, the Alt-copy arrowheads), the Anchor Point caret, the Curvature pen and Free Transform's side-shear arrows are drawn; Lasso, the freehand, symbolism and other tools borrow a drawn cursor until theirs is drawn. `crates/tools/src/cursors.toml` lists every cursor for whoever draws them, and `cargo xtask cursors` warns about one missing from it. Scores unchanged. |
|
||||
| 2026-10-16 | About 160 community PRs landed, each through the full gate. Crashes and hostile files: damaged PDF dictionaries and arrays no longer crash import (#2133, #2240, #2244, #2271), area type with huge row or column counts opens (#2109), hostile mesh edges are bounded (#2051). New: Dimension tool (#1788), legacy version 7 `.ai` save (#1794), Object › Intertwine (#2095), Apple Pencil and touch input on the web (#1740), Sample Color from Screen (#2257), Drop Shadow Darkness (#2252), Smart Blur edge modes (#2154), Scribble variations (#2180), Free Distort corners in its dialog (#2134), Rotate View presets (#2106), tritanopia proofing (#2234), Layers panel filters (#2087), Hide Template (#2117), File › Automate Batch through the Actions panel (#1938), dataset and graph CSV (#1929, #1941), Reset Tracking and Kerning (#2274), Alt+Enter copies in Transform fields (#2236), Shift+Tab panels (#2254), Control bar isolation, Recolor and image Replace (#2258, #2079, #2081). Revolve renders smooth with Cap on by default (#1193); Image Trace keeps tiny parts, thin outlines and shared corners, and Grayscale gradients are grey (#2012, #2025, #2263, #2264, #2265, #1879). Import: many `.ai`, EPS and PDF fidelity fixes (#2014–#2016, #2029, #2030, #2044, #2046, #2050–#2052, #2058, #2129, #2199, #2202, #2218), images up to 1 GB decoded (#2060), `.ai`/`.ait`/`.svgz` files paste from a file manager (#2148, #2201). Fixes across fields (arithmetic #2069, #2209, #2022; caret #1403), New Document (#2158, #2176), menus (#2232), shortcuts (#2235, #2146), Transform Each axes (#2227), Paste in Place (#1926), Color Picker tab order (#1937, #1939) and more. Languages: Bulgarian, Greek, Swedish and Finnish complete under the tests, pt-br completed. Details per PR in the PRs; headline numbers unchanged (estimated). |
|
||||
|
||||
@@ -470,6 +470,20 @@ fn hit_any(n: &Node, p: Point, opt: HitOptions, symbols: &SymbolBoxes) -> Option
|
||||
}
|
||||
}
|
||||
|
||||
/// The path of compound path `n` under `p`, for the Group Selection tool: the one whose outline is
|
||||
/// within `tol`, else the innermost one whose area holds `p` (a hole inside an outer shape, an
|
||||
/// island inside a hole). `None` when `n` isn't a compound path or no part is under `p`.
|
||||
pub fn compound_part_at(n: &Node, p: Point, tol: f64) -> Option<NodeId> {
|
||||
let NodeKind::Compound { children, rule } = &n.kind else { return None };
|
||||
let parts: Vec<_> = children.iter().rev().filter_map(|c| c.path_data().map(|pd| (c.id, pd.to_bezpath(), pd.bounds()))).collect();
|
||||
if let Some((id, ..)) = parts.iter().find(|(_, bp, _)| stroke_contains(bp, 0.0, tol, p)) {
|
||||
return Some(*id);
|
||||
}
|
||||
// The innermost by the size of its box.
|
||||
let size = |b: &Option<Rect>| b.map_or(f64::INFINITY, |b| b.area());
|
||||
parts.iter().filter(|(_, bp, _)| fill_contains(bp, *rule, p)).min_by(|a, b| size(&a.2).total_cmp(&size(&b.2))).map(|(id, ..)| *id)
|
||||
}
|
||||
|
||||
/// Objects (children of layers, or of `scope` in isolation mode) touched by a marquee rect. Symbol
|
||||
/// instances are measured by their art ([`Node::geometric_bounds_with`]). The art of a clip group
|
||||
/// or of a layer with a clipping mask counts only when the marquee meets the region its clipping
|
||||
|
||||
@@ -428,22 +428,23 @@ pub(crate) fn selected_roots(s: &Session) -> Result<Vec<NodeId>> {
|
||||
Ok(roots_of(&st.doc, st.selection.in_paint_order(&st.doc)))
|
||||
}
|
||||
|
||||
/// [`selected_roots`] for the commands that move or reshape the art (Move, Transform, Rotate…): in
|
||||
/// an isolated compound path its paths are objects of their own, so the hole of a ring moves
|
||||
/// without the ring. Paint and the rest still go to the compound path, which holds the paint.
|
||||
/// [`selected_roots`] for the commands that move or reshape the art (Move, Transform, Rotate…): a
|
||||
/// path of a compound path selected on its own (Group Selection, or in the isolated compound path)
|
||||
/// is an object of its own, so the hole of a ring moves without the ring (#2441). Paint and the
|
||||
/// rest still go to the compound path, which holds the paint.
|
||||
pub(crate) fn selected_roots_to_transform(s: &Session) -> Result<Vec<NodeId>> {
|
||||
let st = s.doc()?;
|
||||
Ok(roots_within(&st.doc, st.selection.in_paint_order(&st.doc), st.isolation))
|
||||
Ok(roots_within(&st.doc, st.selection.in_paint_order(&st.doc), true))
|
||||
}
|
||||
|
||||
/// The top-level objects among `ids` (in paint order): compound-path members stand for their
|
||||
/// compound, and ids whose ancestor is also listed, and layers, are dropped.
|
||||
pub(crate) fn roots_of(doc: &Document, ids: Vec<NodeId>) -> Vec<NodeId> {
|
||||
roots_within(doc, ids, None)
|
||||
roots_within(doc, ids, false)
|
||||
}
|
||||
|
||||
/// [`roots_of`], less the swap for the members of `isolation` when it is a compound path.
|
||||
fn roots_within(doc: &Document, ids: Vec<NodeId>, isolation: Option<NodeId>) -> Vec<NodeId> {
|
||||
/// [`roots_of`]; with `members`, a compound path's member listed stays itself.
|
||||
fn roots_within(doc: &Document, ids: Vec<NodeId>, members: bool) -> Vec<NodeId> {
|
||||
// Every id's place in the tree, found in one walk (a lookup per id is a walk per id).
|
||||
let paths = doc.index_paths(ids.iter().copied());
|
||||
// A compound-path member acts as its compound (compounds are one object).
|
||||
@@ -453,7 +454,7 @@ fn roots_within(doc: &Document, ids: Vec<NodeId>, isolation: Option<NodeId>) ->
|
||||
let path = paths.get(&id);
|
||||
let parent = path.and_then(|p| p.split_last()).map(|(_, up)| up).filter(|up| !up.is_empty());
|
||||
match parent.and_then(|up| doc.node_at(up).map(|n| (up, n))) {
|
||||
Some((up, n)) if matches!(n.kind, vectorcraft_doc::NodeKind::Compound { .. }) && Some(n.id) != isolation => (n.id, Some(up.to_vec())),
|
||||
Some((up, n)) if matches!(n.kind, vectorcraft_doc::NodeKind::Compound { .. }) && !members => (n.id, Some(up.to_vec())),
|
||||
_ => (id, path.cloned()),
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1952,13 +1952,14 @@ fn isolated_ring(s: &mut Session) -> (NodeId, NodeId, NodeId) {
|
||||
(c, outer, hole)
|
||||
}
|
||||
|
||||
/// Isolating a compound path makes its paths objects of their own: the hole of a ring, selected
|
||||
/// alone, moves without the ring around it. Outside isolation it still moves its compound path.
|
||||
/// A path of a compound path selected alone is an object of its own for the transforms: the hole
|
||||
/// of a ring moves without the ring around it, in the isolated compound path and outside it, where
|
||||
/// Group Selection selects it (#2441). Selecting the compound path moves the whole ring.
|
||||
#[test]
|
||||
fn an_isolated_compound_paths_member_moves_alone() {
|
||||
let x0 = |s: &Session, id: NodeId| s.doc().unwrap().doc.node(id).unwrap().geometric_bounds().unwrap().x0;
|
||||
let mut s = session();
|
||||
let (_, outer, hole) = isolated_ring(&mut s);
|
||||
let (c, outer, hole) = isolated_ring(&mut s);
|
||||
s.execute("object.transform", &json!({"matrix": [1, 0, 0, 1, 30, 0]})).unwrap();
|
||||
assert_eq!((x0(&s, outer), x0(&s, hole)), (0.0, 40.0), "only the hole moved");
|
||||
s.execute("object.move", &json!({"dx": 5, "dy": 0})).unwrap();
|
||||
@@ -1966,7 +1967,10 @@ fn an_isolated_compound_paths_member_moves_alone() {
|
||||
s.execute("object.exitIsolation", &json!({})).unwrap();
|
||||
s.execute("select.set", &json!({"ids": [hole.0]})).unwrap();
|
||||
s.execute("object.transform", &json!({"matrix": [1, 0, 0, 1, 5, 0]})).unwrap();
|
||||
assert_eq!((x0(&s, outer), x0(&s, hole)), (5.0, 50.0), "not isolated: the whole compound path moved");
|
||||
assert_eq!((x0(&s, outer), x0(&s, hole)), (0.0, 50.0), "not isolated: still only the hole");
|
||||
s.execute("select.set", &json!({"ids": [c.0]})).unwrap();
|
||||
s.execute("object.move", &json!({"dx": 5, "dy": 0})).unwrap();
|
||||
assert_eq!((x0(&s, outer), x0(&s, hole)), (5.0, 55.0), "the compound path selected: the whole ring");
|
||||
}
|
||||
|
||||
/// `depth` and `childLimit` slice a summary read; a level that shows fewer children
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use serde_json::{Value, json};
|
||||
use vectorcraft_doc::hit::{HitKind, hit_test};
|
||||
use vectorcraft_doc::hit::{HitKind, compound_part_at, hit_test};
|
||||
use vectorcraft_doc::{AnchorRef, Node, NodeId, NodeKind, Selection};
|
||||
use vectorcraft_geom::{Anchor, PathData, Point, Rect, Vec2};
|
||||
|
||||
@@ -425,10 +425,15 @@ impl Tool for DirectSelectionTool {
|
||||
self.state = State::Idle;
|
||||
return out;
|
||||
}
|
||||
let Some(h) = hit_test(cx.doc, p, cx.hit_options()) else {
|
||||
let Some(mut h) = hit_test(cx.doc, p, cx.hit_options()) else {
|
||||
self.state = State::Marquee { start: p, cur: p, toggle: ev.mods.shift, enclosed: false };
|
||||
return vec![];
|
||||
};
|
||||
// A compound path's paths are picked one at a time, below the compound path (#2441).
|
||||
if let Some(part) = cx.doc.node(h.leaf).and_then(|n| compound_part_at(n, p, tol)) {
|
||||
h.ancestry.push(part);
|
||||
h.leaf = part;
|
||||
}
|
||||
// Walk up from the leaf: select the first ancestor not yet selected (below the layer).
|
||||
// Stop at the isolated object: the next group up is outside isolation mode.
|
||||
let chain: Vec<NodeId> = h.ancestry.iter().skip(1).rev().copied().take_while(|id| in_scope(cx.doc, cx.isolation, *id)).collect();
|
||||
@@ -1331,6 +1336,37 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
/// #2441: Group Selection picks one path of a compound path (the outer shape or a hole);
|
||||
/// a second click on it adds the compound path, like a group around a member.
|
||||
#[test]
|
||||
fn group_selection_picks_a_path_of_a_compound_path() {
|
||||
let mut d = vectorcraft_doc::Document::new(500.0, 500.0);
|
||||
let l = d.layers[0].id;
|
||||
let (outer, hole, compound) = (d.alloc_id(), d.alloc_id(), d.alloc_id());
|
||||
let rect = |id, a: f64, b: f64| {
|
||||
std::sync::Arc::new(vectorcraft_doc::Node::path(id, vectorcraft_geom::shapes::rectangle(Rect::new(a, a, b, b)), Default::default()))
|
||||
};
|
||||
let mut c = vectorcraft_doc::Node::new(
|
||||
compound,
|
||||
vectorcraft_doc::NodeKind::Compound {
|
||||
children: vec![rect(outer, 0.0, 200.0), rect(hole, 50.0, 150.0)],
|
||||
rule: vectorcraft_geom::FillRule::EvenOdd,
|
||||
},
|
||||
);
|
||||
c.appearance = vectorcraft_doc::Appearance::default_art().into();
|
||||
d.insert(Some(l), 0, c).unwrap();
|
||||
let p = paint();
|
||||
let none = Selection::default();
|
||||
let click = |s: &Selection, x, y| DirectSelectionTool::new(true).pointer(&cx(&d, s, &p), &PointerEvent::new(PointerKind::Down, x, y));
|
||||
let set = |id: NodeId| vec![Action::Exec("select.set".into(), json!({"ids": [id.0]}))];
|
||||
assert_eq!(click(&none, 25.0, 100.0), set(outer), "the fill between the outline and the hole");
|
||||
assert_eq!(click(&none, 50.0, 100.0), set(hole), "the hole's outline");
|
||||
assert!(click(&none, 100.0, 100.0).is_empty(), "inside the hole nothing is hit");
|
||||
let mut s = Selection::default();
|
||||
s.set([outer]);
|
||||
assert_eq!(click(&s, 25.0, 100.0), vec![Action::Exec("select.add".into(), json!({"ids": [compound.0]}))]);
|
||||
}
|
||||
|
||||
/// A path inside an inner group, a sibling path outside it, and the groups' ids.
|
||||
/// The inside path is the rectangle at (100, 100); the outside one at (300, 300).
|
||||
fn nested_group_doc() -> (vectorcraft_doc::Document, NodeId, NodeId, NodeId, NodeId) {
|
||||
|
||||
@@ -5076,3 +5076,6 @@ mark-style Japanese Japonské
|
||||
@msg a mask has more than one art block maska má více než jeden blok kresby
|
||||
@msg mask art ends outside a mask dictionary kresba masky končí mimo slovník masky
|
||||
@msg cancelled; nothing was changed zrušeno; nic nebylo změněno
|
||||
@msg a linked image can't become a gradient mesh: embed it first propojený obraz nelze převést na síť přechodu: nejprve jej vložte
|
||||
@msg the image has no usable size or position obraz nemá použitelnou velikost ani polohu
|
||||
@msg the image's pixels can't be read pixely obrazu nelze přečíst
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5070,3 +5070,13 @@ swatch Bright Violet Kraftig violet
|
||||
Uniformly Scaled Ensartet skaleret
|
||||
Vertically Scaled Lodret skaleret
|
||||
“{name}” already exists. Replace it? »{name}« findes allerede. Erstat den?
|
||||
Enable Guides for 9-Slice Scaling Aktivér hjælpelinjer til 9-udsnitsskalering
|
||||
Lock Variables Lås variabler
|
||||
Unlock Variables Lås variabler op
|
||||
Change to Artboard Rulers Skift til kunstpladelinealer
|
||||
Cutout… Udklip…
|
||||
Neon Glow… Neonglød…
|
||||
Poster Edges… Plakatkanter…
|
||||
Cutout Udklip
|
||||
Neon Glow Neonglød
|
||||
Poster Edges Plakatkanter
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4637,3 +4637,6 @@ effect Regular Regelmäßig
|
||||
@msg a mask has more than one art block eine Maske enthält mehr als einen Grafikblock
|
||||
@msg mask art ends outside a mask dictionary die Maskengrafik endet außerhalb eines Maskenwörterbuchs
|
||||
@msg cancelled; nothing was changed abgebrochen; es wurde nichts geändert
|
||||
@msg a linked image can't become a gradient mesh: embed it first ein verknüpftes Bild kann kein Verlaufsgitter werden: Betten Sie es zuerst ein
|
||||
@msg the image has no usable size or position das Bild hat keine verwendbare Größe oder Position
|
||||
@msg the image's pixels can't be read die Pixel des Bildes können nicht gelesen werden
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5028,3 +5028,6 @@ effect Points Σημεία
|
||||
@msg a mask has more than one art block η μάσκα έχει περισσότερα από ένα μπλοκ γραφικών
|
||||
@msg mask art ends outside a mask dictionary τα γραφικά της μάσκας τελειώνουν έξω από το λεξικό της μάσκας
|
||||
@msg cancelled; nothing was changed ακυρώθηκε· δεν άλλαξε τίποτα
|
||||
@msg a linked image can't become a gradient mesh: embed it first μια συνδεδεμένη εικόνα δεν μπορεί να γίνει πλέγμα διαβάθμισης: ενσωματώστε την πρώτα
|
||||
@msg the image has no usable size or position η εικόνα δεν έχει χρησιμοποιήσιμο μέγεθος ή θέση
|
||||
@msg the image's pixels can't be read τα εικονοστοιχεία της εικόνας δεν μπορούν να διαβαστούν
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 1923 and column 19.
|
@@ -5018,3 +5018,6 @@ mark-style Japanese Japonesas
|
||||
@msg a mask has more than one art block una máscara tiene más de un bloque de ilustración
|
||||
@msg mask art ends outside a mask dictionary la ilustración de la máscara termina fuera de un diccionario de máscara
|
||||
@msg cancelled; nothing was changed cancelado; no se ha cambiado nada
|
||||
@msg a linked image can't become a gradient mesh: embed it first una imagen enlazada no puede convertirse en una malla de degradado: incrústela primero
|
||||
@msg the image has no usable size or position la imagen no tiene un tamaño ni una posición utilizables
|
||||
@msg the image's pixels can't be read no se pueden leer los píxeles de la imagen
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5040,3 +5040,6 @@ mark-style Japanese Japanilainen
|
||||
@msg a mask has more than one art block maskissa on useampi kuin yksi grafiikkalohko
|
||||
@msg mask art ends outside a mask dictionary maskin grafiikka päättyy maskin sanakirjan ulkopuolelle
|
||||
@msg cancelled; nothing was changed peruutettu; mitään ei muutettu
|
||||
@msg a linked image can't become a gradient mesh: embed it first linkitetystä kuvasta ei voi tehdä liukuväriverkkoa: upota se ensin
|
||||
@msg the image has no usable size or position kuvalla ei ole käyttökelpoista kokoa tai sijaintia
|
||||
@msg the image's pixels can't be read kuvan pikseleitä ei voi lukea
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5075,3 +5075,6 @@ theme Appearance Apparence
|
||||
@msg a mask has more than one art block un masque contient plusieurs blocs graphiques
|
||||
@msg mask art ends outside a mask dictionary les éléments graphiques du masque se terminent en dehors d’un dictionnaire de masque
|
||||
@msg cancelled; nothing was changed annulé ; rien n'a été modifié
|
||||
@msg a linked image can't become a gradient mesh: embed it first une image liée ne peut pas devenir un filet de dégradé : incorporez-la d’abord
|
||||
@msg the image has no usable size or position l’image n’a ni taille ni position utilisables
|
||||
@msg the image's pixels can't be read impossible de lire les pixels de l’image
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5062,3 +5062,6 @@ imageTrace Outline Körvonal
|
||||
@msg a mask has more than one art block egy maszk egynél több grafikai blokkot tartalmaz
|
||||
@msg mask art ends outside a mask dictionary a maszk grafikája a maszk szótárán kívül ér véget
|
||||
@msg cancelled; nothing was changed megszakítva; semmi sem változott
|
||||
@msg a linked image can't become a gradient mesh: embed it first csatolt kép nem alakítható színátmenetes hálóvá: előbb ágyazza be
|
||||
@msg the image has no usable size or position a képnek nincs használható mérete vagy helyzete
|
||||
@msg the image's pixels can't be read a kép képpontjai nem olvashatók
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5070,3 +5070,13 @@ swatch Bright Violet Violet cerah
|
||||
Uniformly Scaled Diskalakan seragam
|
||||
Vertically Scaled Diskalakan vertikal
|
||||
“{name}” already exists. Replace it? “{name}” sudah ada. Ganti?
|
||||
Enable Guides for 9-Slice Scaling Aktifkan panduan untuk penskalaan 9-iris
|
||||
Lock Variables Kunci variabel
|
||||
Unlock Variables Buka kunci variabel
|
||||
Change to Artboard Rulers Ubah ke penggaris artboard
|
||||
Cutout… Potongan…
|
||||
Neon Glow… Pendar neon…
|
||||
Poster Edges… Tepi poster…
|
||||
Cutout Potongan
|
||||
Neon Glow Pendar neon
|
||||
Poster Edges Tepi poster
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3755 and column 19.
|
@@ -4675,3 +4675,6 @@ lighting Light Luce
|
||||
@msg a mask has more than one art block una maschera contiene più di un blocco grafico
|
||||
@msg mask art ends outside a mask dictionary la grafica della maschera termina fuori da un dizionario di maschera
|
||||
@msg cancelled; nothing was changed annullato; non è stato modificato nulla
|
||||
@msg a linked image can't become a gradient mesh: embed it first un’immagine collegata non può diventare una trama sfumata: incorporala prima
|
||||
@msg the image has no usable size or position l’immagine non ha dimensioni o posizione utilizzabili
|
||||
@msg the image's pixels can't be read impossibile leggere i pixel dell’immagine
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4716,3 +4716,6 @@ lighting Light ライト
|
||||
@msg a mask has more than one art block マスクに複数のアートブロックがあります
|
||||
@msg mask art ends outside a mask dictionary マスクのアートがマスク辞書の外で終わっています
|
||||
@msg cancelled; nothing was changed キャンセルしました。何も変更されていません
|
||||
@msg a linked image can't become a gradient mesh: embed it first リンクされた画像はグラデーションメッシュにできません: 先に埋め込んでください
|
||||
@msg the image has no usable size or position 画像に使用できるサイズまたは位置がありません
|
||||
@msg the image's pixels can't be read 画像のピクセルを読み取れません
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4639,3 +4639,6 @@ lighting Light 광원
|
||||
@msg a mask has more than one art block 마스크에 아트 블록이 두 개 이상 있습니다
|
||||
@msg mask art ends outside a mask dictionary 마스크 아트가 마스크 사전 밖에서 끝납니다
|
||||
@msg cancelled; nothing was changed 취소됨; 변경된 내용이 없습니다
|
||||
@msg a linked image can't become a gradient mesh: embed it first 연결된 이미지는 그라디언트 메시로 만들 수 없습니다: 먼저 포함하십시오
|
||||
@msg the image has no usable size or position 이미지에 사용할 수 있는 크기나 위치가 없습니다
|
||||
@msg the image's pixels can't be read 이미지의 픽셀을 읽을 수 없습니다
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5070,3 +5070,13 @@ swatch Bright Violet Felviolet
|
||||
Uniformly Scaled Gelijkmatig geschaald
|
||||
Vertically Scaled Verticaal geschaald
|
||||
“{name}” already exists. Replace it? „{name}” bestaat al. Vervangen?
|
||||
Enable Guides for 9-Slice Scaling Hulplijnen voor 9-slice-schalen inschakelen
|
||||
Lock Variables Variabelen vergrendelen
|
||||
Unlock Variables Variabelen ontgrendelen
|
||||
Change to Artboard Rulers Wijzigen in tekenbordlinialen
|
||||
Cutout… Knipsel…
|
||||
Neon Glow… Neongloed…
|
||||
Poster Edges… Posterranden…
|
||||
Cutout Knipsel
|
||||
Neon Glow Neongloed
|
||||
Poster Edges Posterranden
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4922,3 +4922,6 @@ mark-style Japanese Japońskie
|
||||
@msg a mask has more than one art block maska ma więcej niż jeden blok grafiki
|
||||
@msg mask art ends outside a mask dictionary grafika maski kończy się poza słownikiem maski
|
||||
@msg cancelled; nothing was changed anulowano; nic nie zostało zmienione
|
||||
@msg a linked image can't become a gradient mesh: embed it first połączony obraz nie może stać się siatką gradientu: najpierw go osadź
|
||||
@msg the image has no usable size or position obraz nie ma użytecznego rozmiaru ani położenia
|
||||
@msg the image's pixels can't be read nie można odczytać pikseli obrazu
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -4993,3 +4993,6 @@ mark-style Japanese Japonesas
|
||||
@msg a mask has more than one art block uma máscara contém mais de um bloco de arte
|
||||
@msg mask art ends outside a mask dictionary a arte da máscara termina fora de um dicionário de máscara
|
||||
@msg cancelled; nothing was changed cancelado; nada foi alterado
|
||||
@msg a linked image can't become a gradient mesh: embed it first uma imagem vinculada não pode virar uma malha de degradê: incorpore-a primeiro
|
||||
@msg the image has no usable size or position a imagem não tem tamanho nem posição utilizáveis
|
||||
@msg the image's pixels can't be read não é possível ler os pixels da imagem
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -4671,3 +4671,6 @@ lighting Light Свет
|
||||
@msg a mask has more than one art block маска содержит более одного блока графики
|
||||
@msg mask art ends outside a mask dictionary графика маски заканчивается за пределами словаря маски
|
||||
@msg cancelled; nothing was changed отменено; ничего не изменено
|
||||
@msg a linked image can't become a gradient mesh: embed it first связанное изображение нельзя превратить в сетчатый градиент: сначала встройте его
|
||||
@msg the image has no usable size or position у изображения нет пригодного размера или положения
|
||||
@msg the image's pixels can't be read не удаётся прочитать пиксели изображения
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
@@ -5032,3 +5032,6 @@ theme Appearance Utseende
|
||||
@msg a mask has more than one art block en mask innehåller mer än ett grafikblock
|
||||
@msg mask art ends outside a mask dictionary maskens grafik slutar utanför en maskordlista
|
||||
@msg cancelled; nothing was changed avbrutet; inget ändrades
|
||||
@msg a linked image can't become a gradient mesh: embed it first en länkad bild kan inte bli ett övertoningsnät: bädda in den först
|
||||
@msg the image has no usable size or position bilden har ingen användbar storlek eller position
|
||||
@msg the image's pixels can't be read bildens pixlar kan inte läsas
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 25.
|
@@ -4655,3 +4655,6 @@ lighting Light Світло
|
||||
@msg a mask has more than one art block маска містить більше одного блоку графіки
|
||||
@msg mask art ends outside a mask dictionary графіка маски закінчується за межами словника маски
|
||||
@msg cancelled; nothing was changed скасовано; нічого не змінено
|
||||
@msg a linked image can't become a gradient mesh: embed it first зв’язане зображення не можна перетворити на сітчастий градієнт: спочатку вбудуйте його
|
||||
@msg the image has no usable size or position зображення не має придатного розміру чи положення
|
||||
@msg the image's pixels can't be read не вдається прочитати пікселі зображення
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 723 and column 40.
|
@@ -4655,3 +4655,6 @@ theme Appearance Giao diện
|
||||
@msg a mask has more than one art block mặt nạ có nhiều hơn một khối đồ họa
|
||||
@msg mask art ends outside a mask dictionary đồ họa mặt nạ kết thúc bên ngoài từ điển mặt nạ
|
||||
@msg cancelled; nothing was changed đã hủy; không có gì thay đổi
|
||||
@msg a linked image can't become a gradient mesh: embed it first không thể biến ảnh liên kết thành lưới chuyển sắc: hãy nhúng ảnh trước
|
||||
@msg the image has no usable size or position ảnh không có kích thước hoặc vị trí dùng được
|
||||
@msg the image's pixels can't be read không đọc được các điểm ảnh của ảnh
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3852 and column 10.
|
@@ -4904,3 +4904,6 @@ lighting Light 光源
|
||||
@msg a mask has more than one art block 蒙版包含多个图稿块
|
||||
@msg mask art ends outside a mask dictionary 蒙版图稿在蒙版字典之外结束
|
||||
@msg `{key}` must be a #rrggbb color `{key}` 必须是 #rrggbb 格式的颜色
|
||||
@msg a linked image can't become a gradient mesh: embed it first 链接的图像无法转换为渐变网格:请先嵌入它
|
||||
@msg the image has no usable size or position 图像没有可用的尺寸或位置
|
||||
@msg the image's pixels can't be read 无法读取图像的像素
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 2 and column 73.
|
File diff suppressed because one or more lines are too long
+3
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user