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.
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.
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.
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.
A raster that SVG import decodes and stores again (a TIFF, a BMP or any
other format that is not PNG, JPEG, GIF or WebP, or an image whose EXIF
or TIFF orientation turns or flips it) was written as a PNG with no pHYs
chunk, and a turned or planar CMYK TIFF was written without resolution
tags, so the image lost the resolution its file declares.
The converted PNG now carries the source's resolution in a pHYs chunk,
and the CMYK TIFF in its resolution tags, as Open and Place store them.
A quarter turn (orientations 5 to 8) swaps the horizontal and vertical
values. An image that declares no resolution is stored without one, and
an image stored unchanged keeps its own bytes.
The PNG, JPEG, TIFF, WebP and BMP resolution readers and the pHYs writer
move from the engine to vectorcraft-doc, so the SVG importer can use
them; the engine and renderer entry points forward to them unchanged.
perspective.grid.preset stored the preset's grid every time, so applying
the preset the document already holds recorded an undo step that changed
nothing. It now compares the new grid with the stored one, as
perspective.grid.set does through grid_kept, and records a step only when
the grid changes. When only whether the grid shows or its active plane
differs, the preset sets them without an undo step, as
perspective.grid.show and perspective.plane.set do.
With Window › Arrange › Tile or floating document windows, every document
other than the front one was drawn through the profiles the front document
is assigned, since the active color settings are process-wide.
- cms::with_active puts other settings in place of the active ones on one
thread, fast paths included, and puts them back after (also on a panic).
cms::for_document gives the context a document's assigned profiles make,
the same one each time for the same profiles and working settings.
- Each pane renders its document's art through colormgmt::doc_cms, on the
render worker and on the UI thread alike, and draws its paper, artboard
colors and transparency grid through the same settings.
- Loading or removing a profile redraws the documents assigned it, the
ones behind the front one included.
- The ink and separation tables keep the tables of up to four color
settings, so documents with different CMYK profiles side by side do not
rebuild them on each redraw.
Placed documents inside a document behind the front one still draw through
the front document's profiles.
A graphic style from a .ai or EPS library whose fill, or the fill or
stroke of a style of one paint, paints with one of the file's gradients
by name was left out of the library. Such styles now load with that
gradient at the style's angle. The style stores only the gradient's name
and angle, so the gradient is fitted to the bounds of each object the
style is applied to; this placement is VectorCraft's own rule.
- A style of one paint reads a gradient instance's fill or stroke as
that gradient; a gradient outside an instance is still not read.
- A fill filter paints with its last paint: a color, a gradient or a
pattern replaces whichever of the others came before it.
- A style naming a gradient the file doesn't define, or painting with a
pattern, is still left out.
Docs: docs/mcp.md, graphicStyle.loadLibrary params, progress doc.
The Graph Data window's Import Data read UTF-16 only after a byte-order
mark, so a UTF-16 file without one filled the cells with NUL characters.
It now reads such a file in the byte order Import Data Sets' rule (#7348)
gives it: at least half of the two-byte units hold a NUL byte, and the
byte order is the one that reads the line breaks. The text is then read
as after a byte-order mark: an odd last byte is dropped and an unpaired
surrogate reads as U+FFFD. A file the rule refuses is read as UTF-8, as
before.
The rule now also gives a byte order to a one-line file, which reads a
line break in neither order: big-endian when more of its units start
with a NUL byte than end with one, else little-endian as before. Import
Data Sets still refuses a one-line file, which has no data rows; read in
the new order, such a file can be refused with a different error first.
When an arriving box that joins everything it overlaps covers an open
box to the right and below, and starts lower than it, the open box now
keeps only its part above the arriving box's top in the sweep's tree.
Any later box that would have met the removed part meets the arriving
box instead, which is open at least as long and in the same set, so
the groups stay the same. A box held by an open box is not opened and
cuts nothing short.
512 boxes, each 1 pt right of and below the one before, now meet 511
open boxes in the sweep instead of 130,816, with and without
transparency. Staggering right and up in sweep order still meets every
earlier open box.
The every-pair test oracle skips boxes that aren't finite, as the
sweep does.
Object > Live Paint > Make gave each new face and edge one fresh row
built from only the source's topmost fill or stroke paint and the top
stroke's weight. A lower row that draws was lost, a hidden top row
became visible, and the rows' opacity, blending mode, effects and
stroke settings were dropped.
- A face takes every fill row that draws (shown, with paint and an
opacity above 0) of its front-most covering source that has one and
an opacity above 0, in order with their settings. A source in front
whose fill does not draw no longer hides the fill behind it.
- An edge takes every stroke row of its source that draws (also with a
weight above 0). Faces and edges take the source's opacity and
blending mode; gradients keep their fit on the source, and pen
pressure stays with the source.
- Where a path is cut into several edges, each edge runs the way the
path does, its dashes go on from where it starts along the path, the
arrowheads stay at the path's own ends, and a width profile or brush
stays only on an edge that runs the whole path.
- Rows that draw nothing stay with the stored sources, which Release
returns unchanged. Merge and Gap Options build their new parts the
same way.
Docs: livePaint.make params, docs/mcp.md, docs/target-app-parity.md.