Commit Graph
6741 Commits
Author SHA1 Message Date
bflatastic 63a5889895 bs: language names keep their own name in the picker 2026-10-31 01:31:09 +07:00
nine-codesandClaude Opus 5.5 64b92627c2 Add Bosnian (bs) to the interface languages
bs.tsv: Bosnian (Latin script, Ijekavian) catalog covering every key of
VectorCraft's other catalogs, its wording shared with storytold/craft-i18n
locales/bs/ and the strings craft-i18n lacks translated new. Every bs-*
locale selects it; counts use one/few/other. Locale and plural tests,
localization docs and an attribution entry (AI-assisted, not yet
reviewed by a native speaker).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tayw8nmxoLLmKv13jK93z
2026-10-31 01:17:11 +07:00
bflatastic f38cdaeaa7 Testkit: temp_dir starts empty in each process, so a reused process id can't fail a test 2026-10-31 01:17:06 +07:00
BFlat 2166aca02e Merge pull request #4734 from storytold/feat/addon-duotone
Add-ons: Color Effects — Duotone effect and Print Ink Fixes
2026-10-31 00:52:57 +07:00
BFlat 41c3f71880 Merge pull request #4735 from storytold/fix/4711-drag-modifiers
Canvas: Shift, Alt and Cmd/Ctrl pressed or released mid-drag apply with the pointer held still
2026-10-31 00:52:41 +07:00
BFlat 259faa3dba Merge pull request #4705 from dotCooCoo/fix/trace-library-global-swatch-same-color
Image Trace: Document Library links to a global swatch that shares a process swatch's color
2026-10-31 00:52:27 +07:00
BFlat a5b3d2cf6d Merge pull request #4714 from dotCooCoo/feat/perspective-selection-copy-drag
Perspective Selection: Cmd/Ctrl+Alt-drag copies objects in perspective
2026-10-31 00:52:06 +07:00
BFlat 071a94ce4a Merge pull request #4729 from mockydevs/fix/ai-import-review-followups
.ai import: outlines from the editing data keep their look and threads; mesh corners with non-numbers are unread
2026-10-31 00:51:49 +07:00
BFlat e8b3d1a6cb Merge pull request #4727 from mockydevs/fix/ai-cropped-page-units-and-pages
.ai import: pages cropped to the art in UserUnit units, and their copies' type
2026-10-31 00:51:31 +07:00
BFlat 319027c456 Merge pull request #4723 from mockydevs/fix/ai-placed-retry-unpruned
.ai import: weigh unseen text again at the placed files' other placement
2026-10-31 00:51:12 +07:00
BFlat aeb827ff89 Merge pull request #4708 from mockydevs/fix/ai-all-caps-text
.ai import: keep All Caps and Small Caps on type from the editing data
2026-10-31 00:50:52 +07:00
BFlat 4f5a2c87ed Merge pull request #4730 from dotCooCoo/feat/pathfinder-repeat-shortcut
Pathfinder: Cmd+4 repeats the last Pathfinder operation
2026-10-31 00:50:33 +07:00
BFlat 64ae5ee8de Merge pull request #4706 from dotCooCoo/fix/pencil-alt-smooth-fidelity
Pencil and Blob Brush: Alt smooths with the Smooth tool's Fidelity
2026-10-31 00:50:21 +07:00
BFlat 7f7c943595 Merge pull request #4726 from dotCooCoo/feat/knife-straight-cuts
Knife: Alt cuts in a straight line and Shift+Alt cuts at 45° steps
2026-10-31 00:50:04 +07:00
BFlat feb2aafb6c Merge pull request #4713 from dotCooCoo/fix/new-style-highlight
Character and Paragraph Styles: a style made by the New style dialog or the panel menu is highlighted
2026-10-31 00:49:40 +07:00
BFlat 1dd6fcf199 Merge pull request #4731 from dotCooCoo/fix/invert-colorize
Images: color edits recolor a colorized image's fill
2026-10-31 00:49:23 +07:00
BFlat ed0b1c7dc7 Merge pull request #4720 from dotCooCoo/fix/pdf-colorize-transparency
PDF: colorized images count as transparency for PDF 1.3 and PDF/X
2026-10-31 00:49:05 +07:00
BFlat d90eee669f Merge pull request #4718 from dotCooCoo/fix/stylelib-ids-null
Graphic Styles: addFromLibrary treats ids: null as left out
2026-10-31 00:48:50 +07:00
BFlat d6fcc5ac4e Merge pull request #4717 from dotCooCoo/fix/stylelib-name-check
Libraries: library loads check name before reading the file
2026-10-31 00:48:34 +07:00
BFlat dc2c46f4ae Merge pull request #4716 from dotCooCoo/fix/pdf-image-repeat-bound
PDF export: bound a colorized image's color channel
2026-10-31 00:48:17 +07:00
bflatastic ebc5b7038c Add-ons: Color Effects — Duotone effect and Print Ink Fixes
Effect › Color Effects › Duotone… (addon.color.duotone, also in Object ›
Plug-ins › Color Effects) prints the grey-equivalent tone of each colour
with one to four inks, each with its own tone curve. It is a colour
adjustment like the add-on's others, so it stacks with them and works as
a filter through addon.color.filter.

