Commit Graph
6787 Commits
Author SHA1 Message Date
BFlat 1660cd1b41 Merge pull request #4781 from storytold/fix/shared-edge-panel-fields
Path Precision Tools: the Shared Edges fields read like the others in the panel
2026-10-31 07:57:58 +07:00
bflatastic 41508e7b24 Path Precision Tools: the Shared Edges fields read like the others in the panel 2026-10-31 07:47:55 +07:00
BFlat 9b26bccd3f Merge pull request #4780 from dotCooCoo/fix/render-mask-image-failure
Render: leave out an object whose opacity mask lost an image
2026-10-31 07:46:56 +07:00
dotCooCoo 44bac0d7cf Render: leave out an object whose opacity mask lost an image
With undecoded-image marks off, an image in an opacity mask's art that
failed to draw left a hole in the mask. Without Clip, the area outside
the mask art counts as white, so the masked object showed in full.

The renderer now notes an image that fails to draw while mask art is
drawn and leaves the masked object out, as PDF export does since #4765.
This covers images in pattern tiles and in cached effect and shadow
rasters, which remember the failure and report it again when they are
reused. Nested masks pass the failure outward, and View Opacity Mask
shows no coverage for such a mask. An image still waiting to be decoded,
or drawn with the undecoded-image mark, keeps today's behavior.
2026-10-31 07:33:49 +07:00
BFlat b0ab477272 Merge pull request #4777 from dotCooCoo/fix/trace-library-unlinked-fills
Image Trace: Document Library fills are not linked to swatches
2026-10-31 07:33:13 +07:00
BFlat 6acdea31ed Merge pull request #4776 from dotCooCoo/feat/tabs-ruler-indent-markers
Tabs: the ruler's indent markers set the first-line and left indents
2026-10-31 07:32:57 +07:00
BFlat 63c97dde5d Merge pull request #4778 from storytold/feat/addon-shared-edges
Add-ons: Path Precision Tools — Shared Edge Merge
2026-10-31 07:32:42 +07:00
dotCooCoo 462b7cca15 Image Trace: Document Library fills are not linked to swatches
With Document Swatches as the library, traced fills and strokes take the
library color without a swatch link. Global, spot and tint swatches no
longer link the trace, so editing a swatch later leaves the trace
unchanged, and swatch order no longer decides whether a fill is linked.
Each region still takes the nearest library color, and a tint traces at
the color the tint swatch shows.
2026-10-31 07:17:08 +07:00
dotCooCoo edbcc5a88c Tabs: Delete Tab and Repeat Tab are off while an indent marker is selected 2026-10-31 07:17:04 +07:00
dotCooCoo 830cbbcecb Tabs: the ruler's indent markers set the first-line and left indents
The Tabs panel's ruler shows an upper marker at the first line's position
(left indent plus first-line indent) and a lower marker at the left
indent. Dragging the upper marker sets the first-line indent. Dragging the
lower marker sets the left indent and keeps each paragraph's first line
where it was; Ctrl-dragging it (Command on macOS) moves both markers.
Marker drags land on whole points, or on ruler ticks with Snap to Unit or
Shift, and each release is one undo step through text.setFormat. With a
marker selected, the X (or Y) field shows and sets its position.

When the touched paragraphs have different left indents, only the upper
marker is shown, and its position applies to every touched paragraph.
2026-10-31 07:17:04 +07:00
bflatastic 79f7b393e9 Add-ons: Path Precision Tools — Shared Edge Merge
Path Precision Tools gains the Shared Edge Merge Tool, kept out of the
toolbars (All Tools drawer and Object › Plug-ins › Path Precision Tools,
no shortcut), and Keep Shared Points Together:

- Shared Edge Merge Tool (sharedEdge): over two paths touching at two
  coincident anchors (tolerance 0 to 3 pt) hovering shows the two
  stretches and the merged edge; a click replaces both with it, half way
  between them, or following the upper (Shift) or lower (Alt) path. Both
  paths stay closed or open, anchors either stretch has inside are
  matched on the other, one undo step.
- Making ends: near anchors meet on a click and an anchor one path lacks
  is added to match; Shift+Alt asks for this inside a stretch.
- Keep Shared Points Together: an option that makes Slide Anchor Along
  Path, Extend Path and Set Anchor take coincident anchors along. Nothing
  else in the app changes.
- Shared Edges section in the Anchor Inspector: brush diameter,
  coincidence and the option.
- Commands addon.pathtools.mergeEdge and movePointsTogether, params
  validated and covered by the command sweep.
