Commit Graph
13399 Commits
Author SHA1 Message Date
dotCooCoo 1a01d591f3 Shapes: addon.shapes params text parses, and configure keeps omitted values
The ranges in the addon.shapes params text are in parentheses, so each
description reads as a params object. The configure description and
docs/mcp.md say that an omitted or null value keeps each shape's setting;
the defaults apply to the drawing commands only.
2026-11-13 19:56:50 -08:00
dotCooCoo 7c40cd2df2 Plug-ins: unlinking a gradient stop's spot swatch also clears its plates
A filter or importer that changes a gradient paint unlinks each stop from
its swatch and resets its tint, but left the stop's process plates. The
PDF and EPS writers read plates only with a spot swatch, so the stop kept
a plates array with no ink, saved with the document and compared in later
edits. Unlinking now clears the plates too, in fills and strokes; a paint
returned unchanged keeps its link, tint and plates.

The plate clamping test now checks the decoded output, before admission.
2026-11-13 19:56:38 -08:00
dotCooCoo 621f9b6287 Control bar: a bar too narrow for Document Setup still shows Preferences
With nothing selected, the Preferences button was drawn only after
Document Setup, so a bar with 90 to 111 points left showed neither,
although Preferences is 90 points wide and fits. The two buttons now
check the room left for each of them on their own.
2026-11-13 19:51:02 -08:00
dotCooCoo e9ae8b9661 Merge main into fix/ai-calligraphic-samples 2026-11-13 19:50:31 -08:00
dotCooCoo f643cddec4 Dimension tool: a reflected aligned dimension has its line on the reflected side
An unlinked aligned dimension that was reflected on its own kept its
offset, which is measured along the left normal of a to b. A reflection
turns that normal to the other side, so a line 30 pt above two level
points stayed 30 pt above them after a flip top to bottom instead of
going below them. The offset now changes sign when the transform
reverses orientation, as a reflection or a scale by a negative factor
does. Other transforms leave it as before, and linked, horizontal and
vertical dimensions keep their own rules.

Docs: docs/dimensions.md.
2026-11-13 19:48:30 -08:00
bflatastic f56146635f SVG: rustfmt the SVGZ error arms
#7398 left crates/svg/src/lib.rs unformatted, so main's CI stopped at
fmt and skipped clippy and the tests.
2026-11-14 10:47:02 +07:00
dotCooCoo 2d862c1c67 i18n: French leaves the SVG filter and composite font messages to their own pull requests
Open pull requests #7211 and #7378 add French rows for these 51 messages.
Keeping them here too would make bundled_catalogs_are_consistent fail on a
duplicate row once both merge.
2026-11-13 19:43:10 -08:00
dotCooCoo 9ab8b6ce16 i18n: German translates the messages no catalog had a row for
The untranslated report listed 167 status and error messages with no
row in any complete-message catalog, and 11 more that other catalogs
translate but German did not, so with the interface in German these
messages showed in English.

- de.tsv gains 116 `@msg` rows for the listed messages: image export
  and encoding errors, color profiles, color books and swatch exchange
  files, binary DXF and DWG import, 3D and Revolve limits, and script,
  zip and file errors. They sit in one commented block after the
  existing message rows.
- de.tsv gains 10 `@msg` rows for the Banner Hems and Grommets errors
  and the failed recovery save.
- The 51 listed messages that open #7211 and #7378 translate (composite
  fonts and SVG filters), and the justification order error that open
  #7116 translates, are left out, so no row is added twice.
- Placeholders, parameter names, command ids and literal values stay as
  the English writes them. The translations use the catalog's existing
  terms and typography.
- docs/localization-parity.md and docs/target-app-parity.md give the
  German counts: 3,563 `@msg` and 48 `@msgplural` rows, 52 messages
  still listed.
