Commit Graph
4259 Commits
Author SHA1 Message Date
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
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 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 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
dotCooCoo 766e291e3c Save and Export: notes of what the file loses come before notes on options
Each writer marks its notes as a loss (something of the document that the
file leaves out or that reaches it changed) or as a note on the options
(an option it didn't apply or applied another way while the art reaches
the file as it looks, or something an option turns off). The PDF, SVG,
EPS, legacy .ai, DXF and HP-GL writers return their notes on the options
in a list of their own (`setting_notes`) beside `warnings`, and the
engine's `Encoded` does the same.

The replies of the save and export commands, and of
`clipboard.exportPdf` and `clipboard.exportPng`, list the losses first,
each kind in the order the writers gave them, across every file that
Export for Screens writes. The status bar names the first note, so an
export to lossy WebP of type in a font that isn't installed now names the
fallback-font note instead of the lossy WebP note. A print to a file
keeps the order its notes are given in.
2026-11-12 08:33:57 -08:00
dotCooCoo ff6dac4a5d Shaper: a click on an original shape's outline enters Construction mode
With a Shaper Group or one of its faces selected, a Shaper click within
3 screen pixels of one of the group's original shapes' outlines enters
Construction mode with that shape selected, also where the outline runs
through a merged face. shaper.select takes a tolerance in points
(default 3, at most 1000); hidden and locked shapes are skipped, and a
Shaper Group above the selected one still takes the click.
2026-11-12 08:33:29 -08:00
jmverges e0c5b0818a Merge remote-tracking branch 'upstream/main' into fix/ai-type-pattern-paint
# Conflicts:
#	docs/file-format-parity.md
2026-11-12 16:30:04 +00:00
dotCooCoo a17acb852f Selection: Show Bounding Box While Moving and Drawing shows the box during moves and shape drawing
The new General preference Show Bounding Box While Moving and Drawing
(`boundingBoxWhileMovingAndDrawing`, off by default) keeps the bounding
box and its handles visible during two kinds of drag, with View › Show
Bounding Box on. While a drag moves the selection (a Selection tool
move, an Alt-drag copy, or a shape tool's move by the center point),
the box is drawn where the drag has moved the selection. The box is
measured once when the drag starts and offset by each step's move.
While the Rectangle, Rounded Rectangle, Ellipse, Polygon and Star tools
draw a shape, the box is drawn around the shape. A rotation and a
widget drag still hide the box until the release. The Line Segment
tool, the Pen, the Pencil and the Paintbrush draw no box.

With the preference off, the box hides during a move (#737, for #712)
and while a shape is drawn (#5839), as before. A Selection tool move
with Real-time Drawing off still moves the box with the pointer, and a
shape tool's move by the center point hides it in both modes.

With Real-time Drawing off, the box of a shape being drawn is measured
from the pending preview, in the color of the layer the shape goes on.
A shape being drawn shows no box until a preview step has succeeded,
so a failed preview does not show the box of the selection from before
the drag. The preference's label has a row in every catalog.

Session::deferred_move() is replaced by Session::move_drag_box(), which
returns the moved box, and Session::deferred_transform_box() now also
returns the layer color of the box.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-12 08:28:21 -08:00
dotCooCoo a5541ab42a Blend: steps of brushed strokes interpolate the pen pressure, tilt and angles
A blend between two strokes drawn with a pressure-sensitive brush gave
every step the pen recording of the nearer key, so the brush jumped at
the middle step. The steps now interpolate the pressure, tilt, bearing
and rotation at every position either key has a sample. A key without a
recording counts as half pressure, half tilt and 0 degrees, as brushes
read it. Angles turn the shorter way round, and steps and whole turns in
a recording stay in the steps. Different brushes still switch halfway.
2026-11-12 08:26:32 -08:00
BFlat 932830283d Merge pull request #6841 from dotCooCoo/feat/docinfo-spot-color-objects
Document Info: Spot Color Objects lists the objects that use spot colors
2026-11-12 23:10:59 +07:00
BFlat b85f546ace Merge pull request #6893 from dotCooCoo/test/command-sweep-path-keys
Plug-ins: `diffPath` is a file key and Slice Options' `url` is not; the command sweep uses these keys
2026-11-12 23:10:48 +07:00
BFlat cc6509827d Merge pull request #6878 from dotCooCoo/fix/opacity-mask-follows-reshape
Opacity masks: linked masks follow group effects, the Free Transform distort and envelopes
2026-11-12 23:10:24 +07:00
BFlat 0cb73d0d66 Merge pull request #6845 from dotCooCoo/feat/linux-screen-color-portal
Color: Sample Color from Screen works on Linux through the desktop portal
2026-11-12 23:10:13 +07:00
BFlat 3df161a972 Merge pull request #6903 from dotCooCoo/feat/gradient-repeat
Gradients: repeat or reflect a gradient's stops a set number of times
2026-11-12 23:10:02 +07:00
BFlat 12d72b3eb0 Merge pull request #6901 from dotCooCoo/fix/trace-smooth-area-contours
Image Trace: band borders in smooth areas follow the image's contours
2026-11-12 23:09:43 +07:00
BFlat 4920df33c0 Merge pull request #6885 from dotCooCoo/fix/screens-preset-folder-background
Export for Screens: an export into a preset's folder runs in the background
2026-11-12 23:09:16 +07:00
BFlat 3a1426eff3 Merge pull request #6898 from dotCooCoo/feat/justify-cluster-gap
Type: letter spacing and Full Justify keep shaped clusters together
2026-11-12 23:08:43 +07:00
BFlat a38903aa72 Merge pull request #6900 from dotCooCoo/feat/global-edit-highlight-similar
Global Edit: selecting one object highlights the similar objects before the start
2026-11-12 23:08:32 +07:00
BFlat f43d00aa11 Merge pull request #6902 from dotCooCoo/fix/eps-named-cid-show-operators
EPS import: charpath, cshow, kshow and glyphshow read named CIDFont type by its CMap
2026-11-12 23:08:23 +07:00
dotCooCoo 2defb49002 Font menu: one wide layout wherever it opens, with larger samples
The font menu opened at its field's width, so from the Control bar's narrow
Character field the filters wrapped one chip per line and family names were
cut off after a few letters.

- The filters keep the same four rows wherever the menu opens: the scripts;
  the star, Any Kind, Serif / Mincho, Sans Serif / Gothic and Rounded;
  Script / Brush, Monospaced and Decorative; Font Technology with Variable.
- The menu opens at least wide enough for those rows and for a family name
  up to 220 points wide with room for its sample, up to 60% of the window,
  and stays in the window. A field wider than that keeps its width.
- Where the row has room, the sample starts after the widest name instead of
  halfway along the row. It takes the row's whole height instead of 4 points
  less, so samples draw larger at every Font Preview Size.

Requested by POGO.
2026-11-12 08:06:24 -08:00
dotCooCoo e242eeb609 Actions: progress doc names the command that passes a limit only as it runs
A recorded command whose step passes a limit only from the values it adds
as it runs keeps its edit. The status bar names the limit, later recorded
commands do not run, and Stop Playing/Recording leaves its step out.
2026-11-12 08:01:39 -08:00
dotCooCoo d3b18465f9 New Document: file.new and artboard.new take the same largest artboard side
file.new refused a side over 163,830 pt, while artboard.new took larger
artboards. Both now take each side more than 0 and at most 3,999,856 pt:
the 4,000,000 pt the canvas reaches from the origin, less a 72 pt bleed
on both sides. A side outside that range is refused with an error that
names the limit in points and, when the document's units are not points,
in those units, rounded down so the value shown is accepted.

artboard.new now refuses a supplied width or height of 0 or less instead
of making a 1 pt side, and refuses a size taken from a larger artboard.
Saved and Recent presets are read with sides up to the new limit.

Follows #6643.
2026-11-12 07:45:32 -08:00
makesomethingshit c36f863073 Merge upstream/main into fix/6865-ai-oversized-artboard 2026-11-13 00:44:37 +09:00
ruchirguitar b732d4f4b2 Merge remote-tracking branch 'upstream/main' into fix/pdf-indic-text-5235
# Conflicts:
#	docs/file-format-parity.md
2026-11-12 21:01:38 +05:30
dotCooCoo 04fd1b127b Brushes: Art Brush Options' Width can follow the pen's tilt, bearing and rotation
The Width menu now offers Tilt, Bearing and Rotation beside Fixed and
Pressure, each with the second width. Tilt goes from Width with the pen
lying flat to the second width upright; Bearing and Rotation go from
Width at -180 degrees to the second width at 180 degrees, as Scatter
Brush Options' modes do. A stroke drawn without that input is half way
between the two widths. brush.options takes width_mode tilt, bearing
or rotation.
2026-11-12 07:28:26 -08:00
dotCooCoo 2e968acc47 Align: the Align panel aligns and distributes the selected artboards
With the Artboard tool chosen, the Align panel's Align Objects,
Distribute Objects and Distribute Spacing buttons, their UI commands and
the Control bar's Align and Distribute buttons act on the artboards the
tool has selected, as the public page describes:
https://helpx.adobe.com/illustrator/desktop/create-manage-artboards/organize-manage-artboards/align-and-distribute-artboards.html

- artboard.align, artboard.distribute and artboard.distributeSpacing
  move whole artboards with their guides, and with the art inside them
  when Move Artwork with Artboard is on, in one undo step. No undo step
  is recorded when no artboard moves.
- Align To offers Align to Selection and Align to Artboard. Align to
  Artboard keeps the active artboard in place, and the Distribute
  buttons then send the Distribute Spacing value. A locked artboard
  stays where it is. These rules are VectorCraft's own.
- The Control bar shows the Align buttons, the Align To menu and the
  Distribute buttons after the artboard controls while it has room.

Docs: docs/mcp.md, docs/ui-parity.md.
2026-11-12 07:28:16 -08:00
ruchirguitar f18fb4e92d PDF import: Indic type that would not draw as the file does keeps the file's glyphs (#5235)
Gujarati text from a PDF came in jumbled even with its fonts installed:

- A glyph with no advance (a vowel sign or anusvara set over its letter)
  was taken for vertical type and opened as an object of its own, which
  type then drew on a dotted circle. In a font the file writes
  horizontally it now stays on its line.
- A line read glyph by glyph is not always the text that was set: the
  file draws a vowel sign before the consonant it follows, and may not
  name a conjunct. A line with characters of U+0900 to U+0DFF is now set
  again and its glyphs compared with the ink the file drew; when they
  differ the line keeps the file's glyphs as outlines, with a note.

Tests: crates/pdf/src/tests/reshaped.rs (two fail without the change).
2026-11-12 20:56:16 +05:30
Taha-Mahmoodi 2d62c35d69 Merge remote-tracking branch 'origin/main' into feat/glyph-alternates
# Conflicts:
#	docs/gaps.md
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-11-12 19:55:05 +04:30
dotCooCoo 5d40a1c6d0 View: the art keeps its size at a zoom whatever the UI Scaling
Preferences > User Interface > UI Scaling sets egui's zoom factor, and the
canvas mapped one document point to one of the interface's points at
100%. A document point then covered UI Scaling times as many device pixels,
so the art grew and shrank with the interface.

The canvas now maps the document at the view's zoom divided by the UI
zoom (View::screen_zoom, Xf::at). The rendered frame, the pointer, rulers,
grids, Fit and Actual Size, pan, scroll, zoom and turn about a point, the
Zoom tool's marquee, Pixel Preview's check, tiled panes, the Navigator's
view box and the tools' tolerances use that mapping. The zoom value means
the same at every UI Scaling, and the interface still follows UI Scaling.
fit_zoom, zoom_about, rotate_about, pan_pixels and scroll_by take the UI
zoom, and Xf::new is now test-only.

Found while looking into a report by bortek about the art's size at 100%.
2026-11-12 07:24:43 -08:00
BFlat 10ea235ee4 Merge pull request #6659 from ruchirguitar/fix/numfield-short-drag-1326
Numeric fields: a sub-threshold pointer movement keeps its caret (#1326)
2026-11-12 22:21:11 +07:00
dotCooCoo fd81eae9b5 Type: text.create and the type style commands refuse a size outside 0.1 to 1296 pt
text.create clamped a size above 1296 pt to 1296 without an error, so a
request for 2835 pt type returned 1296 pt type. text.createInPath,
text.setStyle and text.setRangeStyle clamped the same way. Each now
refuses a size outside 0.1 to 1296 pt with "`size` must be from 0.1 to
1296" and changes nothing. Both ends of the range are still taken.

Follows #6643.
2026-11-12 07:20:37 -08:00
dotCooCoo fa0a0753bb Merge main into feat/weed-box-and-lines 2026-11-12 07:20:06 -08:00
dotCooCoo b4ffd4a97e MCP: a hidden path's file: URL shows as the file name, and rewritten keys keep every field
Under automation read roots, a reply replaced only the path inside a
`file:///outside/a.svg` URL, which left `file://a.svg`, a URL that names a
host. The whole URL of an absolute path, with `localhost`, another host or
no host, is now replaced with the file name, unless part of its scheme was
already replaced. A reply key rewritten to read the same as another key of
its object took that key's place and its field was lost; the rewritten key
now takes ` (2)`, ` (3)` and so on, and a key that is not rewritten keeps
its name.
2026-11-12 07:17:50 -08:00
dotCooCoo 07423c22d6 MCP: save and export replies keep the path the client gave under read roots
Under automation read roots, a reply shows each path outside the read roots
that the request sent by its file name. A save or export to a path the
client gave inside the write roots then answered with the bare file name in
`path`, where the save replies keep the given path. The `path` and `files`
entries of the reply's result, a `command.batch` step's result included,
that equal a path param the request gave inside the write roots now stay as
given; every other occurrence is still shown by its file name, and loaded
libraries outside the read roots keep their `loaded/<file name>` ids.
2026-11-12 07:17:50 -08:00