Commit Graph
13399 Commits
Author SHA1 Message Date
dotCooCoo 6d8412c4d4 Merge main into fix/dxf-ellipse-doc-line 2026-11-14 04:31:45 -08:00
dotCooCoo 4a5f916fe2 Merge main into fix/warichu-rtl-gap-caret 2026-11-14 04:31:30 -08:00
dotCooCoo bfa0c8e15e Dimensions: an opened file redraws its labels in its own composite fonts
When a document opens or is reverted with dimensions whose art is not in
its color mode, the dimensions are drawn again before the document's
composite fonts are registered. A label whose font names a composite font
that another open document defines differently was measured in that other
definition, so it was centered off its anchor. The redraw now measures the
labels in the document's own composite fonts, in front and in the back.
2026-11-14 04:31:29 -08:00
dotCooCoo deb3c4345a Merge main into fix/art-brush-proportional-weight 2026-11-14 04:31:00 -08:00
dotCooCoo 94b6b905a3 Merge main into fix/live-paint-expand-drawn-stroke 2026-11-14 04:30:58 -08:00
dotCooCoo 0e6151011d Export: clipping type with geometry effects clips where the canvas does
Type used as a clip group's clipping path, with a geometry effect on the
object, on one of its fills or strokes, or a perspective, was baked into
its outlined pieces with the effects applied, so SVG, PDF and the other
exports clipped by all of them while the canvas clips by the plain glyph
outlines. The baked clipping path was also a group, so the type's fills
and strokes were not painted.

bake_node now bakes such a clip group as the canvas draws it: the
clipping path is a path of the region effects::clip_outline gives, the
type's fills (effects baked) paint behind the clipped art inside the
clip, and its strokes paint over it outside the clip, in a group that
keeps the clip group's id and transparency.
2026-11-14 04:30:45 -08:00
dotCooCoo b276e97440 Merge main into fix/web-open-keeps-both-link-lines 2026-11-14 04:27:37 -08:00
dotCooCoo 5909f1c643 Merge main into fix/de-missing-message-rows 2026-11-14 04:27:37 -08:00
dotCooCoo d43ff88b38 Merge main into fix/shortcut-optional-typed-params 2026-11-14 04:26:54 -08:00
dotCooCoo 3a6b016253 Blend: steps between gradients linked to the same spot swatch keep its process plates
A blend between two gradients whose matching stops are tints of one spot
swatch kept the link and interpolated the tint, but every step's stop lost
the process inks (C, M, Y, K) printed with the spot ink, so PDF export wrote
the steps as the spot ink alone.

- Matching stops linked to one swatch interpolate each process ink with the
  tint; a stop without process inks counts as none of each, and the ends
  keep their own.
- Gradients with different stop counts keep the inks at every resampled
  stop, interpolated with the midpoint-adjusted fraction between two stops
  of one swatch.
- A solid blended with a gradient brings no process inks of its own: its
  stand-in gradient no longer copies the other gradient's.

Stops of different swatches, or linked and unlinked stops, still blend into
unlinked process colors without plates.
2026-11-14 04:25:55 -08:00
dotCooCoo fdb58f4951 Merge main into fix/nl-message-rows 2026-11-14 04:22:24 -08:00
dotCooCoo e784370c77 Merge main into fix/reflected-dimension-line 2026-11-14 04:22:15 -08:00
dotCooCoo 5e21d265ef Merge main into fix/ai-calligraphic-samples 2026-11-14 04:22:11 -08:00
dotCooCoo 1d8fd3f9dd Merge main into fix/actions-load-reports-unknown-commands 2026-11-14 04:18:07 -08:00
dotCooCoo 61a7784588 Merge main into fix/graph-label-paint-recolor 2026-11-14 04:18:07 -08:00
dotCooCoo 72e790503e Merge main into fix/issue-6784 2026-11-14 04:17:39 -08:00
dotCooCoo c90759af77 Merge main into fix/ai-warped-image-pieces-cropped 2026-11-14 04:17:17 -08:00
dotCooCoo e012d80f88 Merge main into fix/smooth-keeps-closed-start 2026-11-14 04:13:01 -08:00
dotCooCoo efb31aa51a PDF and EPS export: gradients name only the spot inks of stops that color something
A gradient's Separation or DeviceN space, and EPS's %%DocumentCustomColors,
named the spot ink of every linked stop. A stop out of order whose
neighboring stretches have no width, a stop at a tint of 0 without process
plates, and in PDF a stop whose stretches are fully transparent print no
ink, but their spot inks were still declared, so separations got an empty
plate.

