A path's Drop Shadow, glow, blur, Feather or pixel filter listed before a
Transform effect that makes copies was drawn once under all the copies, at
the object's own distances. Each copy now carries those raster effects,
scaled by the copy's mean scale, with a Drop Shadow's offset turned,
reflected and scaled with the copy. Raster effects listed after the
Transform effect still paint once around all the copies. Copies that stop
at the effect budget keep their effects, and a Transform effect without
copies draws as before.
The canvas, the object's bounds, export, baking and Expand Appearance use
the same art. Type, images, symbol instances, groups, a fill's or stroke's
own copying Transform effect, and paths with Rasterize or an SVG filter
before the copying effect keep one set of raster effects.
With useArtboards off, PDF, .ai and HP-GL exports sized their one page
by every visible object, including art they then leave out. A PDF
without includeNonPrinting or createLayers drops non-printing layers, so
art on such a layer made the page larger than what was drawn, and a
document whose only visible art did not print came out as a blank page.
An HP-GL plot draws nothing of non-printing layers, objects at 0%
opacity, placed images, gradient meshes whose every point is at 0%
opacity and paths that paint nothing, and such art moved the plot's
origin.
The page is now measured with that art hidden, and a document with no
other visible art is refused. A .ai file is measured with the PDF
options it is written with, so it keeps non-printing layers unless both
createLayers and includeNonPrinting are off. The PDF writer's own
non-printing filter uses the same helper, and the HP-GL writer's
plots_nothing says which objects a plot draws nothing of. Export As
measures an HP-GL plot of the art's bounds the same way, so a document
with nothing the plot draws stays in the dialog before the save panel.
object.textWrap.make and object.textWrap.options kept an offset outside
-1000 to 1000 pt at the nearer end of the range, and read an offset that
is not a number, or an invert that is not true or false, as if it had
been left out. Both commands now return an error for such a value and
leave the wrap options and the undo history unchanged. An omitted or
null value still takes the default (6 pt and no invert for Make, the
current options for Text Wrap Options), and Text Wrap Options with only
null values reads the current options. A stored offset outside the range
is kept when only Invert Wrap changes.
The MCP text_wrap tool checks offset, invert and release before it
changes the selection, so a refused call changes nothing, and a release
that is not true or false is an error instead of making a wrap.
A trace handed in for imageTrace.make or imageTrace.makeAndExpand was
matched by its object, image, pixels and settings alone, so a trace made
in one document could stand in for the command in another open document
with the same image and settings. The trace's inputs now carry the
document's uid: TraceRun::current is false in any other document, and the
commands there drop the trace handed in and trace their own image, as one
undo step.
Test: a_trace_run_applies_only_in_its_own_document.
Document::symbol_art_bounds measured a symbol's art without the
document, so an instance of another symbol in that art counted as the
20 x 20 square. It now measures the art through SymbolBoxes, so a nested
instance takes its own symbol's art, and an inline graphic of the outer
symbol is sized by it and follows it when that symbol changes.
- The inline resolve order also follows the instances that size a
symbol's art, so a symbol is measured after the type in the art of
the symbols it holds is laid out again.
- A symbol whose art reaches itself through an instance and an inline
graphic is an empty slot. Only instances that the measurement uses
count, so one a clipping path hides adds no dependency.
- A missing symbol, a symbol without art, a symbol that holds an
instance of itself, and nesting 32 deep still measure as the square.
- SymbolBoxes finds symbols through a name index built once, and the
inline resolve pass and inline_art_bounds share one index, instead
of scanning the symbol list for each lookup.
swatch.spotOptions and swatch.resetDefaults {replace: true} rewrite the
fill and stroke for new art through map_default_paints, which also runs
for command.batch steps. Two tests now run each command on its own and
as a batch step followed by a rectangle, and check that the default
paints and the rectangles match: a Lab spot link keeps its tint and
takes the Lab values or their CMYK equivalent in both directions, and a
link to a swatch the replace removes is dropped while the color stays.
Both tests fail when map_default_paints skips every interaction.
The progress line for swatch steps in a batch names the two commands and
the new tests.
A gradient stop linked to a spot ink that also carries process plates
(a DeviceN stop opened from a PDF) printed only its spot tint: print
separations and Separations Preview left its Cyan, Magenta, Yellow and
Black plates blank. They now print the stop's plates beside the tint.
With spots printed as process, each process plate prints the stop's
plate layered with the spot tint's process equivalent, as a separated
image's spot plates layer. Plates beside no spot link, or beside
Registration, still print nothing of their own.
The color visitor also skipped a freeform gradient's points, so print
plates kept their display colors and Document Color Mode left them
unconverted. The points are now visited as unlinked colors.
swatch.edit stored a replacement gradient without its placement, so a
radial gradient with an aspect, Alt-dropped on a gradient swatch or
given as `paint`, lost that aspect, while swatch.new keeps it and
applies the swatch with it. A gradient given an aspect without `start`
and `end` lost the aspect in both commands. A replacement pattern kept
the tile transform of the swatch it came from, while swatch.new stores
a pattern untransformed, and `paint: {pattern: name}`, which an Alt-drop
of a pattern fill sends, was refused.
swatch.edit and swatch.new now store a gradient or pattern through one
helper: a gradient keeps its aspect, with or without a vector, and holds
no swatch link, and a pattern is untransformed. swatch.edit takes a
pattern by name, as swatch.new does.
brush.freehand drew the plain path when `brush` named no brush in the
document or was not a string, and drew a pencil stroke for any `style`
other than "brush". It now refuses an unknown name with "no brush named
`<name>`", as brush.apply and brush.setCurrent do, a `brush` that is not
a string, and a `style` other than "pencil" or "brush". The document does
not change and no undo step is recorded. A `brush` left out or null still
draws the plain path.
The Paintbrush skips a tool brush or current brush that has been deleted
and paints with the other, or draws the plain path when neither is in the
document, so a stroke after a brush is deleted is not refused.
With points of a gradient mesh picked (Mesh tool, Direct Selection or the
Lasso), a solid fill color from the Color panel recolors just those points,
but the Fill proxy, the Color panel, the Color Wheel and the Control bar's
fill chip kept showing the mesh object's own fill, so the panel's sliders
jumped back after each drag.
- The new `Session::fill_mesh_points` resolves the targets as
`paint.setFill` does: the picked points of every selected mesh, unless the
Appearance panel's active row is a fill or an object of a symbol instance
is selected. When the first selected object is a mesh among them, the Fill
proxy (`paint.proxies`) shows its first picked point's color, and "?"
compares the picked points' colors with each other and with the other
selected objects' fills.
- `Session::mesh_points_picked` lists the points `transparency.set` fades: it
is empty while the Appearance panel's active row takes the opacity, and
`transparency.info` and the Transparency panel now follow it there too.
- The cached "?" state and the Transparency panel's values are recomputed when
other points are picked, which gives the document no new revision.
- The Control bar's opacity shows the first picked point's opacity, which
`transparency.set` changes then.
- The `paint.setFill` and `transparency.set` params texts name the picked
points instead of the point last clicked, and the `paint.proxies` text,
docs/mcp.md and the progress doc describe what the panels show.
When a document opens or is reverted with dimensions whose art is not in
its color mode, the dimensions are drawn again before the document's
composite fonts are registered. A label whose font names a composite font
that another open document defines differently was measured in that other
definition, so it was centered off its anchor. The redraw now measures the
labels in the document's own composite fonts, in front and in the back.
A gradient's Separation or DeviceN space, and EPS's %%DocumentCustomColors,
named the spot ink of every linked stop. A stop out of order whose
neighboring stretches have no width, a stop at a tint of 0 without process
plates, and in PDF a stop whose stretches are fully transparent print no
ink, but their spot inks were still declared, so separations got an empty
plate.
- vectorcraft-color: Gradient::drawn_stops (the rule Document Info uses,
moved here) and Gradient::reached_stops (every stop taken as opaque).
- PDF: Separation and DeviceN shadings, the Perceptual spot shadings and
the spot-image warning name only inks of drawn stops at a tint above 0
or with process plates; other stops are written with no ink, so their
process inks and RGB or Lab colors no longer shape the space either.
- EPS: the same with reached stops, since EPS writes stops opaque; a
transparent spot stop keeps its ink.
Output is unchanged when every stop colors part of the gradient and every
spot stop has a tint above 0 or process plates.
The canvas clips a clip group by its clipping path with the path's live
geometry effects applied, but clicks, hovers and marquees still tested
the plain clipping path. A click where a Transform effect had moved the
clip selected nothing, and a click on the clipping path's own place
selected art that was not drawn there.
- The engine registers the effect-shaped region with the doc crate
(`hit::set_clip_region`), as it does for image paint and live art. It
gives a region only when the clipping path holds a visible geometry
effect; otherwise clicks keep the plain shapes, and type keeps
counting by its frame.
- Clicks, `objects_at`, the hidden art of a selected object, the Unlock
submenu's list and marquees inside a clip group or a clipping layer
use that region. Outline view and layers with Preview off draw no
effects and keep the plain shapes; the Selection, Direct Selection
and Enclosing Lasso marquees pass the view's outline state
(`hit::marquee_in_view`). Each container around a selected object
tests its clipping path in the outline state a click has there.
- A marquee touches the clipping path itself by its own geometry, as a
click on its outline finds it, and also on the edge of the region, so
a marquee around a clipping path that an effect moved into large art
still selects it. `hit::marquee_in` keeps the plain shapes for the
Color Theme Picker, which clips by them.
- The region is kept per thread until the clipping path or the live
inputs change. A clip group's reach takes in the region's box, so
culling does not skip art the region moved past the plain clipping
path. Up to 4096 boxes are kept; when they are full, a new box
replaces only as many others as it needs room for.
Docs: docs/target-app-parity.md.
Create Outlines copied each character run's fills and strokes onto every
glyph, ruby glyph and underline or strikethrough bar as they were, so a
gradient with no vector of its own refitted to each piece's own box,
while the canvas fits it across the whole layout. A gradient with a
vector kept its text-space coordinates in the document, and the
characters' stroke kept its text-space weight on scaled type.
Each piece is now painted by paint_type_piece, the rule outline_text
already used: unplaced gradients are fixed to the layout's bounds, then
the type's transform places the piece, its gradients, stroke weights and
pattern tiles. Object > Expand outlines type the same way, and
object.expand.info measures gradient fills on the same paths.
A CMYK TIFF written again, a CMYK JPEG that the Compression settings
resample or compress again, and a CMYK image written with its mask as
its soft mask lost the CMYK profile the image embeds. Such an image is
now written in an ICCBased space holding that profile, byte for byte,
when output.profiles is all or taggedSource, and in PDF/A-2b, PDF/X-3
and PDF/X-4 unless profiles is destination. Pixels the Output settings
convert are never tagged with it.
A CMYK JPEG embedded as it is now follows the same rule instead of
always carrying its own ICC_PROFILE segments: with profiles none it is
DeviceCMYK, and PDF/X-1a export no longer refuses a CMYK JPEG that
carries a profile.
A profile tags an image only when it is at most 16 MiB and its declared
size, acsp signature, device class, CMYK color space and tag table are
well formed. Tagged CMYK documents blend transparency in the document's
CMYK profile space, not in an image's own; without that space they
blend in DeviceCMYK, or keep their RGB space in PDF/A.
Place, Open and relink read a CMYK or grayscale TIFF with an alpha
channel through extra_samples_tiff_rgba, which cut every 16-bit sample
to its high byte before converting it. A faint ink or a low alpha was
lost: cyan 129 at full alpha showed as white, and an alpha of 129
became fully transparent.
The samples are now normalized at the depth the file stores them, and
only the resulting color and alpha are rounded to 8 bits (a 16-bit
alpha to the nearest 8-bit value). Associated alpha is divided out at
16 bits. A pixel whose associated alpha is zero now has no color,
instead of keeping its stored color. TIFF 6.0's Associated Alpha
Handling section states this arithmetic and the zero-alpha rule for
RGB data; applying them to CMYK and gray samples is VectorCraft's own
rule.
type.ruby, text.setStyle, text.setText, text.fitHeadline, text.reshapeArea,
text.reshapePath and text.setPathHandle recorded an undo step even when the
call left the type as it was: the same ruby reading again, a removal where
there is no ruby, attributes the characters already have, the same text, a
second run of Fit Headline, or a reshape by 0. Each now runs on a copy and
records a step only when one of its type objects (or, for text.setStyle, a
graph's kept label styles) changed; otherwise the undo and redo steps and
the saved state stay as they were.
Area Type Options already skips unchanged options, and Scale Text
Attributes returns an error for type with no scale to bake, so neither
changes. Type Orientation, Optical Margin Alignment, System Layout and
Fractional Widths are fixed in #7505.