Commit Graph
940 Commits
Author SHA1 Message Date
bflatastic baadbe2c67 Image Trace: a quick trace leaves the panel as it was; the Image Trace button opens it 2026-10-16 01:36:25 +07:00
RICHRAN2030 313b1a52b9 fix(UI.TRACE): expose trace adjustments and reliably apply and undo them 2026-10-16 01:36:25 +07:00
Dan Green 67e17c1b66 Part of #868: legacy .ai options Hidden Objects and Text, and docs
The Legacy .ai Options dialog gains Hidden Objects (Hidden Layer, Omit, Make Visible) and Text
(Editable, Outlines), translated in every catalog. Docs: type and hidden objects in the legacy
.ai paragraphs, the restored revision rows and roadmap row.
2026-10-16 01:36:24 +07:00
Dan Green 91ed4853a8 Part of #868: legacy .ai options dialog, Transparent Images and an artboard picker
The .ai options dialog offers Legacy (version 7). In that mode it shows Transparent Images
(Flatten, Omit) and, with more than one artboard, thumbnails to check with the file each is
saved to (long names keep their end). OK is greyed out until an artboard is checked. A save
panel's Enter no longer confirms the options dialog it opens.
2026-10-16 01:36:24 +07:00
bflatastic 7217dcd121 Dimensions: a file whose dimensions carry options this version doesn't know still opens; commands still refuse unknown options 2026-10-16 01:36:24 +07:00
Osama Amin 8aea665c4e Dimension tool: the documented gestures, arcs, picas and text positions; Properties section; review fixes
Drag out from a segment, corner, circle or arc to place a dimension; plain clicks pick two points or two lines. Radial dimensions on perfect arcs, picas, Away/Between and Left/Center/Right text placement. The Properties panel edits a selected dimension, with Apply to All (dimension.applyToAll) and Set as Default. Dimension Selected Paths, the Arc/R/Ø prefixes and the custom defaults are left out. The refresh returns at once in documents without dimensions (Document::dimensions); a linked dimension moved on its own keeps its place; modes, units, line types, arrows and text placement are enums; the tool has its own icon.
2026-10-16 01:36:24 +07:00
Osama Amin 9d813e906a Fix #1372: Dimension tool and Object > Dimensions: linked length, angle, radius and diameter annotations 2026-10-16 01:36:24 +07:00
gniax 6f23190925 fix(web): preserve pen buttons and touch-only input 2026-10-16 01:36:24 +07:00
gniax 9fc7fd7038 feat(canvas): pen strokes keep every position reported between frames
A pen reports far more often than frames come (an Apple Pencil up to 240 times
a second): the canvas now hands the tool each move of the frame with its
pressure instead of the last one only, and the web shell feeds Safari's
coalesced pen events. Mouse input is unchanged.
2026-10-16 01:36:24 +07:00
gniax 51673cd098 feat(web): Apple Pencil input on iPad with palm rejection
Read pen and finger Pointer Events in the web shell (capture phase) instead of
eframe's touch handlers, which can't tell a pen from a finger and see every
touch twice. The pen drives the pointer with its pressure and hovers; fingers
are touch contacts for pinch, two-finger pan and undo/redo taps. Once a pen
has been seen (remembered in localStorage), a finger or a resting palm never
presses a tool on the canvas, and a pen landing cancels fingers already down.
A long press drops the tool press and opens the context menu.

