Twist was read as a live effect only on an unstroked path or compound
path whose segments were all straight, and on those at any angle.
- A curved path or compound path, or a group, with nothing stroked and
no guide in it now opens with its Twist live when the twist is at
most 90° either way. Larger twists on these keep the file's drawn
look. The 90° limit is VectorCraft's own.
- Paths and compound paths with straight segments and nothing stroked
keep their Twist live at any angle, as before, guides included.
- Stroked objects keep the drawn look, as before.
- .ai save keeps a link to a Twist graphic style on the objects the
reader reads it on, and leaves it out, with the style-link warning,
on the others.
Docs: docs/file-format-parity.md, docs/target-app-parity.md.
SVG Options gets an Include Variable Data checkbox (the `variableData`
option, off by default). With it on, the saved SVG carries the document's
text variables, its data sets' text values and each text variable's bound
type object as a `variableSets` element, in the layout Load Variable
Library already reads. A bound object is named by its element id in a
`docRef="id('...')"` attribute; an object without an id gets one.
Opening such an SVG reads the variable data back: the text variables, the
data sets (none active) and the bindings, so choosing a data set changes
the type again. Variable data that Load Variable Library would refuse is
left out with a warning, and the art opens. Markup that only looks like
the element (in comments, CDATA sections, processing instructions or the
document type declaration) is skipped.
Variables of other kinds, names XML can't hold, more than 256 text
variables or 1,000 data sets, and variable data over 8 MiB or 2,000,000
XML nodes are left out of the file, each with a warning. Type written as
outlines opens as art, so its variables are written unbound, with a
warning.
docs/file-format-parity.md held 36 copies of the paragraph on the
editing copy of a file. #6202 and #6249 each added a combined copy
without removing the copies it replaced, so the count went from 34 to
35 and then to 36. The section now holds one copy: #6249's combined
copy, with the Align to Path distance clause that seven of the other
copies carry from #6247. Every other clause of the removed copies is in
the kept one, word for word or in the newer, longer form another copy
wrote. The older Align to Path clause, with its measurements for one
font at 24 pt, is removed because #6247's wording replaces it. The
paragraph now starts with a capital letter.
The summary table also repeated its "Formats opened or placed" and
"Formats saved (Save As)" rows. The older row of each is removed: the
one that still lists HEIC/HEIF as missing, and the one that lists fewer
contents of the editing copy that `.ai` saves write.
The text document reader never read a story's manual kerning, so type
kerned by hand in a .ai or EPS editing copy came in with automatic
kerning on every pair and drifted from the file's page from each kerned
pair on. Envelopes of such type drew apart from their drawn art and
kept it.
Key 8 of a story's text holds the kerning as runs of characters (key 1),
each with a value in thousandths of an em (key 0 of key 0) or empty
where the automatic kerning applies. Each character with a value now
takes it as its Kerning, the space after it, and the style runs split
where the value changes. A value that can't be read keeps the automatic
kerning, a run whose length can't be read ends the runs there, and past
65,536 runs the characters keep the automatic kerning.
- ate.rs: Story reads the runs (manual_kerning) and node() splits its
text runs at them (Kerns), with a unit test over values, style-run
boundaries, hostile values and the laid-out gap, and one that pins
the limit of runs.
- tests_native.rs: an imported story with kerned and automatic runs.
- docs/file-format-parity.md: status line, mapping line, revision row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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).
- `charpath` in a CIDFont only named, over a predefined CMap, adds the
outlines of the characters its codes stand for, placed as `show` sets
them, and moves the point as `show` does. It added no outlines.
- `cshow` gives its procedure each code of such type, two bytes for a
two-byte code, with the code's width. It split two-byte codes into
single bytes.
- `glyphshow` sets the named character itself. It set the character's
UTF-8 bytes as Latin-1 letters.
- `kshow` runs its procedure between each two codes of such type, with
the two codes' values. It didn't run it. The procedure sees the font
the file set as current, and a font it sets stays current.
- A name that ends in the row-and-cell CMap `H` or `V` splits off the
CMap only when the file defines the CIDFont of that name (as a
resource or with `definefont`), or the name has a hyphen and an
installed face that covers Japanese has it. `Foo-Bold-H` stays a font
of the whole name.
- In a CMap that can't be read (`GBT-H`), each code moves the point one
em, along the line or down the column; a tab or carriage return byte
is a code of its own.
- One parser reads the names of the predefined Unicode CMaps, for EPS
and legacy `.ai` type.
- Outlines added to a path by `charpath` stop at the path's point limit.
- docs/file-format-parity.md, docs/gaps.md and docs/mcp.md describe type
in named CIDFonts over the predefined CMaps.
The editing copy of a PDF-compatible .ai now holds the Brushes panel's
Calligraphic, Scatter and Art brushes in the panel's order, with the art
of Scatter and Art brushes. A path or compound path with a Calligraphic
brush, or with an Art brush in Tints whose art bends along the path,
keeps the brush on its stroke. Other brushed strokes are still written
as their brush's art.
The writer reads each brush back with the reader's code before writing
it. Brushes that would not come back with their settings, brushes past
the reader's limits and every brush on a large canvas are left out with
a warning. A brush that has the name of an earlier brush that was left
out is written, and no path is written with it on its stroke.
An object linked to a graphic style that is left out at the object
limit now also raises the warning about links left out.
Brushes and their options:
https://web.archive.org/web/20241230205225/https://helpx.adobe.com/illustrator/using/brushes.html
Docs: docs/file-format-parity.md.
In the text document of a .ai's editing copy, a character's fill (key
53) or stroke (key 54) is a paint with a colour under key 0 and, under
key 5, the name of an art style of the editing data. For a pattern
swatch, key 0 is black and the pattern is only in that style: a style
of one paint (/SimpleStyle) that paints with `(name) ... [matrix] p`.
The reader took key 0 alone, so type painted with a pattern came in
black.
The art style reader now keeps the pattern of a style that is one
paint, and the import places it as a path's pattern fill would be (its
matrix in art space; the files' own pages tile such type with it), by
the style's name. A run whose fill or stroke is on and names such a
style takes the pattern, in the type's text space, so its tiles stay
where the document has them. A pattern the file doesn't define or can't
place, a key 5 that isn't a string, and a style of any other paint keep
the colour as before.
A style that also has filters gives no pattern for type, and a pattern that
can't be placed in the type's text space keeps the colour. A .ai saved
again writes such type as outlines with a warning, as it already does for
any type with pattern paint (#5965).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Horizontal type keeps both marks, and the legacy .ai writer writes such
type as text, but the marks were dropped without a warning. Version 7
text has operators for both (section 15.3.4 of the published format
specification): Tv for Roman characters upright in vertical writing,
and TY for a Kumi block in horizontal text recorded for later vertical
use. The writer now writes 1 Tv and 0 Tv, and 1 TY and 0 TY, where a
run's mark changes, closes an open Kumi block before the text object
ends, and writes neither operator for type without the marks. The
legacy .ai reader reads both back onto the same characters. The prolog
defines Tv and TY so the file still runs as PostScript.
With Envelope Options > Distort Appearance on, the import tries type in an
envelope mapped from its glyphs, and from its glyphs grown by half its
strokes' weight (#6535), on its own warp and on its saved grid. In users'
files the drawn art of some stroked type maps from the box of what the type
paints instead, which differs from those where:
- the type has sharp corners at its edges (slanted stems, pointed feet) and
miter joins: the miter tip pokes out past half the weight, as far as the
miter limit lets it, though not as far as the bounds with strokes allow
(a miter at every corner);
- a stroke carries a Transform effect that moves it (a drop shadow): the
moved stroke paints past the glyphs on that side;
- a glyph holds a contour of zero length at its edge, which paints nothing:
the glyphs' box counts it.
Such an envelope failed the drawn-art check and kept its drawn art.
After every way it was tried before, and before a grid moved onto its drawn
art, the envelope is now also tried mapped from what its type paints, where
that box is another: its glyph outlines with their fills and strokes baked
as the envelope bakes them under Distort Appearance (geometry effects
applied), each piece measured by its visual bounds. Those are exact for
miter joins (a tip counts where the limit keeps it) and round joins, and an
upper bound for bevel joins, miters the limit cuts, width profiles and
square-capped dashes. Effects on the type object itself are left out, as
VectorCraft applies them after the envelope bends the type. Groups round
type and other objects in the contents are measured as before. A side
within 1e-4 pt of another box's counts as that side, so a box measured two
ways isn't tried twice. The box is measured only when its try comes and a
check is left for it, and once for an envelope: on a synthetic file of 256
envelopes of 2,000 characters each the import takes 13.3 s, as before,
where measuring it up front took 14.7 s.
On 224 of our own files (used locally, never committed), envelopes of type
that open live go from 154 in 45 files to 161 in 50, none fewer in any
file; no file changes whether it opens from its layers or its PDF part.
Tests: ai::envelope::tests::
mitred_type_is_also_tried_mapped_from_what_its_stroke_paints_miter_tips_included,
type_with_a_mitred_character_stroke_is_also_tried_mapped_from_what_it_paints,
a_stroke_moved_by_a_transform_effect_counts_where_it_paints,
round_joined_type_is_not_tried_twice_for_the_same_box,
a_contour_of_zero_length_paints_nothing,
a_side_within_the_slack_of_the_geometric_box_is_that_side, and
tests_native::a_warp_of_mitred_type_maps_from_what_its_stroke_paints_where_its_drawn_art_does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/gaps.md, docs/file-format-parity.md and docs/ui-parity.md still
listed the CNC preset as open after #5500 added it. They now name DXF
Options' Preset menu and dxfPreset: "cnc" on document.exportDxf; VCarve
QA stays open. The ui-parity row also no longer lists native CIRCLE/ARC
export as pending.
VectorCraft could open and place HP-GL plot files but not write them,
so art for a pen plotter or a vinyl cutter had to go through another
program.
Export As, document.export and Export Selection now write HP-GL.
vectorcraft_cad::hpgl::export draws each visible path once along its
own line: a filled shape is its closed outline and a stroked path its
center line. Type is drawn as glyph outlines, a gradient mesh as its
outline, and a symbol instance as its art with its effects and the
instance's stain. Clipping masks cut the art they clip, and the art is
cut at the artboard's edges. Hidden and non-printing layers, hidden objects,
objects at 0% opacity, template layers, guides and placed images are
left out. Coordinates are plotter units (1016 to the inch, y up) from
the artboard's bottom-left corner or its center, and art more than
8,388,607 units from the origin is cut off.
Each color is a pen, in the order the plot first draws in it (up to
255), or a pen table maps each path to the pen of the nearest color.
With Use Artboards every file of the export uses the same numbering.
The pens draw in turn, each in paint order or, with sortPaths, nearest
path first. Curves are flattened to curveTolerance (0.1 pt by default).
hpglVersion "hpgl" writes IN, SP, PU and PD; "hpgl2" also writes the
palette (NP, PC) and each pen's paths as one encoded polyline (PE).
Options are checked, and Export As writes the file with the defaults.
Plots read back by the HP-GL reader give the same lines.
Docs: docs/mcp.md, docs/control-protocol.md, docs/file-format-parity.md,
docs/target-app-parity.md.