mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 01:53:57 +00:00
Merge main (433ddb59) into feat/native-save-precision
This commit is contained in:
+4
-21
@@ -1,16 +1,14 @@
|
||||
# Contributors in the About window
|
||||
|
||||
**About ▸ Contributors** credits everyone who contributed to VectorCraft, and **About ▸ Models** credits
|
||||
the AI models named in `Co-Authored-By` trailers. This follows the shared craftrules standard
|
||||
[`standards/contributors.md`](https://github.com/storytold/craftrules/blob/main/standards/contributors.md);
|
||||
this page is the local copy of the decision.
|
||||
the AI models named in `Co-Authored-By` trailers.
|
||||
|
||||
## Decision
|
||||
|
||||
- Two files, both **compiled into the binary** by the UI crate's `build.rs` (nothing is read from
|
||||
disk or the network at run time; the web build has them too):
|
||||
- [`contributors/contributors.json`](../contributors/contributors.json): commit stats per GitHub
|
||||
username. **Generated** by `craftrules/scripts/contributors.py`; never hand-edit.
|
||||
username. Never hand-edit.
|
||||
- [`contributors/people.toml`](../contributors/people.toml): the names people chose for
|
||||
themselves. **Each contributor adds only their own entry**, in their own PR.
|
||||
- Each contributor gets one line: GitHub username (always), display name (opt-in, or their synced
|
||||
@@ -37,20 +35,5 @@ display_name = "Nickname"
|
||||
sync_github_name = true # use the name on your public GitHub profile as display name
|
||||
```
|
||||
|
||||
or, with craftrules checked out next to `craft-apps/`:
|
||||
|
||||
```sh
|
||||
python3 ../../craftrules/scripts/contributors.py --add-me . --real-name "Your Name" --sync-github-name
|
||||
```
|
||||
|
||||
Names show after the next refresh: the script checks that each entry was committed by its own
|
||||
user (or by a maintainer with a `consent_source`). Delete your entry to remove your names.
|
||||
|
||||
## Refreshing (maintainers)
|
||||
|
||||
```sh
|
||||
python3 ../../craftrules/scripts/contributors.py . # regenerate + verify; needs git, Python 3.11+, gh
|
||||
python3 ../../craftrules/scripts/contributors.py --check . # verify people.toml only
|
||||
```
|
||||
|
||||
Commit the updated `contributors/contributors.json`. Git author names and emails are never recorded.
|
||||
Names show for entries committed by their own user (or by a maintainer with a `consent_source`).
|
||||
Delete your entry to remove your names. Git author names and emails are never recorded.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Control protocol
|
||||
|
||||
> **Last updated:** 2026-10-25 · **Change:** Object → Expand… dimmed while the selection has an appearance Expand Appearance expands (`object.expand.info`'s `appearance`, #3089); previously: brush library panels (`window.brushLibrary`, `window.brushLibrary.other`, `ui.saveBrushLibrary`); previously: Transform Each opens on the values it was last confirmed with; its Copy button confirms with `copy: true` (#1732); previously: panel docking on craft-ui's layout: `ui.docking`, the parameters of `window.panel.float` and `window.panel.dock`; previously: `ui.screenshot`'s 64 MiB inline-PNG cap and its path-plus-data downgrade; symbol library panels (`window.symbolLibrary`, `window.symbolLibrary.other`, `ui.saveSymbolLibrary`); synthetic input budgets (#1709); bounded transport waits (#1726).
|
||||
> **Last updated:** 2026-10-31 · **Change:** Confining file access refuses a `:` in a name after the drive on Windows, an NTFS alternate data stream such as `x.svg:evil` (#3604); previously: Object → Expand… dimmed while the selection has an appearance Expand Appearance expands (`object.expand.info`'s `appearance`, #3089); previously: brush library panels (`window.brushLibrary`, `window.brushLibrary.other`, `ui.saveBrushLibrary`); previously: Transform Each opens on the values it was last confirmed with; its Copy button confirms with `copy: true` (#1732); previously: panel docking on craft-ui's layout: `ui.docking`, the parameters of `window.panel.float` and `window.panel.dock`; previously: `ui.screenshot`'s 64 MiB inline-PNG cap and its path-plus-data downgrade; symbol library panels (`window.symbolLibrary`, `window.symbolLibrary.other`, `ui.saveSymbolLibrary`); synthetic input budgets (#1709); bounded transport waits (#1726).
|
||||
|
||||
`vectorcraft --control <port>` listens on `127.0.0.1:<port>` (loopback only). The port must be a number
|
||||
from 1 to 65535 (`--control=<port>` works too), given once; otherwise the app prints an error and exits
|
||||
@@ -68,7 +68,7 @@ writes (save, export, package, captures, library saves…) inside a write root;
|
||||
ordinary error reply. Paths are made absolute against the app's working directory, links are followed
|
||||
(for a file that doesn't exist yet, its folder's), and the comparison is by whole folder names (`/work2` is
|
||||
not inside `/work`), ignoring case on Windows; `..` below a folder that doesn't exist, a link that leads
|
||||
nowhere and Windows device names are refused. A root left out grants none of its access. The roots must be
|
||||
nowhere, Windows device names and, on Windows, a `:` in any name after the drive (an NTFS alternate data stream such as `x.svg:evil`) are refused. A root left out grants none of its access. The roots must be
|
||||
existing folders, or the app doesn't start; without `--control` they are ignored. See `docs/mcp.md`
|
||||
› Confining file access for the details.
|
||||
|
||||
@@ -456,6 +456,9 @@ Use Preview Bounds: the Align panel flyout's Use Preview Bounds item shows and t
|
||||
preference (`prefs.set`); while it is on, the bounding box and the Transform panel, Properties and Control bar
|
||||
fields measure visual bounds.
|
||||
|
||||
Align to Glyph Bounds: the Align panel flyout's Align to Glyph Bounds submenu shows and toggles the
|
||||
`alignGlyphBoundsPoint` (Point Text) and `alignGlyphBoundsArea` (Area Text) preferences (`prefs.set`), checked while on.
|
||||
|
||||
Align To: the Align panel's Align To choice is saved with the preferences, and `ui.inspect` reports it as
|
||||
`ui.align_to` (`"selection"` or `"artboard"`; Align to Key Object stores no choice). The align buttons of the Align
|
||||
panel, the Control bar and the Properties panel run `object.align` with `to: "artboard"` when one object is selected,
|
||||
@@ -811,7 +814,8 @@ Paintbrush, Blob Brush; on by default for the Pencil and Paintbrush and off for
|
||||
the path a stroke draws, continues or merges into is not selected afterwards), `mergeOnlySelection` (Blob Brush;
|
||||
off by default, and while it is on a stroke merges only with selected blobs), `closeWithin` and `editWithin`
|
||||
(screen pixels, 0 turns it off; Pencil, Paintbrush), `size` (pt; Blob Brush, Eraser), and `angle`
|
||||
(°, −180 to 180; 0) and `roundness` (%, 1 to 100; 100) of the Eraser's tip (Eraser). `ui.dialog.confirm` runs
|
||||
(°, −180 to 180; 0) and `roundness` (%, 0 to 100 for the Blob Brush, where 0 is drawn as 0.1, and 1 to 100 for
|
||||
the Eraser; 100) of the tip (Blob Brush, Eraser); the tip keeps its angle on the page along a stroke. `ui.dialog.confirm` runs
|
||||
`tool.setOption {tool, values}`.
|
||||
|
||||
`ui.pointer` events also take `holdMs` (0..60000): the pointer then holds still that long, button down, before the
|
||||
@@ -951,6 +955,7 @@ hidden tab (whose frames the browser pauses) answers when it is shown again.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-31 | minor | Confining file access: on Windows a `:` in a name after the drive (an NTFS alternate data stream) is refused with the device names (#3604). |
|
||||
| 2026-10-25 | minor | Panel docking on craft-ui's layout: `ui.docking`, the floating and dock parameters, native floating windows. |
|
||||
| 2026-10-24 | minor | Documented the brush library panel commands (`window.brushLibrary`, `.other`, `ui.saveBrushLibrary`, `window.userBrushLibrary1`…`10`). |
|
||||
| 2026-10-24 | minor | Documented `ui.screenshot`'s 64 MiB inline-PNG reply cap: with `path` the file is still written and `pngBase64` is omitted when over the cap; a path-less `data: true` request fails before encoding. |
|
||||
|
||||
+14
-4
@@ -1,5 +1,9 @@
|
||||
# Development
|
||||
|
||||
> **Last updated:** 2026-11-01 · **Change:** Linux: Automatic Linux Display Server opens the window through XWayland when a pen is attached on a Wayland session, so the pen draws (#4967); `VECTORCRAFT_NATIVE_WAYLAND=1` keeps Wayland.
|
||||
> **Last updated:** 2026-10-31 · **Change:** files opened while the app runs open in its window on Windows and Linux (#4892); `--new-instance`.
|
||||
> **Last updated:** 2026-10-29 · **Change:** Linux clipboard: the Flatpak on GNOME copies and pastes text through the core Wayland protocol.
|
||||
> **Last updated:** 2026-10-29 · **Change:** Linux clipboard: a clipboard that can't be opened is retried with a growing wait and logged once.
|
||||
> **Last updated:** 2026-10-25 · **Change:** Linux Wayland drag-and-drop note names eframe 0.37 (still on winit 0.30).
|
||||
> **Last updated:** 2026-10-23 · **Change:** Tests: cargo xtask test, one integration-test binary per crate, the dev profile's debug info.
|
||||
> **Last updated:** 2026-10-21 · **Change:** the interface faces as vectorcraft-ui-egui's `interface-fonts` feature, and `theme::install_fonts` for an embedder that draws the panels itself.
|
||||
@@ -107,24 +111,27 @@ On macOS the menus live in the system menu bar, not in the window's app bar (whi
|
||||
- **Keys stay with egui.** AppKit runs a menu's key equivalents before the window sees the key, so the item's key goes back to egui as the key press it was (⌘X/⌘C/⌘V as egui's Cut/Copy/Paste events), through `raw_input_hook`: `shortcuts::handle` runs it once, user shortcuts apply, and a focused text field keeps ⌘A, ⌘C, ⌘V and ⌘Z. A click runs the item like an in-window click. Bare keys and ⌥/⇧ chords are never key equivalents (they type).
|
||||
- Built and clippy-checked for `aarch64-apple-darwin` and `x86_64-apple-darwin` from any host: `cargo clippy -p vectorcraft --target aarch64-apple-darwin --all-targets -- -D warnings`.
|
||||
|
||||
## Files opened while the app runs (Windows and Linux)
|
||||
|
||||
A file opened from the file manager (double-click, Open With, a drop on the executable) or given on the command line while VectorCraft already runs opens as a new document tab in that window, which comes to the front; the second launch exits (#4892). `apps/vectorcraft/src/single_instance.rs`: the running app listens on a loopback port and records the port and two random tokens in `instance.json` next to the preferences (owner-only on Unix). A launch with files reads it, connects, checks the app's greeting, sends the token and the absolute paths as one JSON line and waits for the acknowledgement; the app keeps only existing files (at most 256, 64 KiB per message). A stale file (no listener, a wrong greeting) is ignored and replaced; the app removes its file when its window closes. Launches with `--control` or `VECTORCRAFT_NO_PREFS` neither hand files over nor listen, so tests and agents start as many apps as before; `--new-instance` opens a launch's files in a window of its own. macOS hands Finder's files to the running app as open-document events (`open_documents.rs`).
|
||||
|
||||
## Linux: Wayland and X11
|
||||
|
||||
On GNOME/Wayland, enable **Preferences › User Interface › System Title Bar** and restart to use winit's font-free Adwaita window controls (`wayland-csd-adwaita-notitle`); the existing custom title bar remains the Linux default.
|
||||
|
||||
The window runs natively on Wayland (eframe's `wayland` feature) and on X11. On machines with two GPUs it renders on the one the desktop runs on unless Preferences say otherwise; see [Desktop graphics processor](#desktop-graphics-processor) (#502). The system clipboard (`apps/vectorcraft/src/clipboard.rs`) is arboard with its `wayland-data-control` feature:
|
||||
|
||||
- **Clipboard:** under Wayland arboard talks to the compositor through the data-control protocol (wlroots compositors such as Sway and Hyprland, KDE Plasma), so bitmaps (`image/png`), SVG markup and text copied in any app paste (#398). Where the compositor lacks the protocol (GNOME's Mutter, [arboard#223](https://github.com/1Password/arboard/issues/223)), arboard falls back to the X11 clipboard through XWayland, which only holds what X11 apps copied. egui's own text paste into fields goes through smithay-clipboard and works either way.
|
||||
- **Clipboard:** under Wayland arboard talks to the compositor through the data-control protocol (wlroots compositors such as Sway and Hyprland, KDE Plasma), so bitmaps (`image/png`), SVG markup and text copied in any app paste (#398). Where the compositor lacks the protocol (GNOME's Mutter, [arboard#223](https://github.com/1Password/arboard/issues/223)), arboard falls back to the X11 clipboard through XWayland, which only holds what X11 apps copied. Where there is no X11 either (the Flatpak on a Wayland session: `--socket=fallback-x11` gives it none), Copy and Paste use the compositor's core data-device protocol on the window's own connection through smithay-clipboard: text only (a copy's text or its SVG markup), and only while the window has focus. smithay-clipboard waits for the owner's data with no limit, so its reads run on a worker thread and a Paste waits 2 s at most: an owner that never sends its data costs one Paste 2 s, and later reads return at once until it answers. A clipboard neither backend opens is tried again after 1 s, doubling to a minute (a Copy or Paste of the user's at most once a second), and logged once when it goes and once when it comes back: before, the background Paste check reconnected and logged a warning every 250 ms. egui's own text paste into fields goes through smithay-clipboard and works either way.
|
||||
- **Clipboard owners that never answer (#510):** reading the clipboard waits on the app that owns it: arboard gives up on an X11 owner after 4 s, and a Wayland read waits for the owner to send its data. So on Linux the check that enables the Paste menu items runs on a background thread with a second clipboard handle (`crates/ui-egui/src/clipboard_probe.rs`, installed as `Services::clipboard_probe`), only while nothing is copied in the app and a document is open, and the window keeps drawing. A paste itself still reads on the UI thread, so pasting from such an owner waits for it once. Windows and macOS keep the check on the UI thread: Windows only asks which formats the clipboard holds, macOS asks the pasteboard server.
|
||||
- **Copied files:** files copied in a file manager (`text/uri-list`; `CF_HDROP` on Windows, file URLs on macOS) paste as the first one that is art (SVG, PDF, EPS, EMF/WMF or a bitmap; a `.ai` or `.ait` file from the editing data it holds, else as the PDF or PostScript it holds), before the clipboard's other formats (which include the files' paths as text).
|
||||
- **Dropping files on the window does not work under Wayland:** winit 0.30, which eframe 0.37 runs on, has no Wayland drag and drop ([winit#1881](https://github.com/rust-windowing/winit/issues/1881), added in winit 0.31; [egui#1563](https://github.com/emilk/egui/issues/1563)), so no `dropped_files` arrive. Until eframe moves to winit 0.31: copy the files in the file manager and paste them, use File › Place or Open, or open the window through XWayland, where drops work: set **Preferences › Performance › Linux Display Server** to **X11 (XWayland)** and restart (#1151), or start the app with `WAYLAND_DISPLAY= vectorcraft`. The preference (`linuxDisplayServer`, read at startup in `apps/vectorcraft/src/main.rs`, shown on Linux only) has winit open the window on X11 (`EventLoopBuilderExtX11::with_x11`) when the session is Wayland, `DISPLAY` is set and the X11 libraries winit loads are installed (`apps/vectorcraft/src/xwayland.rs` reads `ldconfig -p` and the usual library directories); otherwise the window opens on Wayland and the log says why. Unlike clearing `WAYLAND_DISPLAY`, it leaves the clipboard on the compositor's own.
|
||||
- **Pens and pen displays under Wayland (#491, #2028):** winit 0.30 doesn't bind the Wayland tablet protocol (`zwp_tablet_v2`; tablet input arrives in winit 0.31, [winit#4318](https://github.com/rust-windowing/winit/pull/4318), [egui#7731](https://github.com/emilk/egui/pull/7731)). Since Plasma 6.3, KWin no longer turns tablet input into pointer input for such apps ([kwin!6336](https://invent.kde.org/plasma/kwin/-/merge_requests/6336), commit [25c65abd](https://invent.kde.org/plasma/kwin/-/commit/25c65abddd95eb87fb892a8594faccbf509ff62f)), and GNOME's Mutter does not turn it into pointer input either (that commit's message): on KWin the pen moves the compositor's cursor over the window, but the app gets no motion or presses and shows none of its own cursors. Until eframe moves to winit 0.31, either run the app under XWayland, which supports the tablet protocol and hands the pen to X11 apps as a pointer (Preferences › Performance › Linux Display Server › X11 (XWayland); X11 (XWayland) When a Pen Is Attached (`x11WithPen`), which opens the window through XWayland only when `/proc/bus/input/devices` lists a pen as the app starts, a device with the `BTN_TOOL_PEN` key and the `ABS_X` and `ABS_Y` axes, and logs `pen found: opening the window through XWayland`; `WAYLAND_DISPLAY= vectorcraft`, or `env -u WAYLAND_DISPLAY vectorcraft`; for a desktop launcher, put `env WAYLAND_DISPLAY=` before the command in its `Exec=` line), or turn KWin's deprecated emulation back on for the whole session by setting `KWIN_WAYLAND_EMULATE_TABLET=1` in KWin's environment (for example in a file under `~/.config/environment.d/` or in `/etc/environment`) and logging in again. The pen then works as a mouse. Under XWayland the app also reads the pen's pressure (next item); with KWin's emulation on native Wayland the pen has no pressure. Other compositors that don't emulate a pointer for tablets behave the same way.
|
||||
- **Pens and pen displays under Wayland (#491, #2028):** winit 0.30 doesn't bind the Wayland tablet protocol (`zwp_tablet_v2`; tablet input arrives in winit 0.31, [winit#4318](https://github.com/rust-windowing/winit/pull/4318), [egui#7731](https://github.com/emilk/egui/pull/7731)). Since Plasma 6.3, KWin no longer turns tablet input into pointer input for such apps ([kwin!6336](https://invent.kde.org/plasma/kwin/-/merge_requests/6336), commit [25c65abd](https://invent.kde.org/plasma/kwin/-/commit/25c65abddd95eb87fb892a8594faccbf509ff62f)), and GNOME's Mutter does not turn it into pointer input either (that commit's message): on KWin the pen moves the compositor's cursor over the window, but the app gets no motion or presses and shows none of its own cursors. Until eframe moves to winit 0.31, the app runs under XWayland, which supports the tablet protocol and hands the pen to X11 apps as a pointer: Preferences › Performance › Linux Display Server's Automatic (the default) and X11 (XWayland) When a Pen Is Attached (`x11WithPen`) open the window through XWayland when `/proc/bus/input/devices` lists a pen as the app starts, a device with the `BTN_TOOL_PEN` key and the `ABS_X` and `ABS_Y` axes, and log `pen found: opening the window through XWayland`, as PhotoCraft does (#4967; `VECTORCRAFT_NATIVE_WAYLAND=1` keeps the window on Wayland). For a pen attached after the app started, either run the app under XWayland (Preferences › Performance › Linux Display Server › X11 (XWayland); `WAYLAND_DISPLAY= vectorcraft`, or `env -u WAYLAND_DISPLAY vectorcraft`; for a desktop launcher, put `env WAYLAND_DISPLAY=` before the command in its `Exec=` line), or turn KWin's deprecated emulation back on for the whole session by setting `KWIN_WAYLAND_EMULATE_TABLET=1` in KWin's environment (for example in a file under `~/.config/environment.d/` or in `/etc/environment`) and logging in again. The pen then works as a mouse. Under XWayland the app also reads the pen's pressure (next item); with KWin's emulation on native Wayland the pen has no pressure. Other compositors that don't emulate a pointer for tablets behave the same way.
|
||||
- **Pen pressure under X11 and XWayland (#764):** winit 0.30 hands a pen to an X11 window as a mouse, without its pressure. When the window is on X11, XWayland included, the desktop app opens a second X connection (x11rb's `RustConnection`) and reads XInput2 raw events for every device (`apps/vectorcraft/src/tablet.rs`, from PhotoCraft's `crates/tablet`). A device with an `Abs Pressure` valuator is a pen, unless its XInput type is `TOUCHPAD` or `TOUCHSCREEN`. While a pen is the pointer that moved last, its pressure, scaled from the valuator's range to 0..1, reaches the tools that use pressure: the Paintbrush's pressure-sensitive brushes and the Liquify tools' Use Pressure Pen. A pen device whose name or XInput type contains `eraser` (in any case) is the pen's eraser end: while the pointer is over the window, the canvas selects the Eraser tool when the eraser end moves, and it selects the tool used before when the tip moves again (`crates/ui-egui/src/stylus.rs`). The X server needs XInput 2.1 or later; otherwise the log has a `tablet pressure:` warning with the reason, and the pen draws at full pressure.
|
||||
|
||||
## Fonts: craft-fonts (optional build input)
|
||||
|
||||
Font files are never committed to this repository. Fonts shared by the Crafting Apps live in
|
||||
[storytold/craft-fonts](https://github.com/storytold/craft-fonts); the rules are in craftrules
|
||||
[`standards/fonts.md`](https://github.com/storytold/craftrules/blob/main/standards/fonts.md). To add
|
||||
[storytold/craft-fonts](https://github.com/storytold/craft-fonts). To add
|
||||
a font, add it there. (The Latin fonts in `assets/fonts/` predate the rule and stay.)
|
||||
|
||||
VectorCraft builds, tests and runs without craft-fonts. To embed its Japanese fonts (BIZ UDPGothic
|
||||
@@ -492,6 +499,9 @@ Scores and hour estimates are unchanged.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-31 | minor | Files opened while the app runs open in its window on Windows and Linux (#4892); `--new-instance` opts out. |
|
||||
| 2026-10-29 | minor | Linux clipboard: core Wayland protocol text fallback where arboard has neither data-control nor X11 (the Flatpak on GNOME).; its reads wait 2 s at most. |
|
||||
| 2026-10-29 | minor | Linux clipboard: a clipboard arboard can't open is retried after 1 s doubling to 60 s and logged once, instead of every 250 ms. |
|
||||
| 2026-10-28 | minor | Localisation: Catalan (`ca`) catalog and registry entry (every `ca-*` locale); complete under the catalog tests. |
|
||||
| 2026-10-25 | minor | Linux Wayland drag-and-drop note names eframe 0.37 (still on winit 0.30); behavior unchanged. |
|
||||
| 2026-10-23 | minor | Tests: `cargo xtask test` (nextest, then doctests), one integration-test binary per crate and the files that keep their own, the dev profile's debug info. |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Effects parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-28 · **Change:** minor (Drop Shadow Darkness uses fixed RGB subtraction and CMYK black addition; scores unchanged; Pathfinder › Trap: the Pathfinder panel's Trap… and Effect › Pathfinder › Trap… add an overprinting strip of the lighter colour where two solid colours meet; recounted with Hard Mix (#3061) and Soft Mix already in the catalogue: Pathfinder 13/13, Illustrator effects 49/50; previously: Transform effect: Transform Objects, Transform Patterns and Scale Strokes & Effects, #885; G2: the Effect Gallery shipped (#2883): Effect › Effect Gallery… browses the Artistic, Brush Strokes, Distort, Sketch, Stylize and Texture filters, edits each filter's settings, builds an ordered stack (add, reorder, hide, remove) with a live canvas preview, and OK applies it as separate appearance effects in one undo step; remaining: filter thumbnails and a preview area inside the dialog; G2 estimate 4–6 → 1–2 h; Raster effects 82% → 85% (power-user view 49% → 52%), estimated, a modest move because the named missing dialog landed without thumbnails or an in-dialog preview; previously:; stacked geometry effects make at most 2 million anchors of a path and about 8 million lines to draw; Roughen, Zig Zag, Free Distort, Twist and the warps build within it, #3578; scores unchanged; G2: Effect › Sketch › Conté Crayon (Foreground Level, Background Level, Texture, Scaling, Relief, Light Direction, Invert; a black crayon in the dark areas and a white one in the light areas on textured mid-grey paper; ranges and defaults unverified VectorCraft choices); measured Photoshop-style filters 57/57, the Effect Gallery remains (4–6 h); 3D: original Standard, Diffuse, Top Left and Right lighting presets; command access, effective-setting recognition and preview/history; scores and estimates unchanged; G2: Effect › Sketch › Note Paper; Halftone Pattern and Note Paper defaults documented as unverified VectorCraft choices; G2: Effect › Artistic › Smudge Stick, Sponge and Watercolor; Sketch › Bas Relief, Charcoal, Photocopy and Stamp, #2533; Photoshop filters 46/57, 11 remaining (8–14 h); G2: Sketch › Chrome; Sketch › Chalk & Charcoal, Graphic Pen and Reticulation and Artistic › Plastic Wrap, #2972, #2967, #2976, #3034: 37/57 Photoshop effects; 3D lighting: one to ten colored lights, smooth colored Inflate, legacy white-light appearance preserved; surface batching and restored seam minimum; scores and estimates unchanged; Zig Zag's Smooth points make a continuous wave, #2343; G2: Effect › Sketch › Halftone Pattern; Photoshop filters 46/57, 11 remaining (8–14 h); Round Corners also rounds corners where a curve meets a line or another curve, with Live Corners' cut; straight corners unchanged; score unchanged; Revolve: automatic smooth shading and default-on Cap with continuous rims; wide shadows and glows at high zoom, #1706; stacked Transform effects, #1705; 3D on nonzero compound paths, #1724; pattern tiles redraw, #1723; scores unchanged; Roughen's Smooth turn-backs, #1643; Scribble per region, #1648; score unchanged; Warp Arc bends in the object's proportions, #1578; Zig Zag ridges evenly spaced, #1558; effect parameters checked, #1592; score unchanged; raster effects after a pattern, radial or freeform gradient fill export at their place and size, #1536; score unchanged; 3D and Materials on outlined type and other shapes of many small curves, #1481; Twist 0° to 360°, #1524; twisted walls keep their faces, #1525; score unchanged; 3D and Materials: Inflate takes Twist, Taper and Cap; score unchanged; 3D and Materials: Perspective as the documented 0°–160° angle; 3D and Materials: the documented light settings) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-28 · **Change:** minor (Effect dialogs clamp bounded length inputs immediately on commit and flash rejection on invalid input (#4638); previously: Drop Shadow Darkness uses fixed RGB subtraction and CMYK black addition; scores unchanged; Pathfinder › Trap: the Pathfinder panel's Trap… and Effect › Pathfinder › Trap… add an overprinting strip of the lighter colour where two solid colours meet; recounted with Hard Mix (#3061) and Soft Mix already in the catalogue: Pathfinder 13/13, Illustrator effects 49/50) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
Every entry of Illustrator's Effect menu, by its public feature name, against VectorCraft's effects catalogue
|
||||
(`effect_catalog()` in `crates/effects/src/lib.rs`) and the Effect menu built from it
|
||||
@@ -193,6 +193,7 @@ angular cut caps, exact visibility, 3D Classic, Turntable, 3D export) is 25–45
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-30 | minor | Effect dialogs: bounded length fields (Color Halftone Max Radius) clamp on commit and visibly reject invalid input (#4638); scores unchanged. |
|
||||
| 2026-10-23 | minor | Pathfinder › Trap ([trapping](https://helpx.adobe.com/illustrator/using/trapping.html)): the Pathfinder panel's Trap… (`object.pathfinder.trap`, one undo step, the traps grouped above the topmost selected object and selected) and Effect › Pathfinder › Trap… (`pathfinder.trap`, live on groups) add an overprinting strip of the lighter colour inside the darker one where two solid colours meet (Reverse Traps: the darker into the lighter, but not a rich black), with Thickness, Height/Width, Tint Reduction and Traps with Process Color; the effect also has Precision and Remove Redundant Points. Recounted: Hard Mix (#3061) and Soft Mix had shipped, so Pathfinder 11/13 → 13/13 and Illustrator effects 46/50 → 49/50 (SVG Filters remains); remaining 6–10 → 4–8 h. Tests: `vectorcraft_pathops` `trap::tests`, `vectorcraft_effects` `trap::tests` and `group::tests::trap_effect_adds_an_overprinting_strip_above_the_members`, `vectorcraft_engine` `tests_trap`, `panels::pathfinder::tests::trap_opens_its_options_and_ok_traps_the_selection`. |
|
||||
| 2026-10-22 | minor | The Transform effect has Transform Objects, Transform Patterns and Scale Strokes & Effects, with visible checkboxes (#885); on a fill's or stroke's own Transform effect the last two are still missing. Counts unchanged. |
|
||||
| 2026-10-22 | minor | G2: the Effect Gallery shipped (#2883): Effect › Effect Gallery… browses the Artistic, Brush Strokes, Distort, Sketch, Stylize and Texture filters, edits each filter's settings, builds an ordered stack (add, reorder, hide, remove) with a live canvas preview, and OK applies it as separate appearance effects in one undo step; remaining: filter thumbnails and a preview area inside the dialog; G2 estimate 4–6 → 1–2 h; Raster effects 82% → 85% (power-user view 49% → 52%), estimated, a modest move because the named missing dialog landed without thumbnails or an in-dialog preview. |
|
||||
|
||||
File diff suppressed because one or more lines are too long
+80
-27
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
# Hardware parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-24 · **Change:** minor (pen pressure and the pen's eraser end on macOS, read from AppKit's tablet events, #852, not yet tried on a Mac; previously: patch: web pen buttons/modifiers preserved, touch-only input left to eframe, session-only palm rejection; tool cursors painted into the window on Wayland, #1652, not run on Linux; borderless title-bar window on Windows, #1758, awaiting confirmation; a window surface larger than 8192 px keeps working, #1459 in part; Linux Display Server preference opens the window through XWayland, #1151) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-01 · **Change:** patch (Linux: on a Wayland session with a pen attached, Automatic opens the window through XWayland, where the pen draws, #4967) · **Target:** Adobe Illustrator 2026 (30.x)
|
||||
|
||||
What hardware Illustrator uses, per platform, against VectorCraft. Illustrator's side is from its public
|
||||
documentation (GPU Performance, touch workspace, pen pressure pages); ours from the code
|
||||
@@ -21,11 +21,11 @@ reads the pen's eraser end on Windows, on macOS and on Linux under X11 and XWayl
|
||||
| Multithreaded rendering off the UI thread | partial | yes | yes | yes | single-threaded | beyond Illustrator |
|
||||
| Hybrid-graphics GPU choice | automatic | power-saving GPU by default, Preferences › Graphics Processor | same; DX12 then OpenGL; no Vulkan unless asked (#545, #806) | the desktop's GPU | browser | done |
|
||||
| Restart on another GPU when the first fails to present | — | yes (#502, #964) | yes | yes | restart on lost device (#369) | done |
|
||||
| Pen pressure | yes (Wacom, Windows Ink, macOS tablet events) | yes, read from AppKit's tablet events before the window gets them (winit reports none), each move of a stroke with its own pressure, mouse event coalescing off (#852; not yet tried on a Mac) | yes (pointer force via `WM_POINTER`) | under X11 and XWayland (Preferences › Performance › Linux Display Server, #1151, #2028), read from XInput2 raw events (#764); **no** on native Wayland, where winit reports none and the pen may not reach the window (#491) | browser pointer events, with coalesced events; Apple Pencil on iPad (hover, palm rejection: fingers navigate after a pen contact until reload) | partial: 2–4 h for Wayland (winit 0.31), plus a check on a Mac |
|
||||
| Pen pressure | yes (Wacom, Windows Ink, macOS tablet events) | yes, read from AppKit's tablet events before the window gets them (winit reports none), each move of a stroke with its own pressure, mouse event coalescing off (#852; not yet tried on a Mac) | yes (pointer force via `WM_POINTER`) | under X11 and XWayland (Preferences › Performance › Linux Display Server, #1151, #2028; Automatic uses XWayland when a pen is attached on a Wayland session, #4967), read from XInput2 raw events (#764); **no** on native Wayland, where winit reports none and the pen may not reach the window (#491) | browser pointer events, with coalesced events; Apple Pencil on iPad (hover, palm rejection: fingers navigate after a pen contact until reload) | partial: 2–4 h for Wayland (winit 0.31), plus a check on a Mac |
|
||||
| Pen tilt, bearing, barrel rotation (6D Art Pen) | yes, drives brushes | no | no | no | no | missing: 4–8 h after the input layer (#372) |
|
||||
| Pen eraser end | yes | the eraser end (AppKit's tablet proximity events) selects the Eraser tool and the tip brings back the tool used before, as on Linux (#852; not yet tried on a Mac) | no | under X11 and XWayland, the eraser end selects the Eraser tool and the tip brings back the tool used before (#764); **no** on native Wayland | a press of the eraser end (Pointer Events eraser button, `button` 5) selects the Eraser tool, and that press erases; a press of the tip brings back the tool used before; Pointer Events report no end while the pen hovers | partial |
|
||||
| Pen eraser end | yes | the eraser end (AppKit's tablet proximity events) selects the Eraser tool and the tip brings back the tool used before, as on Linux (#852; not yet tried on a Mac) | with Windows Ink, an inverted pen or its eraser button (`PEN_FLAG_INVERTED`, `PEN_FLAG_ERASER` in the pen's pointer messages) selects the Eraser tool and the tip brings back the tool used before, as on Linux (not yet tried with a pen) | under X11 and XWayland, the eraser end selects the Eraser tool and the tip brings back the tool used before (#764); **no** on native Wayland | no | partial |
|
||||
| Touch gestures (pinch zoom, two-finger pan, rotate view, Touch workspace) | yes (Windows touch, Surface) | trackpad pinch, scroll and rotate | pinch, pan; two-finger tap undo, three-finger redo (#585) | same where winit reports touch | eframe until the first pen contact, then Pointer Events (pen and fingers told apart); long press opens the context menu | partial: touch workspace and touch-screen rotation missing, 3–5 h |
|
||||
| Touch gestures (pinch zoom, two-finger pan, rotate view, Touch workspace) | yes (Windows touch, Surface) | trackpad pinch, scroll and rotate | pinch, pan (a second finger cancels the first finger's tool press, #4198); two-finger tap undo, three-finger redo (#585) | same where winit reports touch | eframe until the first pen contact, then Pointer Events (pen and fingers told apart); long press opens the context menu | partial: touch workspace and touch-screen rotation missing, 3–5 h |
|
||||
| Trackpad (smooth scroll, pinch) | yes | yes | precision touchpads | yes | yes | done |
|
||||
| HiDPI / Retina, per-monitor scale | yes | yes | yes | yes | yes | done; a window dragged between monitors of different scale can still grow on Windows (#1459, open); the custom title bar's window on Windows stays truly borderless so the pointer lines up with what is drawn (#1791, #1758; awaiting the reporter's confirmation) |
|
||||
| Multiple monitors: panels and document windows on another screen | yes | no (one OS window) | no | no | — | missing: 6–10 h (with multiple windows, gap G7) |
|
||||
@@ -36,6 +36,8 @@ reads the pen's eraser end on Windows, on macOS and on Linux under X11 and XWayl
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-11-01 | patch | Linux (#4967): on a Wayland session, Linux Display Server › Automatic opens the window through XWayland when a pen is attached as the app starts, as X11 (XWayland) When a Pen Is Attached does and as PhotoCraft does; on native Wayland winit 0.30 gets no tablet input and KWin 6.3+ and Mutter emulate no pointer, so the pen moved only the compositor's cursor. `VECTORCRAFT_NATIVE_WAYLAND=1` keeps Wayland. Unit-tested (`xwayland::tests`); not tried with a tablet; score unchanged (estimated) |
|
||||
| 2026-10-30 | patch | Touch (#4198): a second finger landing cancels the tool press the first finger began, also in the same frame (the Pencil's stroke and a Selection move are rolled back, nothing enters the undo history), and a finger landing while another is down presses nothing, so a pinch or two-finger pan only navigates. Headless canvas test `a_second_finger_cancels_the_tool_gesture_the_first_began`; not tried on a touch screen; score unchanged (estimated) |
|
||||
| 2026-10-24 | minor | macOS: an AppKit local event monitor reads each mouse and tablet event's pen pressure and the pen's end before the window gets it and writes them into the canvas's pen feed (#852): each pointer move of a stroke keeps its own pressure, mouse event coalescing is off, and the eraser end selects the Eraser tool. The mapping is unit-tested on every platform and the macOS code type-checks for `aarch64-apple-darwin`; not yet tried on a Mac with a tablet, so the score is unchanged (estimated) |
|
||||
| 2026-10-15 | patch | Web review: preserve pen buttons and modifiers; leave fingers to eframe before the first pen contact; remove persistent pen policy. Canvas regression tests cover intermediate moves and long-touch cancellation on native and web input. Physical-device QA pending. |
|
||||
| 2026-10-14 | minor | Tool cursors are painted into the window on Wayland (#1652; not run on Linux, #1645 stays open until confirmed); On Windows the custom title bar's window stays truly borderless, so the pointer lines up with what is drawn on systems where the hidden caption offset it (#1791, #1758; awaiting the reporter's confirmation); neither is confirmed on the hardware that reported it, so nothing is marked done |
|
||||
|
||||
@@ -46,10 +46,10 @@ most `colors` of its colors are used. A missing group and a group with no solid
|
||||
mode, palette or library in the panel clears the group. A group the active document does not have shows as All
|
||||
and traces as All.
|
||||
|
||||
**Document Library linked colors.** With Library › Document Swatches, with or without a color group,
|
||||
a traced fill or stroke whose color comes from a global or spot swatch is linked to that swatch, and
|
||||
one whose color comes from a tint swatch is linked to its base at the tint. Editing the swatch
|
||||
recolors the trace. Colors from process swatches and from swatch libraries are not linked.
|
||||
**Document Library colors.** With Library › Document Swatches, with or without a color group,
|
||||
traced fills and strokes take the library color without a link to its swatch. This includes global,
|
||||
spot and tint swatches. Tints trace at the color shown by the tint swatch. Editing a swatch later
|
||||
does not recolor the trace. Colors from other swatch libraries are also unlinked.
|
||||
|
||||
**Document Library** traces with the library's colors as they are. Each pixel takes the library
|
||||
color nearest to it in lightness and hue, with a difference in hue or chroma counted three times
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Localization parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-29 · **Change:** minor (Vietnamese text: stacked diacritics tested and attach in every form, #4491; previously: Catalan (`ca`) catalog added, complete under the tests)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-31 · **Change:** minor (Brazilian Portuguese: 154 rows for the strings the sibling catalogs translate — smart-filter and print presets, dimension lines, swatches, canvas messages; previously minor: Bosnian (`bs`): complete catalog; previously minor: Vietnamese text: stacked diacritics tested and attach in every form, #4491; previously: Catalan (`ca`) catalog added, complete under the tests)
|
||||
|
||||
Per-language status of VectorCraft's interface. How the catalogs work and how to add a language:
|
||||
[`development.md` › Localisation](development.md#localisation). Part of
|
||||
[target-app-parity.md](target-app-parity.md).
|
||||
|
||||
**How it is measured:** rows with a translation in each `crates/ui-egui/src/i18n/<code>.tsv`, counted on
|
||||
origin/main `01e165af`, except the rows that give a count date, which were counted on `main` at `cb0a7d9` (2026-10-21).
|
||||
origin/main `01e165af`, except the rows that give a count date: those were counted on the `main` commit named in the row (the other dated rows on `main` at `cb0a7d9`, 2026-10-21; the Portuguese row on `main` at `d26dd933a`, 2026-10-31).
|
||||
The reference is the French catalog, which was complete when counted: 3,416 interface
|
||||
strings (menus, command labels, `tl!` literals: panels, dialogs, tooltips, Preferences) plus 604 `@msg` status and
|
||||
error messages, 4,020 in all. A language's % is its rows over 4,020 (capped at 100% per part). A missing
|
||||
@@ -32,7 +32,7 @@ Chinese by `imachus`). Only Georgian is recorded as reviewed by a native speaker
|
||||
| Hindi | `hi` | 0 | none | Devanagari: the document's text shapes (HarfRust), with tests of conjuncts, reph, pre-base matras, nukta forms and caret stops that run when an OpenType Devanagari font is installed, but the egui interface does no complex shaping | no | none | 20–30 |
|
||||
| Arabic | `ar` | 0 | none | document text: bidi layout and Paragraph Direction; interface: no right-to-left layout, no Arabic shaping in egui | no | none | 25–40 |
|
||||
| French | `fr` | 4,020 / 4,020 (100%) | all | Latin | no | full | — (review) |
|
||||
| Portuguese | `pt-br` | 5,194 catalog entries (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one/other plurals | all | Latin | contributor is a Brazilian Portuguese speaker; further native review welcome | full | — (review) |
|
||||
| Portuguese | `pt-br` | 6,106 catalog entries (counted 2026-10-31 on `main` at `d26dd933a`): menus, `tl!` literals and messages complete when counted; one/other plurals | all | Latin | contributor is a Brazilian Portuguese speaker; further native review welcome | full | — (review) |
|
||||
| Indonesian | `id` | 5,279 rows, 750 of them `@msg` (counted 2026-10-21): menus and `tl!` literals complete when counted; its messages are partial; one plural form | dialogs and tooltips all; 750 message rows (French has 796) | Latin | no | full | — (review) |
|
||||
| Japanese | `ja` | 4,004 / 4,020 (99.6%) | all | CJK UI font as above; Japanese IME; vertical type partial; Japanese crop marks and composition settings | no | full | — (review) |
|
||||
| German | `de` | 3,952 / 4,020 (98%; menus, literals and messages complete when counted) | all (602 of 604 message rows; landed 2026-10-10) | Latin | contributor-written, not reviewed | full | — (review) |
|
||||
@@ -58,6 +58,7 @@ plus review. Native-speaker review is human work and isn't in the hours.
|
||||
| Polish | `pl` | 5,130 rows (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one/few/many plurals | full; native review pending |
|
||||
| Finnish | `fi` | 5,318 rows (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one/other plurals, 797 `@msg` rows | full; AI-assisted, native proofreading pending |
|
||||
| Czech | `cs` | 5,240 catalog entries, including 795 `@msg` rows (counted 2026-10-21); menus, literals and messages complete when counted | catalog complete; render-site gaps reduced; native review pending |
|
||||
| Bosnian | `bs` | 5,841 rows (counted 2026-10-30): menus, `tl!` literals and messages complete when counted; one/few/other plurals | full; AI-assisted, native review pending |
|
||||
| Swedish | `sv` | 5,251 rows, 795 of them `@msg` (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one/other plurals | full; native review welcome |
|
||||
| Bulgarian | `bg` | 5,245 rows, 763 of them `@msg` (counted 2026-10-21): menus and `tl!` literals complete when counted; its messages are partial | full; AI-drafted, native review pending |
|
||||
| Greek | `el` | 5,251 rows, 795 of them `@msg` (counted 2026-10-21): menus, `tl!` literals and messages complete when counted | full; native review welcome |
|
||||
@@ -95,6 +96,7 @@ font for the web build.
|
||||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-30 | minor | Bosnian (`bs`, Latin, Ijekavian): complete catalog of 5,841 rows, every `bs-*` locale, one/few/other plurals; AI-assisted, not yet native-reviewed |
|
||||
| 2026-10-29 | minor | Vietnamese text: letters with two marks (Ể, Ứ, Ự) attach in precomposed, decomposed and keyboard forms, and a font lacking the marks falls back for the whole letter (#4491); scores unchanged |
|
||||
| 2026-10-28 | minor | Catalan (`ca`): complete catalog under the tests (menus, literals, messages; one/other plurals); every `ca-*` locale resolves here; AI-drafted, native review welcome. Added the Turkish and Indonesian rows the table was missing. Scores and estimates unchanged |
|
||||
| 2026-10-23 | patch | A missing translation never fails a test or a build; one untranslated report, printed by `cargo xtask ci` and `cargo xtask i18n-report`, lists the missing strings per language; scores unchanged |
|
||||
|
||||
+852
-85
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -65,7 +65,7 @@ pinned commit (the `ref:` of its craft-fonts checkout step) and builds with `CRA
|
||||
`CRAFT_FONTS_REQUIRED=1`, so releases embed its Japanese fonts and fail rather than ship without
|
||||
them (the web build embeds only the UI font, BIZ UDPGothic Regular, to stay small). The packages carry each embedded font's licence as `OFL-<family>.txt`
|
||||
(`copy_font_licences` in `packaging/env.sh`). Bump the pins deliberately, in every job at once.
|
||||
The rules are in craftrules `standards/fonts.md`, the build option in
|
||||
The build option is in
|
||||
[`docs/development.md`](development.md) › Fonts.
|
||||
|
||||
### macOS
|
||||
@@ -164,7 +164,7 @@ to the target triple, so host build scripts aren't affected.
|
||||
AppStream metainfo, the MIME type for VectorCraft documents, the icons and the licence files.
|
||||
|
||||
**Document types.** The desktop entry's `MimeType` lists every format File › Open reads but PSD,
|
||||
PSB, `.ps` PostScript, Targa and PCX, so file managers list VectorCraft under Open With for them.
|
||||
PSB, `.ps` PostScript, Targa, PCX and JPEG 2000, so file managers list VectorCraft under Open With for them.
|
||||
`ai.storyteller.vectorcraft.mime.xml` declares the types that shared-mime-info lacks: VectorCraft
|
||||
documents and templates, `.ait` templates and Affinity files (`application/x-affinity`). An `.af`
|
||||
file gets the Affinity type by its content, and `.afdesign` and `.afpub` files by their extension.
|
||||
|
||||
+13
-7
File diff suppressed because one or more lines are too long
+323
-46
File diff suppressed because one or more lines are too long
+14
-6
File diff suppressed because one or more lines are too long
@@ -24,7 +24,7 @@ can use installed system fonts, while the web app uses the fonts supplied by its
|
||||
6. Adjust **Font Size** (the field beside **T**) and **Tracking** (beside **VA↔**) in the Character
|
||||
panel. Hover a field's label to see its name. For example, enter `72 pt` for a large heading and
|
||||
try tracking `50` to spread its letters slightly. Positive tracking adds space; negative tracking
|
||||
tightens it. **Leading** controls the spacing between lines; **Kerning (0 = Auto)** adjusts pairs.
|
||||
tightens it. **Leading** controls the spacing between lines; **Kerning** adjusts pairs.
|
||||
7. To change only part of the text, select **Type Tool**, click into the text and drag across the
|
||||
characters before using the Character panel. Press **Escape** when finished. Keep the text
|
||||
editable until its wording, font and spacing are settled.
|
||||
|
||||
+92
-14
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user