In SVG and PDF output, each piece of a warped image whose pieces can show
through was drawn through a mask of every later piece that reaches it. On a
later piece's antialiased edge the viewer multiplies the earlier piece's
coverage by the mask and draws the later piece over it, so an image with
both opaque and partly transparent pixels came out lighter at its opaque
pixels along the triangles' edges (alpha 184 of 255 in the new SVG test).
A later piece now goes into an earlier piece's mask only when a pixel of
either piece's image within 2 pixels of their overlap is less than opaque
(vectorcraft_effects::WarpSeams). Where two pieces overlap over opaque
pixels, the later one is drawn over the earlier one without a mask.
An envelope or the Warp effect cuts an image into triangle pieces that
reach a little past their edges, so neighbors overlap and no seams show.
On an image with alpha, the overlap drew that alpha twice: a 50% image
came out about 75% opaque along every cell edge and diagonal.
- The pieces now form a knockout group, and each piece is marked as a
warp piece (`warp_piece`) whose knockout shape is its whole triangle,
so where pieces overlap only the top one draws.
- The canvas knocks each piece out by its triangle at full coverage.
- SVG and PDF draw the pieces of a partly transparent image (its pixels,
opacity, color mask or colorize paint) through one mask each, of the
later triangles that reach it; pixels on a triangle's antialiased edge
come out slightly lighter there. Pieces of an opaque image are drawn
one over another as before.
- SVG writes one copy of the image for pieces cut by opacity masks
(Preserve Shape Using Transparency) too.
- A cell count past the generated-object budget makes an empty group
instead of overflowing.
Docs: docs/target-app-parity.md.
The Gradient panel's Method menu gets two methods of VectorCraft's own
beside Classic and Perceptual. They mix a linear, radial, conic or
diamond gradient's colors around the hue wheel: hue, saturation and
brightness each change evenly from one stop to the next, and the hue
angle keeps one direction, as the fixed-direction rules of
https://www.w3.org/TR/css-color-4/#hue-interpolation do. Hue Clockwise
lowers the angle (red, magenta, blue), which is clockwise on the color
wheels, and Hue Counterclockwise raises it (red, yellow, green).
Two stops whose hues are less than half a color level apart count as
one hue and keep it, so a color and a tint or shade of it do not turn
the whole wheel. A stop whose RGB numbers are less than half a color
level apart is gray and takes the hue of the stop it mixes with, and
black takes that stop's saturation too.
- `paint.editGradient` and `paint.setFill` take `method: hue-clockwise`
or `hue-counterclockwise`, in any case, with a space or an underscore
for the hyphen or without it; other spellings are an error. The native
file writes `HueClockwise` and `HueCounterclockwise`.
- The canvas and raster exports draw the gradient through stops on its
curve, within half a color level.
- Reverse turns the method the other way with the stops, and a Reflect
spread is repeated from the curve's stops, so both keep the colors.
- SVG and PDF write the gradient as an RGB image, CMYK and spot color
stops included, with the spot warning. EPS writes a shading in process
colors with a warning for spot stops. A legacy .ai file and the .ai
editing data get the colors between the stops as stops of their own,
in process colors, at most 256, with a warning. CSS gets those stops
too.
- The `method` error names the four values, in every catalog.
- The Method menu is as wide as its longest name in the interface
language, within the panel.
Docs: docs/mcp.md, docs/plugins.md, docs/target-app-parity.md, ROADMAP.
PDF export without a PDF/X or PDF/A standard writes pages longer than
200 in at full size in points instead of with a UserUnit scale.
longPagesInPoints is now on by default in PdfSettings, the built-in
presets and the Save PDF dialog. Turning it off writes such a page with a
UserUnit from PDF 1.6 on, as before. PDF/A-2b files keep the UserUnit,
and .ai saves keep it unless longPagesInPoints: true is passed.
Docs: params text, docs/mcp.md, docs/target-app-parity.md.
A print to a file and the print preview list their notes as saves and
exports do since #6920: what the job leaves out of the document or prints
differently first (art outside the imageable area, type in a fallback
font, transparency flattened for PostScript), then the notes on the
options (halftone screens and a fixed flatness that aren't written, copies
per sheet that don't fit, a printer profile left out, ink options that
name no ink). Each kind keeps the order it is given in.
The print layout, the PDF print and the PDF print plan return the notes
on the options in `setting_notes` beside `warnings`, as `ExportReport`
does. The status message after a print to a file names the first note,
so a fixed flatness no longer hides type printed in a fallback font.
- The link watch and links.updateChanged look at a DCS file's plate files
of their own, so a changed plate file is read again.
- links.update and links.relink apply the file's clipping path to the
images in symbols, graph designs, patterns and masks too. When the new
file has no clipping path, a clip group holding the old file's clipping
path loses that path and stays as a plain group of the image, keeping
its id, name, visibility and transparency. The image keeps that path with its plates to tell it from a
clipping mask made in the document; a clipping path given another fill
rule in the document stays. An even-odd clipping path in the file is
kept as the same area under the nonzero rule.
- links.update and links.relink return the swatch warnings file.place
gives, including two files that add one ink in two colors.
- links.relink with copy fails for a DCS file with plate files of its own.
- file.place answers the image id of a clipped DCS placement as image,
and checks page and crop for a DCS file as it does for an EPS file.
- Print separations and Separations Preview take a spot plate's color
from the document's swatch of its ink, and a reduced image's plates
keep their coverage.
- Show DCS Transparency Interactions counts a transparent DCS image and
characters filled or stroked with a transparent gradient.
- %%PlateFile names keep their spaces, and header bytes that are not
UTF-8 are read as Latin-1.
- A plate program that draws more than one image, art besides its image,
or its image through a clipping path is an error naming the plate
instead of printing the wrong ink.
- Nested clipping paths around the composite clip the image together.
- A kept image with more plates than are read, or more TIFF directories
than its composite and plates, is the CMYK image of its composite
only, not a set of plates cut short.
- swatch.unused counts a spot or process swatch as used only while an
image the art shows has a spot plate of its name.
File › Place with Link reads a DCS 1.0 or 2.0 file (an EPS file whose
header names one EPS program per printing plate) as one linked image of
its plates. Each spot plate adds a spot swatch in the CMYK values the
file gives, and the clipping path the file's composite is drawn through
clips the image. document.open, file.place without link or from bytes,
and links.embed refuse a DCS file and change nothing.
- The screen, composite print and exports show the plates mixed into
CMYK. Separations Preview and print separations show each plate on
its own ink; a spot plate prints as its CMYK values when spots print
as process.
- links.list answers the format DCS, and with dcsTransparency marks the
DCS images that are transparent or overlap transparent objects (the
Links panel menu's Show DCS Transparency Interactions).
- swatch.unused leaves out a spot swatch while a DCS image has a plate
of its ink.
- links.update and links.relink read the plates and the clipping path
again, and the link shows as modified when one of its plate files
changes or is gone.
- The plates go on the first plate's pixel grid, grown to hold every
plate where it prints; a plate of another size or position is
resampled onto it.
- A file may name 64 plates, a plate file may be 1 GB, and the plates
together may hold 512 MB of ink amounts. A file naming more plates is
an error.
Docs: docs/mcp.md, docs/target-app-parity.md, docs/file-format-parity.md.
Each writer marks its notes as a loss (something of the document that the
file leaves out or that reaches it changed) or as a note on the options
(an option it didn't apply or applied another way while the art reaches
the file as it looks, or something an option turns off). The PDF, SVG,
EPS, legacy .ai, DXF and HP-GL writers return their notes on the options
in a list of their own (`setting_notes`) beside `warnings`, and the
engine's `Encoded` does the same.
The replies of the save and export commands, and of
`clipboard.exportPdf` and `clipboard.exportPng`, list the losses first,
each kind in the order the writers gave them, across every file that
Export for Screens writes. The status bar names the first note, so an
export to lossy WebP of type in a font that isn't installed now names the
fallback-font note instead of the lossy WebP note. A print to a file
keeps the order its notes are given in.
Gujarati text from a PDF came in jumbled even with its fonts installed:
- A glyph with no advance (a vowel sign or anusvara set over its letter)
was taken for vertical type and opened as an object of its own, which
type then drew on a dotted circle. In a font the file writes
horizontally it now stays on its line.
- A line read glyph by glyph is not always the text that was set: the
file draws a vowel sign before the consonant it follows, and may not
name a conjunct. A line with characters of U+0900 to U+0DFF is now set
again and its glyphs compared with the ink the file drew; when they
differ the line keeps the file's glyphs as outlines, with a note.
Tests: crates/pdf/src/tests/reshaped.rs (two fail without the change).
A linear, radial, conic or diamond gradient has a spread: Pad (the
default, as before), Repeat or Reflect, with a count of 1 to 100
(VectorCraft's own limit). Repeat and Reflect run the stops that many
times along the vector (around the turn for a conic) and keep going past
both ends, Reflect running every other run backwards, as SVG's
spreadMethod does.
The Gradient panel has a Spread menu and a Repeats field, and the
Gradient tool marks where the runs meet. paint.setFill and
paint.editGradient take `spread` and `repeats`; bad values are errors.
Presets, swatches, blends, strokes along or across a path, Outline
Stroke and Object › Expand follow the spread; Expand gives each run the
same whole number of objects, and Outline Stroke's mesh keeps the color
on each side of a sharp step between two stops at one offset.
SVG writes and reads spreadMethod: SVG import now reads a repeating or
reflecting gradient as one that repeats or reflects once, instead of
expanding its stops over the shape. CSS writes repeating gradients.
PDF writes a conic's sweep shading over one run. PDF, EPS, legacy .ai
and the .ai editing data write the other kinds with their stops
repeated across the shape: at most 256 runs and 16,384 stops (256 stops
in .ai files), and for a radial or diamond no farther than 65,536 runs
from its center, with a warning past those. PDF import now finds sharp
steps in any axial or radial shading instead of blurring them.
Docs: docs/mcp.md (Spread), docs/target-app-parity.md, docs/gaps.md.
- 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.
Object › Plug-ins › Image Tools gains Color Mask… (`addon.image.colorMask`),
Remove Color Mask and Apply Color Mask. Color Mask hides colors of the
selected images without changing their pixels. It matches colors as Remove
Background does: the edge color, the corner color or picked colors, with
Contiguous, Match, Tolerance and Softness. The mask is kept with the image
object and saved with the document: its settings, and a PNG of the image's
pixels with the hidden colors made clear, at the source's depth with its
color profile and resolution. It is a VectorCraft addition.
- The canvas (clip groups and white-shape opacity masks included),
printing and separations, PDF (soft masks of CMYK images included), SVG,
EPS, the raster formats, the legacy .ai and .ai editing data, EMF/WMF,
DXF and the flattener draw the masked pixels. A linked image stays
linked, and an output that would refer to its file writes the masked
pixels instead.
- Copy and paste, placing a document and placed documents carry the masked
pixels with the image, under the names they are given there.
- The dialog opens on the selected image's mask settings, with a Preview.
Without settings, the command returns them and changes nothing.
- Setting, removing and applying a mask are each one undo step, and no
step is added when nothing changes. Apply makes the masked pixels the
image's own and embeds a linked image. A mask that hides nothing is only
taken off, and the image keeps its pixels and its link.
- When an image's own pixels are replaced (Update Link, Relink, Crop
Image, a recolor, a linked file read again on open), its mask is made
again for the new pixels, in every art tree and in opacity-mask art.
Crop Image cuts the image's own pixels. When the new pixels can't be
masked, the mask keeps its settings and hides nothing.
- Objects in `ids` that are not images, CMYK images, linked images that
show their preview, images past the decode allowance, masks that would
hide every pixel, and grayscale images colorized with a process color
are refused. The Eyedropper, Object Mosaic, Create Gradient Mesh, Crop
Image's trim and Image Trace read the image's own pixels.
- An image is selected by a click anywhere in its frame, as before.
Remove Background now also refuses a grayscale image colorized with a
process color. Its result has an alpha channel, and a process color is
refused on a grayscale image with transparency.
Docs: docs/mcp.md (Image Tools add-on › Color Mask),
docs/target-app-parity.md.
The Stroke panel menu's Edit Arrowheads… (stroke.arrowheads.edit) opens
Arrowheads.vectorcraft next to the preferences, creating it with one
example head when it is missing. Each symbol in the file is one head,
listed by name after the built-in heads in both arrowhead menus: it
points right, its registration point is the tip, and its height is drawn
as wide as the built-in heads. The file is read at startup and again
each time VectorCraft saves it; stroke.arrowheads.reload and
stroke.arrowheads.list read and list it.
Arrowhead gets a Custom variant, appended after the built-in names, that
carries the head's name and outline, so a document that uses one draws,
saves, reopens and exports it without the arrowheads file. stroke.set
takes {"custom": name} or the {"Custom": {name, path}} form that
document.inspect reports.
Part of #5421.
The check that a PDF/X-1a or PDF/X-3 file has no transparency read names
in literal strings and comments as syntax. The file identifier is a
base64 hash of the file, so a file could now and then hold `/BM` or
`/Lab` there and its export was refused as having blend modes or Lab
colors. The check now leaves out the text of literal strings and
comments as well as stream data.
A new gradient kind, `diamond`, runs its stops from the center (the
start) out to a square with a corner at the end of the vector; the
aspect stretches the square across the vector into a rhombus. The
Gradient panel's Type row has a Diamond button, the Gradient tool draws
the square with the aspect handle and center ring, and a gradient
fitted to an object covers its box.
- Model and canvas: the level is |x| + |y| in the square's frame; a
square with no area (no vector, an aspect of 0, numbers out of range)
paints the last stop. The canvas draws it as pixels, out to a
stroke's miters, caps and arrowheads. Transforms keep the vector and
take the mapped size across it as the aspect.
- Commands: `paint.setFill`, `paint.editGradient` and
`paint.setGradientGeom` take `kind: "diamond"`; a negative aspect or
a focal point is an error. A conic or diamond gradient that a plug-in
returns with a focal point loses the focal point.
- Gradient tool: dragging the aspect handle of a radial or diamond
gradient whose file gave it a negative aspect now sets a positive
aspect; only a conic's negative aspect mirrors it.
- Export: PDF, SVG, EPS and legacy .ai write four linear gradients, one
for each quarter of the square, clipped to the shape (PDF as axial
shadings). PDF and SVG write an image for translucent stops, a
dithered fill or a flat square, and for the Perceptual method unless
PDF writes the stops as spot color shadings. SVG writes a diamond on
type characters as a radial gradient through the corners, and so
does CSS. A swatch library saved as CSS gets four corner layers, a
value for the `background` property (a circle when the swatch is
turned by an angle that is not a multiple of 90 degrees). The .ai
editing data holds a radial gradient through the corners. The
document exports give a warning.
- SVG export: a stroke drawn as an image, as conic wedges or as diamond
quarters now covers the miters, caps and arrowheads that reach past
its paint box.
- PDF import reads a function-based shading whose color is the same
along each square about the origin of its space as a diamond.
- Object > Expand gives nested squares or a mesh of rings.
Docs: docs/mcp.md, docs/target-app-parity.md.
A fourth gradient kind, conic (also accepted as `angle` or `conical`),
sweeps the stops once around the center (the gradient's start),
clockwise on the page from the vector, with a seam where the last stop
meets the first. A negative aspect mirrors the sweep, and reflecting an
object turns its sweep the other way, also for a conic without a
vector or with a flat extent.
- Gradient panel: a Conic button in the Type row; the Aspect Ratio
field works for conic gradients and keeps a mirrored sweep mirrored.
- Gradient tool: the extent ellipse, aspect handle and center ring of a
radial gradient, without a focal point.
- Rendering, swatch chips, transforms, warps, plug-in round trips, and
Object > Expand into wedges or a mesh of columns around the center.
- Commands: a negative `aspect` is an error for linear and radial
gradients, and so is a `focal` point for a conic gradient.
- PDF export writes a function-based shading whose calculator function
turns the angle into the ramp, and PDF import reads a function-based
shading that turns around the origin of its space back as a conic
gradient, also when that origin lies outside the painted area. A
PDF/A file, or a conic with more than 97 stops, gets an image
instead.
- SVG export writes 360 solid wedges clipped to the shape for opaque
stops and an image otherwise, and a linear gradient on characters.
- CSS export writes `conic-gradient(from ...)`, with the stops mirrored
for a mirrored sweep.
- EPS and legacy .ai export write 360 solid wedges; the .ai editing data
holds a linear gradient along the vector with the same stops.
- .af files: conical gradients open as conic gradients.
- An export that writes the gradient in another form gives a warning.
Supersedes #2326 and includes switch87's code from it.
Co-authored-by: Gert Pellin <gert@pellin.be>
A PDF/A file at PDF 1.4 has no UserUnit, so a page longer than 14,400 pt is written in points with or without longPagesInPoints. The param text, docs/mcp.md and the exporter comment now say that only PDF/A files at PDF 1.5 and later keep the UserUnit.
PDF/A-2 limits page boundaries to 14,400 units (ISO 19005-2, 6.1.13), and
PDF 1.4 has no UserUnit. A PDF/A-2b export at PDF 1.4 with a page longer
than 14,400 pt was written in points, with a MediaBox over 14,400 units,
whether or not longPagesInPoints was on.
Such a file is now written as PDF 1.6 with a UserUnit and a warning that
names the version, as PDF 1.5 files already are. PDF/A-2 files may declare
PDF 1.0 to 1.7. Pages past 32,767 pt that aren't whole numbers of points
are written too, since the refusal applies only to PDF 1.3 and 1.4 files.
Files whose pages are all 14,400 pt or shorter stay PDF 1.4.
longPagesInPoints now applies only to files without a standard. PDF/A-2 limits page
boundaries to 14,400 units (ISO 19005-2, 6.1.13), so a PDF/A file with a page longer than
200 in keeps its UserUnit whether the option is on or off. The Save PDF dialog disables the
checkbox for PDF/A as it does for PDF/X.
Follows #6643.