Commit Graph

2163 Commits

Author SHA1 Message Date
BFlat 62e6603c30
Merge pull request #1320 from rollroyces/fix/vectorcraft-1299-dxf-closed-spline-bit
fix(cad): set the closed bit on DXF SPLINE entities so closed curves import into CAM (#1299)
2026-10-12 08:53:50 +07:00
Royce 851edd530f fix(cad): set the closed bit on DXF SPLINE entities so closed curves import into CAM (#1299)
A subpath that geometrically closes (e.g. an ellipse outline) was always emitted
with SPLINE group 70 = 8 (planar only). Autodesk's DXF reference defines bit 0
of group 70 as 'closed', and CAM software such as VCarve relies on it to treat
the cut as a pocket or profile rather than asking the operator to join endpoints.

Now `self.e.int(70, if sub.closed { 8 | 1 } else { 8 })`.

Test: extend lines_are_lwpolylines_curves_splines_and_fills_hatches to assert
the existing closed ellipse's SPLINE group 70 is '9' (1 closed + 8 planar).
2026-10-12 08:53:36 +07:00
BFlat 9792ecd6e8
Merge pull request #1321 from dylanmtaylor/fix/ci-node-20-deprecation
ci: upgrade actions to Node 24 to fix deprecation warnings
2026-10-12 08:47:54 +07:00
BFlat f0e1de92be
Merge pull request #1316 from dotCooCoo/feat/no-op-undo-type-runs
Type: Change Case, Smart Punctuation and other commands that change nothing record no undo step
2026-10-12 08:45:34 +07:00
dotCooCoo a24269eb15 Type: Change Case, Smart Punctuation and other commands that change nothing record no undo step
These commands edited the document even when nothing changed, so the
call recorded an undo step, emptied Redo and marked the document
modified:

- Change Case to the case the text has, Smart Punctuation on type with
  nothing left to change or on a selection with no type in it, and
  Find and Replace when every match is replaced with the text it is.
  All three rewrite the text runs through edit_runs, which now edits
  only when a run changes.
- Convert To Area Type with no point type among the objects, and
  Convert To Point Type with no area type among them.
- Type on a Path Options given the values the type has, without Flip:
  OK in the dialog with nothing changed, or a Type on a Path effect
  the type has.
- Fill with Placeholder Text on type that holds its placeholder text
  already.
- type.insert with an empty text on type that ends with a run of
  text.

These commands now return without editing the document. The replies
have the same form as before. A call that changes something still
records one undo step.

One line in the evidence list of docs/target-app-parity.md names every
command above except type.insert.
2026-10-12 08:45:22 +07:00
BFlat 256cd1f85a
Merge pull request #1315 from fabian-co/pr/trace-oversized-image
Image Trace: an image over 64 megapixels is traced scaled down
2026-10-12 08:45:12 +07:00
Dylan M. Taylor c28a9b5dd2
ci: upgrade actions to Node 24 to fix deprecation warnings 2026-10-11 21:42:27 -04:00
bflatastic ae5fa87d9d Image Trace: an oversized image decodes within the allocation its 192 megapixel limit needs (512 MB on the web) 2026-10-12 08:23:19 +07:00
Fabian Grajales e1fe2e388b Image Trace: an image over 64 megapixels is traced scaled down
An image larger than the tracer's 64 megapixels was refused. It is now
decoded and box-filtered down to the largest size of its aspect within
64 megapixels, and the traced paths are mapped back to the image's own
size. Images over 192 megapixels are still refused from their header,
before decoding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XbTizgRsDpFPjtBgZAvfrZ
2026-10-12 08:22:39 +07:00
BFlat 6aa2b9b0fb
Merge pull request #1313 from itrycodinganditsbad/fix-1274
Snap to Point: drag a selection by the anchor pressed near (#1274)
2026-10-12 08:20:33 +07:00
BFlat 9d8d6062e7
Merge pull request #1311 from dotCooCoo/feat/eps-closepath-unbounded-path
EPS: closepath no longer grows the path past its limit
2026-10-12 08:19:43 +07:00
dotCooCoo db8b9bb04c EPS: closepath no longer grows the path past its limit
moveto, lineto and curveto check that the current path holds fewer
than 1,048,576 elements before they add one, and they stop the reading
with "a path has too many points" when it is full. closepath added its
element without that check. In an encoded user path, a byte of 255
runs the next operator 223 times. vectorcraft-cli info on a 622-byte
file with one uappend that runs closepath 11,150,000 times peaked at a
memory footprint of 601.9 MiB and reported "the file draws nothing".
The string operator makes strings of up to 4 MiB, and one uappend of
an operator string that long would add about 468 million elements of
56 bytes, about 24 GiB.

closepath now makes the same check before it adds its element, in the
closepath operator and in the ClosePath arm of append_user. On the
file above, the reading now stops with "a path has too many points",
and vectorcraft-cli info peaks at 62.0 MiB. A path below the limit
closes as before.

Tests: a moveto followed by 1,100,000 closepaths, and a uappend that
runs closepath 1,059,250 times, are each read between two squares.
Each reading stops with "a path has too many points" and keeps only
the first square.
2026-10-12 08:19:31 +07:00
BFlat c117bc6e8a
Merge pull request #1309 from dotCooCoo/feat/artboard-tool-active-artboard
Artboards: the Artboard tool starts on the active artboard
2026-10-12 08:19:25 +07:00
dotCooCoo f8f40e7902 Artboards: the Artboard tool starts on the active artboard
Each tool switch builds a new tool, and a new Artboard tool started on
Artboard 1 whatever artboard was active. With Artboard 2 active, after
the tool was chosen with Shift+O, its toolbar button, Edit Artboards in
Properties or Document Setup, or the Artboards panel menu's Artboard
Options…, the canvas outlined Artboard 1, and Delete, Cut, Copy, the
Transform panel and Artboard Options acted on Artboard 1. The first
pointer event over the canvas, a hover included, then made Artboard 1
the active artboard for Align to Artboard and Paste in Place too.

VectorcraftApp::select_tool now starts a newly chosen Artboard tool on
the active artboard, as the Artboards panel row's Options button does.
Choosing the tool again while it is in use leaves it as it was, and the
artboards Shift-clicked into its selection stay selected.

The test makes Artboard 2 active, chooses the tool with tool.select,
and checks the tool's active option, Artboard Options, a hover over
Artboard 1 and Delete. It then presses Shift+O with two artboards
selected and checks that both stay selected.

Docs: docs/mcp.md (tool.select), docs/target-app-parity.md.
2026-10-12 08:19:12 +07:00
BFlat a40454a4a0
Merge pull request #1302 from Skaywalker/i18n-hu
i18n: add Hungarian (hu) UI translation
2026-10-12 08:19:02 +07:00
bflatastic 48c52787a1 i18n (hu): rows for the strings added since the branch (graph designs and data, center align, Find Linked Files, Film Grain, Select Segments) 2026-10-12 08:18:45 +07:00
Skaywalker b9716366bf i18n: add Hungarian (hu) UI translation
Add the Hungarian catalog (4,524 rows): every menu string, every `tl!`
literal, the contextual and `@id` rows, the plurals and the status and
error messages, written from the meaning of the English labels in
general Hungarian vector-illustration vocabulary. Conventions are in the
header of `hu.tsv`.

- Register `hu` ("Magyar") in `i18n::LANGUAGES` as a complete language
  with `plural_none` (a count takes the singular); every `hu-*` locale
  resolves to it.
- Tests: Hungarian joins the menu-label, menu-string, `tl!`-literal and
  message coverage checks; `hungarian_reads_as_hungarian` pins the core
  vocabulary, the plural, the `file.close` override and a nested
  message; ő ű Ő Ű are checked in the bundled UI fonts.
- README, ROADMAP, docs/development.md and docs/localization-parity.md
  list Hungarian.
2026-10-12 08:18:45 +07:00
BFlat 70e35807e7
Merge pull request #1259 from Losminek/cs-ui-code
i18n (cs): translate labels that bypass the catalog lookup (file filters, diagnostics, credits, gradients, print marks)
2026-10-12 08:18:35 +07:00
Losminek e3dec2e87b M14.i18n: translate Czech labels at UI render sites
Localize native/web file filters, diagnostic labels, numbered presets
and contributor tooltips with English fallback and Czech plural forms.
Fix gradient adjective agreement and disambiguate Japanese printer marks
in PDF/Print choices and summaries. Keep file extensions and names intact.

Add Czech catalog rows and regression coverage; update localization evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:18:13 +07:00
BFlat 25c60fd0f5
Merge pull request #1255 from FredApps/fix/layer-target-validation-785-20261011
Validate explicit targets in layer row commands (part of #785).
2026-10-12 08:17:58 +07:00
FredApps 714f127100 M2: reject malformed explicit layer targets (#785) 2026-10-12 08:17:51 +07:00
BFlat 490989a9f7
Merge pull request #1294 from LucaLorenz/fix/document-setup-dialog-close
Fix Document Setup → Edit Artboards dialog handoff
2026-10-12 08:17:46 +07:00
Luca Lorenz 981f66441e fix(M11): close setup before artboard editing 2026-10-12 08:17:34 +07:00
BFlat d827dc92da
Merge pull request #1296 from LucaLorenz/fix/artboard-escape-exit
Fix Escape exiting Artboard editing
2026-10-12 08:17:29 +07:00
Luca Lorenz f602dc3d0b fix(M11): claim Escape in the Artboard tool 2026-10-12 08:17:15 +07:00
BFlat 0586ee863d
Merge pull request #1287 from dotCooCoo/feat/link-search
Links: Find in Folder… looks for missing linked files in a folder and its subfolders
2026-10-12 08:16:54 +07:00
bflatastic 5bcd642b76 Links: Find Linked Files tests build paths with the platform separator 2026-10-12 08:16:41 +07:00
bflatastic 7f4f2600e2 Links: the copy test builds the document folder's paths with the platform separator 2026-10-12 08:16:41 +07:00
dotCooCoo b3f832cbcd Links: Find in Folder… looks for missing linked files in a folder and its subfolders
Find in Folder… in Linked File Not Found and in the Links panel menu
looks in a folder the user picks, and in its subfolders, for the files
with the names of missing linked files, in any letter case. In the
Links panel menu it looks for the selected linked files when there are
any. It uses the folder search of the Missing Fonts dialog. Find
Linked Files lists each file it looks for with the files found for it.
A file with the size and contents saved with the link comes first. A
file of the saved size comes next when the link saved no hash or the
file is larger than 1 GB, and any other file of the name comes last.
Within each group, a file named in the same letter case comes first.
Then each file's folder names are compared with the saved path's, from
the innermost outward, up to the first one that differs, and a file
with more matching names comes before one with fewer. A file is chosen
when it is the only file found, or the only one with the saved
contents, and the user can choose another file or Don't Relink.

Relink relinks each file chosen, and each relink is one undo step.
With Copy into the document's folder, which shows for a saved
document, each image's file is copied next to the document first. The
file's name, then Name 2.png, Name 3.png and so on, are tried in turn
until one is free, which gets the copy, or is a file with the same
contents, which is used. A placed document is relinked where its file
is. The status line names the first file that fails to relink, and the
other files still relink. When Find Linked Files opens from Linked
File Not Found, the missing files left without a choice, and any that
fail to relink, go back to that dialog. On the web, Find in Folder… is
disabled in the Links panel menu, and links.findFiles can't start a
search.

- links.findFiles searches on separate threads and returns at once;
  links.findFiles {} reports the search, and {stop: true} stops it. It
  looks for at most 1,000 linked files at once: the active document's
  missing ones, or those of the objects it is given. It hashes a file
  only when a link of its name saved the file's size and a hash, and
  only when the file is 1 GB or smaller. It ends once every linked
  file has its same file, and it searches only the folders
  text.findFontFiles may search, with the same maxSeconds, depth and
  count limits.
- links.relink {copy} copies the file it is given into the saved
  document's folder and links images to the copy; a call that includes
  a placed document fails. Each name it writes is checked against the
  automation write root. text.addFontFiles and links.relink {copy}
  make their copies with fileio::copy_new, which never replaces a
  file. The text.addFontFiles params text and docs/mcp.md say which
  names are tried for a copy.
- vectorcraft-doc adds links::hash_reader, which hashes what a reader
  reads as hash_bytes hashes bytes.
- ui.findLinksInFolder is the Links panel's Find in Folder… for agents;
  docs/control-protocol.md lists the dialog's fields.

Docs: docs/mcp.md, docs/control-protocol.md, docs/target-app-parity.md.
2026-10-12 08:16:41 +07:00
BFlat b865547bc0
Merge pull request #1301 from dotCooCoo/feat/send-to-current-layer-refuses-hidden
Layers: Send to Current Layer refuses a hidden or locked current layer
2026-10-12 08:16:37 +07:00
dotCooCoo fd2ab03cd9 Layers: Send to Current Layer refuses a hidden or locked current layer
A click on a Layers row runs layer.setCurrent, which makes the row's
layer current whether it is hidden or locked and keeps the selection.
Object › Arrange › Send to Current Layer then moved the selected
objects into that layer, or into a sublayer of a hidden or locked
layer, and left them selected. In that case drawing, typing and
pasting put new art on the topmost layer that is shown and unlocked,
and since #1039 they fail with "the target layer is locked or hidden"
when no layer is shown and unlocked.

Send to Current Layer now fails with that error when the current layer
is hidden or locked, or is inside a hidden or locked layer. It makes
the check that DocState::target_parent makes for new art
(Document::is_editable) before it moves anything or records an undo
step. The objects stay where they are and stay selected. The message
already has a row in the cs, de, es, fr, it, ja, pt-br, ru and uk
catalogs.

Docs: docs/target-app-parity.md.
2026-10-12 08:16:24 +07:00
BFlat 431e282c0d
Merge pull request #1303 from dotCooCoo/feat/transform-again-options
Transform: Transform Again repeats the options of the transform it repeats
2026-10-12 08:16:19 +07:00
dotCooCoo ac8d7ebce8 Transform: Transform Again repeats the options of the transform it repeats
Transform Again kept only the last transform's matrix and its Copy
flag. After a Selection tool handle drag resized area type, Transform
Again scaled the type instead of resizing the type area again. After
Move, Rotate, Scale, Reflect or Shear with Transform Patterns set
differently from General › Transform Pattern Tiles, Transform Again
followed the preference, and after a scale whose strokes or corners
param differed from Scale Strokes & Effects or Scale Corners, it
followed those preferences. A recorded Transform Again played back
with the preferences in effect at playback, although its step records
the strokes, corners and patterns values it used.

last_transform now keeps the options with the matrix, as
last_perspective keeps the perspective.transform params.
apply_transform stores the copy, typeAreas and patterns values a
transform command used, and strokes and corners when it scales.
commit_interaction stores the params of a drag's last object.transform
preview with the values that preview noted. object.transformAgain
passes the options to the transform it repeats, and a true or false
value given in its own params under one of those names takes
precedence. A recorded step plays back with the values it records.

Three engine tests fail without the change: Transform Again after a
handle drag on area type, Transform Again after a Move with patterns:
false while Transform Pattern Tiles is on and after a Scale with
strokes: true while Scale Strokes & Effects is off, and a recorded
Transform Again played back with Transform Pattern Tiles on.

Docs: docs/mcp.md, docs/ui-parity.md, docs/target-app-parity.md.
2026-10-12 08:16:07 +07:00
BFlat f714a3f9ff
Merge pull request #1314 from dotCooCoo/feat/grid-prefs-new-documents
Part of #394: new and imported documents use the Gridline every and Subdivisions preferences
2026-10-12 08:15:57 +07:00
dotCooCoo 9ba45990ec Part of #394: new and imported documents use the Gridline every and Subdivisions preferences
Preferences › Guides & Grid › Gridline every and Subdivisions set the
grid of the documents that were open when either value changed, and of
no other document. A document made with File › New, or opened from a
file VectorCraft reads no grid from (SVG, PDF, EPS, .ai and the other
imported formats), got a 72 pt grid with 8 subdivisions, whatever the
preferences were set to. After a restart the saved values applied to no
document, because the desktop app restores the preferences at launch,
before any document is open.

file.new now gives a new document the preferences' grid, and
document.open, file.newFromTemplate and file.revert give it to a
document read from such a file. A native file, and the native document
that an SVG, PDF, .ai or EPS file carries, keep the grid they were
saved with. Changing either preference still sets the grid of every
open document.

Docs: docs/mcp.md (gridlineEvery, gridSubdivisions),
docs/target-app-parity.md.
2026-10-12 08:02:13 +07:00
BFlat 60346d98b7
Merge pull request #1306 from itrycodinganditsbad/fix-1273
Pen + Alt converts anchors of paths in a selected group (#1273)
2026-10-12 07:57:02 +07:00
BFlat f0d2727843
Merge pull request #1305 from haranishi/fix/issue-1272-simplify-preview
fix: Simplify後の選択を更新して点数を表示する #1272
2026-10-12 07:56:48 +07:00
BFlat 86cc73be34
Merge pull request #1282 from Tevinhead/feat/artistic-film-grain
G2: add Artistic Film Grain live effect
2026-10-12 07:51:04 +07:00
BFlat 68b5011d18
Merge pull request #1290 from haranishi/fix/issue-1275-rpm-runtime-dependencies
fix(packaging): RPMの必須依存を共有ライブラリ能力で宣言 (#1275)
2026-10-12 07:50:48 +07:00
BFlat e30147d15c
Merge pull request #1265 from haranishi/perf/issue-1257-craquelure-cell-search
perf: テクスチャ効果の距離判定を軽くする #1257
2026-10-12 07:50:31 +07:00
BFlat ea66635af5
Merge pull request #1291 from imachus/pr/ja-proportional-kerning
Type: Proportional Metrics bring their kerning — `apkn` with `palt`, `vkrn` and `vapk` with `vpal` (#966)
2026-10-12 07:49:54 +07:00
Fabio Lussi 8b839dd50f Snap to Point: drag a selection by the anchor pressed near
With Smart Guides off, the Selection tool grabbed the selection by the
pressed spot, so Snap to Point brought the pointer onto another anchor
while the object's own anchor stayed a few pixels off. A press within
reach of an anchor now grabs the object by that anchor (Smart Guides on
or off, also without a hover event first), and the arrow turns hollow
over such an anchor while Snap to Point is on.

Fixes #1274

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 07:49:47 +07:00
BFlat ae3ee3ed0b
Merge pull request #1284 from haranishi/fix/issue-1236-curvature-points
fix: Curvature Toolの点表示を整理する #1236
2026-10-12 07:49:38 +07:00
BFlat 5734888cf3
Merge pull request #1267 from haranishi/fix/issue-1258-full-font-names
fix: フォントのフルネームを正しい書体へ解決する #1258
2026-10-12 07:49:20 +07:00
BFlat fade678fb9
Merge pull request #1276 from haranishi/fix/issue-1180-align-noop-history
fix: 動かないアンカー整列でUndo履歴を増やさない #1180
2026-10-12 07:49:05 +07:00
BFlat 7c62536e37
Merge pull request #1288 from haranishi/fix/issue-1269-eyedropper-cursor
fix: スポイトの通常カーソルを十字表示から修正する #1269
2026-10-12 07:48:51 +07:00
BFlat 919abd4928
Merge pull request #1260 from haranishi/fix/issue-1251-readable-color-sources
fix: ロック中と隔離の外側の図形から色を取得する #1251
2026-10-12 07:48:36 +07:00
BFlat cd7895f717
Merge pull request #1300 from haranishi/fix/issue-1278-direct-segment-delete
fix: Direct Selectionで線分だけを選択・削除する #1278
2026-10-12 07:48:18 +07:00
BFlat 744ff99f34
Merge pull request #1263 from itrycodinganditsbad/fix-1254
Direct Selection: Shift-click deselects one anchor of a path selected whole
2026-10-12 07:48:03 +07:00
BFlat b3be342360
Merge pull request #1256 from haranishi/fix/issue-1253-stroke-default-width
fix: 線の色追加時にゼロ幅を既定値へ戻す #1253
2026-10-12 07:47:51 +07:00