With Direct Selection, a Shift-click on a corner widget toggled its
corner. With the path selected whole every corner already is, so the
first Shift-click deselected the corner clicked and hid its widget,
leaving the others. While every corner is selected, a Shift-click now
picks that corner alone, as the first click of "click one widget, then
Shift-click the others" does; with some corners picked it still toggles.
The type parity row no longer says the NumLock-on path was tried on
Windows: neither path has been run on a Windows machine yet. The comment
on the NumLock-off egui keys says Clear comes as the top-row 5, and the
test comment names the keys 0151 and 0234 actually use.
Follow-up to #5939. With NumLock off the keypad sends Insert, End, arrows,
Clear, Home and Page Up/Down; Windows still composes the code from them,
but the app also moved the caret, so the character landed elsewhere. With
Alt held, those keys without the extended-key flag now count as digits and
are taken out of the frame; the separate navigation keys keep their meaning.
Each rib of a dashed stroke with a width profile looked up to 256 points
either way along the path, asking the profile at every step, and reached
as wide as the stroke gets anywhere past that. A sliding maximum over the
points' precomputed cover now gives every rib's reach in time in
proportion to the points, with no bound and no fallback to the widest
width (review on #6093).
With a width profile, every slice of a stroke gradient (along or across)
reached as far as the stroke is wide anywhere. Where the stroke crosses
or runs close by itself, the later, narrower part painted a square of
its colour over the wider part beside it, clipped only to the whole
outline. Each rib now reaches as far as the stroke is wide there and on
its way to the next points (each side of a profile stays between its
widths at a span's points); for a dashed stroke, as wide as it gets
within a cap's reach, since caps and dots reach along the path.
A dictionary's state starts afresh, with a black fill. Mask art is written
going on from the paint before the mask's dictionary, which the writer leaves
out when it doesn't change, so a mask rectangle with no colour of its own
came in black and hid the white letters it masks. Mask art now starts from
the paint (fill, stroke, line style, fill rule, overprint) before the
dictionaries it is in; lock, visibility and transparency still start afresh.
Installing a module that lists no permissions under a granted id now
forgets the grant, in the process and in grants.json, so the formerly
approved bytes need a new approval. A refused install leaves the grant.
Attaching a plug-in store forgets the grant of an id whose stored module
lists no permissions. A plug-in folder load forgets the process's grant
for such an id and leaves grants.json alone, because the store keeps the
module its grant covers.
Object > Expand of gradient and pattern fills now expands the pieces a
painted live effect draws one by one, so a piece keeps its own paints.
A later painted effect on a fill replaces only the first fill of a piece
and leaves the piece's other fills in place.
Document Info passes the document when it reads an image's painted fills.
The Export for Screens dialog and the Asset Export panel open
remembered settings and presets without the row and settings keys the
export no longer reads, and without settings for a format it doesn't
write, so their export and Save Preset are not refused.
A format row and a format's settings take `params`, an exporter
plug-in's own, and `security.passwordRequired`, which remembered
settings hold where PDF passwords were left out, and `settings` takes an
exporter plug-in's format, as before the key check. assets.export and assets.settings.set check the
rows and settings they are given as document.exportForScreens does.
An unknown top-level key of document.exportForScreens gets the
command's usual "the command takes" error.
The MCP save and Export for Screens calls no longer check the params
themselves: Session::execute checks them before anything runs.
File › Place reads only built-in formats, so a dropped file that only an
importer reads failed with a place error. It now opens as File › Open
opens it, with or without a drop position, also when an exporter lists
the same extension.
A pattern's definition (in either form) and a brush's art were read
without the file's art styles, so an object there with a style came in
as the look it draws, with a "drawn look" note, while the same object on
a layer or in a symbol came in as itself with its effects live. The
three definition readers now take the art styles as the symbol reader
does, and an object in a pattern's art with a style in the file's style
list keeps that graphic style's id.
An art styles section inside a symbol's, a pattern's or a brush's art
is now skipped, so it no longer replaces the file's own art styles.
The editing-data writer wrote a run's key 35 only for Tate-chu-yoko (3).
Type with Standard Vertical Roman Alignment, on or off, was saved with no
key, so the setting was lost from the editing data. Every run now carries
key 35 in the form the reader reads it (crates/eps/src/import/ate.rs,
Texts::style, lines 669-670): 1 when the setting is on, 2 when it is off
and 3 for Tate-chu-yoko. The document's defaults and the normal character
style carry 1.
Key 35 holds one value, so a run with both Tate-chu-yoko and the setting
is written as Tate-chu-yoko, and the save reports the type attributes
warning for it.
- writer/texts.rs: baseline_direction() gives each run's value;
normal_char() writes 1; loses() and TYPE_ATTRIBUTES name the setting.
- tests.rs: a vertical and a horizontal object with the setting on, off
and Tate-chu-yoko come back the same through the reader, lay out as
before, and carry the expected keys; a run with both is reported.
- docs/file-format-parity.md: the .ai save section lists the written
values.
swatch.new stored a gradient or pattern as it was given. A gradient
swatch made from a gradient swatch by name, from a fill linked to one,
or from a gradient that names one (the Gradient panel's add to
swatches) kept the link to that swatch, so copying art that uses the
new swatch brought the other swatch along too. A pattern swatch made
from a current fill picked up from art with transformed tiles kept
that transform, and art the swatch was applied to took it in place of
its own.
The new swatch now drops the gradient's link and stores the pattern
untransformed. A gradient swatch keeps its aspect as before.
The modern type reader read key 35 of a character style only for
Tate-chu-yoko (3). A run whose key 35 is 1 (Standard), in the run, its
character style or the document's defaults, now opens with Standard
Vertical Roman Alignment on, so its half-width characters stand upright
in vertical type. Horizontal type keeps the mark with no change to its
layout. A value of 2 (rotated), 3, any other value and no key at all
leave it off, VectorCraft's default.
- ate.rs: Style reads the flag and passes it to CharStyle, with a unit
test over defaults, character styles, run overrides and bad values.
- tests_native.rs: a vertical and a horizontal story with Standard,
rotated and unset runs; the test of values the reader ignores also
checks the flag.
- import_fuzz.rs: the vertical fixture also checks the flag.
- docs/file-format-parity.md: one line on the mapping.
Three copies of the Symbols Reset Transformation entry were in
docs/target-app-parity.md. The complete one, which lists all five
tests, stays; the two older copies are removed.
Escape and Cmd+Enter (Ctrl+Enter on Windows and Linux) end text editing
and switch back to the tool that double-clicked into the type, or to the
Selection tool when there was none (`TypeTool::end_editing`). The
evidence lines in docs/type-parity.md, docs/ui-parity.md and
docs/target-app-parity.md, and the doc comments on `prev_tool` and
`claims_key`, said they always switch to the Selection tool.
SVG viewers center each <textPath> glyph on its midpoint on the path and
turn it to follow the path, which is how the Rainbow effect draws. Type on
a path with any other effect and no spacing was written as a plain
<textPath>, so a viewer drew it as Rainbow. It is now written as outlines
with a warning, as type with an end bracket, Align to Path or Spacing
already is.
Docs: docs/mcp.md, docs/target-app-parity.md.
docs/file-format-parity.md held 17 copies of the paragraph under
"Illustrator's private editing data", and they disagreed about what
import reads. The section now holds one copy with every clause from
the others: a filled clipping path keeps its fill, with the exceptions
for multi-layer masks and compound clipping paths whose subpaths paint
differently; paths with an Art brush; the spot colors in brush art and
their limits; symbols defined before the art styles section; and the
Type on a Path options of type on a path. Each clause was checked
against crates/eps/src/import.
A gradient placed with the Gradient tool stayed where it was when the
object's Transform or Free Distort effect moved, turned or scaled the
outline, so the shape slid across its own gradient.
The Transform effect now maps placed gradients by its own transform,
and each of its copies takes them as many times as it takes the
transform. Under Free Distort, each path's placed gradients move and
scale from the path's bounds before the effect to its bounds after it.
This change does not alter gradients fitted to the object.
The canvas, Expand Appearance and export, Pathfinder and compound
shapes, groups, a fill's or stroke's own effects, and Object › Expand
of a gradient fill apply the same rule. In a group, the own fills and
strokes of the group, of the groups inside it and of a symbol's art
follow it too, and images and symbol instances that a group's
Transform effect moves take the placed gradients of their own fills
and strokes along. A group whose path keeps its shape because the
effect would pass the geometry budget keeps its own gradients in
place.
This changes how existing documents draw: a gradient placed on a path,
or on an image's or symbol instance's own fill, inside a group with a
Transform effect now moves with it. Before, only the gradients of type
moved (#2214).
How gradients follow each effect is VectorCraft's own rule. The
Distort & Transform help page describes what the effects do to the
object:
https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html
A top object's corner test treats a straight segment as having its
handles a third of the way along it, so an anchor between two straight
segments is a corner only when it turns out of the outline. docs/mcp.md
and the doc comment now say so, and a new test covers an inward anchor
between straight segments. The bulging-curve corner test checks against
a fixed point instead of the same nearest-point routine the code uses.
Saved corners from an .ai file stay on the same anchors when the
envelope is reflected, as they already did when it was moved or
rotated. A reflected outline runs counter-clockwise; the corners were
then mapped as if the outline had been drawn the other way round, no
longer fit it, and were found again from the outline.
On a tie between two corner anchors, or two nearest outline points,
the one met first along the outline in the order it was drawn wins,
for outlines drawn counter-clockwise too.
The docs state the corner rule in full: a handle 0.01 pt long or
shorter makes an anchor a corner whichever way it turns; otherwise its
tangent unit vectors must differ by 0.01 or more in x or y and turn
out of the outline. Content spreads evenly along a segment without
handles.
An anchor with a handle shorter than 0.01 pt counts as a corner of a top
object whichever way it turns; only an anchor whose tangents differ must
turn out of the outline. docs/mcp.md and the progress line in
docs/target-app-parity.md now say so.
A top-object envelope splits its outline into four sides at four corners
and maps the content onto the Coons patch of those sides. The sides
shared out the content by length, and the corners were the anchors or
curve points nearest the bounding box corners.
Each piece of a side between anchors and corners now takes a share of the
content's width or height in proportion to the length of its control
polygon, spread along the piece by its curve parameter. A straight
segment spreads it evenly by length. A rounded rectangle stays close to
the identity, and the content follows the curves of a side whose segments
differ in size.
Each corner is now the nearest anchor to its bounding box corner among
the sharp anchors that point out of the outline and lie within 47.5% of
the box's width and height from that corner. A handle shorter than
0.01 pt, or tangent unit vectors that differ by 0.01 or more in x or y,
makes an anchor sharp, and the first one along the outline wins a tie.
Without such an anchor, the corner is the outline's nearest point to the
box corner, moved onto the end anchor of its segment within 0.5% of the
segment's parameter. Envelopes opened from .ai files keep the corners the
file saves.
These are VectorCraft's own rules. Existing top-object envelopes redraw by
them. Gradient meshes made from a path keep their sides measured by length.
- crates/doc/src/live/mesh.rs: Coons::from_top_object and the corner
search, used for top-object envelopes.
- EnvelopeKind::TopObject gains an optional `corners` field (anchor
indices); the .ai importer fills it from the mesh's corners.
- Params text of object.envelope.makeWithTopObject, docs/mcp.md
(Envelopes) and a progress line in docs/target-app-parity.md.
Covers the other places a Warp now moves placed gradients: a group's
and a nested group's own strokes and a compound path's stroke (with the
stroke-inflated bounds), the art of a symbol instance and the area of a
compound shape with a Warp, and a stroke's own Warp on the canvas. A
new test checks that Arc's no-bend threshold for gradients matches the
one the warp uses, and the no-bend test now covers all fifteen styles.
The render test's Fisheye case, which left the square's bounds as they
were, is replaced by a vertical Bulge, and each style there is checked
to move the outline's left or right edge. The Object > Expand test
checks that it measures the ramp and not an edge of the outline.
The params text and docs/mcp.md now state which bounds each gradient
follows, and that a warp moves them with a bend or a distortion.