Commit Graph

2590 Commits

Author SHA1 Message Date
BFlat 6f56ad2e7f
Merge pull request #1777 from MarekSpodBiedry/issue-1713
Keep Export for Screens suffix inside the export folder (#1713)
2026-10-14 03:48:36 +07:00
BFlat b374fee789
Merge pull request #1786 from MarekSpodBiedry/issue-1696
Refuse to package over the source document or its linked files (#1696)
2026-10-14 03:47:20 +07:00
BFlat 9abdbb0a71
Merge pull request #1807 from AyberkA0/fix/1710-ruzstd-0.9.1
Fix #1710: ruzstd 0.9.1 (RUSTSEC-2026-0344)
2026-10-14 03:47:05 +07:00
bflatastic d82d6e3620 Test that a hostile Export for Screens suffix or prefix stays in the export folder (#1713) 2026-10-14 03:17:47 +07:00
BFlat 7fc8173253
Merge pull request #1684 from dotCooCoo/feat/mcp-document-reads-faster
Control: replies are buffered, so a 17 MB reply is sent in 0.09 s instead of 34 s on Windows
2026-10-14 03:08:58 +07:00
BFlat 466b4b0180
Merge pull request #1652 from marcoarnulfo/fix/canvas-cursor-wayland-scale
Cursors: paint the tool cursors on Wayland, where the compositor showed the bitmap twice too big
2026-10-14 03:08:35 +07:00
BFlat 65ec1842ac
Merge pull request #1654 from switch87/fix/1653-eps-hard-stops
EPS import: a stitched shading keeps its hard colour changes
2026-10-14 03:04:15 +07:00
BFlat ad358fb4e4
Merge pull request #1651 from switch87/fix/1648-scribble-regions
Scribble: one zig-zag per region, no lines across holes and notches
2026-10-14 03:03:54 +07:00
BFlat 0814b70fe0
Merge pull request #1646 from switch87/fix/1643-roughen-cusps
Roughen (Smooth): a turn-back stays smooth instead of becoming a cusp
2026-10-14 03:03:34 +07:00
BFlat 14df0db488
Merge pull request #1642 from marcoarnulfo/fix/shape-modes-on-group
Pathfinder panel: a group selected alone counts its nested shapes, so an expanded stroke keeps the Shape Modes enabled
2026-10-14 03:03:12 +07:00
BFlat 70937b59ba
Merge pull request #1641 from marcoarnulfo/fix/align-anchors-default-selection
Align: anchor points of one path align to each other, not to the artboard
2026-10-14 03:02:45 +07:00
dotCooCoo 7fde8739a7 Control: replies are buffered, so a 17 MB reply is sent in 0.09 s instead of 34 s on Windows
The control server wrote each reply with writeln!(out, "{r}") on the
bare TcpStream. serde_json formats a Value one piece at a time, and
each piece (a brace, a quotation mark, a key, a colon, a number) was
sent as a write of its own: the 17 MB document.inspect reply of a
document with 50,000 objects on one layer was sent in 7,857,200 writes.
On Windows 11, sending that reply to a client over loopback took 34 s,
and sending the 28 MB document.json reply took 57 s.
vectorcraft-cli mcp reads every reply from a running app over this
connection.

write_line now writes each reply, each refusal and the "too many
control connections" line through a 64 KiB BufWriter, then flushes
it. The 17 MB reply takes 262 writes. Sending it now takes 0.09 s,
and sending the 28 MB reply takes 0.2 s. The bytes are the same.

Docs: docs/target-app-parity.md.
2026-10-14 02:09:15 +07:00
Marco Arnulfo e50bd58146 Cursors: paint the tool cursors on Wayland, where the compositor showed the bitmap twice too big (fixes #1645) 2026-10-14 02:09:09 +07:00
Gert Pellin 3412d3a073 EPS import: a stitched shading keeps its hard colour changes (#1653)
A stitching function's bound became one stop, evaluated at the bound:
the right piece's colour. Where the pieces don't meet, the left piece's
end colour was lost. The colour just before the bound is now a stop at
the same offset too, ahead of the one after it, when the two differ;
continuous stitches keep one stop per bound as before.

Fixes #1653
2026-10-14 02:09:09 +07:00
Gert Pellin 85335e9e14 Scribble: one zig-zag per region, no lines across holes and notches (#1648)
The rows' spans were all chained into one polyline, so where a row had
more than one span the line ran across the hole between them, outside
the shape. A span now continues the previous row's chain whose
connecting line stays inside the shape (the nearest one); otherwise it
starts a chain of its own. In a convex shape the connector always stays
inside, so the result there is unchanged (render goldens pass).

Fixes #1648
2026-10-14 02:09:09 +07:00
Gert Pellin 977b8fb642 Roughen (Smooth): a turn-back stays smooth instead of becoming a cusp (#1643)
Roughen's jitter can put a point behind its predecessor, so the path
turns back. The Catmull-Rom tangent next - prev then shrinks to almost
nothing and the anchor becomes a cusp, which PDF viewers (MuPDF,
poppler, Ghostscript) draw with a miter spike; the preview doesn't.

catmull_rom now keeps the tangent at least half as long as the longer
chord, and where it is shorter (turns of more than about 150 degrees)
points it along the bisector of the two chords: the turn becomes a round
hairpin. Gentler turns keep the plain Catmull-Rom tangent, so Zig Zag,
Scribble and the render goldens are unchanged.

Fixes #1643
2026-10-14 02:09:08 +07:00
bflatastic f05fbfc292 Pathfinder panel: count a group's shapes without copying them 2026-10-14 02:09:08 +07:00
Marco Arnulfo 7ea75b01ba Pathfinder panel: a group selected alone counts its nested shapes, so an expanded stroke keeps the Shape Modes enabled (fixes #1635) 2026-10-14 02:09:07 +07:00
bflatastic 359d9bb833 Distribute spaces the selected anchor points too, and its buttons work with the points of one path (#1636) 2026-10-14 02:09:06 +07:00
Marco Arnulfo dcb963e85b Align: anchor points of one path align to each other, not to the artboard (fixes #1636) 2026-10-14 02:09:06 +07:00
Ayberk A. 0d28ee0872 Fix #1710: ruzstd 0.9.1 (RUSTSEC-2026-0344)
0.9.1 enforces the decompressed size of each block, which 0.9.0 didn't
(memory exhaustion on crafted .ai / Affinity zstd data). The manifests now ask
for at least 0.9.1.
2026-10-13 21:14:00 +03:00
MarekSpodBiedry b50519587d Refuse to package over the source document or its linked files (#1696) 2026-10-13 18:19:12 +02:00
MarekSpodBiedry a5186f5a12 Keep Export for Screens suffix inside the export folder (#1713) 2026-10-13 18:16:12 +02:00
BFlat 0d0ea352df
Merge pull request #1659 from storytold/fix/1597-guide-position
Fix #1597: the Transform panel shows and sets a selected ruler guide's X or Y
2026-10-13 14:05:51 +07:00
BFlat 206e81c3b7
Merge pull request #1658 from storytold/fix/1602-intersect-snap
Fix #1602: drawn points snap to where paths and guides intersect
2026-10-13 14:05:06 +07:00
BFlat 24afe0f517
Merge pull request #1608 from dotCooCoo/feat/script-checker
Scripts: Check Script… reports what a .jsx script needs and does, without running it
2026-10-13 14:03:59 +07:00
BFlat ec67ed9646
Merge pull request #1603 from switch87/feat/1601-inkscape-pages
SVG import: Inkscape's pages become artboards
2026-10-13 14:03:38 +07:00
BFlat ce558ffb73
Merge pull request #1599 from switch87/fix/1598-filter-warning
SVG import: an unsupported filter's warning names the filter and the object
2026-10-13 14:03:18 +07:00
BFlat cbe7f83881
Merge pull request #1606 from switch87/fix/1604-relative-open-path
Open by a relative path finds relative links; convert reports import warnings
2026-10-13 14:03:03 +07:00
BFlat feb319027e
Merge pull request #1611 from switch87/feat/1607-more-opentype-features
Type: stylistic sets, alternates, titling, figure styles, superscript and subscript
2026-10-13 14:02:51 +07:00
BFlat 69e77570b4
Merge pull request #1657 from storytold/u/trace-logo-scans
Image Trace: Flat Logo takes the tones of an unevenly lit colour for one colour
2026-10-13 13:58:19 +07:00
BFlat 4159ffe6fd
Merge pull request #1647 from storytold/u/trace-level-bound
Image Trace: levelling moves no end of a line by more than 1.6 px
2026-10-13 13:57:40 +07:00
bflatastic 51e7044b0e Fix #1597: the Transform panel shows and sets a selected ruler guide's X or Y
With only ruler guides selected, X is the position of the vertical ones and Y
that of the horizontal ones; typing a value moves them (guide.move), together
when several are selected.
2026-10-13 13:36:41 +07:00
bflatastic dae13d57f0 Fix #1602: drawn points snap to where paths and guides intersect
A point placed by the Pen, the shape tools and the other drawing tools, and a
dragged anchor, lands where two paths cross, where a path crosses a ruler guide
and where two ruler guides cross, with the Smart Guides label "intersect".
2026-10-13 13:36:41 +07:00
dotCooCoo 3374d0778d Scripts: Check Script… reports what a .jsx script needs and does, without running it
VectorCraft does not run scripts written for the reference app, and
File › Scripts held only the disabled Other Script…. File › Scripts ›
Check Script… picks a .jsx, .jsxinc or .jsxbin file, reads it without
running any of it, and shows a report: what the script needs (the
script language's own objects, the document model, files, menu
commands, dialogs, or features only the reference app has), what it
would do outside the document, the menu-command strings it passes, the
document-model member chains and type names it uses, its directives,
the files it includes, and the problems that would stop it loading.
Copy Report copies the report as JSON. File › Open and drag-and-drop
show the report for those files too.

- vectorcraft-scriptcheck, a new Standalone crate with no
  dependencies, holds the checker: a lexer for ECMAScript 3 with E4X
  literals and the #name and //@name directive lines, and an analysis
  of the tokens that follows variables, function scopes and the files
  a script includes. It never recurses: open brackets, the levels of
  an XML literal and the function bodies being read are kept on stacks
  capped at 4,096. It reads at most 8 MiB of a file and 32 MiB with the
  included files, follows 64 included files 16 deep, looks up at most
  1,024 paths for them, keeps 1,000 entries in a list, tracks 1,000
  variables holding member chains and 1,000 holding File objects, and
  cuts echoed text to 120 characters. A compiled script is reported as
  compiled and isn't read.
- script.check (engine, a query) takes path, data or dataBase64. With a
  path and includes: true, it reads the files the #include lines name
  from inside the script's folder, through the automation read root,
  and when the script or one of those files assigns a member chain or a
  File object to a variable, the check treats the variable as holding
  it in every file. It doesn't follow absolute names, names, folders or
  links that lead out of the folder, names or folders longer than 4,096
  bytes, or JSINCLUDE, and it reads only regular files.
- ui.checkScript shows the report (dialog scriptCheck). File › Open
  lists Scripts (.jsx, .jsxinc, .jsxbin) and sends a script's path to
  script.check, which reads at most 8 MiB of it.

The language rules come from ECMA-262 3rd edition and ECMA-357 2nd
edition. The directive, platform and document-model root names come
from the public JavaScript Tools Guide and scripting guide pages that
catalog.rs cites by URL, and executeMenuCommand, doScript, loadAction,
unloadAction and selectTool come from the public forum posts cited
there; only names are used. Every script in the tests is written from
scratch with invented names.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-13 13:36:41 +07:00
bflatastic 04bb6d6f27 SVG import: an Inkscape page whose box can't be placed is skipped 2026-10-13 13:36:41 +07:00
Gert Pellin ef0ab7ba9d SVG import: Inkscape's pages become artboards
Inkscape 1.2+ saves a multi-page document as <inkscape:page> elements
in its <sodipodi:namedview>; VectorCraft opened it with one artboard
the size of the root, leaving the other pages' art outside any. Each
page with a size now becomes an artboard at its place (through the
viewBox, as the art is), named by its inkscape:label or "Artboard N".
Files without pages keep their one artboard.

Fixes #1601
2026-10-13 13:36:41 +07:00
Gert Pellin 546c81624a SVG import: an unsupported filter's warning names the filter and the object
A filter that can't become a live effect warned "filter on a group
ignored", even on a plain <rect>: usvg wraps every filtered element in
a group of its own, which the message named. The warning now names the
filter and its primitives and the element (by id, or "an object"), and
says it is drawn without it: "filter 'f' (feColorMatrix) on an object
isn't supported; drawn without it".

Fixes #1598
2026-10-13 13:36:40 +07:00
Gert Pellin 13bd24ba79 Open by a relative path finds relative links; convert reports import warnings
document.open (and file.newFromTemplate) with a path relative to the
working directory took the SVG's folder from Path::parent(), which is
"" for a bare file name and was then dropped, so relatively linked
images were "not found" (and, linked by their bare name, not listed in
missingLinks either). A relative path is now made absolute first: its
folder is the working directory, as for the absolute path.

vectorcraft-cli convert printed only the export's warnings; what reading
the input left out now comes as importWarnings.

Fixes #1604
2026-10-13 13:36:40 +07:00
Gert Pellin eb25a85d90 Type: stylistic sets, alternates, titling, figure styles, superscript and subscript
A character style's OpenType features took nine tags. OtFeatures now
also keeps ss01-ss20, salt, titl, pnum, lnum, sups and subs (off by
default, one bit each in `extra`): they are accepted by the type
commands, stored with the style and passed to the shaper, so a font
that has them uses them.

The Affinity import test used ss01 as its example of a feature kept but
not rendered; it now uses cv01 for that (character variants still
aren't rendered) and keeps ss01 as one that is.

Fixes #1607
2026-10-13 13:36:40 +07:00
BFlat 504e719230
Merge pull request #1650 from storytold/fix/1616-flyout-width
Fix #1616: a tool flyout is as wide as its longest translated row
2026-10-13 13:30:10 +07:00
BFlat d443cb031c
Merge pull request #1649 from storytold/fix/1620-save-fallback
Part of #1620: a save falls back when a folder refuses the temporary file or the rename
2026-10-13 13:29:57 +07:00
BFlat 41afc9f3e5
Merge pull request #1614 from lewandowskit/i18n-polish-review
i18n(pl): confirm the maintainer-added Polish rows
2026-10-13 13:28:33 +07:00
BFlat 4d62e0d0ef
Merge pull request #1622 from dotCooCoo/feat/lock-hide-above-linear
Object: Lock and Hide › All Artwork Above go through each top-level layer once
2026-10-13 13:28:09 +07:00
BFlat 1d1e28a51f
Merge pull request #1621 from dotCooCoo/feat/pattern-tiles-per-scale
Render: pattern tiles at different scales are kept between frames
2026-10-13 13:27:53 +07:00
BFlat f870f3ac09
Merge pull request #1617 from marcoarnulfo/fix/area-type-narrow-top-lines
Area type: a word too wide for the top lines of a shape moves down instead of breaking
2026-10-13 13:27:27 +07:00
BFlat 67dcfd4fc4
Merge pull request #1619 from marcoarnulfo/fix/ai-zero-length-dots
Strokes: a zero-length subpath draws its round or projecting cap as a dot
2026-10-13 13:27:11 +07:00
BFlat 972945f80d
Merge pull request #1625 from marcoarnulfo/fix/smb-save-fsync
Save: a network drive on macOS that refuses the full flush gets a plain fsync
2026-10-13 13:26:55 +07:00
bflatastic 62036eac6c Image Trace: Flat Logo takes the tones of an unevenly lit colour for one colour
A scan's paper is a tenth darker in one corner than in another. Flat Logo found
each tone of it as a colour of its own and traced the bands and the specks
between them: on the scanned inputs 470 paths, 21 px from the art on average.

Two palette colours are now one when the pixels between them are no fewer than
a third of those at the lesser of the two: flat colours leave only their shared
edge between them, tones of one colour fill the gap. Whether the image is flat
art at all is still asked of the tones as found.

Flat Logo on its inputs, all sizes and variants: 3.106 -> 0.090 px off on
average, 88.5 -> 0.82 px at most, 69.9 -> 3.9 paths; clean, aliased, blurred
and noisy art as before.
2026-10-13 13:01:01 +07:00
bflatastic c49fb30032 Fix #1616: a tool flyout is as wide as its longest translated row
A flyout's rows were 250 pt wide whatever they held, so in Spanish (and
other languages with long tool names) a name ran into its shortcut. The
rows are now as wide as the longest name and shortcut need, and never
narrower than before.
2026-10-13 12:58:05 +07:00