- One tone of a swatch the document has gives a tint of that swatch,
  linked, so a spot tone separates onto its plate; several tones give
  the CMYK mix of their tints (the inks overprint, so they multiply).
- Colour adjustments now map paints with their swatch links
  (ColorMap::apply_link); the existing adjustments behave as before.
- Skip Objects with Spot Colors leaves spot-linked colours as they are.
- The dialog has a row per tone and the picked tone's curve (the Curves
  graph, reused), its points and Reset to Linear / Inverse.

Print Ink Fixes (addon.color.printFixes, Object › Plug-ins › Color
Effects › Print Ink Fixes…) scales CMYK colours over a total ink limit
down to it, removes white overprint and sets black overprint (Overprint
Black's logic) in a CMYK document, as one undo step, and reports what
changed. RGB documents are refused.

The panel opens both under Inks.

Deferred: an opaque undercoat, tones for type only, extra gradient stops
for smoother tints, curve flip and all-100 % buttons.
2026-10-31 00:26:18 +07:00
bflatastic 79fe17934a Canvas: Shift, Alt and Cmd/Ctrl pressed or released mid-drag apply with the pointer held still (#4711) 2026-10-31 00:26:15 +07:00
dotCooCoo a2d3841579 Image Trace: look up library swatches once per trace
Each traced path filtered the whole library for its color, twice when
no swatch of that color was linked. The color-to-paint lookup is now
built once before the paths are filled. The first linked swatch of a
color still gives the fill, and the first swatch of that color
otherwise.
2026-10-30 23:57:40 +07:00
dotCooCoo 65f7d3a699 Image Trace: Document Library links to a global swatch that shares a process swatch's color
When a process swatch listed before a global or spot swatch showed the
same color, a traced fill of that color took the process swatch and
stayed unlinked. Of the swatches that trace as one color, the first
linked one now gives the fill, and the first one otherwise.
2026-10-30 23:57:40 +07:00
dotCooCoo 8f56899df9 Perspective Selection: Cmd/Ctrl+Alt-drag copies objects in perspective
With the Perspective Selection tool, Ctrl+Alt-drag (Command+Option-drag on
macOS) now copies objects on their perspective plane, as Alt/Option-drag
does. Before, Cmd/Ctrl lent the last selection tool even with Alt held, so
the drag made a flat copy. Cmd/Ctrl alone still lends the last selection
tool, and the cursor follows the same rule.
2026-10-30 23:57:36 +07:00
Don Omondi 66c797a59b .ai import: outlines from the editing data keep their look and threads; mesh corners with non-numbers are unread
Follow-ups to the review of #4697 and #4698:

- With textAs: outlines, a .ai saved without PDF compatibility, read
  from its editing data alone, has its type outlined too, as an empty
  page or a text-only placeholder already did.
- Threaded type read from the editing data holds its story in its first
  frame: it now flows through its frames before it is outlined, so each
  frame's outlines show the text it holds, and the outlined frames
  leave their threads.
- Each outline group keeps its type's opacity, blend mode, isolation,
  opacity mask and effects (the same carry-over the flattener uses).
- A gradient-mesh corner (/N) holding anything but numbers is unread,
  instead of being read with the numbers after it shifted into its
  colour and opacity.
2026-10-30 23:55:32 +07:00
Don Omondi 1d58ea947d fix(ai-import): pages cropped to the art in UserUnit units, and their copies' type
A page cropped to the art is recognised in a UserUnit page's units too,
when the art's box is the page in those units and the artboard isn't the
page in points. Such pages are taken only when every page is the art's
box, and only the first page's type is read: the later pages are copies
whose type was moved by the first page's offset and could fill the
layers' text objects twice.
2026-10-30 23:55:28 +07:00
Don Omondi 75958ce7da fix(ai-import): weigh unseen text again at the placed files' other placement
prune_unseen ran before the retry that moves placed files to their box's
corner, and that retry cloned the pruned layers: text an image covered
only at its first placement was already gone, so the file came in without
it or as its PDF part. Clone the layers before pruning and prune each
placement on its own.
2026-10-30 23:55:22 +07:00
Don Omondi 530605d4fc fix(ai-import): keep All Caps and Small Caps on type from the text document
Character attribute 12 of the editing data's text document is the case
(1 Small Caps, 2 All Caps). The reader skipped it, so type set in All Caps
came in as typed, in lower or mixed case where the page draws capitals.
Map it onto CharStyle::all_caps and CharStyle::small_caps.
2026-10-30 23:55:16 +07:00
dotCooCoo b4899e665d Pathfinder: batch steps set the operation Cmd+4 repeats
A successful command.batch now records its last Unite, Intersect or other
Pathfinder step as the operation Repeat Pathfinder runs, so playing an
action from the Actions panel updates it. A batch that fails and rolls back
leaves the previous operation in place. action.batch, which runs an action
over other files or data sets, does not set it.
2026-10-30 23:52:27 +07:00
dotCooCoo 7d97c633b7 Pencil and Blob Brush: Alt smooths with the Smooth tool's Fidelity
When Alt switches the Pencil (with Alt key toggles to Smooth Tool on)
or the Blob Brush to the Smooth tool, the drag sent the drawing tool's
own Fidelity (1.5 by default) to path.smoothRegion. The Smooth tool
sends its own Fidelity (2.5 by default, set in Smooth Tool Options).

Both tools now smooth with the Smooth tool's Fidelity. The engine gives
them the stored Smooth Fidelity when it makes the tool, and again when
Smooth Tool Options changes while one of them is active. Each tool's
own Fidelity still sets how its strokes are fitted.
2026-10-30 23:52:26 +07:00
bflatastic 71f566c6aa Docs: keep the Knife entry to the documented behaviour 2026-10-30 23:52:26 +07:00
dotCooCoo bad34b7115 Pathfinder: direct commands set the operation Cmd+4 repeats
Every successful Shape Mode or Pathfinder operation now sets the
operation that Repeat Pathfinder runs, including direct
object.pathfinder.* commands, not only the panel's buttons. Trap,
compound-shape edits and live effects leave it unchanged, and a failed
operation keeps the earlier one. The panel menu names the remembered
operation, and Repeat runs it on the current selection with the current
Pathfinder Options.

With too few objects selected, Cmd/Ctrl+4 leaves the art as it is and
shows the panel's selection message in the status bar. Adds the
"no Pathfinder operation applied yet" rows to the Catalan and Turkish
catalogs, and tests for direct and failed operations, Trap, compound
shapes, current options, a one-path selection and the default keys.
2026-10-30 23:52:26 +07:00
dotCooCoo 9b3e2d873b Pathfinder: Cmd+4 repeats the last Pathfinder operation 2026-10-30 23:52:26 +07:00
dotCooCoo 28936f6174 Knife: Alt counts only at the press and Shift+Alt steps from the canvas axes
A straight Knife cut now starts only when Alt is held at the press.
Alt pressed later in the drag, even before the pointer moves, leaves
the cut freehand. Releasing Alt during a straight cut keeps it
straight.

With Shift+Alt, the cut keeps to 45° steps from the horizontal and
vertical whatever the Constrain Angle. The Pencil's straight line
still steps from the Constrain Angle.

Tests cover Alt after the press, Alt only at the release, a 90° cut,
a 30° Constrain Angle, and the cut boundaries in the engine.

Docs: docs/target-app-parity.md.
2026-10-30 23:51:51 +07:00
dotCooCoo cd9eb0acd5 Knife: Alt cuts in a straight line and Shift+Alt cuts at 45° steps
The Knife cut along the freehand drag whatever keys were held. The
reference app cuts in a straight line with Alt-drag, and it cuts at 45
or 90 degrees with Shift+Alt-drag.

With Alt held at the press, or pressed before the drag has moved, the
Knife's stroke is the press point and the pointer: the dashed line
shows it while dragging, and the release sends path.knife with those
two points. With Shift held too, the line keeps to 45° steps from the
Constrain Angle, as the Pencil's Shift line does. Shift is read on each
drag event and at the release. The cut stays straight when Alt is let
go, a line taken back to its press point sends no command, and Shift
alone leaves the cut freehand.

Docs: docs/target-app-parity.md.
2026-10-30 23:51:51 +07:00
dotCooCoo aea9296fa2 Character and Paragraph Styles: a style made by the New style dialog or the panel menu is highlighted
Squashed from #4713 onto main.
2026-10-30 23:45:42 +07:00
dotCooCoo 29fb6bcd89 Images: color edits recolor a colorized image's fill
paint.invert and paint.complement on the Fill proxy, the Edit Colors
commands, the Blend commands and recolor.apply now recolor the color
that colorizes a grayscale or 1-bit image, as one undo step with the
other targets. Before, they left it unchanged. Expand Appearance and
Object > Expand bake color adjustment effects into that color too.

- A colorized image's pixels are not recolored; they stay the gray
  coverage of its color. A stroke-only pass reaches the image's stroke
  items and leaves its colorize color unchanged.
- A command that would leave a process color on a grayscale image with
  an alpha channel fails with the existing message and changes nothing.
  Object > Expand undoes its earlier steps when that happens.
- A colorized image counts as a filled object in a blend.
2026-10-30 23:44:19 +07:00
dotCooCoo 6c9933666b PDF: colorized images count as transparency for PDF 1.3 and PDF/X
A colorized grayscale or 1-bit image draws its white pixels transparent and is written to
PDF with the image as a soft mask. Node::shows_transparency did not count it, so a PDF 1.3,
PDF/X-1a or PDF/X-3 export whose only transparency was a colorized image was not flattened
and kept the soft mask. A legacy .ai save also wrote such an image as opaque.

- shows_transparency counts a visible image with a colorize paint.
- The legacy .ai writer flattens or leaves out colorized images like other see-through images.
2026-10-30 23:44:15 +07:00
dotCooCoo b3f1d57ecf Graphic Styles: addFromLibrary treats ids: null as left out
graphicStyle.addFromLibrary with apply: true and ids: null tried to
apply the style to no objects and failed with "no such objects" when
nothing was selected. A null `ids` now behaves as leaving `ids` out:
the style is applied to the selection when there is one, and only added
otherwise.
2026-10-30 23:44:10 +07:00
dotCooCoo ae0ce1888d Libraries: library loads check name before reading the file
swatch.library.load, graphicStyle.loadLibrary, symbol.loadLibrary and
brush.loadLibrary read the whole file or decoded data before checking
`name`, so a call with a `name` that is not a string read the file
first, and with a missing file reported the file error instead of the
parameter error. The shared loader now checks every parameter before it
reads anything.
2026-10-30 23:44:05 +07:00
dotCooCoo 16db8b6a1a PDF export: bound a colorized image's color channel
A colorized image's color channel is the paint's samples repeated once a
pixel, and nothing bounded its size: an image colorized in Registration in
a document with many spot swatches could allocate without limit, and an
overflowing length panicked inside repeat. The length is now computed with
checked arithmetic and refused above MAX_RASTER_ALLOC, the image's own
decode budget, and the export leaves such an image out with the existing
"an image couldn't be decoded" warning instead of drawing it uncolored.
2026-10-30 23:43:57 +07:00
BFlat 07188ce11b Merge pull request #4725 from dotCooCoo/feat/spiral-drag-winds-decay
Spiral tool: Alt-drag adds or removes winds and Ctrl/Cmd-drag changes the decay
2026-10-30 23:41:49 +07:00
dotCooCoo 88e2177fec Spiral tool: Alt-drag adds or removes whole winds of four segments
Alt in a spiral drag now rounds the fitted segment count to whole winds
of four segments, counted from the segment count when Alt went down.
Ctrl/Cmd takes precedence when both keys are held, and switching back to
Alt starts from the current count with the held inner end kept. Arrow
keys, Escape, release and a new drag clear the held Alt count.

Tests cover both keys together, a switch mid-drag, Escape, the 2 to 1000
bounds and the committed path's anchor count. docs/mcp.md and
docs/target-app-parity.md describe the rule.
2026-10-30 23:17:01 +07:00
dotCooCoo 856c602310 Spiral tool: Alt-drag adds or removes segments, and Ctrl/Cmd-drag changes the decay
The reference app adds or subtracts winds from a spiral with Alt-drag
and changes its decay rate with Ctrl/Cmd-drag. VectorCraft's Spiral
tool did nothing with either key during a drag.

While a spiral is dragged out, Alt or Ctrl/Cmd keeps the spiral's
inner end at the distance from the center it had when the key went
down, and the outer end follows the pointer. With Alt the number of
segments changes to the nearest whole number that fits, within 2 to
1000, so dragging outward adds segments and dragging inward removes
them. With Ctrl/Cmd the decay changes to fit, within 5 to 99.99
percent, the decays a spiral is drawn with. When both keys are held,
Ctrl/Cmd changes the decay. Up/Down with a key still held move the
held radius to the new segment count. The new values stay when the
key is let go, and as the Spiral tool's segments and decay options
for the next spiral. Both keys also work with a 5 percent decay and
hundreds of segments.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-10-30 23:17:01 +07:00
BFlat f30a77e2d4 Merge pull request #4724 from storytold/fix/3d-on-live-type
3D Extrude & Bevel, Inflate and Rotate apply to type, which stays editable (#4715)
2026-10-30 23:16:42 +07:00
bflatastic f4be2b9006 3D Extrude & Bevel, Inflate and Rotate apply to type, which stays editable (#4715) 2026-10-30 23:03:51 +07:00
BFlat b151163183 Merge pull request #4721 from storytold/feat/addon-live-halftone
Add-ons: Color Effects — live Vector Halftone effect
2026-10-30 22:39:49 +07:00
bflatastic f4c245286e Add-ons: Color Effects — live Vector Halftone effect
Effect › Color Effects › Vector Halftone… (addon.color.halftone, also in
Object › Plug-ins › Color Effects) draws its object as the halftone dots
Object › Vector Halftone makes, live: mono (one dot colour, or each dot in
the art's colour under it) or CMYK screens, the five dot shapes,
frequency, angle, invert and clip to the art's outline.

- The screens, dots and caps move to vectorcraft_effects::addons::halftone,
  shared by the command (its behaviour and tests unchanged) and the effect.
- The renderer samples the art (vectorcraft_render::addons::halftone) and
  keeps the dots by the object's content and what it reads from the
  document, so unchanged art isn't sampled again; past 100000 cells per
  screen the object draws as it is.
- Expand Appearance turns the object into its dots, and the SVG, PDF, EPS
  and AI exporters write them as paths.
- Its dialog reuses the command's fields, without Keep Original.

Deferred: stochastic and radial patterns, a dot-gain curve, per-screen
separation settings, type or symbols as dots.
2026-10-30 22:13:33 +07:00
BFlat efcc334553 Merge pull request #4486 from dotCooCoo/feat/text-styles-select-all-unused
Text styles: Select All Unused highlights the unused styles, and Delete deletes them all
2026-10-30 21:35:34 +07:00