Commit Graph
3087 Commits
Author SHA1 Message Date
bflatastic 4eec70e5cd Automation roots: rustfmt and clippy (redundant closure) 2026-10-24 05:16:21 +07:00
Dylan M. Taylor 42f8b513a2 Fix clipboard read-policy bypass and lock-held file checks
- copied_file: check the read policy on the real path when it is
  valid UTF-8; skip non-UTF-8 paths while automation roots are
  active instead of checking a lossy name (path traversal via
  symlink, CodeRabbit #3872 thread 1).
- full_bytes_cached: collect matching cache candidates under the
  FULL lock, then run the read checks after releasing it, so
  filesystem walks no longer stall other FULL users (thread 2).
2026-10-24 05:16:20 +07:00
Dylan M. Taylor cd043f650b Tests: the recovery folder needs read access too; the Place queue check runs for any active tool 2026-10-24 05:16:20 +07:00
Dylan M. Taylor c99b77060d Test: the Place queue is checked against the read roots 2026-10-24 05:16:20 +07:00
Dylan M. Taylor e95e8418ed Audit: automation roots follow file.showPackage, the Place queue, headless file methods, clipboard files, placed-document workers and caches, folder searches and the recovery folder 2026-10-24 05:16:20 +07:00
Angelo BernardiniandClaude Opus 5.5 52a43eefdb G12: ruler guides nudged with art keep to the page's axes at a turned Constrain Angle
With objects and ruler guides selected together, object.nudge moved the
guides by the art's delta turned through General > Constrain Angle, so at
90 degrees a Right nudge moved a horizontal guide vertically. The guides
in that edit now move by the page-axis delta, as guides selected alone
already did (CodeRabbit finding on #3745).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014gCpjL3yUhaH3jRp7ksufh
2026-10-24 04:59:57 +07:00
BFlat e0c1548049 Merge pull request #3896 from storytold/fix/3869-svg-type-features
SVG export: type with small capitals, superscript, subscript or tab leaders is written as outlines (#3869)
2026-10-24 04:51:54 +07:00
BFlat 8d87932f48 Merge pull request #3891 from aiongg/eps-read-soon-headroom
EPS tests: budget tests wait 120 s for the program to stop
2026-10-24 04:51:38 +07:00
aiongg 6877d6535f Links: resolve stored paths with craft-docpath's resolve_absolute (#3267)
* Links: use resolve_absolute for stored paths

* CI: release only with git dependencies from storytold

* Release: check git sources from the parsed Cargo.lock and cargo config

The grep let any character stand for the dot in github.com, passed a missing or stale
Cargo.lock, and missed source replacement in .cargo/config.
2026-10-23 17:51:28 -04:00
bflatastic 166afce360 SVG export: type with small capitals, superscript, subscript or tab leaders is written as outlines (#3869) 2026-10-24 04:49:08 +07:00
aiongg 88884bcd01 EPS tests: budget tests wait 120 s for the program to stop
search_in_a_loop_runs_out_of_the_budget searches about 3 GB before the operation budget runs
out: 14 s on a fast desktop, over the 20 s limit on the FreeBSD runner. The 20 s limit stays
for the tests that use it as a speed bound.
2026-10-24 04:49:08 +07:00
Gabriel Luís da Silva 60764fb65b Fix #3724: Window > New Window is greyed out until it opens a window
New Window was enabled in the menus and in the control channel's menu
listing, but choosing it opened nothing and answered with the internal
note "multiple windows land with M11.5". It is now disabled, as Window >
Arrange's unimplemented items already are, and a direct call fails with
a message meant for the user, translated in every catalog.
2026-10-24 04:49:07 +07:00
Jürg Lehni 181aeef44c Renderer: colour caches key colours with Color::key
The freeform and dithered gradient grids and the separated inks each built the same exact colour key by hand; they now take the one Color::key gives.
2026-10-24 04:49:07 +07:00
Dylan M. Taylor 5020dc0585 PDF export: past the retry cap, one last run leaves out every image instead of failing 2026-10-24 04:49:07 +07:00
bflatastic 2e71ab5476 PDF import and export: rustfmt 2026-10-24 04:49:07 +07:00
Dylan M. Taylor 4b8e69981e Audit: PDF import and export bounds 2026-10-24 04:49:07 +07:00
bflatastic 9c8afb09ba Image encoders: rustfmt 2026-10-24 04:49:07 +07:00
Dylan M. Taylor 52ceefe906 Audit: Targa and palette encoders check pixel buffer sizes 2026-10-24 04:49:07 +07:00
Dylan M. Taylor 9843d5f1ab Audit: export names, linked-file ids and MCP prompt arguments in one pass 2026-10-24 04:49:07 +07:00
bflatastic 028cafa52e Scribble: the row loop's stop compares with partial_cmp (also stops on NaN; clippy) 2026-10-24 04:49:07 +07:00
Dylan M. Taylor b59235e762 Test: sliding-window maximum 2026-10-24 04:49:07 +07:00
Dylan M. Taylor e3223a419d Audit: Scribble rows counted, Outer Glow dilation in linear time, CSS export names in a set 2026-10-24 04:49:07 +07:00
bflatastic a82bcfe7a5 DXF export: format the far-coordinate check 2026-10-24 04:49:07 +07:00
bflatastic 62333a2128 DXF export: the far-coordinate check compares with partial_cmp (also refuses NaN; clippy) 2026-10-24 04:49:07 +07:00
bflatastic 711b10ca59 Security: DXF export bounds (layer and style names, flattening, entity count, image size) and import dash patterns
Squashed from #3886 onto main.
2026-10-24 04:49:07 +07:00
Gabriel Luís da Silva f0ec1c8506 Fix #3716: a click near an anchor selects without moving the object
A Selection tool press within reach of an anchor or the centre grabs the
object by that point, but the drag threshold was measured from that point
instead of from the press. A press 3-6 px from it was already past the
threshold, so the first pointer wobble started a move and jumped the
object by the offset. The threshold now counts from where the pointer
went down; a real drag still moves the object by the grabbed point.
2026-10-24 04:49:07 +07:00
bflatastic c2ad9f8bbb Type: emoji go with type that effects reshape and Expand Appearance
Squashed from #3879 onto main.
2026-10-24 04:49:06 +07:00
bflatastic 0ecef703ef Security: cap the perspective grid's line-loop bounds at 121 a way 2026-10-24 04:34:18 +07:00
Dylan M. Taylor 1bb904c147 Audit: Perspective Grid lines counted not summed; Liquify subdivision stays under its anchor ceiling 2026-10-24 04:13:37 +07:00
Dylan M. Taylor aa160b969b Audit: path edit work bounds (redundant points in one pass, simplify and join budgets) 2026-10-24 04:13:36 +07:00
Dylan M. Taylor f4a30c1a94 Audit: geometry length measurement refuses coordinates the integrator cannot handle 2026-10-24 04:13:36 +07:00
bflatastic 9827bfbcbb SVG import: the shared appearance needs no conversion (clippy) 2026-10-24 03:52:24 +07:00
bflatastic d9e524df30 SVG entity scan: look for a reference's ';' no further than the longest name 2026-10-24 03:52:24 +07:00
Dylan M. Taylor 98d11ad66b Audit: cap SVG entity expansion, filter layer stacks and export id/companion probing; share compound-path appearances; escape-proof font feature tags 2026-10-24 03:52:24 +07:00
bflatastic 8e8aaa8683 SVG: a Preserve Editing SVG reopened from disk saves as the full document again (#3867) 2026-10-24 03:52:24 +07:00
Jürg Lehni e372d00cb7 Type: tests pin colour glyphs in variable fonts, on paths and on the canvas
A variable font's COLR layers follow its instance, a colour glyph turns with type on a path, and the canvas draws an SVG glyph's art in its own colours and the type's fill.
2026-10-24 03:52:23 +07:00
bflatastic 9f1a001a2b Export for Screens: a per-artboard EPS takes the artboard as its page, so an empty artboard still writes 2026-10-24 03:52:22 +07:00
bflatastic d81145aee3 Artboard documents keep objects without measurable bounds (type in a missing font) 2026-10-24 03:52:22 +07:00
bflatastic 60107cd33a Export for Screens: a document row for an artboard keeps only that artboard's art (#3868) 2026-10-24 03:52:22 +07:00
Zaxaerith 9985d587f7 fix(stroke): preserve extended dash patterns (#3497) 2026-10-24 03:52:22 +07:00
ham9zah 1653790965 Import: an Illustrator gradient mesh comes in as one connected mesh
The editing data writes a gradient mesh as its patches, each with its
place in the grid (`/P`) and the grid's size (`/Size`); the importer
read each patch as a mesh of its own, in a group, so moving a mesh
point tore a patch away and left a hole, and a patch with anchors on
its edges was cut into cells on its own.

The patches are now placed by `/P` in the `/Size` grid and joined at
the corners they share into one GradientMesh. Which index of `/P` runs
along the columns is taken from the one under which the shared corners
meet. Where an edge bends through anchors, a mesh line runs through the
whole row or column of patches there, each patch cut at the same place,
so every cell keeps single-cubic edges. A mesh whose patches don't say
where they are reads as before; one whose patches fill the grid but
don't join up reads as before with a warning. Sizes and lines are
capped; non-finite values fall back.

Hand-written tests: a 2 x 2 grid as one mesh with the old patches'
colours, a moved inner point shared by its four cells, an anchor on a
shared edge adding a line through the mesh, a collapsed patch with
finite values, and unplaced or unjoined patches staying separate.
2026-10-24 03:52:21 +07:00
Marco Arnulfo d0919ad0df Actions: Create New Set and Set Options… name action sets, and a recording goes into the current set (#3712) 2026-10-24 03:52:20 +07:00
Jürg Lehni 7efd8f941a Type: colour glyphs keep each fill's own colour, also between colours that look alike
The colour glyph cache keyed the text's colours by their 8-bit RGB look, so a fill that only looked like an earlier one (a grey and the same RGB grey, a spot colour and its process match) took that one's colour, and its separations. It now keys them exactly.
2026-10-24 03:52:15 +07:00
FractalEncrypt 25abd1f472 text: recheck concurrently loaded fallback faces
A system fallback search can add no new face because another lookup loaded it
first. Re-read the loaded faces regardless of the search's return value, so
concurrent first use does not produce a missing glyph and different advances.

Add an isolated generated-font regression with simultaneous cold lookups.
The original code missed 14 of 16 lookups; the fixed regression passed twenty
runs. Both previously failing Ruby tests pass unchanged.

Validation: Rust 1.98.1 cargo xtask ci, all 10 gates passed; workspace tests
9,635 passed, 0 failed, 14 ignored. Default Rust toolchain unchanged.
2026-10-24 03:52:15 +07:00
NetterSilverandClaude Haiku 5.5 add5e1e7dd Reject signed hex digits in XML-ID _xHH_ escapes
Found while testing crates/doc/src/xml_id.rs:80 (escaped)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 03:52:14 +07:00
bflatastic 0066447eac Global Edit: cache the highlight outlines per document revision 2026-10-24 03:09:12 +07:00
bflatastic 6e3ecc3adf Select: Start Global Edit edits the objects of the same shape together, each in proportion
Squashed from #3781 onto main.
2026-10-24 03:09:12 +07:00
dotCooCoo 2a2e63856c Type: the Paragraph panel's Bullets button turns paragraphs into a bulleted list
VectorCraft had no lists. A bullet could only be typed as a character,
and the tab after it did not stop at the left indent. The reference app
turns paragraphs into a bulleted list from the Paragraph panel, the
context menu and Type › Bullets and Numbering › Apply Bullets.

text.setFormat takes list ("none" or "bullet") and bullet ("none",
"dot", "dash", "circle" or "square"). The layout draws the bullet before
the first line of each list paragraph that has text, in the font, size
and color of its first character, and starts the text at the next tab
stop, with the left indent counted as a stop. Wrapped lines start at
the left indent, and type on a path draws the bullet too. In a
horizontal right-to-left list paragraph the indents are mirrored: the
bullet hangs at the right, and the wrapped lines start at the right
where the first line's text starts after the bullet. The bullet is not
a character of the text. A paragraph whose left and first-line indents
are both 0 gets 18 pt and -18 pt when it joins a list. Return continues
the list, paragraph styles carry it, Reset Panel turns it off, and the
native file saves it only when it is set.

The Paragraph panel has a Bullets button with a list of the five
presets, and Type › Bullets and Numbering › Apply Bullets and the
context menu run type.applyBullets. Live SVG text writes the bullet's
character, and SVG writes type on a path with bullets as outlines. DXF
writes the bullet as a TEXT entity of its own, and legacy .ai export
warns that bulleted lists are left out. The caret, selections, Touch
Type and Show Hidden Characters skip the bullet.

Live SVG text of horizontally scaled type now writes each tab in a
tspan of its own. Before, the characters before a tab shared its tspan,
and its textLength made a viewer stretch them across the tab's gap.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-24 03:09:11 +07:00
Taha-Mahmoodi 5c8e440ab5 Symbols: thumbnails work out the document's resource key once per panel frame, not per tile
Review follow-up (CodeRabbit): each thumbnail hashed every symbol's and pattern's art before its
texture cache lookup, so a panel frame cost visible tiles × (symbols + patterns) even when every
thumbnail was cached. The Symbols panel works the key out once per frame, a symbol library panel
once per library it shows, and the dragged chip once; thumbnails take it as given.
2026-10-24 03:09:11 +07:00
Taha-Mahmoodi f6715487c0 Symbols: the thumbnail test reads pixels as four-byte chunks, as clippy asks 2026-10-24 03:09:11 +07:00