- The legacy .ai and the check for see-through images in pattern tiles
read a color-masked image's masked pixels, as the flattener does. A
legacy .ai flattens a masked opaque image with the art under it, or
leaves it out with `transparentImages: "omit"`, and a pattern tile that
holds one is expanded before PDF/X-1a, PDF/X-3 and legacy .ai output
flatten it.
- Printed separations check whether a colorize paint shows on the masked
pixels, as the canvas does, rather than on the image's own pixels.
- A saved mask that leaves out `contiguous`, `tolerance` or `softness`
reads them as the command's defaults: true, 10 and 10.
- Remove Background is unchanged on this branch. Its refusal of a
grayscale image colorized with a process color is left for a separate
pull request.
Tests: legacy_ai_flattens_a_masked_image_as_a_see_through_one,
a_pattern_tile_with_a_masked_image_counts_as_see_through,
pdf_x1a_and_x3_flatten_the_hidden_pixels (PDF/X-3 added),
separations_colorize_masked_pixels_whose_own_pixels_are_a_preview,
a_record_without_settings_reads_the_defaults, and the dialog's query on a
linked image at its preview.
The merge of main kept main's calls to write_plan, which plan the save
with acknowledgeLoss set, so a save in the app no longer refused to
replace the file the document was read from when that file was one
written beside the path (an EPS artboard file). The save is planned
again without it before it is written, as before the merge.
The files a save writes beside the path still ask before replacing a
file that is there, except those the document's last save wrote. A new
test covers an EPS save with Use Artboards meeting artboard files from
another document: it asks, Cancel writes nothing, OK writes every file,
and the next Save does not ask.
A raster effect listed before a Transform effect follows that Transform
effect on the canvas. Several commands apply and remove the geometry
effects, and they dropped the Transform effect while the raster effect
kept its old values: Object › Expand of a gradient or pattern fill,
Outline Stroke (also Expand's Stroke option and Flatten Transparency's
Convert All Strokes to Outlines) and the 3D effects. For a square with a
Drop Shadow and a 200% Transform effect, the canvas drew a 20 pt offset
and these commands gave a 10 pt one.
- These commands now keep the raster effects at the values the canvas
uses (without_geometry).
- A fill's or stroke's own Transform effect with Transform Patterns or
Scale Strokes & Effects on now transforms the raster effects listed
before it, as one without these options does. Before, Scale Strokes &
Effects only scaled them, and Transform Patterns left them as they
were.
- In a fill's or stroke's own effects, a Transform effect that makes
copies or moves at random keeps the raster effects before it from
following the Transform effects after it, as in an object's effects.
- The params text and docs/target-app-parity.md say that pixel filters
keep their angles and light directions.
The continuous-tone test asked whether 8 colors leave more than a tenth
of the error of one color. A gray picture's tones lie along one line,
where 8 colors come nearer to them, so some gray photos scored 0.078 to
0.093 and were traced as flat art, without the smoothing color photos
get. Their noise then mixed neighboring tones (a 16 Colors trace could
keep 10 or 12 colors) and stepped the edges.
A picture with at least 95% of its opaque pixels within 8 levels across
their channels now also counts as continuous tone when 8 colors leave
more than 0.065 of the error of one color, unless 16 colors leave at
most a fifth of the error of 8. These are VectorCraft's own values. The
exception keeps gray flat art of up to 16 clean levels on its old
route. Pictures with more than 5% of their opaque pixels outside that
8-level range are unchanged.
Anti-aliased or noisy gray flat art can now take the smoothed route as
well. Very noisy gray scans of flat art get fewer specks and staircase
edges; some gray illustrations and sketches get more anchors and
staircase edges at 16 Colors and High Fidelity Photo. Some 16 Colors
and High Fidelity Photo palettes of gray photos grow toward the
requested count, with more anchors and regions, and some 6 Colors
traces get more staircase edges.
The menu items that a pick or a shortcut reads are read once. Rows that
show a name that is user data (a custom toolbar under Window › Toolbars,
a script under File › Scripts, a recent file, a saved selection) are now
left out of them, as rows that list a plug-in already are, so a pick of
Show Toolbar no longer runs with the name of a toolbar that existed when
the items were read.
While a menu item is dimmed and the engine gives no reason (a UI
command, or an Appearance command with nothing targeted), a pick or a
shortcut now opens no dialog and shows "command `<id>` is not available
right now". The message has a row in every catalog that has the
engine's longer "not available right now" message.
Review feedback: with no tolerance, pen or trackpad jitter turned a tap
into a drag and the value was no longer selected. A release within 1 pt
of the press is a tap; anything further keeps the caret.
Regression test: a_tap_with_a_pixel_of_jitter_still_selects_all_on_release.
A shortcut given to Set Corners… (`addon.pathtools.cornerSet`) ran nothing,
on a single key or a chord. The keymap is built from the list in Edit ›
Keyboard Shortcuts, and that list left the command out. An engine command
without a menu path of its own was listed only when it had a default key,
or when it was an undoable command, not an alias, whose params doc ends
each field with `?`. A UI command was listed only when it had a default
key or a params doc of `{}` or `{path…}`, or was Rename. Set Corners…
needs a radius, so it was left out. The same rules left out other
commands that items of the menu bar run:
- View › Perspective Grid's Lock Grid, Lock Station Point, Show Rulers and
Snap to Grid, and Object › Perspective's Attach to Active Plane, Move
Plane to Match Object and Edit Text.
- Edit › Edit Custom Dictionary…, a query.
- UI commands: Recolor Artwork…, the Edit menu's four preset dialogs,
Apply SVG Filter…, Export As…, Export Selection…, Edit Original, Apply
Bullets, Apply Numbers, the four library saves, and the Window menu's
New Toolbar…, Double Column, Keep Tools Beside the Canvas, New
Workspace…, Float in Window and Consolidate All Windows.
Such a command is now listed when an item of the menu bar runs it as a key
press would: with no params, or with the one set of params all its items
give. `needs_a_value` already used this check, and it moves into
`a_menu_bar_item_runs` so that both use it. The command is listed in the
group named by the first part of its id, next to the commands of its
family that were listed before (Set Corners… under Addon with Corner
Tool, the grid toggles under Perspective).
File › Export Selection… was the row of `document.exportSelection`, which
no item of the menu bar runs. That row now runs `file.exportSelection`, as
the menu item does, and `document.exportSelection` is listed as Document ›
Export Selection…. A shortcut already given to it keeps running it. The
Window menu's Learn item gets no row, because the Learn panel's row
already has its name.
Tests: on F and on a chord, Set Corners…, Edit Custom Dictionary…, Recolor
Artwork…, the four preset dialogs and Apply SVG Filter… open the dialog a
click on their menu item opens. Snap to Grid turns off and on from F, and
Export Selection… on F opens Export for Screens. Every command the menu
bar runs this way is listed, none of them shares its group and label with
another entry, and a shortcut on four of them is kept through a saved
set's export and import. The other Object › Plug-ins dialogs, Select by
Link Status… and Composite Fonts… already opened from a shortcut and are
checked the same way.
A compressed arrowheads file is refused when the data after its document, the preview included, unpacks to more than 64 MB, so the whole stream is read and its checksum checked. Other files are read as before.
Under --automation-read-root, an error about a file or folder the client
did not give now names it whole only when it is inside the read roots.
Outside them it names the file or folder by its file name, or as "a file
or folder outside the read roots" when it has none, and keeps the roots
and the reason. A path the client gives stays whole.
This covers a save without a path (the document's own file and the files
written beside it, also inside action.batch, and the refusal to write
over a file read with losses), file.revert, script.listInstalled,
plugin.reload without a path and plugin.list's folder report, and
links.relink with copy (the document's folder, its error when the
document's path has no folder, and the copies in the reply). Export for
Screens' refusal for an export preset's folder uses the same helper.
The canvas kept the art of an image whose own fill or stroke follows the
outline of its pixels for as long as the image object stayed the same. When
the document's pixels for the image changed under the same key (Update Link
replacing a preview with the linked file's pixels), the stroke kept the old
outline while hit testing and Use Preview Bounds used the new one. The
renderer now keys that art by the document's pixels for the image too.
- vectorcraft-effects: `follows_image_pixels` names such images.
- vectorcraft-render: `reads_outside` counts them, and the resources key
hashes the address of the document's pixels for them; their walk is not
kept between frames.
- A test places an off-center opaque area in a smaller copy of the pixels
under a turned and reflected placement.
- Docs: the Outline Object params text names every case that keeps the frame
and the 50% cutoff as VectorCraft's own; docs/mcp.md's `effect.apply` entry
for Outline Object, how long an outline is kept and the 16-bit RGBA limit;
docs/target-app-parity.md's evidence lines.
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.
docs/mcp.md lists the four easingType values. It and the
object.blend.setEasing params text say that a blend made without a
spine takes easingType and ramp once Replace Spine has given it one,
which the set_easing test now checks.
Each built-in category (Mobile, Web, Print, Film & Video, Art &
Illustration, Branding, Social) has a New Document profile, a native
document in the New Document Profiles folder next to the preferences.
file.new copies the profile's swatches, graphic styles, brushes, symbols,
patterns, character and paragraph styles, rulers, Document Setup options,
assigned color profiles and print settings into the new document. The
preset's size, units, artboards, bleed, background, color mode and
resolution still apply, and the profile's art and layers are not copied.
- file.newProfiles lists the profiles, file.newProfiles.edit opens one
as a document (writing the shipped profile first), and
file.newProfiles.reset deletes its file. file.new takes `profile`.
- Saved and Recent presets keep the profile of the preset they came from.
- A profile that cannot be read, is larger than 64 MiB or is not a native
document leaves the defaults, and file.new reports it in profileError.
- New Document has a Manage Profiles pop-up with Edit and Reset.
Docs: docs/mcp.md, docs/target-app-parity.md.
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.
- Expanding a layer removed its ruler guides with its members. The guides
of the layer and of its sublayers now stay on the layer, after the edges.
- Geometry effects after a 3D effect reshaped all the faces as one path, so
Offset Path merged faces that touch. Each effect now reshapes each face on
its own, about the bounds of all the faces, within one shared budget of
anchors, as it reshapes the drawn surface.
Docs: docs/mcp.md.
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.
With Background Export on, an Export for Screens call that gives only an
`exportPreset` whose preset keeps a folder ran at once on the UI thread,
because the background route looked at the call's own `folder` only. It
now takes the preset's folder as well and writes in the background with
the progress dialog and Cancel, as an export into a folder it names.
When that folder is outside an MCP client's read roots, the prepared
export carries the folder's shown name, so the reply written later lists
the files relative to the folder with no ZIP `path`, a refused write names
the folder by its name, and the status bar does the same, as for an
export made at once.
The status of a preset-only export made at once named an empty folder
("Exported 1 file to "); it now names the preset's folder.
- `Session::screen_export_folder` returns the folder an export writes
into and its shown name when the reply leaves it out.
- `ScreenExport::write` applies the read-root rule decided when the
export was prepared.
- docs/mcp.md and docs/target-app-parity.md describe the change.
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.
A custom arrowhead takes a clipping path's own fills and strokes only where the clipping path paints them on the canvas. A group used as the clipping path paints nothing, so its members' fills no longer widen the head past the clipped art.
effect.expandAsWireframes returned "draws no faces" for an object with
Revolve (Classic). It now takes the faces of Revolve (Classic) with that
effect's own options, and Rotate (Classic) is expanded as Rotate is: every
fill and stroke turned as one plane.
Docs: docs/mcp.md, docs/three-d.md.
The Dynamic Text: Block entry says the Contextual Task Bar offers the
item for point type too, and that turning it on makes point type area
type with Block on. The Dynamic Text entry no longer says point type in
the selection is left as it is.
`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 plug-in host's manifest, module and run errors, the errors about an
importer's, exporter's or effect's output and the approval error had no
@msg row in most complete-message catalogs, and the reasons its error
helpers put inside them (bad(), wrong(), out_err(), in_range(), unit(),
read_packed()) were never scanned, so the status bar showed them in
English or mixed two languages.
- Every complete-message catalog gets the rows in a "Plug-in host
messages" section, and the Hindi rows for these messages are fixed.
- The message scan reads the plug-in host's error helpers, and
objects.rs writes its two duplicate-id errors as whole strings.
- message() leaves a captured JSON object or array as written.
- Templates that start with text match before templates that start
with a placeholder, so a wrapping message uses its own row.
A pick in Search Commands ran its command with no params, while the
menu bar item gives the command params and opens a dialog for them.
Clean Up, Create Gradient Mesh, Smart Punctuation, Release Type on a
Path and Deep Ungroup ran at once with their default values, Find and
Replace reported "missing `find`", and Print Ink Fixes reported that it
needs a value. A pick now runs what a click on the menu item runs, so
these open their dialogs and nothing changes until the dialog is
confirmed.
While the menu item is dimmed (Remove Background or Object Mosaic with
no image selected, Find and Replace with no document open), a pick and
a shortcut open no dialog, and the status line says why the command
can't run. Before this, a shortcut of such a command opened its dialog,
and confirming it failed. Both routes use one helper,
shortcut_editor::menu_target_now.
The menu items that helper reads are read once. Items that list an
installed plug-in (File › Open With importers, Object › Plug-ins
filters) are now left out of them, so a plug-in installed or removed
later does not leave an item there that the menu no longer shows.