Commit Graph
12834 Commits
Author SHA1 Message Date
BFlat f63827478c Merge pull request #6892 from dotCooCoo/fix/trace-gray-photos-smoothed
Image Trace: gray photos are smoothed before tracing, as color photos are
2026-11-13 00:49:52 +07:00
BFlat 80359e415f Merge pull request #6874 from dotCooCoo/fix/script-failed-run-keeps-no-place
Scripts: a named engine keeps no source map for a run whose script does not compile
2026-11-13 00:49:38 +07:00
BFlat 77d8113073 Merge pull request #6924 from dotCooCoo/fix/followup-5139
.ai import: cite the sources of the Distort & Transform effect keys
2026-11-13 00:49:28 +07:00
BFlat 8bf4de0a5a Merge pull request #6919 from dotCooCoo/feat/bbox-follows-move-and-draw
Selection: Show Bounding Box While Moving and Drawing shows the box during moves and shape drawing
2026-11-13 00:49:17 +07:00
dotCooCoo 556123e691 3D and Materials: Expand as Wireframes keeps a layer's path guides and cuts Revolve's art for Revolve
A layer expanded to its edges keeps the paths made into guides inside it, as it keeps its ruler
guides. A clipping group with Revolve and Rotate is cut for Revolve, the effect the canvas draws,
so its fills go in one piece and art with more fills than a 3D effect takes still expands.
2026-11-12 09:47:53 -08:00
bflatastic cfce336215 Dashes fitted to corners take a subpath with no segments
An HP-GL wedge of almost no radius drawn with an adaptive line type
(LT-1;EW0.000001,0,0;) leaves a lone moveto. Fitting the dashes to its
corners indexed the empty segment list and panicked while rendering. Such
a subpath now uses the exact plan, which has no runs to fit.

Found by import_fuzz::random_hpgl_instructions_never_panic.
2026-11-13 00:47:30 +07:00
dotCooCoo 369de5bc4c Merge main into fix/read-roots-error-messages 2026-11-12 09:45:21 -08:00
dotCooCoo 812cf5f4cd .ai save: RGB values are written in the working RGB space
Plain RGB fills and strokes and RGB gradient stops were written with
their display RGB values. The reader reads those values as working RGB,
so with a working RGB space other than sRGB a reopened file was saved
with different RGB values and CMYK equivalents. They are now written
with the color's own RGB values, as global process and spot colors
already were.

A spot color in a gradient stop now writes its RGB values from its full
color as the palette writes it (Lab to four decimals and clamped), the
same values its CMYK equivalent comes from.
2026-11-12 09:40:31 -08:00
dotCooCoo 4b9a611189 artboard.new: keep sides below 1 pt as given
artboard.new no longer raises a width or height below 1 pt to 1 pt, and artboard.setProps raises only a supplied side, so an edit to a small artboard's name or lock keeps its size.
2026-11-12 09:39:51 -08:00
dotCooCoo 6213d1c471 EPS tests: the reader's long tests check counts and shared state instead of a 20 s limit
many_tiling_patterns_and_spot_inks_read_in_linear_time checked that a
program setting 200,000 different tiling patterns and 200,001 spot inks
reads within 20 s of wall-clock time. It reads in about 4 s alone; while
the crate's full test suite ran in parallel it took more than 20 s and
failed.