The page no longer scrolls, zooms or selects under touch, and the canvas
stays inside the safe areas of a full-screen app.
2026-10-16 01:36:23 +07:00
bflatastic b5b9264d71 Revolve: the Cap option is saved as cap, as Extrude & Bevel and Inflate save it 2026-10-16 01:36:23 +07:00
alpha-rock f703e6bd85 M9: smooth Revolve rendering and default Cap
Use automatic vector smooth shading without a separate control.
Enable Cap by default and keep continuous rim curves and bounded seam joins.
Integrate the shared dialog with the other three 3D effects.
2026-10-16 01:36:23 +07:00
Vikram Bhaskaran 0c11ff656c Format the reworked select_all_on_focus. 2026-10-16 01:36:23 +07:00
Vikram Bhaskaran 173c88d2a1 Rework #1326: a short drag the toolkit counts as a click keeps its caret.
The late-focus case in the original change has no reproducible path
(#1339 already covers focus on the press frame), so the button-down
defer is dropped. The real issue is the clicked_focus branch: a very
short drag inside one character produces no text selection, egui still
reports a click, and select-all on release replaced the drag. The press
position is now remembered and a release more than three points away
keeps the caret; a plain tap still selects all.

Also fixes the test placement bug: the new test sat between the #[test]
attribute and keyboard_focus_keeps_selecting_the_entire_numeric_field,
so that test no longer ran. The regression test fails on the fork-point
widgets.rs and passes with this change.
2026-10-16 01:36:23 +07:00
Vikram Bhaskaran 8354dbcd74 Keep a numeric field caret when focus arrives while the pointer is still down.
Select-all ran on that late focus frame and replaced the drag the press had started.
2026-10-16 01:36:23 +07:00
skylar taylor-barrick 05f6e2e6df PDF.R1: reconcile shared PDF migration with current main
Preserve the writer and reader changes while integrating the current main.

The combined candidate passes all eight local CI gates and the 2,048-case
reader panic verification. Hosted checks remain required before landing.

Refs #1893, #1894.
2026-10-14 22:02:49 -06:00
skylar taylor-barrick 52960faf63 PDF.W1: reconcile shared writer with current main 2026-10-14 01:23:19 -06:00
dotCooCoo d1108bdbca i18n: Korean, Polish and Vietnamese rows for Import Shortcut Set and its commands
Since #1352, #1498 and #1507, Korean, Polish and Vietnamese are complete
catalogs: every menu string, tl! literal and status or error message has
a row, and the i18n tests check it. ko.tsv, pl.tsv and vi.tsv get the
rows that the other complete catalogs have for Import Shortcut Set and
its commands: the dialog's strings, the labels Import Shortcut Set…,
Read Shortcut Set File, Import Matches, Remember Import Matches and
Forget Import Matches, the two plurals and the two error messages. Copy
Report and Not read are already in all three, and Shortcut and the
Imported message in pl, so they are not repeated. The dialog's rows go
after Import Print Presets in ko and vi and after the Keyboard Shortcuts
dialog's rows in pl, and the two messages after "not a VectorCraft
shortcut set".
2026-10-14 13:22:08 +07:00
dotCooCoo 04244fa2a2 i18n: remove Import Shortcut Set rows that the catalogs already have
Check Script (3374d077) added Copy Report and Not read to every catalog,
and es and fr gained Shortcut and the Imported message in a747daa3 and
9e39a6d1. The rows that Import Shortcut Set added for the same strings
became second entries, which bundled_catalogs_are_consistent rejects.
They are removed, 26 rows in cs, de, es, fr, hu, it, ja, ru, uk, zh-hans
and zh-hant, and the existing rows stay as they are.
2026-10-14 13:22:08 +07:00
dotCooCoo 612a13b39c i18n: Hungarian rows for Import Shortcut Set and its commands
Since b9716366 (#1302), Hungarian is a complete catalog: every menu
string, tl! literal and status or error message has a hu row, and the
i18n tests check it. hu.tsv gets the rows that the other complete
catalogs have for Import Shortcut Set and its commands: 35 strings, the
two plurals in the single form hu.tsv uses (a count takes the
singular), and the two error messages. Shortcut and the Imported
message already have hu rows on main, so they are not repeated. The
rows are placed after the Keyboard Shortcuts… row.
2026-10-14 13:22:08 +07:00
dotCooCoo f1e634af19 i18n: Czech rows for Import Shortcut Set and its commands
Since #1189, Czech is a complete catalog: every menu string, tl! literal
and status or error message has a cs row, and the i18n tests check it.
cs.tsv gets the rows that the other complete catalogs have for Import
Shortcut Set and its commands: 35 strings, the two plurals with one, few
and other forms, and the two error messages. Shortcut and the Imported
message already have cs rows on main, so they are not repeated. The rows
are placed after the Keyboard Shortcuts… row.
2026-10-14 13:22:08 +07:00
dotCooCoo 8c14609370 Keyboard Shortcuts: Import… and File › Open read text shortcut sets (.kys)
A shortcut set another app saved as slash-name text (a .kys file whose
text starts with a slash name and "{", such as "/Menus {") opens in
Import Shortcut Set from File › Open, from Edit › Keyboard Shortcuts ›
Import… in the desktop app, or from a drop on the window, whether or
not a document is open. The dialog proposes a target for an entry when
an earlier import kept one for that name, or else when one tool,
command or panel matches the name clearly by its id or by one of its
labels. It decodes the file's key and modifier codes from the codes
earlier imports kept, from the example in the AiCommandPalette README
(/Key 48 for the 0 key, with /Modifiers 0 taken as no modifiers), and
from VectorCraft's default shortcuts where at least two entries vote and
four votes in five agree. The user picks the remaining targets, presses
the key for each unknown key code or marks it No equivalent, and chooses
the modifiers for each unknown modifier code. Apply assigns the ready
rows with the Keyboard Shortcuts rules: a tool takes a single key,
optionally with Shift. It goes through the rows from the last one back
and leaves a row out when a later row it applies has the same shortcut
or the same tool, command or panel. Keyboard Shortcuts then shows the
result as unsaved changes until the user clicks OK. Copy Report copies
the set's name, the rows Apply leaves out and the parts of the file that
weren't read.

- shortcutSet.read is a query command: it reads a set and does not
  modify the document or the preferences. It returns each entry with
  its section, codes and line, and up to 1,000 skipped tokens, each cut
  to 80 characters. It reads at most 4 MiB of text and 20,000 entries,
  skips blocks nested more than 16 deep and cuts names at 1,024 bytes.
  With a path it reads at most 4 MiB and 4 bytes of the file, and with
  --automation-read-root (#832) the path must lie inside the read root.
  A file whose text starts with "<", such as an XML shortcut file saved
  as UTF-8, fails with "This shortcut file is in a form VectorCraft
  can't read."
- importMatches.list, importMatches.set and importMatches.reset read
  and change the matches kept with the preferences; resetting the
  preferences keeps them. With Remember My Choices on (the default),
  Apply keeps the targets and codes the user chose, and for the rows it
  assigns, it also keeps the matched targets and the codes decoded by
  agreement. A later import proposes them.
- The name matcher compares a name with ids by exact match and shared
  words. It compares the name with labels, in English and in the
  interface language, by exact match, shared words and character
  pairs. It proposes a match only when one tool, command or panel
  scores at least 0.6 and at least 0.1 more than the next one.
- When Import Shortcut Set is opened from Keyboard Shortcuts, Cancel,
  Escape and ui.dialog.cancel close it and return to Keyboard Shortcuts
  as it was (dialogs::PARENT). A document's queued Missing Fonts dialog
  (#792) opens after Keyboard Shortcuts closes.
- File › Open has a "Shortcut sets" filter, and in the desktop app
  Keyboard Shortcuts' Import… shows .json and .kys files.

Docs: docs/mcp.md, docs/control-protocol.md, docs/development.md,
docs/target-app-parity.md, docs/roadmap.md.
2026-10-14 13:22:07 +07:00
bflatastic f9b051d3d1 Fix #1866: Preferences and Save PDF highlight the section shown
The section lists asked for a selectable button and then turned its frame
off while the pointer was elsewhere, which also dropped the selected row's
fill: the section shown looked like every other row. The selected row now
keeps its fill.
2026-10-14 12:27:04 +07:00
dotCooCoo 014021577b Web: the status bar shows measured render and UI times instead of 0.0 ms
In the web build, now_ms() in crates/ui-egui/src/lib.rs returned 0.0.
The status bar read "render 0.0 ms · ui 0.0 ms" however long a frame
took, and the Layers panel's budget of 8 ms for the row thumbnails it
renders in a frame never ran out, so only its limit of 16 thumbnails
applied.

now_ms() now returns the milliseconds since its first call, read from
the browser's performance.now() through web-time, which the build
already has through eframe. The desktop clock is unchanged. In Chrome,
after a pan frame of 750 ms over a document of 50,000 paths, the status
bar now reads "render 750.7 ms". The Layers panel now renders the
thumbnails of 24 groups of 2,000 paths one per frame, where main
rendered nine of them in one frame of 217 ms. The canvas has no render
worker in the web build, so it still renders on the UI thread and draws
the same pixels.

Docs: docs/target-app-parity.md.
2026-10-14 11:22:41 +07:00
dotCooCoo abe89d5176 Type: Show Hidden Characters keeps no text nodes while it is off or no document is open
Show Hidden Characters keeps each text object's marks together with
the node it laid them out from. Only a frame that drew the overlay
changed what it kept. After the option was turned off, or the
document was closed, those nodes stayed alive until the overlay was
next drawn.

The canvas now takes the kept marks at the start of each frame and
puts them back only when it draws the overlay. A frame that does not
draw it, for example with the option off or with no document open,
drops the marks and their nodes. A frame that draws the overlay still
keeps the marks of the frame before.
2026-10-14 11:22:41 +07:00
skylar taylor-barrick a699a26221 refactor(pdf): use shared writer for export and print (PDF.W1) 2026-10-13 20:41:14 -06:00
bflatastic e802ea8438 Fix #1685: a save or export that fails is reported in a dialog that stays
A save that couldn't write its file (a read-only folder, a file another
program holds open, a full disk) was only reported in the status bar, a line
the next message replaces; a background save's failure arrived there some
time after the user had moved on. Save, Save As, Save a Copy, Save as
Template, Export As and the commands that write one file now also say it in a
dialog naming the file and the reason, which stays until it is closed. The
document stays modified and keeps the file it had. A message that arrives
while another dialog is open waits for it to close instead of replacing it.
An agent's request gets the error as its reply, without a dialog; a failed
recovery write stays in the status bar.
2026-10-14 09:03:51 +07:00
bflatastic 8f8d49110f Fix #1694: a file that finishes opening waits while a dialog is open
A document opened off the UI thread became the active one as soon as it was
ready, also under an open dialog, whose OK acts on the active document: Save
As options confirmed after another file had finished opening wrote that
file's art under the first document's name. Files that are ready now wait
until the dialog is closed.
2026-10-14 09:03:32 +07:00
bflatastic 5ecd045156 Fix #1693: a browser download that can't be started fails the save it is for
The web app's download callback returned nothing, so a save whose Blob, URL or
anchor couldn't be made was reported as written: the document counted as
saved, its recovery copy was dropped, and Save Changes closed it. The callback
now returns the error, which fails the save, export or file command like a
refused write on the desktop. A timer that can't be set after the download
started is not a failure.
2026-10-14 09:03:31 +07:00
bflatastic ea30e411e7 Fix #1725: a control request its caller timed out on is withdrawn, not run later
The worker answered "timeout" after 60 s and left the request on the queue, so
the app ran it whenever it next drained the queue: an edit nobody was waiting
for, and a second one if the caller had retried. A request now leaves the
queue once: taken by the app, or given up by its caller, whichever comes
first. The timeout reply says which ("will not run" / "still running").
2026-10-14 08:47:10 +07:00
Marco Arnulfo 4ef0cb76e6 Transform panel: X/Y/W/H edit the anchors selected with Direct Selection (fixes #1824) 2026-10-14 08:16:26 +07:00
bflatastic 494ce39de5 Fix #1747: Preferences are written when confirmed, not only at exit
The preferences file was written only when the app quit normally, so settings
confirmed with OK were lost when the session ended any other way (the system
shutting down, the process being ended, a crash). OK now asks the host to
write the file at once.
2026-10-14 08:11:06 +07:00
bflatastic 22118a3e8e Edit Toolbar: the drawer's groups have a named type (clippy's type-complexity) 2026-10-14 07:37:54 +07:00
Ayberk A. 8894da68d7 Part of #1736: one toolbar column runs on without group labels too
Without group labels, the single column no longer draws a dash between
the groups: its tools are evenly spaced from top to bottom, as two
columns already run on from group to group. With the labels, each group
still starts under its name.
2026-10-14 07:37:54 +07:00
Ayberk A. cdd656bd48 Part of #1736: two toolbar columns run on without group labels, and the drawer stays under the title bar
- Without group labels, the double-column toolbar fills every row: a
  group no longer starts a half-empty row, as the reference's Basic
  toolbar runs on in two columns. One column keeps its faint dashes, and
  with the labels each group still starts its own row under its name.
- The All Tools drawer, now a tall single column, never goes above the
  toolbar's top: on macOS it ran under the window's buttons. Its scroll
  height is what is left from there to the window's bottom.
2026-10-14 07:37:54 +07:00
Ayberk A. 03c0b8f355 Part of #1736: the toolbar without group labels, and the All Tools drawer's groups, flyout menu and Show section
- Preferences › User Interface › Show Tool Group Labels is off as it
  ships: the toolbar sets its groups apart with a faint dash, as the
  Basic and Advanced toolbars of the public toolbar reference do (the
  categories there are the Getting Started toolbar's). It no longer cuts
  "Navigate" to "Navi...". The labels are a preference away.
- The All Tools drawer lists the tools one per row (icon, full name,
  shortcut on the right), each flyout group framed together under the
  heading most of its tools have (the Pencil's group, led by the Shaper,
  under Draw). Tools already in the toolbar stay dimmed; dragging and
  picking are as before.
- Its ☰ menu has Reset and the Basic and Advanced toolbars, the drawer's
  flyout menu of the reference.
- Its Show section shows or hides the controls under the toolbar's tools
  (Fill and Stroke, Coloring, Draw Mode, Screen Mode), as the reference
  describes; `toolbar.show {control?, on?}`, saved with the preferences
  (`ui.toolbar_show`, all on for older ones). Edit Toolbar's ••• stays.
- New strings in every catalog.

Reference: https://helpx.adobe.com/illustrator/using/tools.html (the look
is VectorCraft's own, with its own icons).
2026-10-14 07:37:54 +07:00
bflatastic 0934f97627 Fix #1629: an action clicked in the Actions panel stays selected, so Play and Delete act on it 2026-10-14 07:37:53 +07:00
bflatastic c10da25ce4 Importers: nesting is capped, so a deeply nested file can't overflow the stack 2026-10-14 07:37:52 +07:00
bflatastic 1f4daf519d Image Trace: enhanced versions of the presets
Each documented preset has an enhanced version (`enhanced: true` in
`imageTrace.make`, an Enhanced checkbox under the panel's preset): the preset
with Auto Grouping, and with Shapes in all but High Fidelity Photo. Gradients
stay an option. Flat Logo, a preset of our own, has none. The legacy presets,
and documents traced with them, are as they were.

So that an enhanced preset is no worse than its preset on that preset's inputs:
- A hole that one colour fills is the same shape as the path that fills it, so
  the two still share one outline (a shape beside a fitted hole left slivers).
- A rectangle is as large as where its sides lie on average, not their farthest
  points.
- Auto Grouping keeps the paths of a group in the order they were traced in. It
  put a path first and what is inside it on top: a white counter traced under
  its black letter was then painted over the letter's edge, a light seam
  (Default with Auto Grouping, edge dE 10.24 -> 9.88; legacy 10.05).

The harness measures every enhanced preset beside its preset.
2026-10-14 06:43:57 +07:00
dotCooCoo fb905ae911 Type: Show Hidden Characters keeps each text object's marks between frames
With Type › Show Hidden Characters on, the canvas laid out every
visible text object in view in every frame to place the dots on
spaces and the ¶ and # marks. With 1,000 two-line labels in view,
drawing the marks took a median of 19.7 ms per frame in a release
build.

The overlay now keeps each text object's marks in document space,
together with the node it laid them out from. In a frame it lays out
a text object only when its node is a new `Arc` (an edit makes one)
or the frame before did not draw it, and it lays out all type in view
again when the fonts or the hyphenation exceptions change. The marks
are still placed for the current view in every frame. With the same
labels, drawing the marks takes 0.8 ms per frame, and the shapes drawn
are the same as before.

Docs: docs/target-app-parity.md.
2026-10-14 06:01:10 +07:00
bflatastic 841ea1716d Canvas: the art texture's quads and the transparency grid share one textured-quad helper 2026-10-14 06:01:10 +07:00
dotCooCoo b3ac169f00 Canvas: the last frame turns with the view until the frame at the new angle is ready
When the last frame took more than 8 ms to render, the desktop app's
canvas sends the next frame to the render worker and draws the last
one until the new one arrives. After a pan or a zoom it draws the last
frame moved and scaled. After the view angle changed, it drew no art
until a frame at the new angle arrived. The angle changes during a
Rotate View drag and when the status bar's angle menu, Reset Rotate
View or a saved view sets it. In a headless run of the canvas on a
document of 50,000 paths, none of the 60 frames of a turn from 0° to
90° drew any art.

The canvas now draws the last frame as a mesh turned into the new
view. Each corner goes where the new view puts the document point that
the corner showed. The frame at the new angle replaces it when it
arrives, as before. Pixel Preview's frames already turned with the
view and are drawn as before.

Docs: docs/target-app-parity.md.
2026-10-14 06:01:10 +07:00
DWAA1660 fdf6ba9c9d M1: bound synthetic control input expansion (#1709) 2026-10-14 06:01:10 +07:00
sanyamsingh001andCodex cfec15d8d9 G13: offer TIFF in Export for Screens and Asset Export
Co-authored-by: Codex <noreply@openai.com>
2026-10-14 05:16:22 +07:00
bflatastic a57aea8e94 DXF export: leave out the centerline option and the 3ds Max preset for now
The VPORT view direction fix and its test stay. The Export Strokes as
Centerlines option and the preset button are not in the documented DXF/DWG
export options, so they wait for the owner's decision.
2026-10-14 05:16:15 +07:00
Osama Amin 4a68f84282 DXF export: strokes as zero-width centerlines, a 3ds Max R12 linework preset, and one view direction in VPORT 2026-10-14 05:16:09 +07:00
sanyamsingh001andCodex bb07d267aa G1: keep Artboard deletion consistent across controls
Co-authored-by: Codex <noreply@openai.com>
2026-10-14 05:15:42 +07:00
sanyamsingh001andCodex 5f4da3beb2 G4: capture character styles from selected text
Co-authored-by: Codex <noreply@openai.com>
2026-10-14 05:15:34 +07:00
sanyamsingh001andCodex 123b8ad8ea G4: propagate character-style Auto-leading resets
Co-authored-by: Codex <noreply@openai.com>
2026-10-14 05:15:30 +07:00
sanyamsingh001andCodex 0c2c98f6e7 G4: show mixed paragraph alignment without a selected button
Co-authored-by: Codex <noreply@openai.com>
2026-10-14 05:15:18 +07:00