Commit Graph
1959 Commits
Author SHA1 Message Date
bflatastic 8412b4658f i18n: catalog rows for the new strings (#1938) 2026-10-16 04:55:01 +07:00
bflatastic 08dde8783e Actions: Batch… stays in the Actions panel menu, as the reference app has it (#1938) 2026-10-16 04:55:01 +07:00
Fabio William ConceiçãoandCursor 0fe70314b8 G6: action.batch for File › Automate › Batch
Play an action on every file in a folder or every data set, with destination
and Override Open/Save/Export. Actions panel and File › Automate › Batch…
open the dialog; new strings in pt-br.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 04:50:07 +07:00
bflatastic b3e484702f i18n: catalog rows for the new strings (#1941) 2026-10-16 04:50:07 +07:00
bflatastic 568008dd47 Variables: graph values go through the dataset CSV too (#1941) 2026-10-16 04:50:07 +07:00
Fabio William ConceiçãoandCursor dc390aba37 G6: graph variables (CSV data merge)
VariableKind::Graph binds a graph root; dataset rows supply CSV as graph.setData.
Make Graph Dynamic, Variables dialog, capture/apply, and pt-br for the new strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 04:50:07 +07:00
bflatastic 799f94ecf1 i18n: catalog rows for the new strings (#1929) 2026-10-16 04:50:07 +07:00
bflatastic 192a671d4f Variables: dataset CSV keeps line breaks in quoted cells and reads a file only up to its cap (#1929) 2026-10-16 04:50:07 +07:00
Fabio William Conceição 5ef090a0c2 G6: dataset CSV import/export with PT-BR UI labels
Load and save variable datasets as CSV for data-merge pipelines, and
translate the new Variables panel commands in Brazilian Portuguese.

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	docs/target-app-parity.md
2026-10-16 04:50:07 +07:00
bflatastic a38c824066 Variables: an image variable keeps the object's bounds with the Placement Options API on main (#1908) 2026-10-16 04:50:07 +07:00
bflatastic 699856f7d5 i18n: catalog rows for the new strings (#1908) 2026-10-16 04:45:08 +07:00
Fabio William Conceição 41c8bd2a2d G6: image variables swap linked files and keep bounds
Add VariableKind::Image with path values on datasets, makeImageDynamic,
panel/dialog UI, and MCP docs so data merge can drive placed images.
2026-10-16 04:45:06 +07:00
bflatastic c8310edea1 i18n: Bulgarian row for Symbol Options Registration (#1959) 2026-10-16 04:45:04 +07:00
Fabio William ConceiçãoandCursor 80090e7623 G5: Symbol Options Registration 9-point grid
Store the registration point with the symbol and place instances so that point lands on (x, y). Symbol Options exposes the same 9-point control as Transform.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 04:45:03 +07:00
sanyamsingh001andCodex 848d902354 G1: Add Warp Options controls for live effects
Expose existing Warp styles, orientation and percentage controls through the shared live effect dialog while preserving preview history and effect targets. Keep ordinary Enter owned by focused non-searchable combo controls.

Co-authored-by: Codex <noreply@openai.com>
2026-10-16 04:45:03 +07:00
Fabio William Conceição ed6d474042 G11: Asset Export seam regression and supersampled thumbs
assets.export of abutting fills must leave no ghost edge (#983 / #1037); panel thumbnails use the same Art Optimized supersample. Progress docs mark the gap closed.
2026-10-16 04:45:01 +07:00
sanyamsingh001andCodex 74573d6bad G1: Cancel existing-guide drags with Escape
Co-authored-by: Codex <noreply@openai.com>
2026-10-16 04:44:59 +07:00
sanyamsingh001andCodex 67f9d134ed G11: Preserve gaps when deleting open-path anchors
Keep surviving drawable runs separate when Delete or Backspace removes an open-path anchor. Preserve appearance, selection and one-step Undo.

Co-authored-by: Codex <noreply@openai.com>
2026-10-16 04:44:58 +07:00
sanyamsingh001andCodex a1b3c4804f G1: Keep the displayed artboard selected after switching documents
Co-authored-by: Codex <noreply@openai.com>
2026-10-16 04:44:56 +07:00
bflatastic 9eddeeb952 Legacy .ai export writes Intertwine groups as their art (#2095) 2026-10-16 04:44:54 +07:00
bflatastic 5e75d26d29 i18n: Bulgarian rows for Intertwine (#2095) 2026-10-16 04:44:54 +07:00
Gert Pellin 3ae6cf28e4 G13: Intertwine tool, Object › Intertwine › Edit, menu and translations (#1763)
Make and Edit choose the Intertwine tool: hovering highlights the overlap
area under the pointer, a click swaps which object is on top there, and a
path drawn around overlaps (Shift: a rectangle) arranges every overlap
inside it; Esc or Enter goes back to the tool chosen before. The overlap
faces move to vectorcraft-tools, shared by the tool and the command.

Clicks inside a raised area pick the member drawn on top there, the
Object menu gets the Intertwine submenu, and the new labels and the
predicate message are translated in the complete catalogs. docs/gaps.md
records what landed under G13.
2026-10-16 04:44:53 +07:00
Gert Pellin 74c391c7ba G13: Object › Intertwine: Make, Release and arranging overlap areas (#1763)
An Intertwine group keeps its objects as they are, in their own stacking
order; each member can be drawn over the others in an area of its own.
The group draws, hits, saves and exports through its live expansion, so the
members stay editable and Release gives them back unchanged.

object.intertwine.arrange picks an overlap area by a click point or by a
closed path drawn around overlaps and toggles which member is on top
there, or brings a member to the front or sends it to the back where three
or more objects overlap.
2026-10-16 04:44:52 +07:00
Marco Arnulfo 20325b1a89 Title bar: a double-click on the macOS app bar zooms the window (fixes #1932) 2026-10-16 04:44:52 +07:00
Gert Pellin ba254a7481 MCP command_batch: draw_path and draw_shape run as steps (#2113)
A step whose id is draw_path or draw_shape runs that tool with its params,
checked as tools/call checks arguments; its result is the tool's, so later
steps can use "$N.id". The reply lists the ids the drawing steps made
under created. The unknown-argument check is shared with tools/call.
2026-10-16 04:44:52 +07:00
Gert Pellin 49fcfbd145 MCP draw_path / draw_shape: dash, cap, join, opacity, name and effects (#2112)
The drawing tools style the object they draw in the same call: dash, cap
and join go to the stroke.set that strokeWidth already sends, opacity and
name to object.setProps, and effects are applied in order as apply_effect
does. The options are checked (effect ids against effect.list) before
anything is drawn, so a bad one leaves no half-styled object behind.
2026-10-16 04:44:52 +07:00
bflatastic 5fc7072600 i18n: catalog rows for the new strings (#2128) 2026-10-16 04:44:52 +07:00
Gert Pellin 736abd811d paint.setFill / setStroke: span "selection" places one gradient across the targets (#2127)
A gradient given to several objects fits each one's own bounds. With
span: "selection", a linear or radial gradient without its own vector is
placed once on the union of the targets' bounds, at its angle and aspect,
and every target gets that vector in document coordinates, so the ramp
runs on across them. A solid colour, a swatch, a freeform gradient or an
explicit start/end with it is refused before anything changes; the next
object drawn still fits the gradient to itself.
2026-10-16 04:44:50 +07:00
Gert Pellin 265552d5f4 Tests: a gradient spanning the selection (#2127) 2026-10-16 04:44:50 +07:00
Gert Pellin e7aacec852 Selection-only commands take ids: the objects are selected first (#2130)
object.group, ungroup, the clipping mask and compound path Make/Release,
the Arrange commands, lock, hide, edit.duplicate, object.move, rotate,
scale, reflect, shear and the Pathfinder commands acted only on the
selection, so a script had to send select.set first. Given ids, they now
select those objects (select.set, with its checks) and run as on the
selection, in the same undo step; without ids nothing changes.
2026-10-16 04:44:50 +07:00
bflatastic e6b28f0e80 Tests: read the PDF/X output intent's profile with the crate's own xref reader (#1962) 2026-10-16 04:44:31 +07:00
Marco Arnulfo 32dbc4b641 PDF export: the output intent shares the stream of the profile that tags the colours (fixes #1954) 2026-10-16 04:44:31 +07:00
bflatastic 2843687ef4 Text: leave out the bottom-handle Auto Size double-click until its behaviour is settled (#1947) 2026-10-16 04:44:31 +07:00
Marco Arnulfo a69371656b Text: Ctrl+Shift+C aligns centre off the Mac, a double-click on area type's bottom handle turns on Auto Size (fixes #1940) 2026-10-16 04:44:29 +07:00
Murat Vural 1ab3940b3d feat: move and copy ruler guides and art together when selected 2026-10-16 04:19:06 +07:00
Lucas LerouxandClaude Opus 5.5 55fadb6afe Text: a bundled-fonts feature (on by default) lets embedders that bring their own fonts leave ours out
The nine OFL faces in `assets/fonts` are compiled into every build of
vectorcraft-text: 3.4 MB of the binary, about 1.6 MB of a gzipped wasm.
An embedder that loads every font at run time with `FontDb::add_font`
(a web app serving its own font catalogue, say) ships them twice and
can't turn them off.

- vectorcraft-text: `bundled-fonts`, a default feature, holds the
  `include_bytes!` list. Off, a database starts without them (craft-fonts
  and system fonts are unaffected) and text has no glyphs until a font
  is added, as when the bundled fonts fail to parse.
- vectorcraft-engine: a `bundled-fonts` default feature forwards to it,
  so the apps and any embedder using the engine keep the fonts unless
  they build it with `default-features = false`.
- The workspace declares vectorcraft-text without default features, so
  no library crate turns the fonts back on. The tests of cad, metafile
  and tools, which lay type out, ask for the feature in their
  dev-dependencies; the other crates' tests get it through testkit.

`cargo test --workspace` builds with the fonts, as before. A new
integration test, `without_bundled_fonts`, covers the configuration
without them (`cargo test -p vectorcraft-text --no-default-features
--test without_bundled_fonts`): the database starts without them, text
in no font lays out with no glyphs, and a font added later is used and
is the fallback for families the database lacks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:19:05 +07:00
Lucas LerouxandClaude Opus 5.5 1e8f5025c6 Render, SVG: vello_cpu and usvg without their text features: one skrifa, read-fonts and harfrust fewer in the engine
The default `text` features of vello_cpu (glyph runs, through glifo) and
usvg (fontdb, harfrust 0.12, skrifa 0.44 and its read-fonts 0.41) build
another copy of the font stack into the engine, next to the workspace's
skrifa 0.47 and harfrust 0.13. Neither is used: the renderer draws the
glyph outlines vectorcraft-text gives it, and SVG import reads <text>
from the XML itself and never gives usvg a font (usvg leaves out text it
has no font for).

- vello_cpu: its default features but `text` (std, png, u8_pipeline),
  plus f32_pipeline as before.
- usvg: `svgz` only, for gzipped SVG images inside an SVG; `text`,
  `system-fonts`, `memmap-fonts` and `writer` are off. text_layout.rs uses
  usvg as a reference viewer with a font, so crates/svg turns `text` on as
  a dev-dependency feature, as crates/pdf does for krilla's `simple-text`.
- A test pins `svgz`: SVGZ images, linked or as a data URL, import as
  vector art.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:19:05 +07:00
IanHollow 83f40f135a Text: make every supplied font family available to documents
Assisted-by: GPT-6
Signed-off-by: IanHollow <72767437+IanHollow@users.noreply.github.com>
2026-10-16 04:19:05 +07:00
YukiHiko 8b5e9e4927 G6: expose vertical writing in MCP add_text 2026-10-16 04:19:05 +07:00
YukiHiko 3a7d422046 G4: keep fullwidth punctuation upright without vertical alternates 2026-10-16 04:19:05 +07:00
ham9zah ad3531d464 Curvature: each three points follow the circle through them, curved ends (#1236, in part)
The Curvature tool built its curve as a uniform Catmull-Rom: both handles of a
smooth point a sixth of the chord between its neighbours, the ends of an open
path without handles. Uneven spacing overshot or looped, a J or U from three
points bent sharply at the middle with straight legs, and the end segments
looked flat.

- `curvature_spline` (draw2.rs) makes each stretch of three points follow the
  circle through them: a smooth point's tangent is that circle's
  (`smooth_handles`), each handle `chord / (3 cos²(α/2))` long, α between
  handle and chord capped at 90° (`arc_handle`). The ends of an open path
  mirror their neighbour's tangent in their chord (`end_handle`). A turn
  tighter than 30° (`TIGHT_TURN`) shortens its handles, so a narrow V comes to
  a point. Degenerate points become corners. `path.curvature` and the rubber
  band use it.
- `catmull_rom` is unchanged for the Pencil and Paintbrush fitting.
- `bend_last` (from: smooth), `curvature_move` on a smooth point, the point
  `curvature_insert` adds on a straight segment, and `path.convertAnchor` to
  smooth without x/y (`curvature_smooth`) use the same rule.
- `curvature_extend` gives the new end its end handle unless Alt-clicked
  (`corner` param on `path.curvatureEdit`).
- Neighbours of a point dragged on an existing path keep their tangents (a
  Pen-drawn shape isn't reshaped); the path being drawn re-curves throughout.
2026-10-16 04:19:05 +07:00
el-j 4913418d1c Type tool: Escape returns to the previous selection tool and preserves isolation mode
When entering text edit mode via double-click from a selection tool
(Selection or Direct Selection), pressing Escape now returns to the specific
tool used before double-clicking (rather than always falling back to
Selection).

Additionally, when editing text while in isolation mode (such as when drilling
into nested groups with the Selection tool), pressing Escape exits text editing
while keeping isolation mode active; a second Escape press is required to exit
isolation mode.

- Record the previous tool in TypeTool on double-click from canvas.
- Return to prev_tool on ToolKey::Escape, consuming the key in shortcuts when claimed.
- Add unit test in vectorcraft-tools verifying Escape returns to prev_tool.
- Add integration tests in vectorcraft-ui-egui verifying Escape returns to Direct
  Selection and that isolation mode persists until a second Escape.
- Update docs/target-app-parity.md and ROADMAP.md.
2026-10-16 04:19:05 +07:00
el-j 28daaf473c Canvas: double-clicking type with the direct selection tool puts the caret there
With the Direct Selection tool ("white arrow", shortcut 'a'), double-clicking
a text element (either standalone or nested inside a group) now switches to
the Type tool and immediately positions the caret at the clicked character,
matching the behavior previously introduced for the Selection tool in #284.

- In DirectSelectionTool::pointer, detect double-click hits on NodeKind::Text
  when !self.group and emit Action::SwitchTool("type").
- Group Selection (group: true) retains its existing group cycling behavior.
- Add unit test in vectorcraft-tools verifying tool switch on both standalone
  and grouped text.
- Add headless egui integration test in vectorcraft-ui-egui verifying tool switch,
  caret positioning, and inline editing without triggering shortcuts.
- Update docs/target-app-parity.md and ROADMAP.md.
2026-10-16 04:19:05 +07:00
bflatastic 9e1590769e i18n(bg): Hide Template and Show Template 2026-10-16 04:19:05 +07:00
wstockandClaude Fable 5.1 7b8730ec14 View › Hide Template (Cmd+Shift+W): template layers leave the canvas and come back (#2000)
Illustrator's View menu has Hide/Show Template (Shift+Ctrl+W) to leave
template layers off the screen while tracing. VectorCraft drew them (dimmed)
whatever the view, with no way to hide them short of disabling the template
option on each layer and losing the dimming.

- `view.template` toggles `ViewFlags::templates` (default on, kept across
  settings files); the View menu lists Hide Template after Lock Slices, and
  the label flips to Show Template.
- The canvas renders with the new `RenderOptions::hide_templates`, which
  leaves template layers out and nothing else; `skip_templates` (exports and
  thumbnails) also drops guide paths, so it is not reused.
- The fifteen menu catalogs translate both labels; `DYNAMIC_LABELS` lists them.

Tests: render `hide_template_leaves_only_the_template_layers_out` (the
template layer's square and image go, a guide path on another layer stays);
canvas `hide_template_leaves_template_layers_off_the_canvas` (real egui
frames: painted pixels, none after Hide Template, the same after Show
Template, each re-rendering once); the dynamic-label and catalog tests cover
the new pair.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011K1peyrh5MdZ6ttHkVq8Gh
2026-10-16 04:08:44 +07:00
NetterSilverandClaude Haiku 5.5 c54a9b0bef Reveal the active layer in the Layers panel after a canvas selection
Fixes #2049

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:42 +07:00
Ayberk A. a86ff7f177 Document Info: Objects gives the paths' total length (#1958)
Document Info › Objects counts the paths but didn't say how long they are,
which sign and print work reads there (an LED strip along the letters, a
cut line). `document.info` now adds up the length of every path it counts,
the pieces of compound paths included and guides left out, and returns it
as `pathLength` (pt); the Objects section shows it as Path Length in the
document's units, right after the Paths count, so Selection Only gives the
selected paths' length. The label is translated in the catalogs that
cover the menus; pt-br only takes strings the UI itself shows.
2026-10-16 04:08:12 +07:00
Fabian GrajalesandClaude Opus 5.5 7135a377f8 Panel menus light up under the pointer, like the menu bar's
Panel (≡) menu rows, and the Control bar's image menu, had no frame at all,
so nothing showed which row the pointer was on. They now draw the hover
frame the menu bar's items draw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:10 +07:00
Fabian GrajalesandClaude Opus 5.5 91e1434cbf Swatches panel follows the selection's swatch
Selecting art scrolls the tiles to its swatch once (centred) and clears the
panel's own selection, so the art's swatch is the one highlighted; so does a
change of the selection's paint (after Recolor Artwork). An unlinked process
colour highlights the swatch of that very colour. A selected image, or text
in a colour no swatch has, highlights nothing (not None).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:08 +07:00
Fabian GrajalesandClaude Opus 5.5 5a43337a42 Replace a selected image from the Control bar, with its own aspect ratio
The Control bar's file name is a menu: Replace…, Go To Link, Edit Original,
Update Link and Placement Options…. Replace… (also in the Properties panel,
in place of Relink…) puts the picked file in the image's place fitted inside
the old bounds and centred, keeping the new file's aspect ratio instead of
stretching it into the old one. links.relink takes `preserve` (transforms,
bounds, fileDimensions, fit or fill) to override the Placement Options for
that read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:08:06 +07:00