Commit Graph
4779 Commits
Author SHA1 Message Date
BFlat 21291ab387 Merge pull request #3438 from dotCooCoo/fix/docs-localization-parity-lists-dutch-danish-indonesian
Docs: localization parity lists the Dutch, Danish and Indonesian catalogs
2026-10-21 23:51:34 +07:00
BFlat 2cf7ad1ad1 Merge pull request #3418 from KnottyDyes/squad/icc-profile-padding
ICC: all built-in profiles are checked for aligned sizes and tags
2026-10-21 23:51:18 +07:00
BFlat de01edb28a Merge pull request #3414 from dotCooCoo/fix/docs-zh-hant-catalog-counts
Docs: localization parity row counts match the catalogs on main
2026-10-21 23:51:05 +07:00
BFlat 0a1c4cdd87 Merge pull request #3406 from oracola91/fix/recovery-folders-owner-only
Data Recovery: the recovery folders are owner-only on Unix
2026-10-21 23:50:49 +07:00
BFlat 5fc175a5ef Merge pull request #3389 from dotCooCoo/fix/tests-data-set-export-fresh-folder
Tests: the data set export test checks the whole file in a folder emptied first (#2969)
2026-10-21 23:50:33 +07:00
BFlat ba047ee5f7 Merge pull request #3382 from dotCooCoo/fix/altgr-typing-runs-no-command
Type: a character typed with AltGr while editing text runs no command
2026-10-21 23:50:18 +07:00
BFlat ecb7ac1fc6 Merge pull request #3376 from dotCooCoo/fix/tests-half-form-face-filter
Tests: the half-form test uses only a fallback face that forms Ka's half form (#2670)
2026-10-21 23:50:02 +07:00
BFlat f9e289410d Merge pull request #3373 from dotCooCoo/fix/docs-pages-sentence-names-the-file
Docs: the document.open pages sentence names the file saved without PDF compatibility
2026-10-21 23:49:47 +07:00
BFlat a1738c15d4 Merge pull request #3372 from dotCooCoo/fix/save-as-replaces-a-typed-extension
Save As: a typed extension of a format the save doesn't write is replaced
2026-10-21 23:49:31 +07:00
BFlat 9a5c5459bd Merge pull request #3371 from nikolainyegaard/language-picker-order
Preferences: list the languages alphabetically by their own name
2026-10-21 23:49:15 +07:00
bflatastic c895f64063 Format: rustfmt after the batch 2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 4e5f5e608b G12: translate Touch workspace for complete i18n catalogs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor cc4836abb7 G4: reuse Character panel Shared/Metric for mixed paragraph fields.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 56cfb79d24 G4: add i18n rows for Scale Text Attributes command and error
Complete menu catalogs need plain and @msg entries so i18n tests pass for the new type command.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 240d8d4891 Fix collapsible_if clippy in object.setLiveShape relative radii path.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
Cursor Agentandnrq6993-a11y b13072b77c M3: rustfmt eyedropper and brush key-color UI
Co-authored-by: nrq6993-a11y <nrq6993-a11y@users.noreply.github.com>
2026-10-21 23:38:03 +07:00
bflatastic e5471be4d9 Commands: an index of 2^32 or more no longer wraps around on 32-bit builds
Squashed from #3292 onto main.
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 1c7b02a6fe G12: honor Enable Touch Workspace preference
Switch to the Touch built-in workspace when the preference is on and a touch
screen is present; restore the prior workspace when it is turned off.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor c7df7a56e8 docs: note G4 Paragraph panel mixed indent fields
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 07a49d447d G4: Scale Text Attributes bakes transform scale into type sizes
After scaling groups, type.scaleTextAttributes matches panel sizes to what draws on canvas without leaving scale in the affine.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor a719b22e1b G1: use "the reference app" in setLiveShape relativeRadii params doc.
cargo xtask brands rejects vendor names in CommandSpec params strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 3f45472e15 i18n: add Key Color eyedropper tooltip to complete catalogs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 45cabc1c3c G4: blank Paragraph panel indents when paragraphs differ
Mixed left/right/first-line indents and space before/after now follow the same shared-value rules as alignment buttons.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 59534c1cbb Fix LiveCorners::style to report stored radii, not fitted draw sizes.
Star corners with a large uniform radius kept None in the panel because fitted draw radii differ per tip; tests and UI expect the value the user set.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 2d85d8818e docs: mark G5 Key Color eyedropper done in gaps.md
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor ab0ddf0eae G1: Live Corners relative rounding (#1144)
Store corner radii as fractions of each corner's max so rounding scales with the shape; expose via Corners dialog and object.setLiveShape relativeRadii.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor 6433b6ca3a G5: Pattern brush Key Color eyedropper in Brush Options
Hue Shift colorization can sample key color from canvas art via the
eyedropper next to the swatches, matching Illustrator's brush workflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:03 +07:00
nrq6993-a11yandCursor cdef620083 G2: Share glass_fields for Glass and Texturizer load-texture UI.
Drop duplicate texturizer_fields/texturizer_params per review.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor b3a380cfa0 G2: translate Hard Mix pathfinder menu and undo label
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 2dcceea8e1 G1: limit Cmd+Alt Group Selection to active Direct Selection
Pen Cmd-borrow keeps Direct Selection when Alt is held so guide copy and other Alt modifiers on the lent tool still work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
bflatastic 0a3628f62f G2: Effect › Artistic › Dry Brush raster filter
Squashed from #3026 onto main.
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 571ac32362 Fix floating tab reorder deadlock by calling strip_tab_reorder in-frame.
Route dock and floating strip reorders through shared logic, sync layout.floating order, and assert reorder via window.panel.move in the harness test.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
bflatastic 58066428c6 Artboards: the Artboards panel locks an artboard and the art on it
Squashed from #2592 onto main.
2026-10-21 23:38:02 +07:00
bflatastic 9c20027778 Keyboard Shortcuts: each Align and Distribute button of the Align panel can be given a key
Squashed from #3317 onto main.
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor dfa7bd12d9 G2: Texturizer Load Texture matches Glass and Illustrator.
Users can pick an image in the Texturizer dialog; it is stored as relief heights and survives save/open like Glass textures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 3f3888d040 G2: Effect › Pathfinder › Hard Mix mixes CMYK per face
Overlapping faces take the highest of each CMYK channel from every covering shape and drop strokes, matching Illustrator's Hard Mix effect.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor fface52206 G1: Cmd+Alt lends Group Selection for one gesture
When Direct Selection was last used or is active, Cmd+Alt borrows Group Selection for pointer presses, matching the documented modifier chord.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 951d1705e3 Fix #2995: unify floating tab reorder with window.panel.move
Route floating strip drags through the same command path as the dock strip and centralize group tab index moves in one helper.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 4cba355f71 Fix #2995: address PR review on tab reorder and dock drag begin
Reuse catalogued window.panel.move errors, keep legacy dock drags from clearing docking on Escape, reorder floating tabs locally without reconcile re-entry, and fix dock_tab_order test setup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor ba2a5bfaed Fix #2995: route tab reorder through window.panel.move and harden dock_tab_order
Legacy and floating strip drags update order via the panel.move command; partial saved orders append missing tabs, with command-level tests and Illustrator workspace doc link.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
nrq6993-a11yandCursor 2c715c9fe3 Fix #2995: reorder grouped panel tabs by dragging within the tab strip
Horizontal drags on dock and native floating tab strips now reorder tabs
instead of only tearing off; storytold/vectorcraft#2995.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 23:38:02 +07:00
bflatastic 5e24e59bd3 Brushes: New Brush and Bristle Brush Options take a bristle brush name of at most 31 characters
Squashed from #3312 onto main.
2026-10-21 23:38:01 +07:00
bflatastic 1cfeaabb2d Docs and format: one row per area after the batch, rustfmt
Rows two PRs of the batch both changed came out twice in localization-parity, target-app-parity and type-parity; the newest of each is kept. prefs_dialog.rs is formatted.
2026-10-21 23:38:01 +07:00
dotCooCoo 3884cf9704 Tabs: a stop placed or moved on the ruler lands on a whole point
A click on the Tabs panel's ruler added a stop, and a drag moved one,
at the fraction of a point under the pointer. The reference app's Tabs
page says that the tab ruler does not set stops in increments smaller
than 1, and that the X or Y field sets them as finely as 0.01 point.
The page does not name the unit of 1. The ruler here uses 1 point, the
unit the page gives for the X or Y field, in every General unit.

With Snap to Unit off and Shift not held, a stop placed or dragged on
the ruler now lands on the nearest whole point. With Snap to Unit on,
or Shift held, it still lands on the ruler's nearest tick, which on a
millimeter ruler is a fraction of a point. A position typed in the X
or Y field keeps its hundredths of a point.

Docs: docs/target-app-parity.md.
2026-10-21 23:32:26 +07:00
dotCooCoo 6807e757af PDF export: PDF and .ai files carry File Info's copyright status, notice and URL
The PDF writer's metadata has no copyright fields, so the XMP packet of
PDF exports and PDF-compatible .ai and .ait saves left out File Info's
copyright status, notice and URL. A PDF exported without its editing
data opened with the status Unknown and an empty notice and URL,
although the reader takes them from dc:rights, xmpRights:WebStatement
and xmpRights:Marked.

The export now adds those three properties to the XMP packet after
the writer has written it, as it does for the modification date.
Marked is True for Copyrighted and False for Public Domain, and is left
out for Unknown. The notice and URL are escaped for XML, and characters
XML 1.0 does not allow are left out. A document without a copyright
gets none of the properties.

Docs: docs/mcp.md (File Info), docs/target-app-parity.md.
2026-10-21 23:32:26 +07:00
Midasdf 32d012f6cc Print: Japanese paper sizes (JIS B4/B5/B6, はがき・封筒・四六判)
The Print dialog's Media list only had Letter/Legal/Tabloid and the ISO A
and B papers, so Japanese papers had to be entered as a custom size, and
"B4"/"B5" were ISO 216 (250 × 353 and 176 × 250 mm) although Japanese
printing uses the JIS sizes (257 × 364 and 182 × 257 mm, JIS X 6310).

Media gains JIS B4, B5 and B6 next to the ISO ones, and はがき
(japanese postcard, 100 × 148 mm), 往復はがき (japanese double postcard,
148 × 200 mm), 封筒 長形3号/長形4号 (japanese envelope #3/#4, 120 × 235
and 90 × 225 mm), 角形2号/角形3号 (kaku #2/#3, 240 × 332 and 216 × 277 mm),
四六判 (yonroku-ban, 127 × 188 mm) and A6, all in millimetres at 72/25.4.
b4 and b5 keep their ISO 216 dimensions so print settings and presets
saved before the Japanese papers existed keep their paper; the dialog
labels say "B4 (ISO)"/"B5 (ISO)" beside "B4 (JIS)"/"B5 (JIS)".

A paper is named by its JSON id or by its dialog label, any case and
spacing ("b5 (jis)", "B5 (JIS)" and "b5jis" all mean the JIS B5), so
agents and the control channel need not know the id spelling; an unknown
name is still refused. Media is written out instead of through the
choice! macro to carry that lookup.

The print.setup/file.print parameter docs and docs/mcp.md list the new
papers; the Print dialog picks them up from Choice::ALL with no UI code
change, and the Japanese labels are translated in ja.tsv (はがき,
往復はがき, 長形3号, 長形4号, 角形2号, 角形3号, 四六判).

Tests: japanese_paper_sizes checks every added size in points, that the
ISO B4/B5 values did not change, name resolution and id/label round
trips, and that each paper prints a PDF page with its own MediaBox size.

Validation: cargo fmt --all -- --check clean; cargo clippy
-p vectorcraft-pdf --all-targets -- -D warnings clean; cargo test
-p vectorcraft-pdf -> 330 passed, 0 failed (328 lib + 2 integration).
2026-10-21 23:32:26 +07:00
dotCooCoo 7d58ce4f9d Place: Word's low, medium and high kashida justification sets Insert Kashidas
A Word paragraph justified with w:jc lowKashida, mediumKashida or
highKashida placed as plain justified type, and its kashida length was
dropped. ECMA-376 Part 1, 17.18.44 (ST_Jc) gives these values a
slightly longer, a medium and the widest kashida length.

Such a paragraph now places justified with Insert Kashidas set to
Short, Medium or Long. A paragraph justified with both, and every other
alignment, still places with Insert Kashidas set to None. VectorCraft
writes no Word or RTF files, so this change does not affect export.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-21 23:32:26 +07:00
Drew DibbleandClaude Opus 5.5 e321c7179b Text: an embedder of the egui panels may leave the bundled fonts out
#2027 gave vectorcraft-text and vectorcraft-engine a `bundled-fonts`
feature for an embedder that supplies every document font at run
time, but vectorcraft-ui-egui (and vectorcraft-mcp) named the engine
with its default features, so an embedder that hosts the panels got
the fonts whatever it asked for. Each now has a `bundled-fonts`
feature of its own, on by default, that turns the engine's on, so a
downstream user keeps the fonts unless it asks otherwise. For a
member to leave the engine's default features out, the workspace has
to declare the engine without them, as it already declares
vectorcraft-text; the crates that used the engine's default now ask
for the fonts: the three apps and vectorcraft-testkit. Off,
vectorcraft-text's copy of the fonts (3.4 MB) is left out; theme.rs's
own copies of five of them, the panels' interface faces, stay either
way.

Nothing the workspace builds changes: for every workspace member and
for the whole workspace, with and without dev-dependencies, for all
targets, wasm32-unknown-unknown, aarch64-apple-darwin and
x86_64-pc-windows-msvc, `cargo tree -e normal[,dev] -f '{p} [{f}]'`
resolves the same features for every package as on main, apart from
the new feature names (the engine's `default` no longer listed;
ui-egui's and mcp's `bundled-fonts` and `default`).

A test of the panels can't see their configuration without the fonts
(their dev-dependencies turn them on), so `cargo xtask ci`'s
`no-bundled-fonts` step now also reads that tree for
vectorcraft-ui-egui and vectorcraft-mcp: with their default features
it must show the fonts, and without them, for any target (a wasm-only
dependency too), it must not. Documented in docs/development.md
(Fonts › Leaving out the bundled fonts).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-21 23:32:26 +07:00
Grant Colloty 84d5d8797f EPS/.ai editing data: type keeps stacked art styles as live appearance
**What:** Illustrator type styled through the Appearance panel came in as its drawn look (outlined compound paths). Comic and "text effect" templates are the common case, and the type couldn't be retyped. This keeps it as editable type with the style as a live VectorCraft appearance.

**Changes**
- **Art styles parsed as a tree.** Compound filters close at their `;`, basic ones at `/Part`. Each fill and stroke in a stack keeps its own effects, opacity and blend mode, and object-level effects stay on the object.
- **Type keeps any plain stack.** That covers several fills and strokes, pattern and gradient fills, Warp, Offset Path, Transform with copies, Drop Shadow, Outer Glow, Feather, Gaussian Blur and Bas Relief. Bas Relief settings are left at their defaults, because Illustrator stores them in a Photoshop plug-in's binary block. Gradients and patterns are placed as the drawn look places them. Other objects keep the existing plain-style rule, since their drawn look is the more faithful option.
- **Point type without a frame matrix.** Illustrator 24 omits the matrix when point type is neither rotated nor scaled. Such stories were left out entirely; they're now read with an identity matrix.
- **Page comparison.** The page's rendering of a style isn't held to match VectorCraft's live rendering where the replaced drawn look lay, and styled made type isn't pruned as unseen.
- **EPS override.** `editingData: "always"` / `convert --editing-data` now applies to Illustrator EPS as well as `.ai`.

**Tests:** 6 new tests, written from scratch; `vectorcraft-eps` passes all 298 on current main. clippy `-D warnings` and rustfmt are clean for eps, engine and cli. `docs/file-format-parity.md` has been updated, including its revision history.

**Clean-room note:** I found the bugs with a user's licensed stock EPS, used locally only; nothing from it is committed. Filter and key meanings come from the public Illustrator Effect docs and public LiveEffect scripting examples (`jntp`, the Warp style order).

**Not included:** VectorCraft's pixel effects treat transparent content as empty instead of using Document Raster Effects Settings › Background (white by default). Because of that, Bas Relief on a transparent pattern gives flat grey. That needs a separate renderer change.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-10-21 23:16:30 +07:00
KnottyDyesandClaude Opus 5.5 52b63e2198 PDF import: letter-spaced text keeps its word spaces
PDF import read every gap wider than a fifth of an em between two
glyphs as a space. Letter-spaced type (Tc, or glyphs placed one by one
with tracking) has such a gap between every pair of letters, so
"OPEN DAILY" came in as "O P E N D A I L Y".

A line now records every gap between its glyphs and decides which are
spaces when it finishes: the spacing its letters share (the gap a third
of the way up from the narrowest, when the line has three or more) is
taken off each gap first. That shared spacing is at most half an em, so
glyphs set wider apart, such as figures in columns, keep their spaces.
Right-to-left lines and glyphs along a curve read their gaps as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 23:16:29 +07:00