Commit Graph
4150 Commits
Author SHA1 Message Date
bflatastic 3033fb9985 i18n: Move Anchor Point, the label of path.moveAnchor, in every catalog that has its sibling labels (#3095) 2026-10-19 23:14:09 +07:00
bflatastic 7e1095f9b1 Tests: the Type arrow tests drop their debug prints (#3004) 2026-10-19 23:14:09 +07:00
BFlat f378c5c836 Merge pull request #3042 from KnottyDyes/squad/place-pdf-keeps-text
PDF: placed and pasted pages keep live text
2026-10-19 23:13:58 +07:00
BFlat 55acd88d42 Merge pull request #3001 from ariymarkowitz/claude/changes
#2558: a drag over a wide blur draws it from the still frame's raster
2026-10-19 23:13:46 +07:00
BFlat 319221c087 Merge pull request #3102 from dotCooCoo/fix/effect-art-follows-fonts-and-color-settings
Effects: effect art redraws when fonts arrive or the color settings change
2026-10-19 23:13:31 +07:00
BFlat 9d43326ad7 Merge pull request #3095 from sungjea713/anchor-point-shift-moves-anchor
Anchor Point tool: Shift-drag on an anchor moves it, handles and all
2026-10-19 23:13:12 +07:00
BFlat 8baf5b1343 Merge pull request #3004 from sanyamsingh001/codex/r82-type-grapheme-boundaries
Keep Type arrows on grapheme boundaries in mixed-direction text
2026-10-19 23:12:59 +07:00
BFlat a60f8d7b9f Merge pull request #3120 from Janiz-zzz/fi-update-20261019
i18n(fi): translate 67 labels added since the Finnish review
2026-10-19 23:12:41 +07:00
BFlat 2c52bed0b5 Merge pull request #2961 from Hamza0101/encrypted-pdf-note
Exports: say that an encrypted PDF still differs, and test the clock fallback
2026-10-19 23:12:28 +07:00
BFlat de3dd27fda Merge pull request #2988 from 00xJS/fix/2675-pdf-invisible-text
PDF import: say when invisible text is left out (part of #2675)
2026-10-19 23:12:13 +07:00
BFlat 575bd0f924 Merge pull request #3006 from rotohun/fix/ai-hyphenation-tab-operators
eps: read Illustrator text with hyphenation and tab attributes
2026-10-19 23:11:54 +07:00
BFlat 1ef66c48c1 Merge pull request #2969 from dotCooCoo/fix/data-sets-file-dialogs-off-ui-thread
Variables: Import and Export Data Sets… show file dialogs on macOS and keep the window running
2026-10-19 23:11:36 +07:00
BFlat 35b5895183 Merge pull request #2964 from dotCooCoo/fix/pdfinfo-thumbnail-page
MCP: document.pdfInfo refuses a thumbnail that is not a page number
2026-10-19 23:11:22 +07:00
BFlat 0bd2a40128 Merge pull request #3074 from Silvertree2010/fix/3036-objects-as-guides-blocks-group-d
Stop locked guide objects from blocking marquee selection
2026-10-19 23:11:05 +07:00
BFlat 605597b09c Merge pull request #2968 from Silvertree2010/fix/h2813-deleting-an-anchor-from-a-closed
Clear dangling handles when deleting anchors from a closed path
2026-10-19 23:10:47 +07:00
BFlat 646563b033 Merge pull request #3115 from Silvertree2010/fix/h550-polygon-covers-rect-treats-a-sel
Reject self-intersecting polygons in polygon_covers_rect
2026-10-19 23:10:35 +07:00
BFlat 2861c113d6 Merge pull request #2821 from dotCooCoo/feat/linux-desktop-ai-eps-types
Linux: file managers offer VectorCraft for .ai, EPS and every other format Finder offers it for
2026-10-19 22:40:08 +07:00
KnottyDyes 48a0206adb PDF: placed and pasted pages keep live text
Honor the requested text mode in the single-page importer, as Open does, instead of forcing outlines for Place and PDF clipboard import.

Add synthetic regressions for bytes, unlinked paths, selected pages and explicit outlines. Update format parity and milestone evidence without changing scores.
2026-10-19 22:19:59 +07:00
Ari MarkowitzandClaude Opus 5.5 1fc3c23096 #2558: the coarser glow test also pans by fractions of a pixel
For review: after pans of (0.5, 0) and (37.3, -21.6), the Outer Glow
made coarser over its whole reach (scale 2 and 3) is still drawn from
the kept raster, placed at the nearest whole pixel as a full-size
raster kept whole is, and each frame equals a fresh renderer's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:57 +07:00
Ari MarkowitzandClaude Opus 5.5 7dc0c034d8 #2558: a coarser glow kept whole draws after a pan as made again
A test for review: an Outer Glow made coarser over its whole reach is
kept for any pan, since its grid starts at the reach's first whole
device pixel, which a whole-pixel pan moves with the art. After pans
that aren't multiples of its scale (2 and 3), the kept raster draws
exactly what a fresh renderer draws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:57 +07:00
Ari MarkowitzandClaude Opus 5.5 be7fd07562 #2558: a drag over a wide blur draws it from the still frame's raster
An effect raster too large to keep whole (a wide blur, a shadow or glow,
or any blur zoomed in) is cropped to what can show in the view, or made
at a lower resolution and resampled to the view's pixels, and kept while
the view stays the same. Dragging other art over the object then draws
its effects from the still frame instead of previewing them at the
drag's lower resolution on every frame. An interaction's frames stay on
the render worker once it drew the frame shown, since only its renderer
holds those rasters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:57 +07:00
dotCooCoo 007f536c79 Effects: effect art redraws when fonts arrive or the color settings change
The renderer kept the art it made for an object's effects while the
object stayed the same. In the web build, type that a geometry effect
outlines, on its own, in a group or in a symbol's art, kept the
substitute font's outlines after its own font loaded. On the desktop,
Refresh Font List left them on a symbol instance whose art holds the
type. Objects with Revolve, Extrude & Bevel, Inflate or Rotate, and
objects and groups with a color adjustment, kept the colors they were
shaded or recolored with after the color settings changed. Live objects
already followed both.

The renderer now keeps that art with the inputs it keeps for the art
of live objects: the font generation when the art holds type, the art
of the symbols it shows, and the color settings. A temporary release
test timed the added key at 11 microseconds a frame for 400 type
objects with a drop shadow and 0.77 ms for 400 symbol instances of 100
paths each with a drop shadow, against warm frames of 5.3 and 72 ms.

Docs: docs/target-app-parity.md, docs/gaps.md.
2026-10-19 22:19:55 +07:00
sungjea kimandClaude Opus 5.5 515569470c Anchor Point tool: Shift-drag on an anchor moves it, handles and all
With the Anchor Point tool, a drag from an anchor pulls out smooth handles.
Shift held at the press now moves the anchor instead, its handles keeping
their offsets; Shift kept down during the drag keeps the move at 45° steps
(the constrain angle), released it frees it. A Shift-click that doesn't
move leaves the anchor as it was. A selected blend's spine points follow
the same rule (object.blend.spine.moveAnchor).

The move goes through a new engine command, path.moveAnchor
{id, subpath?, anchor, x, y}, since path.moveAnchors only acts on the
direct-selected anchors and the Anchor Point tool keeps no anchor selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:53 +07:00
sanyamsingh001andCodex c07945b934 fix: keep wrapped Type fallback on grapheme boundaries
Co-authored-by: Codex <noreply@openai.com>
2026-10-19 22:19:53 +07:00
sanyamsingh001andCodex de4c6b1a6d fix: keep Type arrows on grapheme boundaries
Co-authored-by: Codex <noreply@openai.com>
2026-10-19 22:19:53 +07:00
Janiz-zzzandClaude Opus 5.5 ecaae7ee46 i18n(fi): translate 67 labels added since a466625c
Finnish rows for the labels the other catalogs gained since the Finnish
review merge: dimension tool modes and prompts, image trace blur modes,
the swatch library colour names (swatch context), batch action options
and two status messages. Workspace and perspective preset names stay in
English (MENU_KEEP_AS_IS), as in the other complete catalogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:52 +07:00
Hamza 7bc7025a62 Exports: say that an encrypted PDF still differs, and test the fallback
Two review points on #2880.

The reproducibility claim needed qualifying. PDF encryption draws its AES
initialisation vectors and the file `/ID` from a random seed, which
`SOURCE_DATE_EPOCH` deliberately does not reach, so a PDF exported with a
password never repeats however the variable is set. The docs and the ROADMAP
line say so now.

The byte-identity test passes an explicit `created`, so it never exercised the
clock-or-variable fallback. `pinned_or` takes the environment and the clock as
arguments, and the new test shows the variable is preferred, that a blank,
negative or non-numeric value leaves it to the clock, and that a host with
neither has no date to record. The environment is injected rather than set: a
test that changes this process's environment is `unsafe` under edition 2024 and
would reach every other test running beside it, which is why `cursor_theme`
takes a lookup closure too.
2026-10-19 22:19:51 +07:00
00xJ0 8d123b19ca Test: check which text the PDF import keeps beside invisible text (#2675 review)
The visible line's text comes in as type and the invisible line's doesn't; as type or outlines,
all the art kept lies on the visible line's baseline, none on the invisible one's.
2026-10-19 22:19:50 +07:00
00xJ0 4aa4b0e70b PDF import: say when invisible text is left out (part of #2675)
Text in rendering mode 3 (invisible: a scanned page's searchable OCR layer) was dropped with no
warning, so a scanned PDF opened and saved again lost its searchable text without a hint. The
import now reports INVISIBLE_TEXT_NOTE when it leaves such text out, for type and outlines alike.

Keeping the text needs a kind of type that is kept but not drawn, and the PDF writer (krilla, in
craft-libs) to write it with `3 Tr`; its text API has fill, stroke and fill-and-stroke only.
2026-10-19 22:19:50 +07:00
Ronald Hunter 4614c08476 eps: read Illustrator text with hyphenation and tab attributes
Illustrator 6/8 EPS files whose PostScript can't be run (the Adobe_level2_AI5
procset is provided by the RIP, not embedded) are read through their private
layer data instead. That reader aborted the whole file when a text object
carried the hyphenation/tab-ruler operators `Th` (hyphen control), `XL`
(hyphenation language) and `Xb`/`XB` (a tab definition, with `Xe` descriptions
between them), reporting them as operators it doesn't know.

These carry no geometry, so drop them like the sibling type attributes the
reader already discards (§22 of the Illustrator File Format Specification)
rather than failing the import.
2026-10-19 22:19:49 +07:00
dotCooCoo 2ecc488111 Variables: Import and Export Data Sets… show file dialogs on macOS and keep the window running
The Variables panel menu called import_datasets and export_datasets
directly, so their file dialogs were asked for outside an entry and
shown in line. macOS shows no dialog in line, so the two items did
nothing there. On Linux the dialog held the window until it closed.

Both items now go through picks::button, as the Libraries panel
menu's Import Library… and Export Library… do. When the dialog
answers, the item runs again with the picked path. Errors still go
to the status bar.

variables_panel_data_sets_ask_off_the_ui_thread clicks both items
with dialogs shown as sheets, as on macOS, imports a CSV and exports the
data sets to the path the dialog answers.
2026-10-19 22:19:47 +07:00
dotCooCoo 6ed171c1b4 MCP: document.pdfInfo refuses a thumbnail that is not a page number
document.pdfInfo read thumbnail with as_u64, so a value such as -1,
1.5, "1" or true gave a reply without a thumbnail and no error. This
happened for a PDF and for a PostScript file.

A thumbnail that is present and not null must now be a whole number
from 1 to the page count. Any other value is the existing "thumbnail:
no page {n} (the PDF has {count})" error, or "(the file has 1)" for
PostScript, with the value as given. An absent or null thumbnail still
gives no thumbnail.
2026-10-19 22:19:44 +07:00
NetterSilverandClaude Haiku 5.5 3eed3be8e6 Stop locked guide objects from blocking marquee selection
Fixes #3036

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 22:19:42 +07:00
NetterSilverandClaude Haiku 5.5 85af04a83a Clear dangling handles when deleting anchors from a closed path
Found while testing crates/engine/src/cmd/path.rs:632 (without_anchors, closed-path branch uses keep instead of open_run)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:19:39 +07:00
NetterSilverandClaude Haiku 5.5 bdd5470dcf Reject self-intersecting polygons in polygon_covers_rect
Found while testing crates/geom/src/hit.rs:12-48

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-19 22:19:37 +07:00
dotCooCoo 157679c1a8 Linux: file managers offer VectorCraft for .ai, EPS and every other format Finder offers it for
Squashed from #2821 (its merges of main dropped).
2026-10-19 22:08:38 +07:00
BFlat 320bffb8ad Merge pull request #3066 from dotCooCoo/feat/objects-on-path
Objects on Path: attach objects to a path and spread them along it
2026-10-19 22:07:42 +07:00
BFlat 3d23fc5175 Merge pull request #3052 from dotCooCoo/feat/live-paint-selection-options
Live Paint: Live Paint Selection Tool Options set what a click selects and the highlight
2026-10-19 22:07:12 +07:00
BFlat 8c6085beca Merge pull request #3033 from dotCooCoo/feat/layers-locate-selection-option
Layers: with Locate Selected Objects on, the panel shows the row of art selected on the canvas
2026-10-19 22:06:38 +07:00
BFlat 6cb075b926 Merge pull request #3039 from dotCooCoo/feat/tabs-snap-to-unit
Tabs: Snap to Unit, or Shift held, puts a tab stop on the ruler's nearest tick
2026-10-19 22:06:23 +07:00
BFlat 0f27503f5b Merge pull request #3049 from dotCooCoo/fix/3d-strokes-outlined
3D and Materials: Extrude & Bevel and Inflate build a solid from each stroke's outline
2026-10-19 22:06:10 +07:00
BFlat 92ca32e55d Merge pull request #3048 from dotCooCoo/feat/data-set-applies-nothing-message
Variables: a data set with no value for any bound variable shows a status message
2026-10-19 22:05:53 +07:00
BFlat 37ee8bee3c Merge pull request #3040 from dotCooCoo/fix/hover-highlight-snap-to-grid
Smart Guides: object highlighting stays off with Snap to Grid or Pixel Preview
2026-10-19 22:05:36 +07:00
dotCooCoo 219253f163 Objects on Path: attach objects to a path and spread them along it
VectorCraft had no Objects on Path. A click with the Objects on Path
tool attaches the selected objects to the path clicked. The tool is in
Edit Toolbar's Modify section and the Blend tool's flyout, and Object ›
Objects on Path › Attach and the context menu with two or more objects
selected choose it. The objects and the path go into an Objects on
Path group with the path at its bottom.

- object.objectsOnPath.attach orders the objects column by column from
  left to right and top to bottom in each column. The first one sits
  on the path's first anchor, the last one sits on the end of an open
  path, and the rest are spread evenly by length; a closed path takes
  them all the way round. Each object's attachment point (Pivot, one
  of nine, default the center of its bounds without strokes) sits on
  the path, and the object is turned to the path there. An object that
  was rotated by an angle other than a multiple of 90° is first turned
  to the nearest multiple of 90°. Rotate tilts every object by that
  many degrees counter-clockwise. Symbol instances are measured by
  their art. Guides, compound paths, type, paths without length and
  graphs are refused with a reason.
- After every edit the objects go back on the path: editing the path
  moves them, an object moved on its own goes back, and objects moved
  into or out of the group in the Layers panel join the end of the
  path or leave it. Scaling, shearing or reflecting the whole group
  keeps each object's scale, shear or reflection, and the objects are
  spread evenly along the transformed path again. Undo takes the path
  and the objects back in one step, and a copied group stays live on
  its own path.
- object.objectsOnPath.options changes Pivot and Rotate, and
  object.objectsOnPath.expand leaves a plain group. Both act on the
  groups that `ids` names, or on the groups of the selection when
  `ids` is not given.
- The native file keeps the group live; SVG, PDF and the other exports
  write plain art. The tool highlights the path under the pointer, has
  a cursor entry, and Escape during a press cancels the click.

Part of #2545

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-19 21:51:32 +07:00
dotCooCoo e6c8ce1759 Live Paint: Live Paint Selection Tool Options set what a click selects and the highlight
Double-clicking the Live Paint Selection tool did nothing, and the tool
always selected faces and edges and highlighted them in red at 4 px.
It now opens Live Paint Selection Tool Options with Select Fills,
Select Strokes, Color and Width, the options the reference app's help
page on selecting objects lists.

- With Select Fills off, a click selects the edge nearest the pointer,
  as Alt-click does. With Select Strokes off, Alt-click selects the
  face under the pointer, as a click does. With both off, a click
  selects no face or edge.
- Color (a layer color or a custom color) and Width (1 to 20 px) set
  the highlight on the face or edge under the pointer.
- The defaults are the earlier behavior: both selections on, red
  (#ff2a2a) and 4 px. The options are tool options (tool.setOption
  {tool: "livePaintSelection"}): they last across tool switches and
  are saved with the preferences.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-19 21:51:31 +07:00
dotCooCoo e1761eb489 Layers: the panel options command describes when Locate Selected Objects opens nothing
The params text of ui.layersPanelOptions and the doc comment on
PanelOptions::locate_selected said that, with the option on, the panel
opens the rows around any object selected outside it and scrolls to its
row. When Show Layers Only, a search or the filter leaves the object
without a row, the panel opens no rows for it and scrolls as with the
option off. Both texts now describe that case, as docs/mcp.md does.
2026-10-19 21:51:29 +07:00
dotCooCoo 7f01abd687 Layers: Locate Selected Objects skips a selection recalled from the panel menu
With Locate Selected Objects on, choosing a saved selection in the panel
menu's Save Selection submenu opened the rows around the recalled object
and scrolled to it. A selection changed with the panel's own menu is not
located, and the submenu's recall now follows that rule as the other
panel menu items do.
2026-10-19 21:51:29 +07:00
dotCooCoo 729582dc78 Layers: Locate Selected Objects opens nothing for an object the panel does not list
With Locate Selected Objects on, an object selected on the canvas had the
layers and groups around it opened even when Show Layers Only, a search or
the filter left it without a row. The panel did not scroll to it, but the
rows stayed open, so they showed once the panel listed every row again.

The panel now opens the rows around the object only when the object has a
row once they are open. Otherwise it opens nothing and scrolls as with the
option off. The Layers panel entries in docs/mcp.md and
docs/target-app-parity.md describe this.
2026-10-19 21:51:29 +07:00
dotCooCoo 7c64ecd998 Layers: with Locate Selected Objects on, the panel shows the row of art selected on the canvas
By default the Layers panel opens the layers around a row and scrolls
the row into view when its highlighted rows change, for example after
a click in the panel, a new layer or Locate Object. When no row is
highlighted and a selection makes another layer or sublayer the
active one, the panel does the same for that layer's row. Selecting
art on the canvas or by a command highlights no row, so by default
the panel does not open the layer or sublayer that holds the art or
the groups around it, and does not scroll to the art's row.

Panel Options gets Locate Selected Objects, off by default and kept
with the UI state. With it on, when the last selected object changes
on the canvas or by a command, the panel opens the layers and groups
around it and scrolls to its row, as after Locate Object, but does not
highlight the row. When the selection also changes the active layer,
the panel scrolls to the object's row instead of the layer's row.
When Show Layers Only, a search or the filter leaves the object
without a row, the panel scrolls as it does with the option off. A change made with the panel's own
rows, buttons or menu is not located, and a change made during a drag
is located when the drag ends. Locate Object is unchanged.

On a layer of 5,000 groups of 10 paths with every row open, the first
panel frame after a selection change took a median of 1.6 ms with the
option on and took a median of 1.4 ms with it off, in a release build.

Docs: docs/mcp.md (locateSelected), docs/target-app-parity.md.
2026-10-19 21:51:29 +07:00
dotCooCoo 55f98095f3 Tabs: Snap to Unit, or Shift held, puts a tab stop on the ruler's nearest tick
A tab stop placed or dragged on the Tabs panel's ruler always landed
at a fractional position, and the ruler was numbered in inches with a
tick every 18 pt whatever the document's units. The reference app
snaps stops to the ruler units with Snap To Unit in the panel menu or
with Shift held during a drag, and numbers its tab ruler in the
document's units.

The ruler is now numbered in the General unit with the canvas rulers'
label step at the ruler's scale, and has a tick every tenth of a step.
The panel menu has Snap to Unit, checked while it is on. With it on,
or with Shift held, a stop placed by a click or dragged on the ruler
lands on the nearest tick, through Unit::snap_to_ruler_tick as a
Shift-dragged ruler guide does. A snapped click that lands on an
existing stop's tick selects that stop and records no undo step. The
stops still change through text.tabs.set. The reference app's page
names Shift for a drag only; Shift also snapping a click, and a
snapped click onto a stop's tick selecting that stop, are VectorCraft's
own rules.

Docs: docs/target-app-parity.md.
2026-10-19 21:51:27 +07:00