- vectorcraft-color: Gradient::drawn_stops (the rule Document Info uses,
  moved here) and Gradient::reached_stops (every stop taken as opaque).
- PDF: Separation and DeviceN shadings, the Perceptual spot shadings and
  the spot-image warning name only inks of drawn stops at a tint above 0
  or with process plates; other stops are written with no ink, so their
  process inks and RGB or Lab colors no longer shape the space either.
- EPS: the same with reached stops, since EPS writes stops opaque; a
  transparent spot stop keeps its ink.

Output is unchanged when every stop colors part of the gradient and every
spot stop has a tint above 0 or process plates.
2026-11-14 04:11:40 -08:00
dotCooCoo 490c803080 SVG import: type on a closed path wraps around past the path's start
Text on a path of one closed subpath that is anchored to start before
the path's start point (text-anchor end or middle, right-to-left start,
or a negative startOffset) started at the start point, and text offset
past the path's end started at its end. It now wraps around the path,
as SVG 2's startOffset attribute describes for a single closed subpath
(https://www.w3.org/TR/SVG2/text.html#TextPathElementStartOffsetAttribute):
text-anchor end at startOffset 0 ends at the start point. Open paths
and paths of several subpaths still start the text at the path's start
or end.
2026-11-14 04:04:48 -08:00
dotCooCoo b3fd92ccdc PDF export: CMYK images that keep their numbers carry their ICC profile
A CMYK TIFF written again, a CMYK JPEG that the Compression settings
resample or compress again, and a CMYK image written with its mask as
its soft mask lost the CMYK profile the image embeds. Such an image is
now written in an ICCBased space holding that profile, byte for byte,
when output.profiles is all or taggedSource, and in PDF/A-2b, PDF/X-3
and PDF/X-4 unless profiles is destination. Pixels the Output settings
convert are never tagged with it.

A CMYK JPEG embedded as it is now follows the same rule instead of
always carrying its own ICC_PROFILE segments: with profiles none it is
DeviceCMYK, and PDF/X-1a export no longer refuses a CMYK JPEG that
carries a profile.

A profile tags an image only when it is at most 16 MiB and its declared
size, acsp signature, device class, CMYK color space and tag table are
well formed. Tagged CMYK documents blend transparency in the document's
CMYK profile space, not in an image's own; without that space they
blend in DeviceCMYK, or keep their RGB space in PDF/A.
2026-11-14 03:59:32 -08:00
ruchirguitar e5a881b05f i18n: French keeps [subpath, anchor] in English 2026-11-14 17:27:09 +05:30
dotCooCoo 4eb1b1cf99 SVG import: linked rasters inside a linked SVG file are read
An SVG file that an <image> links to was parsed with usvg's
from_data_nested, which drops every href to a file, so a PNG or JPEG
that the SVG file linked to disappeared without a placeholder or a
warning.

The files a linked SVG file's own <image> elements link to are now read
the way the imported SVG's links are, relative paths from that file's
folder: a raster stays linked, an SVG file imports as vector art, and
one that can't be read (missing, or refused by the reader) gets the
placeholder stretched to its box, its link and a warning. The same href
in SVG files of two folders names two files. A link that leads back to
an SVG file showing it gets the placeholder and a warning. Reading the
links of linked SVG files stops at the element depth cap and at 1,024
reads and 512 MB of text per import, the same limits decoded nested SVG
images have, counted separately from them. An SVG data URL still reads
no file links, having no folder of its own.

SVG 2 tells a viewer to ignore external references in an SVG shown by
<image>; reading them on import is VectorCraft's own rule.
2026-11-14 03:53:02 -08:00
dotCooCoo fb8cf27b9a Effects: clip regions follow fill effects and compound paths in every case
Three cases still clipped differently from what the clipping path draws:

- A clip group with an appearance of its own (a Drop Shadow, a geometry
  effect) was measured for culling by its plain clipping path, so a view
  showing only the part of the clip that an effect moved drew nothing.
  The renderer now grows that measure by the clip region in this case
  too.
- The geometry effects on the fills and strokes of an unpainted clipping
  path applied after the effects of a group around it. They now apply
  first, as for other members. A clipping path that paints keeps them
  live, so its fill and stroke still draw.
- Export baked a compound clipping path with an effect of its own from
  its raw paths, dropping the effects on those paths. It now bakes the
  clipping path as the canvas clips by it, and the pieces it bakes into
  get ids of their own.
2026-11-14 03:52:45 -08:00
dotCooCoo cacbfc8ad6 Merge main into fix/hu-missing-message-rows 2026-11-14 03:51:41 -08:00
dotCooCoo 25e35ee5b1 3D: effect validation builds each Extrude and Inflate solid once
Checking an Extrude & Bevel (both kinds) or Inflate effect built every
shape's profile about the profiles' bounds, then built the fill and
stroke solids again about the bounds of the regions they paint. A
filled shape's profile is its fill's solid, so that solid was built
twice. When a stroke reaches past the shape, the first build also used
bounds the effect does not draw it about.

The check now builds the profile on its own only where no drawn solid
is built from it: every shape for Rotate, and for Extrude & Bevel and
Inflate a shape with no fill (strokes only, or no paint). A filled
shape's solid is built once, about the bounds the effect draws it
about. The shadow check is unchanged.

Tests count the solids the check builds: an object with a fill and a
stroke, a group of two such members, an effect on the fill and the
shadow on; a shape with no fill still has its profile built.
2026-11-14 03:51:00 -08:00
dotCooCoo c764c59825 SVG import: plaintext finds its first strong character across tspans
With `unicode-bidi: plaintext`, SVG import looked for the first strong
character of an element in each text node on its own and kept the
first answer. An isolate that opened in one text node and closed in a
later one hid the rest of that node, and the node then answered left
to right. For `&#x2067;ab<tspan>&#x2069;&#x5D0;</tspan>` the element
ran left to right, where UAX #9 P2 skips the isolate and finds the
right-to-left letter after it
(https://www.unicode.org/reports/tr9/#P2).

The characters of the whole `<text>` are now read once, in order, and
each isolate initiator is matched with its PDI (UAX #9 BD9). Each
element's first strong character is then found in constant time, so
nested `plaintext` elements do not read the same characters again. An
isolate that opens inside an element and closes after it hides the
rest of that element.

vectorcraft-svg takes `unicode-bidi` 0.3.18, which vectorcraft-text
already uses, for the bidi classes.
2026-11-14 03:50:57 -08:00
BFlat 124e3cc2f1 Merge pull request #7537 from storytold/fix/fr-bracket-fields
i18n: French keeps [subpath, anchor] in English (fix main)
2026-11-14 18:50:46 +07:00
dotCooCoo 7e63d4ca0c Recovery: a recovery copy that finishes later keeps a newer status line
A recovery copy written in the background set "Saved recovery data for
<title>" (or its failure line) when it finished, over any message shown
since it started, such as Restore's count with its notes or the
"Saving…" line of a copy started after it.

The status bar now counts the messages VectorcraftApp::status sets. A
copy shows its result only while its own "Saving recovery data for …"
line is still the latest message, or right away when it was written
without the worker. A failure is still logged, and a failed folder is
still recorded for automation replies, when its line is not shown.
2026-11-14 03:48:25 -08:00
dotCooCoo 78dd7dd765 SVG import: direction keywords match in any letter case
SVG import compared `direction` with `rtl` case-sensitively, so
`direction="RTL"` or `style="direction: Rtl"` read as left to right.
CSS keywords are ASCII case-insensitive
(https://www.w3.org/TR/css-values-3/#keywords), and `unicode-bidi` was
already read that way.

The `<tspan>` embedding direction, the `<text>` paragraph direction and
the anchoring of each chunk now read `direction` through one helper
that compares without regard to case.
2026-11-14 03:47:38 -08:00
dotCooCoo fe82f68d6f TIFF: a 16-bit CMYK or gray TIFF with alpha converts at 16 bits
Place, Open and relink read a CMYK or grayscale TIFF with an alpha
channel through extra_samples_tiff_rgba, which cut every 16-bit sample
to its high byte before converting it. A faint ink or a low alpha was
lost: cyan 129 at full alpha showed as white, and an alpha of 129
became fully transparent.

The samples are now normalized at the depth the file stores them, and
only the resulting color and alpha are rounded to 8 bits (a 16-bit
alpha to the nearest 8-bit value). Associated alpha is divided out at
16 bits. A pixel whose associated alpha is zero now has no color,
instead of keeping its stored color. TIFF 6.0's Associated Alpha
Handling section states this arithmetic and the zero-alpha rule for
RGB data; applying them to CMYK and gray samples is VectorCraft's own
rule.
2026-11-14 03:44:41 -08:00
dotCooCoo 48bbcb115d SVG export: masked groups span their region only for effects that are written
A fill or stroke that the export leaves out (hidden, unpainted or zero
width) no longer adds the hidden rectangle for an effect on it. An
instance of a dynamic symbol is checked in its overridden art, so an
override that paints a fill or stroke with an effect still adds it.
2026-11-14 03:43:24 -08:00
dotCooCoo 5803d2da4a Fix #7411: a selection grabbed by an anchor snaps it onto other paths
With Smart Guides on, a selection the Selection tool grabbed by one of
its anchors only landed that anchor on other anchors and centers, or
lined its bounds up. The anchor now also lands on the other objects'
paths ("path"), and where a path crosses another path or a ruler guide
("intersect"), in the order Direct Selection uses for a dragged anchor.
When the anchor lands on a path, the bounds do not also line up with
other objects, and a ruler guide nearby does not pull it off the path.
A selection grabbed anywhere else keeps lining its bounds up.

- Targets::for_move_by_anchor gathers the other art's path segments as
  well, and Targets::snap_onto_path lands a point on them or on their
  crossings with each other and with the ruler guides.
- MoveSnap::by_anchor uses those targets; the Selection tool picks it
  when the press grabbed an anchor.

Reported by pivot-al.

Docs: docs/target-app-parity.md.
2026-11-14 03:42:08 -08:00
dotCooCoo bbf3e5ca7e Merge main into fix/plugin-store-folder-lock 2026-11-14 03:22:06 -08:00
dotCooCoo 14076169fc Merge main into fix/svg-masked-shadow 2026-11-14 03:21:12 -08:00
dotCooCoo 6d7da50374 i18n: Hungarian leaves the answers[{i}] message to the script.run answers change
#7532 adds a Hungarian row for `answers[{i}]` {e}. Two rows with the same source would fail the catalog's duplicate check once both merge.
2026-11-14 03:17:09 -08:00
dotCooCoo e04fa72959 Docs: the automation-roots section names the app-folder commands that are confined
The Confining file access bullet said the app's own folders are not
confined. It now names the commands that check the roots for a file
there: the arrowheads edit, reload and list commands, the New Document
profile commands and file.new, and the Scripts folder listing and run,
each linked to its section.
2026-11-14 03:15:13 -08:00
dotCooCoo cdbd079ee9 Fix #7525: Extrude & Bevel cuts sharp corners square instead of spiking
An inset ring limited a corner's miter by moving the corner four times
the bevel width along its bisector. At a corner sharper than about 29°
that the bevel opens (a convex corner with the bevel outside, a notch
with it inside), the bevel still ran out to a spike up to four times
the width and no longer lined up with the art. With the bevel outside,
the wall behind it spiked the same way.

Such a corner is now given twice in the outline before the solid is
built, and each copy moves along its own edge's normal, so the bevel
(and, with the bevel outside, the wall) cuts the corner square, as a
bevel join cuts a stroke. Corners within the limit keep their miters,
and corners where the inset edges meet keep the four-times limit.

A cap's outline skips the straight segment of no length between the
two copies where they do not move apart.

Docs: docs/three-d.md, docs/target-app-parity.md.
2026-11-14 03:10:33 -08:00
dotCooCoo a7abb3f348 i18n: Greek translates 115 status and error messages it showed in English
Adds a Greek row for 115 status and error messages that the Greek
catalog did not translate: effects, 3D, image export, color profiles,
swatch exchange files, color books, DXF import, the `index` whole-number
error and the PDF export warning for knockout groups. Placeholders,
parameter names, command ids and literal values stay as the English
writes them.
2026-11-14 02:53:24 -08:00
dotCooCoo 0397bfa47f Merge main into fix/ai-calligraphic-samples 2026-11-14 02:53:05 -08:00
dotCooCoo 80fa9015fd Merge main into fix/trace-flat-16-levels 2026-11-14 02:50:21 -08:00
dotCooCoo c21f44b940 Actions: test that a tool's command is checked against the recording limit
A command a tool runs (the Enclosing Lasso's select.set) that takes a
recording past 10,000 steps or past an 8 MiB set file now has tests: the
edit and journal stay, the status bar names the limit on release, the
next recorded command is refused, and Stop Playing/Recording keeps the
steps that fit. The place cursor's file.place has the same test, read at
once and read off the UI thread, where the limit is named on the frame
that places the file. A test-only Placing::wait_for_reads waits for the
reader thread by sending it a marker job after the reads.

The comment on tool_commit_checks_recording_step_limit now says that the
Selection and Rectangle tools both commit a preview.
2026-11-14 02:49:11 -08:00
bflatastic d97bb27d58 i18n: French keeps [subpath, anchor] in English
#7307's French message rows ran CI before #7392 made bracketed field names stay in English,
and two of them translate [subpath, anchor], so main fails
translated_messages_keep_the_field_names_and_values_their_english_lists.
2026-11-14 17:46:50 +07:00
dotCooCoo 9aaa092cc3 Merge main into fix/hu-missing-message-rows 2026-11-14 02:46:11 -08:00
dotCooCoo b1d364033e Artwork Cleanup: Combine and Join Point Text keep hidden and locked pieces apart
With ids, Combine Point Text and Join Point Text take locked and hidden
type. They kept the first piece's object and removed the others, so
naming a visible piece and a hidden one beside it hid the visible text
or showed the hidden text, and the same held for locked pieces and for
pieces in a locked or hidden group or layer.

A piece now joins only pieces that are as visible and as locked as it
is, counting their groups and layers. The selection route takes only
editable type, so it behaves as before.
2026-11-14 02:45:50 -08:00
dotCooCoo ffbc5446d5 i18n: Hungarian translates the index and PDF knockout messages no catalog had
Adds Hungarian rows for two messages that reached main after the earlier rows: the `index` whole-number error and the warning for PDF knockout groups with too many overlapping translucent elements.
2026-11-14 02:43:44 -08:00
dotCooCoo 795fbf0148 i18n: Swedish translates 114 more status and error messages
The untranslated report listed these messages as missing from the
Swedish catalog. Among them are the image export encoders and size
limits, color profiles, color books, swatch exchange files, DXF import,
3D and Revolve errors, and the `index` check of document.activate. Each
now has an @msg row in sv.tsv, with its placeholders, backticked names,
format names and values kept as the English writes them. Messages that
open pull requests already translate into Swedish are left to them.

The Swedish row in docs/localization-parity.md is recounted, and
docs/target-app-parity.md gets a line for the Swedish catalog.
2026-11-14 02:42:29 -08:00
dotCooCoo af750ee599 i18n: Finnish translates the PDF warning for knockout groups with brushed strokes
PDF export warns when a knockout group has a brushed stroke over other
translucent elements and is written as a PDF knockout group. No catalog
had a row for that warning, and untranslated_report does not list it,
because the scanner does not follow the constant into the Err it is
returned in. fi.tsv now has a Finnish row for it, next to the row for
the knockout warning about too many elements.
2026-11-14 02:41:23 -08:00
dotCooCoo 55595f0cff i18n: Dutch messages keep the bracketed field names in English
Ten nl rows translated the field names inside [subpath, anchor], [x, y, width, height] and [width, height], which a command reads only in English. They now keep the English names, as the other catalogs do.
2026-11-14 02:40:39 -08:00
dotCooCoo 27e75cfce2 Merge main into fix/flat-logo-gray-between-black-and-white 2026-11-14 02:40:29 -08:00