The canvas, the gradient chips and the SVG, PDF, EPS and EMF writers mixed
freeform points in display RGB, while Object > Expand and Create Gradient
Mesh mixed them in the model the points share. Points that are all CMYK,
Gray, Lab or RGB now mix in that model in those places too. Points in
different models mix as before: in display RGB, and on ink planes as the
inks of each point.
This changes how existing art looks:
- CMYK and Lab points. With the default Generic CMYK working space and no
ink planes, halfway between C100 and K100 the canvas drew (17, 106, 139)
and now draws (54, 118, 143).
- RGB points in a working RGB space other than sRGB mix in that space.
- On ink planes (a CMYK document that shows transparency), RGB and Lab
points mix first and then separate.
Gray mixes keep their values, and CMYK and Gray points on ink planes draw
as before. RGB points in an sRGB working space draw as before except on
ink planes.
- PDF and EPS write a gradient whose points are all CMYK, or all Gray in a
CMYK file, as a CMYK image. PDF's Output settings convert it as they
convert any CMYK image.
- Darkening applies to the points before they mix.
- With Appearance of Black set to Rich, the canvas mixes a gradient with a
pure CMYK black point in display RGB, and the point fades from RGB black.
A path whose live effect paints its pieces was measured with the
flattened output and the source appearance's strokes, so a piece with a
wider stroke of its own could be culled while the stroke was on screen,
and Rasterize and raster effects worked over bounds that were too small.
visual_bounds and shape_bounds now measure the art reshape returns, each
piece with its own appearance, and a raster effect on a fill or stroke
spreads that art.
The test for Crisp and Strong type in a scatter brush stroke at 50% opacity
now checks that every pixel is half of what the same stroke draws at full
opacity. It fails without the coverage fix for Crisp as well as for Strong.
A piece linked to a global swatch is drawn in the swatch's current color at its own tint, and kept art and rasters follow a color or spot edit and its Undo. A value of `paintOutput` other than true is refused by a translated error. Tests in the effects crate pass the new document argument.
Crisp and Strong reshape each edge pixel by the type's coverage, drawn
in black. Type in the art of a scatter brush on an undashed path drew
that coverage with the path's opacity folded in, so Strong made fully
covered pixels opaque at 50% path opacity. The coverage is now drawn
at full opacity; the pixels keep the folded opacity.
The evidence entry for the Anti-aliasing Method notes that scores and
hours are unchanged.
Generic CMYK's tone curves now pass through the CGATS TR 001 tone value
increase of each ink at 40% and 50% (C 20.0, M 17.6, Y 16.8, K 21.6 at
50%), and its 16 Neugebauer primaries mix linearly, so a single ink's
tints gain as TR 001 gives. The 300% ink limit stays. The primaries, the
black-generation curve and the black point are VectorCraft's own values.
- The black point is 90% black under neutral CMY that fills the ink
limit: sRGB black separates to C75 M68 Y67 K90 instead of C67 M67 Y67
K100.
- Black follows a curve over the gray component of the black-free
solve, raised by how far that solve stays lighter than the target.
Grays from sRGB 177 up carry no black, and sRGB 128 gray separates to
C50.5 M42.2 Y42.0 K7.5 instead of C38.8 M26.3 Y29.9 K24.4.
- Display of CMYK fills, swatches and imported CMYK values and the
separation of RGB and Lab colors use the same model.
Paper white still separates to C0 M0 Y0 K0, but other separations
change, and so does the display of CMYK colors with ink. Tests that held
numbers of the old model are updated.
Found while testing crates/render/src/encode/psd.rs:225
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
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
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.
The reference check now applies wherever a painted effect's geometry is
used: a result whose swatch or pattern is refused keeps its input instead
of giving its geometry. Pathfinder art of type, reshaped groups, compound
shapes, image fills, the renderer's bounds and Object > Expand look the
references up in the document, and the renderer drops its kept bounds and
geometry when the names of the swatches or patterns change.
A gradient placed with the Gradient tool stayed where it was when the
object's Warp effect changed the outline, so the warped shape no longer
matched its gradient.
Under each Warp style the placed gradients of a path now move and scale
from the path's bounds before the warp to its bounds after it, as they
do under Free Distort. This applies to an object's own Warp and to a
fill's or stroke's own (a stroke uses its stroke-inflated bounds), on
the canvas and in Object > Expand of the fill. In a group with a Warp
effect, each path's and compound path's gradient follows its own
bounds, and the own fills of the group and of the groups inside it
follow those groups' bounds. A warp with no bend and no distortion
leaves gradients exactly where they are, and gradients fitted to the
object are unchanged.
This changes how existing documents draw: a placed gradient on art with
a Warp effect now follows the warped outline instead of staying in
place.
How gradients follow the warp is VectorCraft's own rule. What the Warp
effects do to the object is described in
https://helpx.adobe.com/illustrator/using/reshaping-objects-effects.html
A gradient fitted to the object refit to the outline after the object's
Transform effect rotated, reflected or scaled it unevenly, so the
gradient kept running left to right while the shape turned under it.
Object › Transform already turns such a gradient.
A Transform effect that a refit would not reproduce now fixes the
gradient to its fit on the geometry the effect takes, and then maps it
with that effect and the effects after it, as a placed gradient. Under
moves and even scales it draws as a refit does, and an effect that
scales the object to nothing across leaves it fitted. This applies to
an object's own effects, a fill's or stroke's own effects, and a
group's: in a group, the gradients fitted to its paths, to its own
fill, to the groups inside it and to its images' and symbol instances'
own fills each fix to the fit on their own object. Object › Expand of
the fill draws the same.
This changes how existing documents draw: art with a fitted gradient
and a Transform effect that rotates, reflects or scales it unevenly
now shows the gradient turned with the art. How gradients follow the
effect is VectorCraft's own rule.
A blur or shadow over a painted piece is drawn again when a swatch or
pattern the piece names is deleted, or when the tiles of a named pattern
change. The raster's inputs now include the swatch and pattern names and
the pattern definitions for content with a plug-in effect.
Pathfinder effects, compound shapes, Expand Appearance and pattern
expansion now pass the document to the effects they evaluate, so a
painted piece that names a swatch or pattern takes part as drawn instead
of being refused. A path with a painted effect takes part in Pathfinder
and compound shapes as its pieces, each with its own paint, inside the
path's opacity and blend mode.
The renderer's kept effect art and live evaluations now count the
document's swatch and pattern names for objects with a plug-in effect,
so deleting or restoring a swatch a piece names redraws the object.
An envelope mapped type from its laid-out box: ascent to descent for
point type, the frame for area type. The distorted glyphs then filled
less of the envelope than other art does, with room above the capitals
and below the baseline.
The envelope now maps type from the bounds of its glyph outlines,
underlines and strikethroughs when the type is on its own, in groups
and layers, or used as a clipping path. Inline graphics count by their
boxes. Rotated type and type in perspective map from their outlines as
they are drawn. Make with Mesh,
Make with Top Object and Reset with Mesh without Maintain Shape use
those bounds. Type that draws nothing keeps its laid-out box, and so
does type inside any other object, such as a blend, a repeat or a
symbol instance. Shrink Text to Fit type is measured as it is laid out
on the page.
vectorcraft-text's envelope_ink measures the type, and
register_envelope_ink registers it with the document crate. The engine
session, Renderer::new, live evaluation in vectorcraft-effects and the
.ai reader register it. The document crate keeps the measured boxes per
thread, by object and by a hash of the content, and measures again when
the type, the fonts, the hyphenation exceptions or the transform's
scale or rotation change.
This is VectorCraft's own rule. Envelopes of type made in VectorCraft
and in saved files map from the glyph outline bounds instead of the
type's laid-out box, so they redraw differently.
When only anchors of a path or compound path move, the area an edit
changed is now the box of the segments that start or end at a moved
anchor (and the line that closes an open subpath's fill at a moved
end), before and after, grown by the farthest the strokes reach. The
canvas then draws that part of the frame again instead of the whole
object. Objects with a non-solid paint, dashes, a width profile,
arrowheads, a brush, effects or an opacity mask still count whole.
At 1600 x 1200, single-threaded, the frame after one anchor of a filled
closed path moves takes 16.6 million CPU cycles instead of 56.4 million
with 50,000 anchors, and 65.6 million instead of 180.0 million with
200,000 anchors.
Three tests failed on a loaded machine because they asserted elapsed
time. Each now counts the work that the slow behavior it guards
against would repeat, with a counter compiled only into tests:
- The CSS cascade test counts selector tests, at most two per element
(testing every rule against every element tests N x N). It styles
5,000 elements, so the slow behavior fails on the count rather than
on the hang guard, which now waits 300 s.
- The stacked-glow test counts the silhouettes drawn, 30 for 30 glows
with and without the shadow cache.
- The Zstandard frames test counts the bytes looked at to find the
zero padding.
The hang guards for invalid dash patterns, text layout and script
checks of a pipe wait 300 s instead of 20 s.
With Real-time Drawing and Editing off, each pointer move of a drag ran one
boolean union of a group's members to draw its outline. A group of 256
overlapping ellipses took seconds per move, and at 1,024 overlapping ellipses
the union went over its budget and no outline showed.
A move or handle drag now draws the outline of each visible member of a group
or intertwine, and of each object a blend, envelope, repeat, Pathfinder effect
or object effect evaluates to, without uniting them. A gradient mesh draws its
mesh lines and a symbol instance its bounds, as their selection highlights do.
The limit of 100,000 counts outline points and evaluated objects, so a
selection past it shows its moved bounds.
A compound shape or Pathfinder effect still evaluates its boolean on each move,
and so does a clip group whose clipping path is a group.
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
Opening a document laid out every type object for its bounds and
baselines and threw the layouts away, and the first frame laid the same
objects out again. The open now keeps them, up to 128 MiB, and a frame
takes each one once.
A frame takes a layout only for a text object equal to the one laid out,
and only while the fonts, the system fallback setting and the hyphenation
exceptions are unchanged. When the last frame being drawn ends, the rest
are dropped if a frame took one, and all of them are dropped after eight
frames that take none. A layout with bitmap or color glyphs and a text
object with a gradient are not kept.
A 3D effect on a group or layer builds a solid from every path,
compound path and type in it, all turned about one shared axis, as the
public docs describe for groups. Fixes#4506.
The regression test for rebuilding fitted area type after a scale change
used text that overflowed at the minimum size both before and after the
change, so both layouts used the same fit scale and the pixel comparison
did not depend on the fit.
The fixture is now 2 pt type in a small frame, drawn 20 times zoomed in.
It fits at 0.7 of its size, and at 0.733 after a 1.5 times scale. The
test asserts that the two fit scales differ and that the words set at the
earlier fit draw different pixels, and keeps the comparison with a fresh
renderer and the check that the geometry is not reused.
Inner Glow clipped to the art's outline and bled in from outside it; for a
placed image that outline is the frame, so a PNG with transparent areas
glowed along the frame's edge, over pixels that don't show. For an image the
glow is now cast by its pixels' alpha (everything around them, blurred, or
the pixels themselves with Center) and kept to where the image shows, as
much as it shows.
From about 50% zoom on the file of #4155, the pixels drawn are the full 141-megapixel photo,
and in a CMYK document they were separated into ink planes (or colorized, or proofed) whole
for every view: 8 to 9 s of white canvas a zoom step.
When the pixels drawn are larger than a 1,024-pixel tile, their colours are made again for the
frame and part of them is out of view, only the tiles in view are made, each kept under its own
key (`ImageKey::tile`), and drawn together as one pixmap so their edges don't show. The colours
are made pixel by pixel, so the result is the same as for the whole image. CMYK images painting
their own inks are still made whole.
Zooming in to 50%, 100% and 200% on that file went from 9.0, 8.6 and 8.7 s to 0.78, 0.05 and
0.05 s (M3 Pro, one run each), with the same pixels on screen.
With image mips on (the canvas, navigator and layer thumbnails), an image was colorized,
separated into the frame's ink plane and shown through Separations Preview's plates at its
full size, and only then shrunk to the mip drawn. The 141-megapixel image of #4155 made
1.6 GB of planes a frame, more than the image store holds, so every frame made them again.
The mip is now picked first and everything else is made from it, under the keys `kept_mip`
and `nearest_kept` already look up. A CMYK image's own inks are halved with its pixels
(`ink::key_inks`, `images::half_inks`), so it still paints them rather than inks separated
from its displayed colours. Colour bitmap glyphs follow the same order.
On that file the app's first frame went from 9.2 s to 1.6 s and the sharp frame after a pan
from 3.9 s to 8 ms (M3 Pro, one run each). Fine detail now shows its true average: 1-pixel
black and white lines show mid grey, where separating first showed them 44 levels darker.
A linked 1-bit image mask from a .ai file keeps its fill color as a
colorize paint, so the image takes the color once its file is relinked.
Until then the image shows the missing-link placeholder, and the canvas
and PDF export colorized that placeholder too: its light tile turned
nearly transparent and its red cross took the fill color.
ImageBlob::takes_colorize is false for a preview whose pixels are not
grayscale. While it is false, the canvas draws the image and PDF export
writes it as it is, printed separations separate it as an uncolorized
image, and transparency flattening (EPS, PDF 1.3 and PDF/X-1a export,
Flatten Transparency) does not count its paint as transparency. The
paint stays on the image, and a grayscale preview is still colorized.
SVG and EPS export already write only grayscale images colorized.