Commit Graph
5599 Commits
Author SHA1 Message Date
dotCooCoo ab821a776b Symbol Stainer: stained type keeps no link to a global swatch
The Symbol Stainer mixed the color of type characters painted with a
global swatch but kept the swatch name and tint, so the characters'
paint named a swatch whose color it no longer had, and a later edit of
the swatch could put the unstained color back. Their fill and stroke now
become plain colors, as a path's paint does.
2026-10-26 08:18:22 +07:00
dotCooCoo 3088b6dc99 Appearance: Add New Fill and Add New Stroke are off with nothing selected
With nothing selected, Cmd+/ and Cmd+Alt+/ ran the commands, which put
"select objects or give ids" in the status bar, and the command palette
listed both as available. Without ids and without an Appearance panel
subject (a targeted layer, group or object, or a selected one), the two
commands are now off in menus and the palette, as the panel's buttons
are, and their keys run nothing. Called with ids, they still add to those
objects.
2026-10-26 08:18:22 +07:00
dotCooCoo ded22f432c Tests: the Paintbrush closing cursor follows the point a release keeps
The Paintbrush drops a sample less than a pixel from the last kept
point, and a release there keeps that point. The new test moves the
pointer inside Close Paths When Ends Are Within while the kept point
stays outside it, and checks that the cursor shows no closing ring and
that the release leaves the path open.
2026-10-26 08:18:21 +07:00
dotCooCoo 728ef19a42 Tests: two control server line-deadline tests pass on a loaded machine
buffered_partial_control_line_also_expires and
stalled_control_line_is_refused_with_the_reason used short_timeouts(),
which gives a connection 150 ms before its first byte and 150 ms to write
a reply. When a test thread pauses longer than that, the server closes
the connection without a reply, the client reads end of stream, and the
test fails parsing an empty line (CI run 40212833958 on #4152).

The two tests now use line_timeouts(): the same 120 ms line deadline,
with idle and write budgets of 10 s. The other short_timeouts() tests
are unchanged.
2026-10-26 08:18:20 +07:00
skylar taylor-barrick 4ddd0332cf chore(deps): refresh muda, webbrowser and weezl (#4189)
* chore(deps): bump muda to 0.21.2 and webbrowser to 1.2.5

* chore(deps): bump weezl to 0.2 in render and pdf
2026-10-25 19:31:19 -04:00
Dylan M. Taylor 3f8d7a0c5a build: pin craft-update to craft-libs main (495e597) (#4183)
Picks up the startup prompt without the glyphs a font may lack (storytold/craft-libs#343, #344): the close mark is painted and the version pill is ASCII, so apps that panic on a missing glyph no longer take the prompt down.

Part of tracking issue storytold/craft-libs#319
2026-10-25 17:55:25 -04:00
Dylan M. Taylor 8c45a8dd5b Merge pull request #3937 from dylanmtaylor/security/review-findings-pathops
Security: planar map budgets for booleans, Live Paint, Offset Path and 3D effects
2026-10-25 16:46:05 -04:00
Dylan M. Taylor caef923806 feat: startup update prompt modal and direct self-updating (#4138)
* feat: startup update prompt modal and direct self-updating

The update flow (check at start or on request, the startup prompt, the self-update worker) is craft-update's Updater; the app only supplies the suite, its close path and its status window. The check at start is opt-in for the desktop app, and the Windows update helper runs before argument parsing.

Ref: storytold/craft-libs#319

* refactor(updates): hold the install back while documents are unsaved

* fix(updates): drop the manual window's custom id; pin craft-update to craft-libs main (db19c37)

* fix(updates): address review feedback

Wake the UI when a manual check is queued from a menu callback; the update prompt owns the keyboard while it is open (LightCraft); Download opens through the desktop URL hook (FilmCraft); the Help menu dispatches through menus::invoke (FigCraft); print jobs and comment drafts hold an install back (WordCraft); Check for Updates is a registered command (GridCraft); an install holds back while documents are unsaved.

* fix(updates): localize the update status messages

* build: resolve the craft-update pin after rebasing
2026-10-25 16:22:52 -04:00
Dylan M. Taylor caf10cc581 security(pathops): count the sweep budget on the snapped geometry 2026-10-25 16:08:06 -04:00
Dylan M. Taylor 0eebd533c5 security(pathops): signed zeros, reported budget rejections, and a fill-only fallback
Boxes that touch at -0.0/+0.0 now count as overlapping, so the pair cap cannot be skipped. try_boolean_n, try_unite_all and try_area report a refused input, and the Pathfinder shape-mode unite and the Blob Brush use them to show an error. When the planar map is over its budget, the fallback leaves out paths that fill nothing so a flood of cutting lines cannot take the filled shapes down with it.
2026-10-25 16:04:29 -04:00
Dylan M. Taylor cd80d1d859 Security: planar map budgets for booleans, Live Paint, Offset Path and 3D effects
CodeRabbit findings #6, #19, #53, #59, #62, #167:

- Before a sweep builds a planar map (Boolean, normalize, Pathfinder, Offset Path, Live
  Paint, Shape Builder), the pairs of segments whose bounds overlap are counted exactly in
  O(n log n); past 4M the operation fails as `PathOpsError::TooComplex` (a crossing can only
  lie where two segments' bounds overlap).
- Live Paint's winding crossings are sparse: the sweep keeps one per edge, and a vector as
  long as the input count made disjoint shapes quadratic in memory.
- Gap detection groups the segments near a loose end by track once.
- 3D: ring containment checks bounds first and walks at most 50M edges; Inflate's mixed-cell
  booleans take at most 4M outline segments together.
2026-10-25 15:42:41 -04:00
aiongg 714434527e Docking: panels on craft-ui's shared docking, floating panels in OS windows (#4135)
* Build: craft-libs at 2869b8cc

Pin craft-pdf, craft-print, craft-docpath, craft-ui, craft-keymap,
craft-window and the patched hayro/krilla backends to craft-libs
2869b8cc1077530bd07a7e192fb2b0e1304a1354, with the pdf-deps gate,
NOTICE, ASSETS.md and docs/pdf-backend.md at the same revision.

PDF: no modification date beyond the creation date, DeviceN images
are not JPEG-encoded, and clipping text draws nothing (its outlines
arrive as a clip path).

* Docking: compile against craft-ui at 2869b8cc

Floating windows are trees of groups: window_panels and window_active
read one as a flat group, and windows rebuilt from the legacy groups
keep their ids. Unknown dock actions are rejected, the new ones are
checked like the old, and every panel a close action removes keeps its
return location.

* Docking: panels and canvas on craft-ui's docking area

* Docking: tests for the dock area, flyouts, floating panels and the Tools panel

* Docking: catalogs without the old dock's strings

* Build: craft-libs at 8a503cfe

* Docking: floating panels in OS windows of their own on the desktop

* Docking: modal dialogs block panel windows; their keys and dropped files reach the main window

* Docking: art dragged onto a panel in its own window drops there

* Docking: module doc names the OS windows

* Build: craft-libs at a042cf26

* Docking: onto, above, below, collapsed, icon and column places on Float and Dock Panel; ui.docking

* Docking: command descriptions of Float, Dock, Move and Collapse Panel for the craft-ui layout

* Docking: control protocol describes the craft-ui layout, its commands and ui.docking

* Docking: rustfmt

* Docking: layouts saved before the canvas joined convert on load

Saved ui.json files and workspaces from before the shared layout held the
canvas (a dock-only tree plus floating_panels, docking_icons,
docking_collapsed, dock_collapsed and dock_width) convert into one layout:
the dock tree's groups in the main column, the icon column with the panels
dropped on it, floating groups and sets, sets docked as columns, collapsed
groups, the dock width and the places of closed panels. The legacy fields
are read, never written. A ui.json read only in part is copied to
ui.unreadable.json before anything saves over it.

* Docking: catalogs without the old collapse message

* Docking: converted floating sets start at most 720 points tall

* Docking: closed icon panels convert into the icon column; old floating rects, set heights and a copy of the file before conversion

* Build: craft-libs at 27e60765

* Docking: dock column places and icon count from the icon column; a docked column moves to a later place

* Build: craft-libs at d24e4bcc

* Build: craft-libs at 5bbe9f62

* Docs: floating panels in OS windows of their own close the other-monitor gap

* Docking: keys forwarded from a floating panel's OS window run shortcuts while the main window is unfocused
2026-10-25 15:25:35 -04:00
Dylan M. Taylor 6e7854967d Merge pull request #4113 from storytold/codex/egui-037-vectorcraft-20261023
Migrate VectorCraft input, text and capture to egui 0.37
2026-10-25 14:09:31 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 f05c33cdfc Security: document model bounds (id hashing, page ranges, overprint migration, auto slices, nested Repeat bounds) (#3888)
* Audit: document model bounds (id hashing, ranges, overprint migration, auto slices)

* Audit: nested Repeat bounds are measured once per level

* fix(slices): bound auto_slices accumulation strictly by MAX_AUTO_SLICES

* chore(text): use is_some_and instead of unnecessary map_or (clippy)

* Refuse automatic slice layout past a cut-rectangle bound

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 12:32:45 -04:00
6b0df68cc6 Security: EPS and legacy Illustrator bounds (operator recursion, bind, copy, cvn, previews, writer output, ink name) (#3883)
* Audit: EPS interpreter and import bounds

* Audit: EPS writer stops expanding at 256 MB of body

* fix(eps): enforce MAX_BODY budget before committing node and image output

* chore(text): use is_some_and instead of unnecessary map_or (clippy)

* Fix clippy unnecessary_map_or false-default in ITXT compression flag scan

* Reject EPSI previews with an odd number of hex digits

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 12:32:14 -04:00
Brandon Thomas f792c63597 Merge pull request #4090 from marcoarnulfo/feat/recolor-picker
Recolor Artwork: double-click a new color to pick it in the Color Picker, in the model it was picked in
2026-10-25 10:56:13 -04:00
Brandon Thomas e14b2b2c79 Merge pull request #4070 from marcoarnulfo/fix/direct-select-type-on-path
Direct Selection: an anchor of type on a path's path drags and the type reflows along it
2026-10-25 10:56:10 -04:00
Brandon ThomasandClaude Opus 5.5 f0a4f189f3 Docs: Direct Selection reshapes the path of type on a path outside perspective
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 10:44:35 -04:00
Brandon Thomas 378d7d4c6a Merge pull request #4125 from Silvertree2010/fix/h2473-safe-file-name-leaves-a-windows
Protect Windows device names followed by a space in safe_file_name
2026-10-25 10:42:55 -04:00
Brandon Thomas c5c44e0dfb Merge main into fix/h2473-safe-file-name-leaves-a-windows
Combines this branch's screens.rs test module with the one #4123 added.
2026-10-25 10:38:39 -04:00
Brandon Thomas 70a05ba09b Merge pull request #4068 from dotCooCoo/fix/eps-no-art-central-file-text
EPS: the help text says no central file is written when no art shows
2026-10-25 10:38:12 -04:00
Brandon Thomas a25360483f Merge pull request #4077 from dotCooCoo/fix/trace-palette-drops-unused-colors
Image Trace: a color with no traced paths is left out of the palette
2026-10-25 10:38:08 -04:00
Brandon Thomas 45afd85452 Merge pull request #4066 from dotCooCoo/fix/flat-logo-anchor-limit-counts-kept-outlines
Image Trace: Flat Logo counts only the outlines it keeps toward the anchor limit
2026-10-25 10:38:04 -04:00
Brandon Thomas f0e5b5e902 Merge pull request #4069 from dotCooCoo/fix/set-paint-object-count
MCP: set_paint reports how many objects it painted
2026-10-25 10:38:01 -04:00
Brandon Thomas 39e10c81a1 Merge pull request #4108 from dotCooCoo/fix/mcp-headless-relative-paths
MCP: headless file tools pass relative paths to the engine as given
2026-10-25 10:37:57 -04:00
Brandon Thomas dda90f0f4f Merge pull request #4060 from dotCooCoo/feat/unknown-command-suggestion
Commands: an unknown command id is answered with the nearest command id
2026-10-25 10:37:54 -04:00
Brandon Thomas ffa2ced99e Merge pull request #4063 from dotCooCoo/fix/cli-subcommand-help
CLI: --help after a subcommand prints the usage
2026-10-25 10:37:50 -04:00
Brandon Thomas 774314a351 Merge pull request #4050 from dotCooCoo/fix/screens-filename-is-file-name
Export for Screens: <filename> takes the saved document's file name
2026-10-25 10:37:45 -04:00
Brandon Thomas e8c92f6bee Merge pull request #4081 from dotCooCoo/fix/flat-logo-bar-three-pixels-long
Image Trace: Flat Logo finds a bar two pixels wide and three pixels long in its own color
2026-10-25 10:37:40 -04:00
Brandon Thomas f775a31a80 Merge pull request #4117 from zsoltmar/fix/3536-pen-cursor-axis
Pen cursors: a fountain-pen nib on the selection arrow's axis
2026-10-25 10:37:36 -04:00
Brandon Thomas d51660d46e Merge pull request #4064 from dotCooCoo/feat/pencil-continue-line-cursor
Pencil: a path-continuation cursor shows over an end a straight line continues
2026-10-25 10:37:33 -04:00
Brandon Thomas c95d1c403c Merge pull request #4053 from marcoarnulfo/fix/icc-reload-direct-cache
Color management: loading the working RGB profile again under its name takes effect at once
2026-10-25 10:37:29 -04:00
Brandon Thomas 0d50e5f6ce Merge pull request #4059 from dotCooCoo/fix/new-symbol-threaded-text-keeps-its-text
Threaded text: New Symbol on a frame no longer duplicates its text
2026-10-25 10:37:26 -04:00
Brandon Thomas a43a99f531 Merge pull request #4056 from marcoarnulfo/fix/set-bounds-compound-member
Properties and Transform: X, Y, W and H of a compound path's member set only that path
2026-10-25 10:37:22 -04:00
Brandon Thomas 1d1d0192ba Merge pull request #4072 from dotCooCoo/fix/recovery-threaded-continuation-marks
Type: a recovered document keeps continued paragraphs in threaded frames
2026-10-25 10:37:19 -04:00
Brandon Thomas d57bcc3a39 Merge pull request #4047 from dotCooCoo/fix/rasterize-threaded-text-keeps-its-text
Threaded text: Rasterize on a frame no longer duplicates its text
2026-10-25 10:37:15 -04:00
Brandon Thomas 7fc7b41e71 Merge pull request #4061 from dotCooCoo/fix/trace-abutting-seam-note
Docs: the Image Trace page describes the background line between Abutting colors
2026-10-25 10:37:12 -04:00
Brandon Thomas 9a352a285c Merge pull request #4102 from dotCooCoo/fix/mcp-docs-eps-export-files
MCP docs: export's EPS row names its one-file default and rect refuses artboards
2026-10-25 10:37:09 -04:00
Brandon Thomas 4e3c2581c4 Merge pull request #4073 from dotCooCoo/fix/command-chord-test-on-mac
Shortcuts: the Ctrl+Alt chord test presses Cmd on a Mac
2026-10-25 10:37:06 -04:00
Brandon Thomas 33f4246464 Merge pull request #4096 from dotCooCoo/fix/cmd-escape-test-on-windows
Shortcuts: the Cmd+Escape test expects no binding on Windows
2026-10-25 10:37:03 -04:00
Brandon Thomas 9bc0a545a6 Merge pull request #4131 from Silvertree2010/fix/h2469-base64-decode-accepts-misplaced
Reject misplaced or excess '=' padding in base64_decode
2026-10-25 10:36:59 -04:00
Brandon Thomas ca02626de0 Merge pull request #4123 from Silvertree2010/fix/h2465-export-for-screens-size-parser-a
Refuse signs, exponents and non-numeric text in Export for Screens sizes
2026-10-25 10:36:56 -04:00
Brandon Thomas a515e390e5 Merge pull request #4126 from Silvertree2010/fix/h2467-unit-parse-accepts-scientific-no
Reject exponent notation in the pica form of Unit::parse
2026-10-25 10:36:53 -04:00
Brandon ThomasandClaude Opus 5.5 43313f9451 Release 0.17.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.17.0
2026-10-25 09:26:31 -04:00
NetterSilverandClaude Haiku 5.5 7a9818679f Reject misplaced or excess '=' padding in base64_decode
Found while testing crates/format/src/lib.rs:690-717 (base64_decode)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 12:00:58 +00:00
NetterSilverandClaude Haiku 5.5 76f8574b4b Reject exponent notation in the pica form of Unit::parse
Found while testing crates/doc/src/lib.rs:363-373 (parse_measure pica branch)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 10:56:54 +00:00
NetterSilverandClaude Haiku 5.5 80363c7e60 Protect Windows device names followed by a space in safe_file_name
Found while testing crates/engine/src/cmd/fileio/screens.rs:168-177 (safe_file_name)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 11:52:29 +01:00
NetterSilverandClaude Haiku 5.5 50b067c089 Refuse signs, exponents and non-numeric text in Export for Screens sizes
Found while testing crates/engine/src/cmd/fileio/screens.rs:49 (ScreenSize::parse)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 11:16:58 +01:00
Zsolt van den Már de18d80399 Pen cursors: a fountain-pen nib on the selection arrow's axis
The old pen glyph was a crude pentagon with a floating dot and a stray
stem. Redraw it as the precision instrument it is: the pen-tool icon's
nib — sharp point on the hotspot, shoulders flaring to their widest
two-thirds back, a narrower flat heel, a slit widening into the round
breather hole — swung round onto the selection arrow's midline
(arrow_axis), so holding Cmd/Ctrl to swap between the Pen and the
selection tools no longer rotates the cursor under the pointer.

Badges keep their meanings (*, +, -, o, /, j, ^, ~) and multi-stroke
ones now draw all halos under all ink via strokes(), so neighbouring
strokes no longer cut each other into blobs.
2026-10-25 00:19:53 -07:00
skylartaylor 349dafc0bd M0: preserve IME typing sessions and simplify input handling 2026-10-25 08:14:45 +01:00