Outside Windows, a path that starts with a drive (`C:`) or a `\` is read
as a name in the working folder, so with the working folder inside a
read root it passed the read check. ui.inspect then kept it in recorded
action steps and replies did not hide it when a request sent it. The
check now counts such a path as outside the read roots wherever the
control channel and the library commands check a path.
A library loaded from outside a confined client's read roots keeps its
`loaded/<file name>` id for the session, in ui.inspect, ui.docking and
the library commands, so an id taken from an earlier reply still finds
the same library after another library with the same file name is
loaded. swatch.library.copyToUser leaves out `path` when the file is
outside the read roots, as the saves do.
The ids come from the engine's concealed_library_ids, which now reads a
path written with either separator, counts another platform's absolute
path as outside the roots, and keeps each id in the session.
Outside Windows, a library path that starts with a drive or a backslash counts as outside the read roots, since the file access check would read it as a name in the working folder.
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.
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.
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.
Pinning a closed replaced spine opens it with a copy of its first point
at its end, so a two-point ring became three points and Delete Spine
Point could leave a spine of two points in one place. The two-point
check now counts the points left that are apart.