In test builds, the tiling pattern lookup now counts on its thread how
many patterns it compared with the one it looked for (tilings_compared,
gated with cfg(test) like SELECTOR_TESTS in the SVG reader's CSS). The
test, renamed many_tiling_patterns_are_found_again_through_a_hash, reads
through import on a thread of its own and asserts that its 200,000
lookups compared at most 200,000 patterns in all. When every pattern
hashes alike, as when each lookup went through every pattern made so
far, the lookups compare 19,999,900,000 and the test fails. The test
still reads the 200,001 spot inks and checks their swatches, but it does
not count or time their lookups.

The other tests that read through read_soon wait 300 s instead of 20 s,
as a guard against a read that never ends; their budgets and limits
decide what they check. work_on_the_longest_dash_pattern_ends_soon (4.5 s
alone) now also checks that the states gsave, grestore, gstate,
currentgstate and setgstate save, make or set hold the one 65,535-entry
dash pattern, so a copy of the pattern in any of them fails it.
2026-11-12 09:38:05 -08:00
dotCooCoo 60fd410906 Merge main into fix/type-size-range-error 2026-11-12 09:30:29 -08:00
dotCooCoo 1fd194d21d Merge main into fix/ai-look-stroke-warning 2026-11-12 09:30:21 -08:00
dotCooCoo 7dd161cc49 Place: DCS files link with their spot plates as spot swatches and separate on their own inks
File › Place with Link reads a DCS 1.0 or 2.0 file (an EPS file whose
header names one EPS program per printing plate) as one linked image of
its plates. Each spot plate adds a spot swatch in the CMYK values the
file gives, and the clipping path the file's composite is drawn through
clips the image. document.open, file.place without link or from bytes,
and links.embed refuse a DCS file and change nothing.

- The screen, composite print and exports show the plates mixed into
  CMYK. Separations Preview and print separations show each plate on
  its own ink; a spot plate prints as its CMYK values when spots print
  as process.
- links.list answers the format DCS, and with dcsTransparency marks the
  DCS images that are transparent or overlap transparent objects (the
  Links panel menu's Show DCS Transparency Interactions).
- swatch.unused leaves out a spot swatch while a DCS image has a plate
  of its ink.
- links.update and links.relink read the plates and the clipping path
  again, and the link shows as modified when one of its plate files
  changes or is gone.
- The plates go on the first plate's pixel grid, grown to hold every
  plate where it prints; a plate of another size or position is
  resampled onto it.
- A file may name 64 plates, a plate file may be 1 GB, and the plates
  together may hold 512 MB of ink amounts. A file naming more plates is
  an error.

Docs: docs/mcp.md, docs/target-app-parity.md, docs/file-format-parity.md.
2026-11-12 09:30:20 -08:00
dotCooCoo 22a19db2cd Merge main into feat/new-document-profiles 2026-11-12 09:29:46 -08:00
dotCooCoo 075fff4c6d Merge main into fix/library-ids-and-save-replies 2026-11-12 09:29:20 -08:00
dotCooCoo 4e8cd99fff Merge main into feat/font-menu-wide-layout 2026-11-12 09:28:19 -08:00
dotCooCoo 3e46408ab5 EPS import: cshow and kshow procedures see the font PLRM gives them
In a CID-keyed font whose CIDFont the file only names, a cshow procedure
now runs with the CIDFont as the current font, rootfont gives the
composite font, and the procedure gets each code's last byte. A show in
the CIDFont shows the character of that code, and any other string is a
rangecheck error. The current font is restored after each procedure.

A kshow procedure no longer leaves a font it sets current: the current
font is restored when the procedure completes, for every font, and a
kshow the procedure runs sees the font the procedure set.

In GBT-H and CNS2-H, whose mappings are not read, a byte that starts no
row-and-cell code is a code of its own.

docs/gaps.md dates this G9 work in a bullet of its own.
2026-11-12 09:25:14 -08:00
dotCooCoo bccb0f177e Merge main into fix/i18n-plugin-messages 2026-11-12 09:23:31 -08:00
dotCooCoo fe34c2b818 Merge main into feat/custom-arrowheads 2026-11-12 09:23:20 -08:00
dotCooCoo 87d1f0b3d7 Merge main into fix/transform-effect-scales-raster-effects 2026-11-12 09:23:19 -08:00
makesomethingshit 777fb2fa42 Merge upstream/main into fix/6865-ai-oversized-artboard 2026-11-13 02:19:20 +09:00
dotCooCoo 2d66758ce4 MCP: document.json checks brush art and relative link paths against the read roots
Under --automation-read-root, document.json names a linked image or
placed file in a stored brush's art outside the read roots by its file
name alone, as it does in the layers. A stored brush entry that does not
read as a brush is left out of the reply, and a stored brush library
that is not a list becomes an empty one. A link whose file is inside the
read roots loses its stored relative path when that path leads outside
them, from the folder of the file the document was read from or from the
document's own folder.
2026-11-12 09:19:15 -08:00
dotCooCoo 714d72971c 3D and Materials: the 3D area row lists Expand as Wireframes and its tests 2026-11-12 09:16:50 -08:00
dotCooCoo c8a6b4d9c3 MCP: a base64 thumbnail in a reply is sent as it is
Under automation read roots, a reply's base64 `thumbnail` (a library
item's PNG in `library.get`, a page's PNG in `document.pdfInfo`) was
searched for hidden library paths like any other text, so a short path
that happened to occur in the encoded bytes was rewritten and the image
broke. `thumbnail` now joins `dataBase64`, `pngBase64` and
`thumbnailBase64` as encoded data that is left unchanged; text under it
that is not base64 is still searched.
2026-11-12 09:12:40 -08:00
jmverges ad2df449ea Merge remote-tracking branch 'upstream/main' into fix/type-layout-envelopes
# Conflicts:
#	docs/file-format-parity.md
2026-11-12 17:07:51 +00:00
dotCooCoo 70b26c12fb Updates: take craft-update from craft-libs main at e98299546
craft-update and craft-vectorcraft-format move from storytold/craft-libs
at 6e03f65bf to e98299546, craft-libs main with 47b6bbadf. The startup
check's thread now reads whether the copy installs itself, so a slow
disk no longer stalls a frame when the startup prompt is built. Both
crates stay on one craft-libs revision; the other craft-libs pins are
unchanged. Cargo.lock changes only the two crates' source.
2026-11-12 09:02:40 -08:00
dotCooCoo f42b46e5eb Merge main into fix/recovery-held-crashed-areas 2026-11-12 09:00:02 -08:00
dotCooCoo 2d46dcc533 Actions: a deleted recording action does not limit recorded commands
When the action New Action made for the recording in progress is deleted,
Stop Playing/Recording keeps none of the recorded steps. The step and
file limits measured a new action in the original set instead, so a
recorded command could be refused while the set's file was near 8 MiB.
The recording now has no target in that case, and no limit applies.
2026-11-12 08:59:08 -08:00
dotCooCoo 8d27e53115 Merge main into feat/image-color-mask 2026-11-12 08:56:33 -08:00
dotCooCoo 5a7d445807 Merge main into fix/script-failed-run-keeps-no-place 2026-11-12 08:55:15 -08:00
dotCooCoo 91e1412d77 Effects: Roughen at size 0 keeps the outline
With Size 0, Roughen moved no point but still replaced each segment
with its Detail's points joined by straight lines (Corner) or by a
smoothed curve through them (Smooth), so a curved path lost its shape.

At Size 0 each segment is now split at the Detail spacing into pieces
of equal length on the segment itself, with `pathtools::insert_at`: a
straight segment gets corner points without handles, and a curve gets
smooth points whose handles follow it. The path keeps its outline with
Smooth or Corner points alike. The params text of `distort.roughen`
describes size 0.

`insert_at` now counts the anchors added before each returned mark in
one pass. It counted them again for every split segment, which took
quadratic time on a path with many split segments. Its results are
unchanged.

Existing documents with a Roughen of Size 0 on a curved path, or with
Smooth points, draw differently.

This is VectorCraft's own rule. What Roughen does is described in
https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html
2026-11-12 08:55:07 -08:00
BFlat 2304b38f19 Merge pull request #6907 from dotCooCoo/feat/art-brush-width-pen-pose
Brushes: Art Brush Options' Width can follow the pen's tilt, bearing and rotation
2026-11-12 23:54:29 +07:00
BFlat 3fed6e3380 Merge pull request #6911 from dotCooCoo/fix/canvas-zoom-ignores-ui-scaling
View: the art keeps its size at a zoom whatever the UI Scaling
2026-11-12 23:54:20 +07:00
BFlat dc68ae950c Merge pull request #6912 from dotCooCoo/fix/new-document-side-limit
New Document: file.new and artboard.new take the same largest artboard side
2026-11-12 23:54:11 +07:00
BFlat 6a695a01ec Merge pull request #6847 from dotCooCoo/feat/weed-box-and-lines
Cutting Tools: Weed Box and Lines adds a weed box and weeding lines around art
2026-11-12 23:54:01 +07:00
BFlat edfc6c6588 Merge pull request #6891 from dotCooCoo/fix/set-corners-shortcut
Keyboard Shortcuts: a command that a menu bar item runs can take a shortcut, Set Corners… among them
2026-11-12 23:53:51 +07:00
dotCooCoo 0a13aca6ee Docs: gray photos need an eight-color error over 6 levels to count as continuous tone 2026-11-12 08:53:48 -08:00
BFlat a6aac579c0 Merge pull request #6904 from dotCooCoo/feat/ai-editing-data-s6c
.ai save: the editing copy keeps brushes and brushed paths
2026-11-12 23:53:38 +07:00
BFlat ab50f06909 Merge pull request #6914 from dotCooCoo/fix/kept-tiles-test-flake
Render tests: the kept-tile decode-failure test passes while other tests add fonts
2026-11-12 23:53:22 +07:00
BFlat e618783377 Merge pull request #6084 from Taha-Mahmoodi/feat/glyph-alternates
Glyphs: alternates keep the word joined (feature values, one-piece shaping, unencoded glyphs)
2026-11-12 23:53:13 +07:00
BFlat 1c50241ddd Merge pull request #6702 from danngreen/fix/mac-cursor-after-move
macOS: the canvas cursor stays after the pointer moves (#6362)
2026-11-12 23:53:03 +07:00
BFlat 5f3c7f5425 Merge pull request #6906 from ruchirguitar/fix/pdf-indic-text-5235
PDF import: Indic type that would not draw as the file does keeps the file's glyphs (#5235)
2026-11-12 23:52:49 +07:00
dotCooCoo 89e52eaabc MCP: a folder preference is checked as trimmed, and only a %XX escape is decoded
Under automation read roots, `ui.inspect` kept a folder preference whose
stored value was readable even when the trimmed path the app uses was
not: ` /outside/fonts` reads as a name in the working folder, while the
app uses `/outside/fonts`. A folder preference now stays only when both
forms are readable. A reply string is decoded for path matching only when
it holds a `%XX` escape, so a string such as `width="100%"` is no longer
decoded and thrown away. The library list line in the progress doc now
states when a hidden library's `loaded/<file name>` id moves.
2026-11-12 08:50:46 -08:00
dotCooCoo 0ae706c592 Docs: the file-format doc's editing-copy paragraph and summary rows appear once
docs/file-format-parity.md held 36 copies of the paragraph on the
editing copy of a file. #6202 and #6249 each added a combined copy
without removing the copies it replaced, so the count went from 34 to
35 and then to 36. The section now holds one copy: #6249's combined
copy, with the Align to Path distance clause that seven of the other
copies carry from #6247. Every other clause of the removed copies is in
the kept one, word for word or in the newer, longer form another copy
wrote. The older Align to Path clause, with its measurements for one
font at 24 pt, is removed because #6247's wording replaces it. The
paragraph now starts with a capital letter.

The summary table also repeated its "Formats opened or placed" and
"Formats saved (Save As)" rows. The older row of each is removed: the
one that still lists HEIC/HEIF as missing, and the one that lists fewer
contents of the editing copy that `.ai` saves write.
2026-11-12 08:50:41 -08:00
dotCooCoo 9df4a83f07 Merge main into feat/blend-canvas-easing-handles 2026-11-12 08:46:06 -08:00
dotCooCoo fc1a08edbd Merge main into feat/brushes-ink-wash-library 2026-11-12 08:46:00 -08:00
dotCooCoo 5006ba5a2e Merge main into feat/eps-save-use-artboards 2026-11-12 08:45:42 -08:00
dotCooCoo 1bb6582194 .ai import: cite the sources of the Distort & Transform effect keys
The doc comments of the Transform, Free Distort, Tweak and Zig Zag
readers, and the Pucker & Bloat and Twist arms, now name the public
pages that list each effect's dictionary keys. No code changes.
2026-11-12 08:38:10 -08:00
dotCooCoo 66f6be77ee .ai save: RGB and named colors keep their CMYK equivalents when a reopened file is saved
The .ai writers write RGB and Lab values to four decimals next to a CMYK
equivalent, but converted that equivalent from the color at full precision.
When a file was read back and saved again, its CMYK equivalents differed in
the fourth decimal (for example 0.6831 and 0.6832). In the editing data this
affected plain RGB colors, RGB gradient stops, global process and spot colors
and the header's custom colors; in the legacy .ai writer it affected RGB
gradient stops.

The CMYK equivalent of an RGB color, and of a global process or spot color,
is now converted from the values as they are written, so both saves convert
the same values. Lab values of global process and spot colors are now written
clamped to the range the reader reads (L 0 to 100, a and b -128 to 127).

A plain Lab fill or stroke and a Lab gradient stop are still written as RGB
with a CMYK equivalent converted from the Lab values. The reopened file holds
them as RGB, so their CMYK equivalents change once on its next save.

The art style round-trip test now compares the program exactly; its blanked
CMYK values and the four-decimal tolerance are no longer needed.
2026-11-12 08:35:39 -08:00
dotCooCoo cc761c359e Color: a recent color drags into the Swatches panel to become a swatch
A Recent Colors chip in the Color or Swatches panel now starts a paint
drag. Dropped on the Swatches panel's list it becomes a swatch of its
color, in its color model, through swatch.new as one undo step: on a
color group or one of its swatches it joins that group, elsewhere it
joins the ungrouped swatches. A click on a chip still paints the
selected art, and a drag does not.

A paint Alt-dropped on Registration now becomes a new swatch instead of
ending in a "can't be edited" error from swatch.edit.
2026-11-12 08:35:15 -08:00