Commit Graph
14127 Commits
Author SHA1 Message Date
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 fee0577df1 Merge main into fix/export-bakes-symbol-art-effects 2026-11-14 03:54:51 -08:00
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 10382a2f37 Export: symbol art dropped from the budget still counts toward it
An instance whose baked art passed the export's placed symbol art budget,
or drew too deep, gave its count back, so any number of instances could
each bake their art in full and be dropped without the work counting.

- Art baked and then dropped is now counted with the placed art against
  the budget, both before more art is baked and when baked art is checked.
- While an instance's art bakes, the art's objects before baking are held
  in the budget, so instances nested in it are placed only within what is
  left.

Documents whose placed art fits the budget export as before.
2026-11-14 03:51:14 -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 3c562254e8 Text wrap: Invert Wrap with an offset lets a line use all the room the grown shape holds
With Invert Wrap and a positive offset, a line's band was cut into at
most 64 pieces, and anchor cuts were dropped when a shape had more than
64 of them. Beside a notch the offset fills, a line could stop at the
notch instead of at the grown edge: 20 pt short beside a 0.5625 pt notch
with an offset of 1, and short beside sloped notch sides and tall bands.

The grown shape is now measured exactly: the shape near the band is cut
into trapezoids, each grown by the offset into a convex polygon, and the
line keeps the x at which those polygons hold every height of its band.
The work is capped; a shape that needs more steps than the cap, for
example one whose edges cross one another tens of thousands of times,
keeps the 64-piece measure, which keeps the line inside the grown shape.
A band of no height exactly the offset past a shape's tip now holds a
line too.
2026-11-14 03:44:29 -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 848a5ee904 Zoom: Space moves a text-edit zoom marquee after Cmd is let go
While the Type tool edits text, a zoom marquee started with Cmd+Space
read Space as up once Cmd was let go. Space pressed again moved the
marquee only in the frame of the key press, and later frames sized it.
The marquee now reads the Space key itself, so it moves and sizes as it
does outside text editing.

A space typed or committed by an input method during a Zoom tool drag
(the marquee or an animated zoom) is no longer typed into the text.
With no zoom drag, Space types a space as before.
2026-11-14 03:41:39 -08:00
dotCooCoo 6e2123709e Blob Brush: a long drag's settled outline is reused from frame to frame
The outline a Blob Brush or Eraser drag shows was copied, flattened and
tessellated again every frame, settled parts included, so the per-frame
cost of a long stroke grew with its whole length.

- The settled outline blocks are kept as shared paths and returned as a
  new Overlay::SharedPath; a block gets a new path only when it is
  joined again.
- The canvas keeps the mesh each shared path was drawn with, by the
  path's allocation and for the view, clip and stroke it was built for.
  A frame with the same path and view draws the kept mesh; a pan, zoom
  or rotation builds it once more. Lines outside the canvas get no
  triangles. A frame keeps only the meshes it draws.