- Cursor stand-in, catalog rows in every language, docs and tests.
2026-10-31 07:16:22 +07:00
BFlat 690864d4fd Merge pull request #4775 from dotCooCoo/feat/live-paint-bucket-eyedropper-sample
Live Paint: Alt-click and Alt+Shift-click with the Bucket sample with the Eyedropper
2026-10-31 06:47:26 +07:00
BFlat 4abea50cd4 Merge pull request #4773 from mockydevs/fix/audit-slow-eps
M5: opaque knockout fills draw once in hard-edge and supersampled raster export
2026-10-31 06:47:10 +07:00
BFlat 7eb87ab657 Merge pull request #4774 from dotCooCoo/fix/clipboard-text-only-macos
Clipboard: TEXT_ONLY is built on Linux only, so clippy passes on macOS
2026-10-31 06:46:54 +07:00
dotCooCoo 82025e57b5 Live Paint: Alt-click and Alt+Shift-click with the Bucket sample with the Eyedropper
With the Live Paint Bucket, Alt-click on vector art samples its fill,
stroke and stroke weight into the paint defaults, and on a placed image
it samples the pixel as a solid fill with no stroke. Alt+Shift-click
samples only the color under the pointer, including an intermediate
gradient color or image pixels, into the active fill or stroke. Neither
click paints or changes the selection or selected art, and the next
Bucket click paints with the sampled paint. While Alt is held, the
Bucket shows the Eyedropper cursor and no face or edge highlight.

appearance.copyFrom takes `defaultsOnly: true` to update only the paint
defaults, and paint.sampleColor takes `clearStroke: true` to clear the
stroke default after an image sample into the fill.
2026-10-31 06:28:46 +07:00
Don Omondi de703fe722 M5: opaque knockout fills draw once in hard-edge and supersampled raster export
A knockout element with one opaque Normal solid fill (a path or
compound, no mask, effects or isolation) is drawn once under
AntiAlias::None, including the internal hard-edge frame of Art
Optimized supersampled exports, instead of being erased and added back
through per-element backdrop layers. Analytical antialiasing keeps the
existing compositor and rounding.

Exact-pixel tests compare against the general knockout path for paths
and compound holes across precision, supersampling, translucent parents
and copied backdrops, and check that the backdrop rasters are skipped;
translucent fills keep their knockout compositing.

# Conflicts:
#	docs/roadmap.md
#	docs/target-app-parity.md
2026-10-31 06:28:42 +07:00
dotCooCoo de72fc3998 Clipboard: TEXT_ONLY is built on Linux only
The constant is used only by the Linux Wayland arms, so on macOS it is
dead code and `cargo clippy -p vectorcraft --all-targets -- -D warnings`
fails with "constant `TEXT_ONLY` is never used". Gate it with
`#[cfg(target_os = "linux")]`, as the `Wayland` variant beside it is.
2026-10-31 06:28:35 +07:00
BFlat 7b95f9c059 Merge pull request #4768 from dotCooCoo/fix/paintbrush-alt-smooth
Paintbrush: Alt held at the press smooths a selected path
2026-10-31 06:27:41 +07:00
BFlat 3f3a9f6550 Merge pull request #4772 from dotCooCoo/fix/escape-cancel-skips-tool
View: Escape that cancels a ruler or Tools move does not reach the tool
2026-10-31 06:27:30 +07:00
BFlat 3d051a70a3 Merge pull request #4770 from dotCooCoo/fix/backtick-mid-drag-preview
Canvas: pressing or releasing backquote mid-drag updates the live preview
2026-10-31 06:27:14 +07:00
BFlat 998b9536a6 Merge pull request #4769 from dotCooCoo/fix/legacy-ai-colorized-pattern-tiles
Legacy .ai: colorized image pattern tiles keep their color
2026-10-31 06:26:58 +07:00
BFlat ee85476ac4 Merge pull request #4771 from storytold/feat/addon-path-effects
Add-ons: Path Precision Tools — live path effects
2026-10-31 06:26:41 +07:00
dotCooCoo 51b6bbdd17 Paintbrush: Alt held at the press smooths a selected path
With a path selected that the Smooth tool can change, Alt held at a
Paintbrush press now switches the drag to the Smooth tool: it smooths the
selected paths under the drag with the Smooth tool's radius and Smooth Tool
Options' Fidelity, and the cursor shows the Smooth tool before the press.
Alt pressed after a stroke begins still closes the path on release. With no
such path selected (nothing, only text or an image, or only a two-point
line), Alt at the press draws the closed stroke as before.

