visit_node_colors visits the fill and stroke paints a dynamic symbol
instance keeps for objects of its art (symbol_overrides). Before, print
separations, Separations Preview and document color conversion left
those colors as they were, so an instance's own fill printed and
previewed unseparated.
Two PDF export passages in docs/target-app-parity.md said a gradient
that mixes a spot color with RGB or Lab stops is always written without
the spot ink, or as an image when Perceptual. A CMYK document, or an
export that converts colors to a CMYK destination profile, writes those
stops in CMYK first, so the gradient is a DeviceN shading that keeps the
ink; an RGB destination profile keeps them in RGB. The passages now say
so, as docs/mcp.md and the paint.editGradient params text already do.
A new test checks the Classic case in an RGB document, a CMYK document,
with a CMYK destination and with an RGB destination.
Batch with Override Export compares output names without case, so
`a.svg` and `sub/A.svg` get the Export for Screens folders `a` and
`A-2`. A source whose name without its extension is empty (` .svg`)
gets the folder `file`, and a later `file.svg` gets `file-2`. Two tests
cover these cases.
Records why rust:S4790 (`crates/pdf/src/encrypt.rs`) stays, like wordcraft#6187 did for SHA-1 in ODT. MD5 is the key derivation of the PDF standard security handler revisions 2-4 (ISO 32000-1 §7.6.3.3), which PDF 1.3-1.6 encryption uses. It's needed to read those files and to write the compatibility the user picks. The default, 256-bit AES (revision 6), hashes with SHA-2.
Reset Preferences put Points in Units > General, and OK sent it to
prefs.set, which also set the open document's units as an undo step.
OK after Reset now resets the General preference and leaves the
document's units as they are. Choosing a General unit after Reset, in
the dialog or with ui.dialog.set, still sets the document's units.
prefs.set takes documentUnits (default true); false makes unitsGeneral
set only the preference. Docs: params text, docs/mcp.md.
Part of #6435
Shaping split a cluster wherever two characters' styles differed, so
setting Standard Vertical Roman Alignment or a tate-chu-yoko offset on the
f of "fi" in horizontal type broke the ligature. Horizontal type does not
read those settings, so they no longer split a cluster there. Vertical
type still shapes such characters apart.
object.repeat.radial, object.repeat.grid, object.repeat.mirror and
object.repeat.options, and object.pattern.make, object.pattern.edit,
object.pattern.saveCopy, pattern.options and pattern.delete, read their
params with helpers that fell back to the default for a value of the
wrong type: "instances": "8" made 8 instances whatever the text said,
"rows": "2" made 3 rows, "edit": "false" entered pattern editing mode,
and a `name` that was not a string edited the selected object's pattern.
Each such value is now an error naming the param, and the document, the
selection and the undo history stay as they were. An omitted or null
param keeps its default.
- pattern.options refuses an `overlap` that is not an object, and an
`overlap.h` other than left or right or an `overlap.v` other than top
or bottom.
- object.repeat.options refuses a `center` that is not [x, y].
- object.repeat.radial refuses a negative `radius`; it used the
automatic radius before.
- object.repeat.grid reads `rows` and `cols` as object.repeat.options
does: a fraction is cut to a whole number, within 1 to 500.
- object.repeat.options applies `brickOffset` given without `gridType`
to a brick grid, and its params text lists the key.
Docs: docs/mcp.md.
After a Scissors cut (`path.split`) the whole path stayed selected: both
pieces of an open path, or the opened path of a closed one. A Direct
Selection drag from the cut then moved every anchor, so an ellipse cut
at an anchor could not be pulled open by dragging its end.
- `path.split` selects the first anchor of the piece after the cut and
nothing else, as `path.cutAtAnchors` does: anchor 0 of an opened
closed subpath, of the new path when an open path becomes two, or of
the subpath added to a path of several subpaths.
- A Direct Selection press on anchors of a selected path that lie on top
of each other takes the selected one. It took the first in path order,
which in a path of several subpaths was the unselected end.
Docs: docs/mcp.md, docs/target-app-parity.md, the `path.split` params
text.
answer_dialog sent ui.dialog.set and then ui.dialog.confirm or
ui.dialog.cancel as two requests. A dialog another control connection
opened between them was confirmed or canceled without the fields.
ui.dialog.set takes `action: confirm | cancel`, checked before any field
is set, and confirms or cancels the dialog the fields were set in within
the same request, replying {dialog, result}. answer_dialog sends set and
action together; an app whose reply has no `dialog` key did not answer
it, and the dialog is then confirmed or canceled with its own request.
A cap inset by a bevel fitted each run of sampled edges along one curve
as a whole, while the wall next to it fitted each sampled edge by itself.
The two outlines lay up to 0.25 pt apart on an 800 pt circle, which left
a gap or an overlap between the cap and the wall.
An inset outline is now fitted one sampled edge at a time in the cap as
well, so both faces draw the same curves. Caps that are not inset keep
one cubic for each curve of the art.
Test: solid::tests::a_beveled_cap_and_its_walls_share_their_curves.
Docs: docs/three-d.md, docs/target-app-parity.md.
The progress entry said caps and the walls' cap edges are cubics without
its limits. It now lists the cases three-d.md describes: an edge of a
twisted wall that is cut into pieces, a piece of curve that does not fit
after 8 halvings, and the curves past 1,048,576 for one solid.
The check that refuses a symbol instance before its art is placed
counted only the symbol's own objects. Placing art through 9-slice
guides can make up to 28 objects of each one, and an instance's
dynamic-symbol overrides can turn a path that would be cut at the
guides into clip groups in every cell it reaches. Such an instance
passed the check, and its art was placed in full before the work
limit refused it.
The check now counts the symbol's own objects first, then the most
objects placing makes (NineSliceMap::most_placed) of the art with the
instance's overrides applied, and refuses the instance with the same
message before anything is placed.
transparency.makeOpacityMask read `clip` and `invert` with bool_or,
transparency.setOpacityMask read `clip`, `invert`, `disabled` and
`linked` with as_bool, and the New Opacity Masks and page toggles read
`value` with bool_or, so a value of the wrong type was dropped:
"clip": "false" made a clipping mask, "invert": "yes" next to another
flag was ignored, and "value": "on" toggled the page knockout group.
They are now read with switch_or, and such a value is an error that
names the param, before anything changes. Omitting a param or giving
null keeps its default.
Extrude & Bevel (both kinds) and Rotate wrote every face as straight
segments between sample points, so Expand Appearance and the exports
gave a corner at every sample. Sampling now records the curve each
polygon edge follows, and a facet carries an outline of cubics rebuilt
from it: exact without perspective, within 0.001 pt with it, and within
the sampling tolerance for bevel insets. Caps, Rotate's face and the
wall and bevel edges that meet a cap keep curves; interior bevel edges,
edges a twist cuts and edges past 1,048,576 curves stay straight.
Inflate's faces stay polygons.
Docs: docs/three-d.md, docs/target-app-parity.md.
A plug-in that went on calling after a failed `vc_call` still had each
later call made on the document, although the run fails and is undone
at its end. After the run's first failed call, `vc_call` now returns
`-11` (CALL_NO_CONTEXT) and the host makes no further call; the run
still fails with the first call's reason.
object.path.offsetPath, object.path.simplify, object.path.splitIntoGrid,
object.path.cleanUp, object.pathfinder.trap and addon.contour.set read
their params with helpers that fell back to the default for a value of
the wrong type: "offset": true offset by 10 pt, "joins": 3 gave mitered
joins, "addGuides": "yes" added no guides. Each such value is now an
error naming the param, and the document and the undo history stay as
they were. An omitted or null param keeps its default, and a distance
still takes a string with a unit ("5 mm"). An unknown `joins` name is
refused as well.
Make Compound Path leaves each member's graphic style id in place. A
member copied or cut on its own took the compound's appearance but kept
that old id, so the clipboard carried an unrelated style and the pasted
path was linked to a style that did not match its look.
The copied member or piece now takes the compound's link while it has
that style's look, and no link otherwise (no style on the compound, or
a gradient pinned to the compound's bounds). It also takes the
compound's knockout setting with the rest of its transparency.
object.expand read `object`, `fill` and `stroke` with bool_or, `steps`
with f64_or and `gradient` with str_param, so a value of the wrong type
fell back to the default: "fill": "yes" expanded the fill, "steps": "16"
made 255 strips and "gradient": 3 made strips. They are now read with
switch_or, number_or and text_param, and such a value is an error that
names the param, before anything changes. Omitting a param or giving
null keeps its default.
A 3D effect on a symbol instance placed a copy of the symbol's whole art
before counting it against the effect's work limit, so a symbol far past
the limit was copied in full on every check and redraw before it was
refused. The symbol's objects are now counted first, and a symbol that
would pass the limit is refused with the same message without being
placed.
Three Extrude & Bevel dialog tests used a clipping group as their example
of an object a 3D effect refuses, and clipping groups now apply. Their
helper now places an image, and they check for the image message ("can't
build a solid from an image") in place of "requires a path".
They switch the process-wide Color Settings away from the defaults, which
every colour the engine's unit tests show or render goes through, so they
move to tests/color_settings.rs as the note on colormgmt's GLOBAL asks. The
round-trip test now also unregisters the loaded profile before the next
session, so it shows the profile store registering it again before the saved
settings name it.
A drop guard puts the default settings back, unregisters the loaded profile
and deletes the temporary files, so a failed assertion no longer leaves the
process-wide colour state changed for the next test holding GLOBAL.
The interpreter runs skipped every test with a missing built-in's name
anywhere in a string literal, so a test that only mentions Boolean in
a message or in text data was never run. A string now counts when it
is the name alone (a property key such as this["Map"]), or when the
test or an included harness file can run strings as code (eval,
Function or a constructor property, by name or by string key).
Identifiers and property names count as before, and a source that does
not tokenize as ES5 is still skipped.
At tc39/test262 d53ebc8b, language/types/string/S8.4_A6.1.js and
S8.4_A6.2.js now run and pass: the language run goes from 2,459 tests
(205 skipped) to 2,461 (203 skipped), and the failure lists are
unchanged.