2026-11-13 19:42:45 -08:00
dotCooCoo 2720aca362 Tests: the hover-notes test takes its second note from a brushed knockout group
The PDF exporter no longer warns about a plain knockout group, so the test's second note now comes from a knockout group whose soft masks would draw a brushed stroke, and the test checks for that note.
2026-11-13 19:39:30 -08:00
dotCooCoo b006f4a35f i18n: French translates the DWG and damaged binary DXF messages 2026-11-13 19:35:11 -08:00
dotCooCoo 63e9fe5acb Merge main into fix/fr-message-rows 2026-11-13 19:33:21 -08:00
dotCooCoo 7602a7a57a Merge main into fix/ai-warped-image-pieces-cropped
# Conflicts:
#	crates/eps/src/ai_editing/writer.rs
2026-11-13 19:31:11 -08:00
dotCooCoo 3d40ba6c8e Type: COLR glyphs with repeating or reflecting gradients draw as vector art
A COLRv1 linear or radial gradient whose color line repeats or reflects
made the whole glyph an image. Such a gradient now reads into a vector
gradient with the same spread. The COLR specification repeats the
interval from the first color stop to the last, so one run of the stops
spans the gradient's vector:
https://learn.microsoft.com/en-us/typography/opentype/spec/colr

A repeating or reflecting radial gradient that starts at a circle stays
an image, and so does a repeating or reflecting gradient with a stop
whose palette index is outside the palette. A color line with an extend
value the specification does not define now pads, as the specification
says, instead of making the glyph an image.
2026-11-13 19:30:58 -08:00
dotCooCoo 0d06c5b9bd Merge main into fix/control-bar-narrow-fill-stroke 2026-11-13 19:29:37 -08:00
dotCooCoo adc1826c81 Contextual Task Bar: a blank canvas offers Draw (Pencil) and Place Image
With a selection tool in use and no artwork in the document (layers and
guides only), the bar shows Draw (Pencil), which switches to the Pencil
tool, and Place Image, which picks files for the Place dialog, as the
help page lists for a new document:
https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/contextual-task-bar-overview.html

VectorCraft's own rules: the bar sits under the active artboard, or
under the canvas's center when the artboard is out of view, and leaves
out the Fill, Stroke, Recolor Artwork and Lock controls. Other tools, a
selection and a document with artwork keep their bars as before.
2026-11-13 19:27:51 -08:00
dotCooCoo 7e660eb9a7 Control bar: a bar too narrow for Opacity still shows Graphic Style
When the Opacity link and its field had no room, the Control bar also
skipped the Graphic Style check, so the narrower Style link and its chip
were left out even when they fit. The bar now leaves out only the
Opacity part and checks the room for Style on its own.
2026-11-13 19:27:13 -08:00
dotCooCoo 77686c9d17 Merge main into fix/web-open-keeps-both-link-lines 2026-11-13 19:24:46 -08:00
dotCooCoo 497796decc Merge main into fix/more-int-param-wrong-type 2026-11-13 19:24:36 -08:00
dotCooCoo c0b9eed99f Links: a web open with missing and modified links shows both lines
On the web, a document that opened with linked files it can't read and
linked files that changed on disk showed only the line about the changed
files when Update Links doesn't ask. The status bar now shows the line
about the unreadable files and lists the line about the changed files as
the first note in its hover, ahead of the open's notes. With Ask When
Modified the update question opens and the line about the unreadable
files stays, as before.
2026-11-13 19:24:07 -08:00
dotCooCoo eb9976a825 Merge main into fix/graph-label-paint-recolor 2026-11-13 19:22:11 -08:00
dotCooCoo 94db0b1ebd .ai export: a masked image copy whose mask is left out keeps all of its pixels
A copy of an image written whole already was cut to the painted bounds of
its opacity mask even when the mask was then left out, nested too deep or
past the object limit, so the file read back with a cropped image and no
mask. The copy is now cut to its mask only when the mask is written, and
otherwise written whole.

The progress-doc line now gives the measured total for the warped test
image's pieces: about 7 times the image's samples, not twice.
2026-11-13 19:20:35 -08:00
dotCooCoo e41e662aba Merge main into fix/fr-missing-message-rows 2026-11-13 19:18:15 -08:00
dotCooCoo 76c1cd8a96 Merge main into fix/live-paint-expand-drawn-stroke 2026-11-13 19:18:14 -08:00
dotCooCoo 8239ec619a i18n: French has a row for every message no catalog translated
The untranslated report listed 165 status and error messages that no
complete-message catalog translated: messages of the SVG filter and 3D
effects, the image encoders, color profiles, composite fonts, swatch
exchange files and color books. fr.tsv now has an @msg row for each, with
placeholders, parameter names and literal values as the English writes
them, and a no-break space before : ; ? ! as the catalog's header asks.
2026-11-13 19:17:30 -08:00
dotCooCoo 1f6332c0a4 Live Paint: Expand keeps the faces and edges that draw
Expand kept a face only when its topmost fill had paint, and an edge only
when its topmost stroke had paint and a weight. A face or edge drawn by a
lower row under an unpainted top row was removed, and one whose only
painted row was hidden was kept as a visible path.