egui still copies each kept mesh into the frame's mesh on every repaint.
The release sends the same path.blob and path.eraseRegion command as
before. The round Eraser tip's line is unchanged.
2026-11-14 03:39:39 -08:00
ncic bdaaff534c Merge remote-tracking branch 'upstream/main' into pencil-cursors
# Conflicts:
#	docs/ui-parity.md
2026-11-14 12:31:28 +01:00
dotCooCoo 36bccf0f34 3D: Inflate with no volume copies only shapes that might fit its limits
With no volume, each shape waits to be solved until its solid is taken,
so its path is copied first. A shape with more contours or anchors than
the solid's point limit allows is now refused before it is copied, with
the error solving it would give, instead of being copied in full. The
check counts each contour's anchors without reading them.
2026-11-14 03:24:40 -08:00
dotCooCoo 5d3cd69b6a Undo: no step when Ruby, Character or another type command changes nothing
type.ruby, text.setStyle, text.setText, text.fitHeadline, text.reshapeArea,
text.reshapePath and text.setPathHandle recorded an undo step even when the
call left the type as it was: the same ruby reading again, a removal where
there is no ruby, attributes the characters already have, the same text, a
second run of Fit Headline, or a reshape by 0. Each now runs on a copy and
records a step only when one of its type objects (or, for text.setStyle, a
graph's kept label styles) changed; otherwise the undo and redo steps and
the saved state stay as they were.

Area Type Options already skips unchanged options, and Scale Text
Attributes returns an error for type with no scale to bake, so neither
changes. Type Orientation, Optical Margin Alignment, System Layout and
Fractional Widths are fixed in #7505.
2026-11-14 03:22:36 -08:00
dotCooCoo bbf3e5ca7e Merge main into fix/plugin-store-folder-lock 2026-11-14 03:22:06 -08:00
dotCooCoo 6cc43c1d24 Merge main into fix/3d-shadow-builds-once 2026-11-14 03:21:37 -08:00
dotCooCoo 14076169fc Merge main into fix/svg-masked-shadow 2026-11-14 03:21:12 -08:00
dotCooCoo ebf498a823 EPS import: kshow runs its procedure between the characters of a composite font
In a composite font the file carries (FMapType 2, or a CMap), kshow ran
its procedure zero times. It now runs between each two characters with
the values of their codes (font number times 256 plus code, or the CMap
code), and the next character follows where the procedure moves the
current point (PLRM 3rd ed., kshow). What the procedure draws goes after
the type, outside the glyphs' group, as for live type.
2026-11-14 03:20:55 -08:00
dotCooCoo 9e0882199b Image Trace: scaling a large image down keeps the color of pixels next to clear ones
An image over 64 megapixels is scaled down before tracing with a box
filter that averaged red, green and blue without weighing them by alpha.
A clear pixel (stored as transparent black) next to an opaque one pulled
the scaled pixel's color toward black: an opaque red and a clear pixel
gave a half-clear red at half its brightness.

Each scaled pixel now takes its alpha as the mean of its block and its
color from the block's colors weighted by their alpha. A wholly clear
block keeps the plain mean of its colors. Every source pixel now counts
in exactly one block, so the block edges differ slightly from before and
an opaque image can also scale to slightly different values.
2026-11-14 03:20:46 -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 f2ba375478 Merge main into fix/inflate-lazy-puffs
# Conflicts:
#	crates/three-d/src/shadow.rs
#	crates/three-d/src/solid/inflate.rs
2026-11-14 03:15:53 -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 9cf629c7fe Merge origin's fix/export-bakes-symbol-art-effects into fix/export-bakes-symbol-art-effects 2026-11-14 03:15:07 -08:00
dotCooCoo 04b90d88d0 Tests: raster effects draw the same twice while another test assigns a document profile
tests::newdoc::a_profile_brings_the_color_profile_its_file_carries and
tests::saveoptions::an_embedded_profile_is_restored give their front
document a non-sRGB RGB profile. That profile becomes the process-wide
active color settings and stays active until a document without one
comes to the front. Every color the engine test process renders goes
through those settings, so the test
tests::rasterfilters::each_effect_changes_the_canvas_and_draws_the_same_twice
could draw the same art in two colors and fail with "<effect> is
deterministic".

The two tests now run again in a child process of the test binary
through a shared helper, tests::in_own_process. The SVG Drop Shadow test
for a non-sRGB working space uses the helper in place of its own copy,
and the GLOBAL doc comment in tests/colormgmt.rs names this route.

The rasterfilters test now checks that the color settings are the
defaults before it draws and that nothing replaced them while it drew.
A test that changes them in the same process makes it fail with "another
test changed the color settings while this one drew".

With the three tests run together (--test-threads=3) on Linux, the
rasterfilters test failed 10 of 10 runs without the child processes,
each time with that message, and passed 10 of 10 with them.
2026-11-14 03:13:56 -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 26c77228b3 Type: a tabbed right-to-left line with negative tracking stops reading after a bounded number of breaks
Once a right-to-left line holds a tab and a glyph with a negative
advance, the least it can be drawn at no longer grows with its tab
stops, so a line that overflowed in the order of its text read on to
the end of the paragraph before settling its break. Setting every line
of a long paragraph that way took time quadratic in its length.

Such a line now reads at most 256 legal breaks past where it first
overflows in the order of its text, and ends at the latest break read
that fits as drawn, the same limit the breaker uses for breaks it
measures one by one. Lines without negative advances, and lines that
fit, keep their breaks.
2026-11-14 03:06:28 -08:00
dotCooCoo 347458aff7 Place: text files in UTF-16 without a byte-order mark place as UTF-16
File › Place of a text file with the Unicode character set read UTF-16
only after a byte-order mark. Without one, UTF-16 text was read as UTF-8
(or the 8-bit set): characters outside U+0001 to U+00FF came out as
other characters, and each CR LF placed as two paragraph breaks.

Place now reads a file without a byte-order mark as UTF-16 by the rule
Import Data Sets uses, through the shared byte-order helper: an even
length, at least half of the two-byte units holding a NUL byte, the
byte order that reads a line break (for one line, the order its NUL
bytes give), and valid UTF-16 with no NUL character in that order. Any
other file is read as before, as UTF-8 or else the platform's 8-bit set.

Docs: docs/mcp.md, file.place params text, docs/target-app-parity.md.
2026-11-14 03:05:40 -08:00
dotCooCoo fc562960ec Merge main into fix/dimension-second-point-guides 2026-11-14 03:02:44 -08:00
dotCooCoo cde9a27b4f Objects on Path: the widgets flatten the group's path once per lookup
Finding where the Rotate All, Space, Move All and Select/Move widgets
go and testing whether the pointer is over one flattened the group's
path two to three times per widget. Starting a Space, Move All or
Select/Move drag flattened it five times, and one pointer move over the
group could flatten it eleven times. Each lookup now flattens the path
once and shares that measurement across the widgets:

- vectorcraft-doc makes `Measured` public with `stop` and `stops`, and
  adds `attachable`, which returns the path with its measurement.
- `Widgets::of` gives all four widgets for the canvas, `widget_at` gives
  the widget under the pointer, and `WidgetDrag::hit` gives the drag a
  press starts, each from one flattening. The Selection and Objects on
  Path tools and the canvas use them.
- A Space, Move All or Select/Move drag keeps its measurement and
  measures again only when the group's path changes.

Widget places, hits, cursors and drag results are unchanged. The new
`spine-count` feature of vectorcraft-doc exposes the flattening counter
to vectorcraft-tools' tests; it is enabled only as a dev-dependency and
leaves Cargo.lock unchanged.
2026-11-14 03:01:29 -08:00
dotCooCoo 134b8b33a1 Export: placed symbol art keeps its instance's link
An instance whose symbol art has live effects is replaced in the export by a group holding the baked art. That group now takes the instance's attributes as well, so a PDF export keeps the instance's URL as a link annotation over the art where its effects draw it.
2026-11-14 02:59:02 -08:00
dotCooCoo 083180075c Graphs: a black fill set on wedge legend labels stays black on dark wedges
On a pie with Legends in Wedges, the graph draws legend labels white on
dark wedges unless they keep a fill of their own, and it read a kept black
fill as no fill of its own. A label recolored from white to black on a dark
wedge went back to white the next time the graph was drawn.

The graph now marks the legend labels' fill as set when a command sets it
(legendFillSet in the graph's label styles, kept through save and open), and
draws a marked fill on every wedge, black included. Undo clears the mark. A
size, font or stroke change does not set it, and neither does a whole-pie
recolor that gives the legend labels different fills; one that gives them
all the same fill sets it. A swatch edit or color conversion leaves the
default black legend fill as it is, and keeps a non-black legend fill from a
file saved without the mark as the labels' own when it turns black.
2026-11-14 02:54:22 -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 2992ec6aa0 Merge main into fix/followup-7319 2026-11-14 02:51:49 -08:00
dotCooCoo 7fbef2b877 Docs: Danish row counts the catalog on current main 2026-11-14 02:51:21 -08:00
dotCooCoo 80fa9015fd Merge main into fix/trace-flat-16-levels 2026-11-14 02:50:21 -08:00
dotCooCoo c594c1781c Merge main into feat/trace-preset-defaults 2026-11-14 02:50:20 -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
dotCooCoo 5afedf5804 Merge main into fix/blend-reversed-key-stroke-direction 2026-11-14 02:46:52 -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 b59ec11b32 Export: symbol art placement skips instances the export leaves out
Hidden instances, instances in hidden groups, on template layers, and
on hidden layers or layers that do not print when the exporter leaves
those out are no longer placed for PDF, print, EPS and DXF. Their art
was baked and counted toward the 16,000,000-object limit for placed
symbol art, so it could leave a visible instance written without its
effects.

bake_document_placing_symbols takes a WrittenLayers value: PDF passes
the layers its settings write, EPS writes layers that do not print but
not hidden ones, and DXF writes both. Print removes the layers that do
not print before baking.
2026-11-14 02:45:49 -08:00