The Paintbrush no longer reads the Pencil's "Alt key toggles to Smooth Tool"
setting: its Alt close and Alt smoothing do not depend on it.
2026-10-31 06:11:00 +07:00
dotCooCoo a072cf16be View: Escape that cancels a ruler or Tools move does not reach the tool
An Escape that cancels a ruler-origin drag or a floating Tools panel move
now stops there: the active tool does not receive it, so a tool's own
Escape action (for example Intertwine returning to the Selection tool)
waits for the next press. The ruler-origin test also covers the drawer
and Global Edit.
2026-10-31 06:10:57 +07:00
dotCooCoo 501ae57fef Canvas: pressing or releasing ` mid-drag updates the live preview
A Selection or transform drag held still now gets another drag event when
the backquote key goes down or up, as it already did for Shift, Alt,
Cmd/Ctrl and Space, so the preview switches between a pattern-only and an
ordinary transform without waiting for the next pointer move.
2026-10-31 06:10:53 +07:00
dotCooCoo 7584b6335e Legacy .ai: colorized image pattern tiles keep their color
Saving a legacy .ai with transparent images flattened expands pattern
fills whose tile image is see-through or has opacity or a blending mode,
so the tile images flatten with the art under them. A pattern whose tile
is an opaque grayscale image with a colorize paint was not expanded, so
the writer drew the source gray pixels over white. A colorize paint now
counts too.
2026-10-31 06:10:51 +07:00
bflatastic e13c4bc9d0 Add-ons: Path Precision Tools — live path effects 2026-10-31 06:10:47 +07:00
BFlat 72f4159570 Merge pull request #4767 from storytold/feat/flatpak-version-pins-access
fix(flatpak): allow reading launcher version pins
2026-10-31 06:09:38 +07:00
BFlat a557617340 Merge pull request #4765 from dotCooCoo/fix/pdf-colorize-mask-failure
PDF export: leave out an object whose opacity mask lost an image
2026-10-31 06:09:22 +07:00
BFlat a497f3991c Merge pull request #4764 from dotCooCoo/fix/pdf-colorize-cache-reject
PDF export: cache colorized images that can't be exported
2026-10-31 06:09:07 +07:00
BFlat b45658a87b Merge pull request #4766 from mockydevs/fix/testkit-temp-dir-private-setup
Testkit: the temp_dir test pre-makes a private directory, as temp_dir does
2026-10-31 06:08:51 +07:00
Dylan M. Taylor 4d61f4b2f6 fix(flatpak): allow reading launcher version pins 2026-10-31 05:42:54 +07:00
Dylan M. Taylor a61c912f82 fix(flatpak): allow reading launcher version pins 2026-10-31 05:42:54 +07:00
dotCooCoo fa89546397 PDF export: leave out an object whose opacity mask lost an image
An unclipped opacity mask is drawn on a white backdrop. When an image in
the mask art could not be written (a colorized image whose color channel
is over the size limit, an image that can't be decoded, or one placed
beyond the coordinates a file holds), the backdrop stayed white and the
masked object showed in full where the image should hide it.

The exporter now records an image left out while it writes mask art,
and leaves the masked object out instead of applying the incomplete
mask, with a warning. A failure in a nested mask makes the outer mask
incomplete too.
2026-10-31 05:42:51 +07:00
dotCooCoo 7d706ffa26 PDF: colorized images that can't be exported are cached as missing
colorized_image returned before its cache insertion when the image was
missing, left out or undecodable, or when its color channel was larger
than MAX_RASTER_ALLOC. Every placement of such an image then decoded it
and computed its coverage again. Both cases now cache None for the key,
as load_image does.
2026-10-31 05:42:41 +07:00
Don Omondi 20f7f8be1e Testkit: the temp_dir test pre-makes a private directory, as temp_dir does
a_temp_dir_starts_empty_in_a_process_and_stays_for_later_calls
pre-created the "earlier process" directory with create_dir_all, which
under a usual umask gives others access, so temp_dir refused it as not
private and the test failed on every Unix run (main's CI included).
The test now makes it with mode 0o700; temp_dir and the assertions are
unchanged.
2026-10-31 05:42:38 +07:00
BFlat 2ced6b67e4 Merge pull request #4763 from mockydevs/fix/pdf-knockout-groups
PDF import: take a group's knockout and isolate flags from the interpreter
2026-10-31 05:41:37 +07:00
Don Omondi b0cc17343e fix(pdf-import): take a group's knockout and isolate flags from the interpreter
The import read each form's /Group /I and /K from the file in order and
matched them to the transparency groups the interpreter pushed. The
interpreter draws a group that adds nothing (full opacity, Normal, no
mask, neither flag) straight onto its parent without pushing it, so every
group after one took another group's flags. Blend steps written as a
knockout group of falling opacity then painted over each other and drew
as solid dark shapes instead of light rings.

The interpreter already reports the flags right after pushing a group
(set_knockout, set_isolated); the import now uses those and drops the
file-order list. That list was capped at 10,000 entries, past which a page
failed to import; that limit goes with it.
2026-10-31 05:27:13 +07:00
BFlat aee88d4bdf Merge pull request #4760 from mockydevs/fix/eps-blend-layer-state
.ai/EPS import: a layer's state after its last blend stays the layer's
2026-10-31 05:26:38 +07:00
Don Omondi d4745fe046 fix(eps): a layer's state after its last blend stays the layer's
#4757 gives a blend the Xy written after its record. When the blend is a
layer's last object, the layer's own state block (Xy, Xd, 7 () XW, LB)
went to the blend instead, and the layer stayed opaque. The blend's state
is now tentative like a mesh's (#4748): its own 6 () XW confirms it, the
layer's LB gives it to the layer and the blend keeps what it had.

Also records the .ai/EPS audit fixes under G9, the File formats row and M4.
2026-10-31 05:11:04 +07:00
BFlat 60bccc60c4 Merge pull request #4759 from mockydevs/fix/ai-layers-vs-page
.ai import: compare a PDF of some artboards on the artboard its page shows
2026-10-31 05:09:48 +07:00
Don Omondi aa6a960062 fix(ai-import): compare a PDF of some artboards on the artboard its page shows
A PDF saved with Illustrator editing data for only some of its artboards
has pages for those artboards, while the editing data keeps them all. The
layers were compared with the first page on the first artboard, so a page
showing a later artboard never matched and the file came in as its PDF
part, without its layers.

With fewer pages than artboards, the first page is now taken to be the
artboard of its size whose art draws most like it (up to 16 weighed), and
the pages' type goes to that artboard and the ones after it. All the
artboards still come in, and the comparison still decides whether the
layers are used.
2026-10-31 04:55:14 +07:00
BFlat f1b7bd8aa7 Merge pull request #4757 from mockydevs/fix/eps-blend-state
.ai/EPS import: a blend takes the transparency written after its record
2026-10-31 04:54:39 +07:00
Don Omondi c4d2480132 .ai/EPS import: a blend takes the transparency written after its record
Squashed from #4757 onto main.
2026-10-31 04:39:05 +07:00
BFlat 1347e006ed Merge pull request #4756 from mockydevs/fix/eps-masked-mesh-state
.ai/EPS import: a masked gradient mesh takes the transparency after its mask
2026-10-31 04:38:31 +07:00
BFlat c60bdc8b81 Merge pull request #4758 from storytold/feat/addon-corner-tool
Add-ons: Path Precision Tools — Corner Tool and Slide Anchor
2026-10-31 04:38:11 +07:00
Don Omondi a1fc3cfdb1 fix(eps): a masked gradient mesh takes the transparency after its mask
A gradient mesh with an opacity mask has its own state (`Xy`) after the
mask's dictionary, not right after its `/End X!`. The operators of the
mask's art, on `%_` lines, cleared the flag that says a mesh just ended,
so the state was read as the next object's and each masked mesh in a
run drew with the blend mode of the one before it.

The flag now goes back to what it was when a dictionary opened once it
closes, as `after_object` does.
2026-10-31 04:21:56 +07:00
bflatastic c9dc4fa857 Add-ons: Path Precision Tools — Corner Tool and Slide Anchor
Path Precision Tools gains two tools, kept out of the toolbars (All Tools
drawer and Object › Plug-ins › Path Precision Tools, no shortcuts):

- Corner Tool (cornerTool): editable corners on any path through the
  existing Live Corners. Hover shows an eligible anchor, a click cuts a
  corner with the tool's radius and kind, a drag sizes it (Shift: whole
  values), a corner's marker selects it and loads its values, resizes it
  and removes it at 0 or on a double-click; a corner never grows past
  what fits; an Alt-marquee cuts every eligible anchor inside.
- Corners section in the Anchor Inspector: radius, kind, selected count,
  Apply to Selected Anchors.
- Slide Anchor Along Path (slideAnchor): a drag runs an anchor along its
  curve, the neighbouring segments refitted by the keep-shape kernel;
  Shift snaps where the tangent is a multiple of 45° from the constrain
  angle.
- Commands addon.pathtools.cornerSet, cornerRemove and slideAnchor, one
  undo step each, params validated and covered by the command sweep.
- Cursor stand-ins, catalog rows in every language, docs and tests.
2026-10-31 04:21:26 +07:00
BFlat 0494f505d9 Merge pull request #4755 from mockydevs/fix/eps-group-opacity-after-look
EPS import: keep a layer's opacity when its state block has the stroke style
2026-10-31 04:21:09 +07:00
Don Omondi ff1f721013 fix(eps-import): keep a layer's opacity when its state block has the stroke style
A layer's own state block (Xy, Xd, 7 () XW before LB) can have the
stroke style (J j w M d XR) between its Xy and Xd. Read as the art moving
on, it dropped the layer's opacity, so a layer at 17% drew opaque and the
file came in as its page. The stroke style now keeps the pending layer
state, and the state a mesh before it had; an object's own 6 () XW block
still isn't the layer's.
2026-10-31 04:02:35 +07:00