A client confined by --automation-read-root saw paths outside its read
roots that the person or an earlier request had put in the session:
- plugin.list: the plug-in folder last loaded and its failed files;
plugin.list and plugin.info: a plug-in's source file; plugin.list,
plugin.safeMode and plugin.setEnabled: the file of a plug-in turned
off for the next launch.
- file.recovery.list and file.recovery.restore: a document's original
file; file.recovery.list and file.recovery.save: the recovery folder.
- ui.inspect's scriptReport: the files a run wrote and the included
file a failed run stopped in.
A folder outside the read roots is now null, and a file outside them is
named by its file name. plugin.setEnabled {file} takes that name. The
restored documents keep their files, and unconfined clients and the
app's own UI see the same replies as before.
object.objectsOnPath.selectMember and object.objectsOnPath.moveMember
change only the document and its selection, as the other Objects on
Path commands do, so both join the commands a plug-in may call when its
manifest lists them.
The dialog sent the Count instead of a Spacing that was not above 0, so a Spacing below 0 ran with the Count. Now only a Spacing of 0, or none, leaves the Count in use, and any other Spacing goes to the command, which refuses one below 0.
A four-component JPEG whose EXIF orientation turns or flips it went
through the image decoder, which reads CMYK JPEGs as RGB, and was
stored as an RGB PNG without its inks. It is now stored the way a
turned CMYK TIFF is: its inks, 8 bits each, turned and written as a
CMYK TIFF with the turned resolution.
- vectorcraft_doc::cmyk::turned_cmyk turns the inks of a CMYK JPEG or
TIFF, next to stored_cmyk_tiff; tiff_inks is private again.
- raster_image swaps the resolution axes inline, as its HEIF branch
does.
- The links comment and the docs/target-app-parity.md line on EXIF
orientation now describe the turned CMYK TIFF.
A text on a path that many <use> elements show was laid out along the
whole path once per <use>, and the path was found in the file and parsed
again each time, while the 1 MiB limit on texts built for <use> elements
counted only the text's nodes and characters. A file with a short text on
a very long path and many <use> elements of it could keep the importer
busy far past that limit.
- The elements of the path a <textPath> follows now count toward the
limit. Past it, the remaining <use> elements show the text with its own
properties, and the warning names text paths as well as text.
- The path of each <textPath> is found and parsed once and shared by
every <use> that shows its text.
Files within the limit import as before.
`the_menu_bar_is_inert_while_a_file_dialog_is_open` excused a missing
menu row when the composite font or plug-in it named was gone at the
time of the check. A test running alongside can remove such a font and
define it again between the menu read and the check, and the test then
failed. It now runs inside `undisturbed`, as the file's other tests that
compare menu reads do. When the shortcut, plug-in or font generation
changes during a run, the test runs again on a new app. Every row from
before the dialog must then be back as it was.
The element a <use> shows inherits from the <use> rather than from where it
is defined (SVG 2, https://www.w3.org/TR/SVG2/struct.html#UseElement). A
text shown by a <use> now takes the font, size, weight, fill, stroke and
other text properties the <use> or its parents set, in clip paths too,
while the text's own properties still win. Uses with the same parent and
properties share one text. A <use> inside the text it shows is ignored for
inheritance, and texts built for <use> elements stop at 1 MiB of text with
a warning.
An object with an opacity mask draws offscreen over the bounds the
renderer gives it. For a live object (a blend, envelope or repeat) those
bounds took in effects in symbol art and brush art inside it, but not a
path's own effects, so with Clip off the drop shadows of a blend's steps
were cut off at the steps' bounds and did not draw where the mask art
leaves them uncovered. The bounds now also take in how far each path's
own effects paint past it.
The drag chose its place from the point of the path nearest the pointer, but counted each point as
farther by half its distance along the path from the last one. On an open path that turns back on
itself, the object then stayed at its place while the pointer was over another object's ring 10 pt
away. The drag now uses the point nearest the pointer. Where the path passes as near the pointer
more than once, as where it runs back over itself, the drag follows the part nearest along the path
to where it was.
Type in a font found by name with a predefined non-Unicode CMap, such as
`/Ryumin-Light-83pv-RKSJ-H findfont` or a `composefont` with `GBK-EUC-H`,
opened as Latin-1 letters (`ú{A` for 日本A) in a font whose style carried
the CMap name (`Light-83pv-RKSJ-H`). Only Unicode CMaps were split off the
font name, and `composefont` failed with `undefinedresource` for the others.
- The predefined CMap decoder used by legacy `.ai` type moves to
`import/predefined_cmap.rs`, and EPS import decodes these CMaps' codes
with it (Shift-JIS, EUC, GBK, Big Five, UHC and the other public CMaps).
- A font name splits at a predefined CMap unless an installed face has
the whole name. A CMap that can't be read gives a warning.
- Type over a vertical CMap (`-V`) is set as vertical type, and each code
moves the point one em down the column, the default `DW2`
displacement.
- Every show operator sets decoded type with the same spacing and shaping
as other fonts found by name.
- Decoding a string counts against the import's memory budget.
In a full parallel `cargo test -p vectorcraft-ui-egui` run, other tests
add and remove composite fonts in the process-wide font database and
remove plug-ins from the plug-in registry. Two tests failed when that
happened between their reads, and passed when run alone.
- `font_menu::tests::the_scroll_bar_leaves_the_stars_clear` starred
`FontDb::global().families()`, but the menu lists the composite fonts
first, so the top rows had no star. The test now turns on the starred
filter and counts the rows it listed.
- `tests::nativemenu::the_menu_bar_is_inert_while_a_file_dialog_is_open`
required every menu row from before the dialog to be back afterwards.
A row may now be missing only when the composite font or plug-in it
names is gone from the database or the registry.
- Four font menu tests took the first families from
`menu_family_list()`, which can be a composite font that is removed
before the frames run. They take them from the families that stay
listed. The variable-filter test checks that every family listed
before the click is listed again, instead of comparing two frames.
Opening or placing an image whose orientation turns it a quarter
(EXIF or TIFF Orientation 5 to 8) stored the pixels turned but kept
the resolution as stored, so a photo at 300 x 150 ppi came in at the
wrong width and height. XResolution counts pixels in the ImageWidth
direction of the stored image (TIFF 6.0,
https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf; EXIF
uses the same tag, CIPA DC-008-2012,
https://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf), so a quarter
turn now swaps the axes, in the size Open and Place use and in the
stored image, with jxlread::oriented_resolution as JPEG XL does.
Three kinds of TIFF did not follow their Orientation tag:
- grayscale TIFFs with extra samples and 1-bit CCITT Group 3 TIFFs
were not turned;
- a CMYK TIFF with its inks together was turned but stored as RGB,
losing its inks, and one with a plane per ink did not open
("Planar TIFF with CMYK color type is not supported").
They now turn as the other images do, and a CMYK TIFF keeps its inks,
8 bits each, written again with the turned resolution.