Expand now keeps a face or edge when it is shown, its opacity is above 0,
and any fill or stroke row is shown, has paint and an opacity above 0 (a
stroke also a weight above 0), with all of its rows. The rows are checked
with the new Appearance::has_drawn_fill and has_drawn_stroke.

Merge carried a face's topmost fill paint by the same topmost-row test.
It now carries every row of each face that draws by this rule, and of
each edge, pins their unplaced gradients to the old outline as
repaint_from does, and leaves the strokes' pen pressure, tilt, bearing
and rotation behind, since the rebuilt parts are other paths.

Docs: livePaint.expand params text, docs/mcp.md, and a line in
docs/target-app-parity.md, which also drops a repeated Live Paint
Selection marquee line.
2026-11-13 19:17:21 -08:00
dotCooCoo 88012ed92b Merge main into fix/i18n-literal-brace-messages 2026-11-13 19:15:55 -08:00
dotCooCoo 46584e4495 Merge main into fix/3d-export-builds-once 2026-11-13 19:14:40 -08:00
Dylan M. Taylor 1e4e3534f5 Merge pull request #7398 from storytold/feat/craft-libs-migration
Migrate CAD (DXF), EPS/PostScript, and SVG to craft-libs (#778)
2026-11-13 22:14:10 -05:00
dotCooCoo ee780e672d Merge main into fix/nl-message-rows 2026-11-13 19:12:48 -08:00
dotCooCoo cc1875e3c0 Merge main into fix/actions-load-reports-unknown-commands 2026-11-13 19:11:08 -08:00
dotCooCoo 485636acf8 Merge main into fix/zh-hant-message-rows 2026-11-13 19:09:36 -08:00
dotCooCoo f383ce1475 Merge main into fix/knockout-groups-flat-masks 2026-11-13 19:09:32 -08:00
dotCooCoo 49a3c3d718 Merge main into feat/ai-art-brush-options 2026-11-13 19:09:26 -08:00
dotCooCoo b992531dcf Merge main into fix/more-int-param-wrong-type 2026-11-13 19:09:14 -08:00
dotCooCoo 531fad0532 MCP: path, type, panel, library, style and ruler indices refuse a wrong-type value
A required index given as something other than a whole number of 0 or
more, such as "3", 2.5, -1 or true, was reported as missing: `anchor` of
path.setHandle, path.moveAnchor and text.setPathHandle, `segment` of
path.insertAnchor, and `to` of artboard.reorder, library.moveGroup and
graphicStyle.move. Each now refuses it with "`anchor` must be a whole
number", naming the key; left out or null, it is still missing.

An optional `subpath` of path.appendAnchor, path.close and path.reverse
given that way was read as left out, so the command extended, closed or
reversed the default subpath (path.reverse reversed every subpath). The
`artboard` of the ruler origin commands answered "index out of range"
for such a value and for null. Both now refuse such a value with the
same message and change nothing. A null `artboard` is artboard 0, as one
left out is; a whole number past the artboards is still out of range.
2026-11-13 19:08:16 -08:00
dotCooCoo dea57b348b Dimension tool: the first preview of a drag-out is drawn at the pointer
Dragging out a dimension from a segment (Linear) or a corner (Angular)
drew its first preview frame at the wrong distance. The preview placed
the dimension at the pointer before reading the segment's end points or
the corner from the art, and measured the offset from the placeholder
points the dimension starts with. A drag from the top edge of a
rectangle to 40 pt above it showed an offset of 60 instead of -40.

The preview now clears the offset, reads the art's points, places the
dimension at the pointer and checks the result. Clearing the offset
keeps an out-of-range offset from the last pointer position from
failing the read.

Tests: the segment and corner drag-out tests fail without the change.
placement_recovers_after_a_position_out_of_range also passes on main;
it fails when only the offset clear is removed.
2026-11-13 19:08:02 -08:00
dotCooCoo 2f2fed7218 Merge main into fix/control-bar-narrow-fill-stroke 2026-11-13 19:06:54 -08:00
bflatastic 3da4c4ba13 Tests: warichu PDF check reads only text objects
warichu_is_a_character_attribute_set_saved_and_exported looked for Tj or
TJ anywhere in the exported PDF. The file ID in the trailer and the XMP is
a base64 hash that changes each second and now and then spells one of
them, so the test failed on main twice (bf3cf422e, 446bf59bc) while
export outlines warichu type every time. It now counts text-object lines
only, as the colour font PDF test already does.
2026-11-14 10:06:23 +07:00
dotCooCoo 86e085f73d Control bar: a narrow bar keeps the Transform link
With something selected, the Fill and Stroke, Opacity, Graphic Style and
Character controls now show only while the Transform link and the
separator ahead of it still have room after them, the way the Paragraph,
vertical alignment and Align groups keep the link's room. A narrow bar
leaves those controls out first and keeps the link, instead of leaving
out the link.

- The Character controls show whole or not at all. While they are left
  out, the Paragraph, vertical alignment and Align controls after them
  are left out too, so a wider bar never drops a group that a narrower
  one showed.
- The room checks for the width profile, Recolor Artwork and Global Edit
  Options count the spacing after each control.

Tests: the_control_bar_s_controls_stay_inside_the_bar_in_a_narrow_window
now also checks selected type.
2026-11-13 19:04:05 -08:00
dotCooCoo 751b50bf58 i18n: messages keep bracketed field names and accepted values in English
49 status and error messages in the Hindi, Bulgarian, Danish,
Indonesian, Dutch, Brazilian Portuguese, Swedish and Turkish catalogs
translated the field names in brackets, such as `[subpath, anchor]` or
`[start, end]`, which the parameter documentation spells in English, or
the values an `unknown` or `bad model` message lists, such as
`(points, lines)` or `(left|right|top|bottom)`. Commands match those
values against the English words, so a user who passed the translated
value got the same error again. These rows now keep the English names
and values and translate the rest of the sentence.

A new test, translated_messages_keep_the_field_names_and_values_their_english_lists,
checks every catalog for bracketed field lists, `a|b|c` value lists and
the values listed in parentheses after `unknown` and `bad model`.
2026-11-13 19:01:48 -08:00
dotCooCoo 1dc8b72bbf Type: hyphenated type lays out again when the hyphenation exceptions change
Changing Preferences › Hyphenation › Exceptions bumped each open
document's revision, but the caches of laid-out type outside the text
crate were keyed on the font generation alone. The renderer kept the
glyph geometry, raster-effect pixels, live-effect and envelope art,
pattern tiles and placed symbol art of unchanged type objects, so
hyphenated area type kept its old line breaks on the canvas. The
hit-test art of blends and envelopes, the Fit to Artwork Bounds answer,
the layout caches of the Type and Touch Type tools and the out port's
overflow mark were keyed the same way.

vectorcraft_text::layout_inputs() returns a number that changes with
the fonts and with the hyphenation exceptions. Every one of those
caches now keys on it instead of FontDb::generation(), and envelope ink
uses it in place of the private envelope_ink_inputs(). The hit-test key
hashes it together with the plug-in revision.

Tests: a renderer that drew hyphenated area type, alone, with a drop
shadow, in a group with a Transform effect, in a symbol instance and in
an envelope, draws it as a new renderer does after the exceptions
change; the out port of selected area type shows the overflow that the
new exceptions cause. The render test helpers that run a step again
when the fonts change during it now also run it again when the
exceptions change.
2026-11-13 18:56:48 -08:00
dotCooCoo 87c8def043 .ai save: a linked image with a Warp keeps its live Warp and its link
A linked image whose appearance is one Warp effect, with no opacity mask,
was saved to the .ai editing data as its drawn art, so its live Warp was
lost. It is now written with an art style of that Warp, as an embedded
image is: its bent pieces are its drawn look, and the image itself
follows on %_ lines as a placed file with its path, its folder relative
to the document's and its preview. In an opacity mask's art the copy is
embedded, with the existing warning for linked images in masks.

Opening such a file reads the image back linked, with its Warp live.
A hidden image with a Warp, embedded or linked, is now compared with its
drawn look shown, so it keeps its Warp too; before, the look drew
nothing and the image came in as its drawn pieces.
2026-11-13 18:51:03 -08:00
dotCooCoo fecf724501 Smart Guides: Parametric Shape and Slice tools snap as the drawing tools do
The Parametric Shape tool's center and the Slice tool's corners snapped
with Smart Guides to the bounds of the art only, so View › Snap to Glyph
had no effect on them, and neither did the anchors and segments of
paths that the other drawing tools snap to. The point dragged out from a
Parametric Shape's center did not snap at all, and neither tool showed
Smart Guides while hovering before a press.

Both tools now snap through the drawing tools' shared snapping
(DrawSnap). A Parametric Shape's center (from a drag or a double-click),
the point dragged out from it, and a slice's corners land on glyph
guides and on path anchors and segments. The guides show while hovering
and during the drag. When a ruler guide then takes a slice corner, the
Smart Guides are no longer shown. A click with the Parametric Shape tool
still draws nothing when its center snaps a few pixels from the pointer.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-13 18:50:03 -08:00
dotCooCoo 59084a3aab Merge main into fix/recovery-keeps-open-notes 2026-11-13 18:48:54 -08:00
dotCooCoo 01de2a14cf Recovery: restoring documents keeps their linked-file lines and warnings
After Restore in the dialog Data Recovery shows at launch, the status
bar wrote the restore count over the line about the restored document's
linked files, and the warnings each copy restored with were never shown.

The status bar now shows the count followed by the first of the
restored documents' notes: each document's lines about its linked
files, then its warnings, what reading the copy left out first, named
with the document's title when more than one was restored. Hovering
the message lists them all. The count is the number of documents
restored.

The questions about each restored document's missing or modified
linked files now come one document at a time, with that document made
the current one, so a later document's question no longer replaces an
earlier one's. When a copy can't be restored, the status bar shows the
error and its hover keeps the count and the restored documents' notes.
2026-11-13 18:47:55 -08:00
bflatastic 797fcf16db Tests: font menu tests draw until the menu stays put
egui places an Area by the size it had the frame before. When a family
name measured late (a face added for its script, a font found in the
background) widened the menu on the helper's last frame, that frame drew
it where the narrower menu fit, and a_menu_wider_than_its_field_stays_in_the_window
saw it 0.7 pt past the window's edge (three failed CI runs on 2026-11-13).
The helper now draws until the menu stops moving.
2026-11-14 09:37:35 +07:00
dotCooCoo ffd9579ccb Merge main into fix/mcp-docs-stack-file 2026-11-13 18:37:26 -08:00
dotCooCoo 0104aaeb9d Docs: script stack frames and $.fileName name the file of the code
docs/mcp.md's line and stack row said $.stack shows at most 64 lines
and uses [global] only for the script's own code. It keeps the
innermost 64 frames after a leading line "…" when some are left out,
and [global] names any code outside a function, including code that
an included file, $.evalFile or eval runs. The row now also says how
a frame's file compares with $.fileName in each case: the same file
for code from a file, the run's name where $.fileName is empty for a
script given as source, [eval] where $.fileName is the file being run,
and [unknown] at line 0 where $.fileName is empty.

The engineName row now gives the #targetengine name, and the
script.run params text, the script module doc and the Scripts evidence
line say $.fileName is the file of the code that reads it rather than
the file being run.
2026-11-13 18:36:47 -08:00
dotCooCoo a4a570323e Merge main into fix/3d-export-builds-once 2026-11-13 18:36:39 -08:00
dotCooCoo 3d9a461be5 3D: Export 3D Object builds each Extrude and Inflate solid once
Export 3D Object built every Extrude & Bevel (both kinds) and Inflate
solid twice: once for the facets that decide whether the art draws it and
count toward the object's face limit, and again for its mesh.

The solid builder now keeps the projected facets and the faces before
projection from one pass (`extrude_meshed`, `inflate_meshed`), and the
export decides and meshes each part from that one build. Where a mesh
built alone cuts Inflate's twisted sides differently (it has less room
left after keeping the faces turned away), the mesh's sides are cut with
its own room. Strokes past their limits are still left out, a fill's
error and the object's face limit still stop the export at the same
part, and the triangle budget is unchanged.

Tests compare the facets and meshes with separately built ones bit for
bit, and count one build per solid.
2026-11-13 18:35:48 -08:00