mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-14 15:57:49 +00:00
Merge main into fix/fr-message-rows
This commit is contained in:
@@ -948,7 +948,7 @@ events take `pressure` (0..1, default 1): it is the Liquify intensity while Use
|
||||
|
||||
Freehand Tool Options: double-clicking the Pencil, Paintbrush, Smooth, Blob Brush or Eraser tool
|
||||
(`tool.options {tool: "pencil"}`) opens a `freehandOptions` dialog. Its fields are `tool` and the options the tool
|
||||
keeps: `fidelity` (screen pixels for the Pencil and Paintbrush, the same at any zoom; pt for Smooth and Blob Brush), `fill` (Pencil, Paintbrush), `keepSelected` (Pencil,
|
||||
keeps: `fidelity` (screen pixels for the Pencil, Paintbrush and Smooth, the same at any zoom; pt for the Blob Brush), `fill` (Pencil, Paintbrush), `keepSelected` (Pencil,
|
||||
Paintbrush, Blob Brush; on by default for the Pencil and Paintbrush and off for the Blob Brush, and while it is off
|
||||
the path a stroke draws, continues or merges into is not selected afterwards), `mergeOnlySelection` (Blob Brush;
|
||||
off by default, and while it is on a stroke merges only with selected blobs), `closeWithin` and `editWithin`
|
||||
|
||||
@@ -40,6 +40,13 @@ community. The stroke corner names (Bevel Join, Miter Join, Round Join) and the
|
||||
जॉइन. `hindi_rows_use_one_term_for_a_variable_and_for_joining_paths` checks both terms in every
|
||||
row.
|
||||
|
||||
A sentence keeps no English connecting word such as "or", "must" or "give": write या, होना
|
||||
चाहिए and दें. Parameter names, enum values and command IDs stay in English, and a list of
|
||||
accepted values such as `(left|right|top|bottom)` keeps the English's spelling and its `|`
|
||||
separators. `hindi_rows_keep_no_english_words_in_their_sentences` checks every row outside
|
||||
backticks, quotes, braces and brackets, and `hindi_messages_keep_their_lists_of_accepted_values`
|
||||
checks every `@msg` row's lists.
|
||||
|
||||
## Terminology
|
||||
|
||||
| English | Hindi |
|
||||
|
||||
+94
-10
@@ -761,8 +761,15 @@ outline, so these commands do not store a stroke paint or weight for a series th
|
||||
`paint.swap`, they still store a stroke opacity and blend mode set on a band, and the band's outline takes them. Graph
|
||||
designs keep their own paint. A row that had no
|
||||
paint before the command and has none after it does not change the paint the graph stores. `paint.setFill`,
|
||||
`paint.setStroke`, `paint.none` and the commands that apply one paint kind to the other store the topmost row of the kind
|
||||
even when it is hidden, and store a stroke set on a band.
|
||||
`paint.setStroke`, `paint.none`, `addon.color.fillToStroke` and `addon.color.strokeToFill` follow the same rules, and so
|
||||
does `library.use` when it applies a gradient or pattern. They write the topmost row of the kind; `paint.setFill` and
|
||||
`paint.setStroke` write the row `item` names instead, and without ids the three `paint.*` commands write the active
|
||||
row of the Appearance panel when it is of that kind. The graph stores only the paint of the topmost visible row of the
|
||||
kind, and only when the command wrote that row or changed its paint or weight. A paint written to a hidden row or to a
|
||||
row under the topmost visible one is not stored, also when that row shows through a translucent row above it, and the
|
||||
mark loses it when the graph is drawn again. A mark whose row
|
||||
already has the paint counts as written, so its paint replaces the one another mark of the series left on the graph.
|
||||
When one of these commands writes several paths of a series, the frontmost of them sets what the graph stores.
|
||||
|
||||
`appearance.addFill`, `appearance.addStroke`, `appearance.setItem`, `appearance.removeItem`,
|
||||
`appearance.duplicateItem`, `appearance.moveItem`, `appearance.clear`, `appearance.reduceToBasic`,
|
||||
@@ -809,6 +816,22 @@ kind takes them when the graph is drawn again. The graph saves the paragraph att
|
||||
`categoriesPara` and `legendPara` in its label styles, and still sets each label's alignment for its place. The legend
|
||||
leaves room for a legend label's stored indents, spacing and leading.
|
||||
|
||||
The `appearance.*` commands, `graphicStyle.apply` and `graphicStyle.redefine`, and the paint, stroke, gradient and
|
||||
transparency commands given an `item` (or the Appearance panel's active row) store a graph label's object rows for its
|
||||
kind of label: the paint, weight, opacity and blend mode of its topmost visible fill and stroke row, their order and
|
||||
their place relative to the Characters row, and the label's object opacity and blend mode. They store them even when the
|
||||
label already showed them. `transparency.set` without an `item`, `object.setProps` with an opacity or blend mode, and
|
||||
an `appearance.copyFrom` (Eyedropper) pick of transparency store only the label's object opacity and blend mode;
|
||||
`appearance.copyFrom` with `append` stores the rows. When the graph is drawn again, every label of that kind gets what
|
||||
is stored, with a placed gradient fitted to each label, and the graph saves it as `valuesRows`, `categoriesRows` and
|
||||
`legendRows` in its label styles. Rows below the topmost one of each kind, a row's effects, other stroke options (caps,
|
||||
joins, dashes) and effects applied with `effect.*` are not stored. When labels of one kind are edited together, the
|
||||
last one in the order of the targets (`ids` as given, otherwise paint order) sets what the kind keeps.
|
||||
`appearance.copyFrom` onto the whole text of a label also stores the character attributes it applies and, from type,
|
||||
the paragraph attributes. `paint.setFill` and `paint.setStroke` store a character fill or stroke when the paint goes to
|
||||
the label's characters (the whole label, or all of its text highlighted with the Type tool), and the row when it goes to
|
||||
a row. A stored character gradient also fits each label.
|
||||
|
||||
`effect.apply {"effect": "path.outlineObject"}` (Effect › Path › Outline Object) takes no parameters. Type that carries
|
||||
it is drawn, exported and expanded as its glyph outlines and stays editable type, and the effects after it reshape
|
||||
those outlines. On paths, compound paths and images it does not change what is drawn. On an image's own fill or stroke
|
||||
@@ -1065,6 +1088,8 @@ Images follow the `compression` settings of their kind (`color`, `gray`, or `mon
|
||||
`abovePpi` as placed they are resampled (`downsample`: `average`, `subsample` or `bicubic`) to `ppi`, and compressed
|
||||
with `zip`, `jpeg` (at `quality`; images with transparency stay lossless) or `auto` (JPEGs stay JPEG, the others
|
||||
lossless). `none`, `jpeg2000`, CCITT and `runLength` are written as ZIP, with a warning when an image needs them.
|
||||
The pieces of an image bent by a Warp effect are resampled once, for the widest and the highest size any piece places
|
||||
the image at, and all paint that one image.
|
||||
A 16-bit PNG that is not resampled, recompressed or converted keeps its 16 bits a sample in PDF 1.5 and later files,
|
||||
and is written at 8 bits in PDF 1.3 and 1.4 files.
|
||||
CMYK images stay CMYK (DeviceCMYK, or ICC-based with the CMYK profile when colours are tagged, as in PDF/X-3 and
|
||||
@@ -1098,7 +1123,10 @@ ignore `UserUnit` show such a page at its full size. The option applies
|
||||
only to files without a standard: PDF/X files write such a page in points anyway, and PDF/A files keep the `UserUnit`, which
|
||||
keeps their page boundaries within PDF/A-2's limit of 14,400 units (ISO 19005-2, 6.1.13), a PDF/A file at PDF 1.4
|
||||
included (written as PDF 1.6). The dialog disables the
|
||||
checkbox when a standard is chosen. In PDF 1.3 and 1.4 files, PDF/X-1a and PDF/X-3 among them, a real number can
|
||||
checkbox when a standard is chosen. In a PDF without a standard (the option
|
||||
off, PDF 1.5 or later), the warning for a page written with a `UserUnit` above 1 ends by naming the option; in PDF/A
|
||||
files and `.ai` saves it does not.
|
||||
In PDF 1.3 and 1.4 files, PDF/X-1a and PDF/X-3 among them, a real number can
|
||||
be at most 32,767, and whole numbers are written as integers: a page longer than 32,767 pt whose sides aren't whole
|
||||
numbers of points fails the export with an error naming the page before the thumbnails are drawn and the transparency is
|
||||
flattened, and one whose art needs a real number past 32,767 fails with the same error when the file is written. A page whose short side is 3 pt or longer but would be under 3 units at that
|
||||
@@ -2664,7 +2692,10 @@ compound path or symbol instance selected, it finds the objects of the same shap
|
||||
ones), among those `select.all` would take and the objects in their groups, and returns `{active: true, count, ids}`,
|
||||
the selected object first (at most 10,000). With a group of such objects selected (nested groups and clipping paths
|
||||
included; not type or images), it finds the groups like it: as many objects, in the same order, each of the same
|
||||
shape, lying the same way relative to each other (the group moved or scaled as a whole). `appearance` also asks for
|
||||
shape, lying the same way relative to each other (the group moved or scaled as a whole). While Global Edit is off,
|
||||
the command is disabled for any other selection, including a group that holds type, an image or nothing (it is off in
|
||||
the Select menu, the Properties panel's Quick Actions do not show it, and the Control bar does not show its Global Edit
|
||||
Options). `appearance` also asks for
|
||||
the same fill and stroke (for groups, of each object in them), `size` for the same width and height; `artboards` is
|
||||
`"all"` or a range such as `"1, 3-5"`, and `includeCanvas: false` leaves out the objects on no artboard. Missing
|
||||
params come from `select.globalEditOptions` (the Global Edit Options, kept for the session; it returns them with
|
||||
@@ -3440,7 +3471,10 @@ already walks Image Trace. Short agent entry points:
|
||||
tool opens them, dialog `livePaintSelectionOptions`) are `selectFills` and `selectStrokes` (both on), `color` (the
|
||||
highlight color, `#rrggbb` or a layer color's name; `#ff2a2a`) and `width` (the highlight's width, 1 to 20 screen
|
||||
pixels; 4). The dialog's OK gives an error for a `color` with an alpha part (`#rrggbbaa` or `#rgba`) and changes
|
||||
nothing.
|
||||
nothing. `tool.setOption` gives an error that names the option and sets none of the values, whether the tool is
|
||||
chosen or not, for a `selectFills` or `selectStrokes` that is not `true` or `false`, a `color` that is not `#rrggbb`,
|
||||
`#rgb` (with or without `#`), a layer color's name or a basic color name such as `white`, or that has an alpha part,
|
||||
a `width` that is not a number, and an option the tool does not have. A `width` outside 1 to 20 is set to 1 or 20.
|
||||
With `selectStrokes` off, Alt-click selects the face under the pointer as a click does; with
|
||||
`selectFills` off, a click selects the edge nearest the pointer as Alt-click does; with both off, a click selects
|
||||
no face or edge. A drag of 3 screen pixels or more draws a marquee, and the release runs `select.set {ids}` with
|
||||
@@ -3457,7 +3491,11 @@ already walks Image Trace. Short agent entry points:
|
||||
them, dialog `livePaintBucketOptions`) are `paintFills` (on), `paintStrokes` (off), `highlight` (on), `color` (the
|
||||
highlight color, `#rrggbb` or a layer color's name; `#ff2a2a`) and `width` (the face highlight's width, 1 to 20 screen
|
||||
pixels; 4; an edge's highlight is half as wide). The dialog's OK gives an error for a `color` with an alpha part
|
||||
(`#rrggbbaa` or `#rgba`) and changes nothing. With `paintFills` alone on, a click runs `livePaint.fill` and Shift-click runs `livePaint.strokeEdge`.
|
||||
(`#rrggbbaa` or `#rgba`) and changes nothing. `tool.setOption` gives an error that names the option and sets none of
|
||||
the values, whether the tool is chosen or not, for a `paintFills`, `paintStrokes` or `highlight` that is not `true`
|
||||
or `false`, a `color` that is not `#rrggbb`, `#rgb` (with or without `#`), a layer color's name or a basic color name
|
||||
such as `white`, or that has an alpha part, a `width` that is not a number, and an option the tool does not have. A
|
||||
`width` outside 1 to 20 is set to 1 or 20. With `paintFills` alone on, a click runs `livePaint.fill` and Shift-click runs `livePaint.strokeEdge`.
|
||||
With `paintStrokes` alone on, a click runs `livePaint.strokeEdge` on the edge within 4 screen pixels of the pointer,
|
||||
or nothing when none is in reach, and Shift-click runs `livePaint.fill`. With both on, a click runs
|
||||
`livePaint.strokeEdge` when an edge is within 4 screen pixels of the pointer and `livePaint.fill` otherwise, and
|
||||
@@ -5442,6 +5480,11 @@ length that isn't a number above 0 is an error. An ellipse (Ellipse Properties):
|
||||
counterclockwise from 3 o'clock; 0 to 360 is the whole ellipse) and `invertPie: true`, which swaps them. Each call is
|
||||
one undo step.
|
||||
|
||||
`object.setLiveShape` returns a parameter error, and leaves the document and its undo history as they were, for a key
|
||||
it does not take, at the top level (`` unknown parameter `path` ``) or in one of `items`
|
||||
(`` unknown parameter `items[0].corner`; did you mean `items[0].corners`? ``), for a `sides` that is not a whole number
|
||||
from 3 to 1000, such as 2.5, 2 or 1001, and for a negative `radius`. A `radius` of 0 removes the rounding.
|
||||
|
||||
```json
|
||||
{"name":"run_command","arguments":{"command":"object.setLiveShape","params":{"sides":8,"polygonAngle":22.5,"sideLength":40}}}
|
||||
{"name":"run_command","arguments":{"command":"object.setLiveShape","params":{"makeSidesEqual":true}}}
|
||||
@@ -9750,6 +9793,11 @@ active the active artboard (the navigator's and the Artboards panel's).
|
||||
{"name":"run_command","arguments":{"command":"tool.setOption","params":{"tool":"twirl","values":{"width":60,"rate":90}}}}
|
||||
```
|
||||
|
||||
The Pencil's, the Paintbrush's and the Smooth tool's `fidelity` is in screen pixels: the tools send `path.freehand` and
|
||||
`path.smoothRegion` the option divided by the zoom, so a stroke keeps as many points and a Smooth drag smooths as much
|
||||
at any zoom. The Smooth tool's `fidelity` (0.05 to 100 px, 2.5 by default) is also the one an Alt smoothing drag with
|
||||
the Pencil, Paintbrush or Blob Brush uses. The Blob Brush's `fidelity` is in points.
|
||||
|
||||
`tool.options {tool}` opens what double-clicking the tool's button opens (its params doc lists every tool), in the
|
||||
desktop app. The Flare tool's are its Flare Tool Options (dialog `flareOptions`): `diameter` and `pathLength` (pt),
|
||||
`opacity`, `brightness`, `growth`, `fuzziness`, `longest`, `rayFuzziness` and `largest` (%), `rays`, `rings`,
|
||||
@@ -9789,7 +9837,12 @@ pointer show the current fill and the swatches before and after it), `selection`
|
||||
default; when it is off, merge mode shades no regions), `gapDetection` (off) with `gapLength` (pt, 0 to 72; 3), `clickStrokeSplitsPath` (In Merge Mode,
|
||||
Clicking Stroke Splits the Path; off), `highlightStroke` (Highlight Stroke When Editable; on) and `highlightColor`
|
||||
(`#rrggbb` or a layer color's name; `#ff4f4f`, the layer color Red). The dialog's OK gives an error for a
|
||||
`highlightColor` with an alpha part (`#rrggbbaa` or `#rgba`) and changes nothing. With `clickStrokeSplitsPath` on, in merge mode,
|
||||
`highlightColor` with an alpha part (`#rrggbbaa` or `#rgba`) and changes nothing. `tool.setOption` gives an error that
|
||||
names the option and sets none of the values, whether the tool is chosen or not, for a switch that is not `true` or
|
||||
`false`, a `pickColorFrom` other than `artwork` or `swatches`, a `selection` other than `freeform` or `straightLine`, a
|
||||
`gapLength` that is not a number, a `highlightColor` that is not `#rrggbb`, `#rgb` (with or without `#`), a layer
|
||||
color's name or a basic color name such as `white`, or that has an alpha part, and an option the tool does not have. A
|
||||
`gapLength` outside 0 to 72 is set to 0 or 72. With `clickStrokeSplitsPath` on, in merge mode,
|
||||
the pointer shows scissors within 4 screen pixels of a stroke, `highlightStroke` draws the run of stroke under it in
|
||||
`highlightColor`, and a click splits that run off its path: the run goes from the anchor or crossing point before the
|
||||
pointer to the one after it, the path keeps the rest of it, and a copy of the path with the run, in the path's
|
||||
@@ -10874,9 +10927,9 @@ it ends up in front), baked with `effect.expandAppearance`, then `object.pathfin
|
||||
|
||||
## Cutting Tools add-on
|
||||
|
||||
Cutting Tools is a built-in add-on that prepares art for cutting. Its commands are `addon.cutting.bridges` and
|
||||
`addon.cutting.weed`; in the desktop app they are Object › Plug-ins › Cutting Tools › Stencil Bridges… and Weed Box and
|
||||
Lines….
|
||||
Cutting Tools is a built-in add-on that prepares art for cutting. Its commands are `addon.cutting.bridges`,
|
||||
`addon.cutting.weed` and `addon.cutting.banner`; in the desktop app they are Object › Plug-ins › Cutting Tools › Stencil
|
||||
Bridges…, Weed Box and Lines… and Banner Hems and Grommets….
|
||||
|
||||
### Stencil Bridges
|
||||
|
||||
@@ -10966,6 +11019,37 @@ dialog with Preview; a Spacing above 0 is used instead of the Count.
|
||||
{"name":"run_command","arguments":{"command":"addon.cutting.weed","params":{"margin":"0.25 in","direction":"both","spacing":"2 in","gap":1}}}
|
||||
```
|
||||
|
||||
### Banner Hems and Grommets
|
||||
|
||||
`addon.cutting.banner {hem?, grommets?, spacing?, grommetInset?, diameter?, top?, right?, bottom?, left?, weight?,
|
||||
swatch?, allArtboards?}` marks where a printed banner is hemmed, its edge folded back and sewn
|
||||
([hem](https://en.wikipedia.org/wiki/Hem)), and where grommets, rings set into the material to hang it, are punched
|
||||
([grommet](https://en.wikipedia.org/wiki/Grommet)). The ranges, defaults and rules below are VectorCraft's own. The banner
|
||||
is the bounds of the selected art, or each artboard when `allArtboards` is true (the default when nothing is selected).
|
||||
`top`, `right`, `bottom` and `left` (each true by default) choose the sides that get marks. On each chosen side a hem
|
||||
line runs the whole length of the edge, `hem` points inside it (0 to 100000, default 72; 0 leaves the hem lines out).
|
||||
With `grommets` on (the default), each chosen side gets grommet marks `grommetInset` points inside the edge (0 to
|
||||
100000, default 36): one at each end of the side, `grommetInset` from the edges across it, and the rest spread evenly
|
||||
between them, as few as keep them at most `spacing` points apart (more than 0 and at most 100000, default 1728, 24 in). A corner that two
|
||||
chosen sides share has one grommet. Each grommet mark is a circle `diameter` points wide (0.01 to 1000, default 27) with
|
||||
a cross through its center. The marks are stroked `weight` points wide (0.01 to 1000, default 0.3) in the color swatch
|
||||
`swatch` (default `"[Registration]"`), with no fill.
|
||||
|
||||
Each banner gets one group named "Banner Marks", holding its hem lines (named "Hem") and its grommets (groups named
|
||||
"Grommet"), added on top of the current layer and selected, as one undo step. While a clip group, or a group inside one,
|
||||
is edited in isolation, the groups go on top of the container that holds the outermost clip group around it. The command
|
||||
fails with every side off, with no hem and no grommets, with nothing selected while `allArtboards` is false, when a
|
||||
banner has no width or height, when a `hem` above 0 reaches the far edge of the banner (the full height with only one
|
||||
of the top and bottom chosen, or the full width with only one of the left and right) or meets the hem on the opposite
|
||||
side (half the height or width with both chosen), when a `grommetInset` does the same for the grommets or is more than half
|
||||
the length of a chosen side, and when the grommets would be more than 100000. Result:
|
||||
`{id, ids, hems, grommets}`: the first group's id, every group's id, and the number of hem lines and grommet marks.
|
||||
Banner Hems and Grommets… opens the command dialog with Preview.
|
||||
|
||||
```json
|
||||
{"name":"run_command","arguments":{"command":"addon.cutting.banner","params":{"hem":"1 in","grommetInset":"0.5 in","spacing":"2 ft"}}}
|
||||
```
|
||||
|
||||
## Color Effects add-on
|
||||
|
||||
Color Effects is a built-in add-on: its effects are colour adjustments in Effect › Color Effects, its command is
|
||||
|
||||
@@ -41,6 +41,7 @@ Window → Help Bar toggles the bottom tool-help strip independently of the stat
|
||||
The shared assessment status line and revision history are current upstream; this dated section records the submission's feature evidence and revisions without rescoring upstream or claiming a new combined build or runtime measurement.
|
||||
|
||||
- File formats and Type core (#6147): `.ai`/EPS type from the text document keeps its paragraphs' tab stops, and right-aligned area type sets the text before a line's last tab at its stops, from the left edge, and the text after it against the right edge. Evidence: `ate::tests::a_paragraph_keeps_its_tab_stops`, `ate::tests::a_story_s_tab_stops_are_bounded`, `tests::right_aligned_area_type_sets_the_text_after_its_last_tab_against_the_edge`, `import_fuzz::text_frames_with_hostile_paragraph_attributes_never_panic`; scores and estimates unchanged
|
||||
- Type core: a right-to-left line with tabs is measured in the order it is drawn, with tab stops still measured from the left edge. Each tab goes to its stop from where the glyphs drawn before it end, and right, center and decimal stops align the text drawn after the tab. Right, Auto and centered lines are aligned by that width, and area type wraps a line that is too wide when drawn. Evidence: `tests::justify::a_right_to_left_line_with_a_tab_is_aligned_as_it_is_drawn`, `tests::justify::a_right_to_left_line_with_a_tab_wraps_when_it_does_not_fit_as_drawn`, `tests::justify::right_to_left_tab_stops_align_the_text_drawn_after_them`, `tests::justify::a_right_to_left_line_with_two_tabs_and_a_latin_run_ends_on_the_right_edge`, `tests::justify::right_aligned_right_to_left_point_type_with_a_tab_ends_at_its_origin`; scores and estimates unchanged
|
||||
- File formats and Type core (#6137): `.ai`/EPS type from the text document keeps auto leading at the paragraph's share of each line's largest type, the paragraph's hyphenation options, and may show more of the last lines the file sets in an area frame of its own, when growing the frame by its lines' deepest descent plus 0.05 pt shows them; a line a soft return ends is justified as a wrapped line is. Evidence: `ate::tests::auto_leading_follows_the_size_of_each_line`, `ate::tests::a_paragraph_keeps_its_hyphenation_options`, `ate::tests::the_last_lines_the_file_sets_in_its_frame_show`, `tests::fit_source_lines_keeps_the_last_lines_the_source_sets`, `tests::typo::soft_return_in_justified_text_spreads_like_a_wrapped_line`. Limits: frames grow only for area type of one frame, horizontal, by its lines' deepest descent plus 0.05 pt; type in a font that isn't installed, and hyphenation in a language that isn't imported, still lay out differently; scores and estimates unchanged
|
||||
- Current-main conflict reconciliation retains upstream and feature behavior; scores and estimates unchanged
|
||||
- Superseded 2026-10-20 behavior, retained as history: Artboard Options shares existing presets and orientation controls and can fit artwork without moving it; artwork fitting uses the original target artboard and revision-scoped bounds caches (scores/hours unchanged)
|
||||
@@ -616,6 +617,7 @@ since 2026-10-01.
|
||||
- **Warp effects bend images:** a Warp effect on an image, or on a group that holds one, bends the image's pixels with its frame, as the Warp effect is documented to distort bitmap images in [Reshaping with effects](https://helpx.adobe.com/illustrator/using/reshaping-objects-effects.html): after the last effect, the image is cut into 10 × 10 cells of two triangles, each a clipped piece under its own affine map. Effects after the Warp reshape only the frame, a second Warp bends the same pieces, and warps saved without a version bend the pixels with their earlier map, as they bend the frame. A placed gradient on a group that holds the image follows the group's bounds as the pieces draw them. SVG writes the image once for the pieces; PDF, EPS, `.ai` and PNG write the bent pieces. The images stay unbent when their pieces would make the art pass 2 million objects, and so does an image whose frame keeps its shape past the anchor budget. A grayscale image's fill color now colorizes the pieces of a warp or an envelope, and an image under any geometry effect keeps that color and its smoothing setting. Existing documents with a Warp effect on an image, or on a group that holds one, draw differently: before, the image showed unbent, cut by the bent frame. So do existing documents with a colorized image under an envelope or a geometry effect, or an image drawn without smoothing under a geometry effect: before, those lost the color or the setting. The cell count and the limits are VectorCraft's own (effects `tests::warped_images_stay_within_the_object_budget`, `tests::warped_images_keep_document_keys_and_hidden_images_apart`, `tests::an_image_whose_frame_passes_the_budget_stays_whole`, `tests::effects_after_a_warp_reshape_an_images_frame_and_not_its_pieces`, `tests::an_images_pixels_take_the_map_their_warps_version_names`, `tests::an_image_under_a_geometry_effect_keeps_its_color_and_smoothing`, `tests::a_nested_groups_gradient_follows_its_warped_image`; engine `warp_images::an_images_pixels_bend_with_effect_warp`, `a_warped_image_keeps_its_bend_in_svg`, `a_warped_image_keeps_its_bend_in_pdf`, `a_warped_image_keeps_its_bend_in_ai`, `a_warped_image_keeps_its_bend_in_eps`, `a_warped_image_keeps_its_bend_in_png`, `svg_writes_an_image_clipped_twice_in_a_users_group_twice`, `expand_appearance_of_a_warped_image_draws_as_the_canvas_did`, `a_colorized_image_keeps_its_color_when_warped`, `a_warp_on_a_group_bends_the_image_in_it`, `envelope_distort::a_colorized_image_keeps_its_color_in_an_envelope`). Scores and hours unchanged.
|
||||
- **`.ai` files keep an image's Warp live:** an embedded image whose appearance is one Warp effect, with no opacity mask, is saved to the `.ai` editing data with an art style of that Warp: its bent pieces are its drawn look, and the image itself follows on `%_` lines, as for other styled objects. Opening an `.ai` file reads such an image as the image with its Warp live, its pixels, placement, name and opacity kept, when the live warp draws as the file's drawn look and the import has a comparison left; otherwise the drawn look stays, with the drawn-look note. The Warp effect applies to bitmap images ([the help page](https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html)), and native files keep live effects ([the help page](https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/supported-file-formats-in-illustrator.html)). A linked image with a Warp is saved as its drawn art, as before, and its live Warp is not saved. Images with an opacity mask, and images with a Warp and another effect or with another geometry effect, are saved and opened as their drawn art. Existing `.ai` files with an embedded image on `%_` lines open differently: before, that image also came in beside its drawn look. Which images keep the Warp and the comparison are VectorCraft's own rules (eps `ai_editing::tests::an_image_with_a_warp_reads_back_with_its_warp_live`, `an_image_whose_warp_draws_otherwise_than_its_look_keeps_its_look`, `an_image_on_hidden_lines_does_not_come_in_beside_its_look`, `other_warped_images_are_written_as_their_drawn_art`, `import::ai::read::ops::tests::an_image_takes_a_style_of_one_warp_alone`). Scores and hours unchanged.
|
||||
- **EPS writes a repeated image's samples once:** an image drawn more than once in an EPS file (the pieces of an envelope or a Warp effect, copies of one image, or one image in a symbol's instances) has its compressed samples written once in the setup, and each placement reads them from there: a reusable stream rewound for each placement at Language Level 3 ([PostScript Language Reference, 3rd ed., §3.13](https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf)), and an array of strings of at most 49,152 bytes fed to the image by a procedure at Level 2. An image drawn once is written where it is drawn, as before. The 256 MB limit on the page counts the samples once, so an envelope of a large photo no longer loses pieces to it. A colorized image is reused per ink (eps `tests::an_image_placed_twice_writes_its_samples_once_at_both_levels`, `tests::an_envelopes_image_pieces_draw_one_copy_of_its_samples`, `tests::each_ink_of_a_colorized_image_placed_twice_is_written_once`, `tests::samples_longer_than_a_string_are_reused_at_both_levels`, `tests::the_page_limit_counts_a_repeated_images_samples_once`). Scores and hours unchanged.
|
||||
- **PDF writes a warped image once:** with downsampling on, the pieces of an image bent by a Warp effect are resampled for the widest and the highest size any piece places the image at, so every piece paints one image XObject (a colorized image: one colorized image and its soft mask), instead of one image for each size a piece is placed at. Another placement of the same image is still resampled for its own size. Without downsampling, a colorized image and a CMYK image with a grayscale image mask on its grid are decoded and encoded once for all the sizes they are placed at (pdf `tests::compression::a_warped_image_is_written_once_for_all_its_pieces`, `tests::colorize::a_colorized_warped_image_is_written_once_for_all_its_pieces`, `export::images::tests::colorized_and_grid_masked_images_are_made_once_for_every_size_without_downsampling`). Scores and hours unchanged.
|
||||
- **Distort Appearance with Transform effect options:** with Envelope Options › Distort Appearance on, a path whose Transform effect has Scale Strokes & Effects or Transform Patterns on, or copies it with a gradient, is bent as the same per-copy art it draws and expands as outside the envelope: each copy's own stroke weight, dashes, pattern placement and gradient (effects `bake::tests`). Scores and hours unchanged.
|
||||
- **Fitted gradients turn with the Transform effect:** a gradient fitted to the object (not placed with the Gradient tool) turns, reflects and stretches with the object when its Transform effect rotates, reflects or scales it unevenly, as Object › Transform already does: the gradient is fixed to its fit on the geometry the effect takes, then follows the effect and the effects after it as a placed gradient does. Under moves and even scales it draws as a refit does, and a Transform effect that scales the object to nothing across leaves it fitted, with Scale Strokes & Effects or Transform Patterns on too, and on each copy. This holds on the canvas and in Object › Expand of the fill, for an object's own effects, a fill's or stroke's own, and a group's, where 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 their own object's fit. Existing documents with such a Transform effect on fitted-gradient art draw differently: before, the gradient refit to the turned outline. The Gradient tool still shows a fitted gradient's vector at its unturned fit. How gradients follow the effect is VectorCraft's own rule; what the effect does to the object is described in [Distort and transform effects](https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html) (effects `bake::tests::a_fitted_gradient_turns_reflects_and_stretches_with_a_transform_effect`, `bake::tests::a_transform_effect_that_scales_to_nothing_leaves_a_fitted_gradient_fitted`, `group::tests::a_groups_transform_turns_the_gradients_fitted_to_its_members_and_its_own_fill`; render `objectfx::a_fitted_gradient_turns_and_reflects_with_its_transform_on_the_canvas`; engine `objexpand::a_fitted_gradient_turned_by_a_transform_expands_as_the_canvas_draws_it`). Scores and hours unchanged.
|
||||
- **Placed gradients follow Transform and Free Distort effects:** a gradient placed with the Gradient tool moves, turns and scales with the object when the object's Transform effect moves its outline, and each copy of the Transform effect takes it as many times as it takes the transform. Under Free Distort it moves and scales from the path's bounds before the effect to its bounds after it. This holds on the canvas, in export, in Expand Appearance, in Pathfinder and compound shapes, and in Object › Expand of the fill, for an object's own effects, a group's (the own fills of the group, of the groups inside it, of a symbol's art, and of the images and symbol instances it moves, included) and a fill's or stroke's own. A gradient on a path inside a group with a Transform effect now moves with the path (#2214 moved only the gradients of type), and so does a gradient on an image's or symbol instance's own fill. When a path keeps its shape because the effect would pass the geometry budget, the group's own gradients stay in place; a hidden path in a layer, which the layer's bounds leave out, does not hold them. A freeform gradient whose points were edited moves its points in the same way. How gradients follow each effect is VectorCraft's own rule; what each effect does to the object is described in [Distort and transform effects](https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/distort-and-transform-effects-in-illustrator.html) (effects `bake::tests::a_baked_transform_moves_a_placed_gradient_with_the_path`, `bake::tests::a_strokes_own_transform_and_free_distort_move_its_placed_gradient`, `bake::tests::a_fills_gradient_follows_the_effects_around_its_transform_with_options`, `bake::tests::baked_free_distort_moves_placed_gradients_from_the_bounds_to_the_distorted_bounds`, `group::tests::a_groups_transform_and_free_distort_move_the_gradients_placed_on_its_paths`, `group::tests::a_groups_transform_moves_the_gradient_of_its_own_fill`, `group::tests::a_nested_groups_own_gradient_follows_the_outer_groups_transform_and_free_distort`, `group::tests::a_groups_transform_moves_the_gradients_placed_on_an_images_own_fills`, `group::tests::shape_art_moves_gradients_with_a_transform_effect`, `group::tests::shape_art_moves_the_gradient_of_a_symbol_instances_art_with_its_transform`, `tests::art_past_the_budget_keeps_its_own_gradients_in_place`, `tests::a_hidden_path_past_the_budget_leaves_a_layers_gradients_free_to_move`, `tests::edited_freeform_points_follow_a_transform_effect_and_free_distort`; render `objectfx::a_paths_gradient_moves_with_its_transform_and_free_distort`; engine `objexpand::a_placed_gradient_moved_by_a_transform_or_free_distort_expands_as_the_canvas_draws_it`). Scores and hours unchanged.- **Constrain Angle (#394):** General › Constrain Angle turns the arrow keys' axes (guides stay on the page's), holds Shift drags of the Selection, Direct Selection, Free Transform, Slice Selection, Reshape and Measure tools and the Pen's handles to the turned axes, and new rectangles, rounded rectangles, ellipses, grids, point and area type, Shift-drawn polygons and stars and the shape size dialogs are drawn along it with their bounding box turned; 0° and whole turns are exactly as before, quarter turns exact (<https://helpx.adobe.com/illustrator/desktop/manage-objects/arrange-objects/rotate-objects-by-specific-angles.html>). Tests: `tests_constrain_tools`, `tests_constrain_new` (engine), `geom` `constrain_axes` / `rotate_deg`, the shape, grid and type tool tests.
|
||||
@@ -627,9 +629,10 @@ since 2026-10-01.
|
||||
- **Escape in Selection tool drags:** Escape during a Selection tool move or Alt-drag copy, a bounding-box scale or rotation, a marquee, or a corner widget, pie widget or bracket drag cancels it: the art returns to its state at the press, no copy is left, no undo step is added, the release does nothing, and the tool stays chosen. This is VectorCraft's own behavior. Regression tests: `escape_cancels_*` in `select/tests.rs` and `pie.rs`, and `escape_cancels_a_selection_tool_move_copy_scale_or_rotation` in `tests/selectescape.rs`.
|
||||
- **Selection passes through raster effects:** clicks with the Selection, Direct Selection and Group Selection tools (Group Selection's repeated click included), the Selection tool's pointer and marquee, Direct Selection's marquee, pointer and anchor highlight, and Group Selection's marquee (E for enclosed objects included) leave out the area that a drop shadow, a glow, a blur or another raster effect paints beyond an object. A click on a shadow selects the object under it, or nothing over an empty canvas, a repeated Group Selection click there adds the groups of the object under it, and a press on the shadow of a selected object does not move it ([the help page](https://helpx.adobe.com/illustrator/using/selecting-objects.html)). Over a shadow, Direct Selection highlights only the anchors of the object under it, and Group Selection keeps its own pointer and highlights no anchor, as it does everywhere (VectorCraft's own rule). No setting changes this. This covers paths, groups, type, symbol instances and images. Regression tests: `crates/engine/src/tests/select_effects.rs`.
|
||||
- **Global Edit: Shift-click leaves a match out:** while Global Edit is on, a Shift-click with the Selection tool on a highlighted match, or on an object inside a matched group, leaves that match out (`select.globalEditExclude`): it is no longer highlighted and later edits leave it as it is; the object the edit started from stays, and Global Edit ends when fewer than two matches are left ([Update assets quickly with Global Edit](https://helpx.adobe.com/ph_fil/illustrator/how-to/global-editing-sensei.html)). Regression tests: `a_shift_click_*`, `an_object_left_out_*`, `a_group_left_out_*` and `leaving_out_all_but_one_*` in `crates/engine/src/tests/globaledit.rs`.
|
||||
- **Global Edit leaves out groups holding type or images:** Select › Start Global Edit on a group that holds type or an image, at any depth, refuses to start, and such a group is not taken as a match, as Global Edit does not take images or text ([Edit similar objects globally](https://helpx.adobe.com/illustrator/desktop/manage-objects/edit-objects/edit-similar-objects.html)). The menu item checks only that the selection is a group; starting checks its contents. Regression test for a group holding type: `global_edit_needs_one_supported_object` in `crates/engine/src/tests/globaledit.rs`.
|
||||
- **Global Edit leaves out groups holding type or images:** Select › Start Global Edit on a group that holds type or an image, at any depth, refuses to start, and such a group is not taken as a match, as Global Edit does not take images or text ([Edit similar objects globally](https://helpx.adobe.com/illustrator/desktop/manage-objects/edit-objects/edit-similar-objects.html)). Regression test for a group holding type: `global_edit_needs_one_supported_object` in `crates/engine/src/tests/globaledit.rs`.
|
||||
- **Global Edit Options in the Control bar:** while Select › Start Global Edit can run, the Control bar shows a Global Edit Options dropdown that opens the same options as the Properties panel's (Match: Appearance, Size; On Artboards; Include Objects On Canvas; Result(s)); both set the same options. The dropdown is off while Global Edit is on; it sits after Recolor Artwork, ahead of the X/Y/W/H fields ([Edit similar objects globally](https://helpx.adobe.com/illustrator/desktop/manage-objects/edit-objects/edit-similar-objects.html)). Regression test: `the_control_bar_shows_the_global_edit_options` in `crates/ui-egui/src/chrome/tests.rs`.
|
||||
- **Global Edit's enabled check on large paths:** the check that decides whether Select › Start Global Edit can run on the selected path, compound path or symbol instance (which the Control bar makes every frame) measures the box of its anchors and handles instead of building and normalizing a copy of every anchor, with the same answer. On a 200,000-anchor path the check takes 0.7 ms instead of 2.2 to 3.0 ms. Regression tests: `support_*` in `crates/engine/src/cmd/globaledit.rs`.
|
||||
- **Start Global Edit is offered only for a group it can start on:** with a group selected, Select › Start Global Edit is disabled, and the Properties panel's Quick Actions and the Control bar do not offer it or its options, when the group holds type, an image or nothing, at any depth; the check walks the group's objects the same way, stopping at the first one Global Edit does not take. This is VectorCraft's own rule. Regression test: `start_global_edit_is_offered_only_for_a_group_of_supported_objects` in `crates/engine/src/tests/globaledit.rs`.
|
||||
- **Control bar's inline X, Y, W and H fields fit the bar:** the Control bar shows the inline X, Y, W and H fields only when all four, their labels as drawn in the current language and the W/H link fit inside the bar's margin; otherwise it shows the Transform link alone. This is VectorCraft's own layout rule. Regression test: `the_control_bar_shows_the_inline_transform_fields_only_when_they_fit` in `crates/ui-egui/src/chrome/tests.rs`.
|
||||
- **Control bar docks to the top or the bottom, or floats:** the Control bar's panel menu, at the bar's right end, has Dock to Top and Dock to Bottom, the edge in use checked and neither while the bar floats. Dragging the bar's gripper and releasing it within 24 points of the top (under the menu bar) or the bottom of the window docks it at that edge, with a band along that edge while it moves; releasing it farther from both edges floats the bar there, with its outline under the pointer while it moves, and a floating bar's gripper moves it or docks it again (`window.control.dock {edge: "top"|"bottom"|"float"}`), as the help page describes ([Control panel overview](https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/control-panel-overview.html)). Escape cancels a gripper drag. The 24-point zones, the floating bar's 800-point width and first position, a release outside the window leaving the bar where it was, a window too short for a floating bar docking it at the nearer edge, the floating bar staying inside a window that shrinks, and keeping the edge and the floating position with the workspace, with older workspaces docking the bar at their edge, are VectorCraft's own rules. Regression tests: `the_control_bar_panel_menu_docks_it_to_the_top_or_the_bottom`, `dragging_the_control_bar_gripper_docks_it_at_the_nearer_edge`, `dragging_the_control_bar_gripper_away_from_both_edges_floats_it`, `floating_control_bar_moves_and_redocks_from_each_edge`, `floating_control_bar_menu_docks_to_either_edge`, `control_bar_drag_escape_restores_placement`, `control_bar_drag_release_outside_window_keeps_previous_placement`, `floating_control_bar_stays_reachable_in_tiny_and_resized_windows`, `the_control_bar_dock_command_takes_top_bottom_or_float` and `menus_stop_above_a_control_bar_docked_at_the_bottom` in `crates/ui-egui/src/chrome/tests.rs`, `saved_workspaces_restore_the_control_bar_edge` and `saved_workspaces_restore_floating_control_bar_position` in `crates/ui-egui/src/workspaces.rs`.
|
||||
- **Control bar panel menu turns groups of options on or off:** the Control bar's panel menu lists the bar's groups of options (Snapping, Anchor Points, Tool Options, Object Options, Image Options, Fill and Stroke, Opacity, Graphic Style, Character, Paragraph, Vertical Alignment, Align and Distribute, Transform, Artboard Options and Document Options) above Dock to Top and Dock to Bottom, each checked while it is on; a click turns that group off or on (`window.control.options {group, visible?}`), and a group that is off stays out of the bar even while its tool or object is selected, as the help page describes ([Control panel overview](https://helpx.adobe.com/illustrator/desktop/get-started/learn-the-basics/control-panel-overview.html)). The list of groups and what each holds, every group on to start, a group that is off leaving its room to the groups after it, and keeping the groups with the preferences and the workspace are VectorCraft's own rules. Regression tests: `the_control_bar_panel_menu_turns_each_group_on_or_off`, `the_control_bar_keeps_its_label_and_menu_with_every_group_off`, `the_control_bar_panel_menu_scrolls_in_a_short_window`, `the_control_bar_options_command_turns_a_group_on_or_off`, `groups_that_are_off_leave_their_room_to_the_later_groups`, `the_artboard_tool_s_control_bar_follows_its_two_groups` and `the_anchor_points_group_holds_convert_and_anchors` in `crates/ui-egui/src/chrome/tests.rs`, `the_image_options_group_holds_the_image_and_trace_controls` in `crates/ui-egui/src/tests/place.rs`, `the_character_and_paragraph_groups_hold_the_type_controls` in `crates/ui-egui/src/panels/paragraph/tests.rs`, `saved_workspaces_restore_the_control_bar_groups` in `crates/ui-egui/src/workspaces.rs`.
|
||||
@@ -655,6 +658,7 @@ since 2026-10-01.
|
||||
- **Delete Empty Artboards:** the Artboards panel menu item ([Delete artboards](https://helpx.adobe.com/illustrator/desktop/create-manage-artboards/add-edit-artboards/delete-artboards.html)) runs `artboard.deleteEmpty`: every unlocked artboard with no artwork goes with its guides in one undo step, artboard 1 stays when every artboard is empty and none is locked, and the panel makes an artboard that is left active; an artboard is empty when no object (hidden, locked and template art included; guides not) has visual bounds that meet or touch it, a group counting by its members and a clip group or clipping layer by its members inside the clip (our reading of "no artwork"; the pages give no finer rule). Engine tests in `tests/panelcmds.rs` (`delete_empty_artboards_*`) and the panel test `delete_empty_artboards_deletes_the_empty_ones_and_selects_one_left`.
|
||||
The menu item's enabled check measures nothing in a document with one artboard, and Save Gradient Preset's check reads the proxy's paint without measuring the object; both give the same answer as before. An artboard that no path's control points, grown by the farthest its strokes reach, can meet is found empty without measuring the path. With an open path of 200,000 anchors selected, the checks take under 0.01 ms instead of 21.9 ms and 17.2 ms in a release build; with a second, empty artboard, Delete Empty Artboards' check takes 0.85 ms instead of 42.1 ms. Tests `delete_empty_artboards_is_enabled_exactly_when_it_deletes_something`, `delete_empty_artboards_enabled_state_matches_the_command_on_varied_documents`, `empty_artboard_checks_match_the_visual_bounds_on_varied_strokes`, `the_empty_artboard_check_matches_measuring_every_artboard`, `the_save_check_matches_saving_with_and_without_a_gradient`, `the_unmeasured_proxy_paint_is_the_measured_one` and `the_unmeasured_proxy_paint_is_the_measured_one_on_varied_objects`.
|
||||
Delete Empty Artboards' enabled check measures each version of a document once, so the panel menu does not measure the document again on every frame while it is open. With an open path of 200,000 anchors across two artboards, the check takes under 0.001 ms on a later frame instead of 70.4 ms in a release build, and with 20,000 objects on two artboards it takes under 0.001 ms instead of 9.1 ms. Tests `delete_empty_artboards_check_measures_a_document_once`, `delete_empty_artboards_check_follows_each_change_to_the_document`, `delete_empty_artboards_check_follows_a_change_in_place`, `delete_empty_artboards_check_follows_a_document_switch` and `delete_empty_artboards_check_matches_measuring_after_varied_changes`.
|
||||
Delete Artboards, Delete Empty Artboards and Cut Artboard remove all their artboards and those artboards' guides in one walk over the artboards and one over the ruler guides and layers, however many artboards go, instead of one walk over every guide and layer per artboard. The artboards, guides and selected guides left are the same as deleting the artboards one at a time. Tests `deleting_many_artboards_walks_the_artboards_and_guides_once` and `delete_empty_and_cut_artboards_walk_the_artboards_and_guides_once`.
|
||||
The Eyedropper, the Live Paint check for paint to sample, the Appearance panel's Characters chips and the colors the Libraries panel adds from the selection also read the proxy's paint without measuring the object; the Eyedropper measures it only to sample a gradient or a pattern, and the Libraries panel only for a gradient. The colors and paints are the same as before. With an open path of 200,000 anchors, the Live Paint check and the Eyedropper's sample for a point inside it take 0.004 ms together instead of 26.0 ms in a release build. Tests `samples_give_the_measured_proxy_paints_colors` and `colors_and_gradients_come_from_compound_paths_groups_and_colorized_objects`.
|
||||
- **Artboard history selection:** headless pointer/key tests in `panels/properties.rs` pass for panel New → Undo → Delete/Backspace/Properties, Duplicate → Undo → Delete, pruning removed indices and preserving valid multiselection. They assert board survivors, artwork and object selection, Move/Scale Artwork options, saved state and Undo/Redo. Full workspace CI passes.
|
||||
- **Artboard tab-switch follow-up:** changing the active document through its tab aligns the Artboard tool with the displayed board before Properties Delete; clicking the already-active tab preserves multiselection and Move/Scale Artwork options. Three headless `chrome::tests::artboard_document_tab_*` regressions cover actual tab A → B → A clicks followed by Properties Delete, surviving boards and guides, preserved artwork/symbols and Undo/Redo; controls cover same-tab multiselection, Move/Scale Artwork options and other tools. Historical focused validation on `dbd2497b` recorded one expected RED failure with two passing controls, then all three GREEN tests passed. All three also passed in historical full CI on `a0671777`. A full CI retry on the five-unit combined source at `a0671777` passed all seven stages with 6,613 test outcomes on 2026-10-14. An earlier full-CI run on the identical source panicked in the randomized `ai_mutated_save_never_panics` test; the cause remains unresolved. This five-fix batch does not claim to repair that failure.
|
||||
@@ -662,6 +666,7 @@ since 2026-10-01.
|
||||
- **Colour emoji with bitmap glyphs:** `sbix` (Apple Color Emoji) and `CBDT` (Noto Color Emoji) glyphs draw as their largest strike's PNG, placed with the type and unpainted by its fill; PDF writes them in Type 3 glyphs or as images, SVG as images with outlined text, EPS and legacy `.ai` as images, and Create Outlines makes embedded images. Synthetic test fonts in `crates/text/src/test_fonts.rs`; tests `crates/text/src/tests/bitmaps.rs`, `crates/render/src/tests/bitmapglyphs.rs`, `crates/svg/tests/it/colour_glyphs.rs`, `pdf::tests::colour_bitmap_glyphs_export_as_images`, the `eps` `colour_bitmap_glyphs_*` tests and `tests_pathops::create_outlines_turns_bitmap_glyphs_into_images`. COLR and OpenType SVG fonts remain.
|
||||
- **COLR colour fonts:** v0 and v1 glyphs draw as vector layers (solid colours, linear and radial gradients, clips, blend modes, the foreground colour from the run's fill) on the canvas, as paths in SVG, EPS, legacy `.ai` and PDF with outlined text, as Type 3 text in PDF, and as editable groups with Create Outlines; sweep gradients and Porter-Duff compositing draw the glyph as an image. Measured by `tests_colr`, `render::tests_colrglyphs`, `pdf::tests::colr_glyphs_export_as_vector_art`, `svg/tests/it/colour_glyphs.rs`, `eps` `colr_glyphs_*`, `tests_pathops::create_outlines_turns_colr_glyphs_into_layer_groups`. Scores unchanged (estimated).
|
||||
- **OpenType SVG colour fonts:** each glyph's SVG document is read by the SVG importer (registered by the engine) into vector art in the run's colours, then drawn, exported and outlined as COLR glyphs are; PDF real text writes them as text that draws nothing and draws their art where they sit. Measured by `tests_svg_glyphs`, `svg/tests/it/svg_glyphs.rs`, `tests_colourfonts::create_outlines_turns_svg_glyphs_into_groups`, `tests_colourfonts::pdf_real_text_draws_svg_glyphs_as_art_and_keeps_their_characters`. Scores unchanged (estimated).
|
||||
- **Composite fonts that two documents define differently:** when two open documents each define a composite font (Type › Composite Fonts…) by the same name with different parts, each document draws and exports its type in its own definition: in a tiled or floating window drawn while the front document draws, when it is placed in a document that defines the name differently, and in an export made while another document is in front. Evidence: `tests::composite::nested_loans_of_one_name_use_each_documents_definition` and `threads_lending_one_name_at_once_use_their_own_definitions` (`crates/text`), `tests::fontchange::a_placed_document_draws_its_own_definition_of_a_name_the_page_defines` (`crates/render`). Scores unchanged (estimated).
|
||||
- **Character-style Auto leading:** capture and explicit style attributes retain Auto as a reset, distinct from omitted leading. Redefine and later numeric updates preserve local leading overrides; the Character Styles marker recognizes Auto correctly. Regression assertions cover partial definitions, Undo/Redo and native save/load serialization. Public references: [Character and paragraph styles](https://helpx.adobe.com/illustrator/using/character-paragraph-styles.html) and [Leading](https://helpx.adobe.com/illustrator/using/line-character-spacing.html).
|
||||
- **Character-style numeric bounds:** `charStyle.new`, `charStyle.edit`, and `charStyle.setAttrs` accept size from 0.1 to 1296 pt, explicit leading from 0.1 to 5000 pt, horizontal and vertical scale from 1% to 10,000%, and baseline shift and Tate-chu-yoko offsets from -1296 to 1296 pt. Out-of-range input leaves the style and Undo history unchanged; Auto leading remains available. These limits match the Character panel controls.
|
||||
- **Character Style Options, General and Basic Character Formats:** the dialog edits a style's name and stored character formats together. Empty fields remain unset, checkboxes show an indeterminate unset state, Basic's Reset Panel clears its explicit settings, and Preview can be canceled without changing history. OK saves one undo step; New Character Style offers the same fields from captured text or the interface language's defaults without a selection. Public reference: [Character and paragraph styles](https://helpx.adobe.com/illustrator/using/character-paragraph-styles.html).
|
||||
@@ -870,6 +875,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- Hindi (2026-11-06): Hindi (`hi`): 7,877-row machine-assisted catalog, zero/one singular plurals, desktop font fallback and optional Devanagari craft-fonts fallback; all 55 translation tests pass; native review and a web font remain; scores and estimates unchanged. [Terminology and limitations](localization-hi.md).
|
||||
- Hindi wording (2026-11-13): rows outside the plug-in messages keep their English's meaning, quantities and clauses, and use the catalog's save, swatch, crop, resolution, path and type terms; a test checks those terms and the point unit in every row; native review remains; scores and estimates unchanged.
|
||||
- Hindi terms (2026-11-13): every row that names a variable (data merge, variable fonts and widths, environment variables) says वेरिएबल, and joining paths, anchor points, point type and lines says जोड़ें instead of शामिल हों, which stays for joining the community; a test checks both terms in every row; scores and estimates unchanged.
|
||||
- Hindi English words (2026-11-13): 264 rows no longer keep English words in their sentences, repeat a parameter's name in Hindi or garble them, among them "unknown align", which now names the alignment; lists of accepted values such as `(left|right|top|bottom)` stay as their English writes them; two tests check every row; native review remains; scores and estimates unchanged.
|
||||
- Window › Help Bar shows or hides the tool-help strip at the bottom of the window apart from the status bar (`window.helpBar`). Each setting is kept with the UI preferences and in saved workspaces, and Presentation Mode hides both bars. Layouts saved before the setting existed show the Help Bar where they show the status bar (`help_bar_toggle_is_independent_and_saved_in_workspaces`, `help_bar_and_status_bar_render_independently`, `legacy_help_bar_visibility_follows_each_layouts_status_bar`, `a_help_bar_setting_the_file_lacks_is_saved`).
|
||||
- Czech render-site labels: desktop/web file filters, diagnostics, suggested preset names and contributor tooltips/plurals now use catalog lookups; gradients have Czech adjective agreement and printer marks have a separate context (PDF/Print and Summary). Search, Home, toolbar/panel tooltips and Preferences already look up their labels. Every complete catalog has rows for these labels and for the Roman and Japanese printer mark styles. Evidence: `i18n::tests::czech_render_site_follow_up`, `i18n::tests::complete_catalogs_translate_render_site_labels`, `dialogs::tests_modal::printer_mark_labels_are_distinct_from_language_names`; see [localization-parity.md](localization-parity.md).
|
||||
- The History panel, Edit › Undo and Edit › Redo translate the names of the steps that apply or redefine a character or paragraph style and of the step that redefines a graphic style: each such step keeps its template (`Apply {name}`, `Redefine {name}`, `Redefine Graphic Style “{name}”`) and the style's name, every complete catalog has a row for each template, and the panel and the menu show the style's name as the document holds it, except the Normal styles' names, which they show in the interface language (`steps_named_after_a_style_list_the_template_around_the_name`, `undo_and_redo_name_a_style_step_around_the_style_name`).
|
||||
@@ -1047,6 +1053,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
With the Blob Brush, Alt held before the press, or pressed before the drag has moved, switches to the Smooth tool, as the reference app's [Default keyboard shortcuts](https://web.archive.org/web/20260726060015/https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html) page lists: the cursor shows the Smooth tool, the drag shows a thin line and, with a path selected that it can smooth, the dashed band it smooths, without the length label, Shift does not constrain it, and the release smooths the selected paths under the drag (`path.smoothRegion`) instead of painting; with nothing selected the release changes no path. A stroke that has moved keeps painting when Alt goes down.
|
||||
Curvature point markers are circular, with no direction handles. While drawing, its own point feedback replaces generic selection markers; existing paths use the selection overlay, including partial selections and Hide Edges. Anchor Size applies, and Direct Selection and Pen retain their handles. The real egui-frame regressions in `crates/ui-egui/src/canvas.rs` verify marker positions, counts and unchanged documents (#1236, in part); the existing-path interpolation request remains open. The curve through the points (`curvature_spline` in `crates/tools/src/draw2.rs`) makes each stretch of three points follow the circle through them: a smooth point's handles lie along that circle's tangent, each `chord / (3 cos²(α/2))` long (α between handle and chord, capped at 90°), and the ends of an open path mirror their neighbour's tangent in their chord, so a J or a U curves evenly, a turn tighter than 30° comes to a point, and uneven spacing doesn't loop; the rubber band, a dragged or inserted point and `path.convertAnchor` to smooth use the same rule, while the Pencil's fitting keeps its own; `tests/draw2.rs` checks that the rubber band is the path the click makes (#1236, in part). The Smooth tool smooths only the stretch of path under the drag (#1547, fixes #1512). A path the Smooth tool changes stays selected whole, and the anchor points and segments selected on it with Direct Selection are deselected. Selected paths the drag does not change keep their selected anchors, and undo restores the earlier selection (`tests/draw2.rs`, `smoothing_a_path_drops_its_direct_selected_anchors`). While the Smooth tool drags with a path selected that it can smooth, a dashed outline shows the band it smooths: everything within its radius of the drag (12 screen pixels, VectorCraft's own value), round at both ends; Alt smoothing with the Pencil, Paintbrush and Blob Brush shows the same band.
|
||||
While Alt is held during a Paintbrush stroke or before a press with no path selected that the Smooth tool can act on, the Paintbrush shows a closing cursor (a crosshair with a ring), and so does the Pencil with Alt key toggles to Smooth Tool off when Alt is pressed after the drag starts; releasing the mouse button with Alt still held closes the path. Before a Paintbrush press with such a path selected, Alt shows the Smooth cursor, and holding Alt at the press smooths that path with the Smooth tool's radius and Smooth Tool Options' Fidelity. A Pencil drag started with Shift or Alt held draws a straight line instead, which stays open.
|
||||
Smooth Tool Options' Fidelity is in pixels, as [the help page](https://help.adobe.com/archive/en_US/illustrator/cs3/illustrator_cs3_help.pdf#page=79) gives it: the Smooth tool, and an Alt smoothing drag with the Pencil, Paintbrush or Blob Brush, refits the path at Fidelity divided by the zoom, so a drag smooths a path as much on screen at 25 % as at 800 %. Reading the pixels as screen pixels is VectorCraft's own rule, as for the Pencil and the Paintbrush (#5729); the range (0.05 to 100 px) and the default (2.5 px) are VectorCraft's own values, and a saved Fidelity keeps its number (`crates/tools/src/draw2/gesture/tests.rs` test `smooth_fidelity_is_in_screen_pixels_at_any_zoom`, `crates/engine/src/tests/draw2.rs` test `smooth_region_refits_at_the_tolerance_sent_at_any_zoom`).
|
||||
With Shift held at the press, the Pencil draws a straight line from the press point to the pointer at 45° steps from the Constrain Angle, as [Draw straight lines with the Pencil tool](https://helpx.adobe.com/illustrator/desktop/draw-shapes-and-paths/draw-shapes/draw-straight-lines-with-the-pencil-tool.html) describes; pressed on an end of a selected open path, the line continues the path from that end (part of #3799). With Option/Alt held at the press and Alt key toggles to Smooth Tool off, the Pencil draws a straight line at any angle, whose ends snap to Smart Guides, and it stays open when Alt is still held at the release; Shift and Alt together keep the 45° steps (#3799). While Shift or Alt is held before the press, the Pencil shows a straight-line cursor (a crosshair with a short line), and over an end of a selected open path, where the line continues the path, a path-continuation cursor (the same line leaving a small square), as the page describes.
|
||||
- **Shapes:** all shape tools (including Flare) and the line, arc, spiral and grid tools. Space held while dragging out a shape, line, arc, spiral or grid moves it at its current size. While a grid is dragged out, Up/Down change its rows (concentric dividers) and Left/Right its columns (radial dividers). A click with a grid tool asks for the size, the divider counts and the grid options (#1377, in part): a skew for each set of dividers, Use Outside Rectangle As Frame or Create Compound Path From Ellipses, and Fill Grid; they are parameters of `shape.rectangularGrid` and `shape.polarGrid`, stay as the tool's options and apply to drags too. A shape just drawn stays adjustable with its tool: its Live Shape widgets drag, a press on its centre point (Show Center) moves the selection with the Selection tool's move arrow, snapping and Alt copy, and a press in the rotate zone just outside a bounding-box corner turns it about the centre with the Selection tool's rotate cursor (#5477; tests `a_shape_tool_moves_the_selection_by_its_centre_point_and_turns_it_from_a_corner` and, through the engine, `shapetools.rs`). A drag on one of its eight bounding-box handles scales it as the Selection tool's handles do, with their cursors and snapping, instead of drawing a new shape from the handle. A shape tool takes a press as a handle's only on the drawn handle square (VectorCraft's own rule: 3 screen points from its centre along each axis at the default Anchor Size, a half point more or less per step; the Selection tool takes 5), so a press just beside a handle still draws (tests `a_shape_tool_scales_the_selection_by_its_bounding_box_handles`, `a_shape_tool_draws_from_a_press_just_beside_a_handle` and `a_shape_tool_scales_the_shape_just_drawn_by_its_bounding_box_handle`). The curve a skew percentage follows and the direction of the radial skew are our own (the public documentation gives neither), and the dialogs have no reference point locator. An ellipse's Pie Start and End Angle and Invert Pie (Transform and Properties panels' Ellipse Properties, `object.setLiveShape {pieStart, pieEnd, invertPie}`) cut it as a pie (#812). With the bounding box showing, the Selection tool shows a selected ellipse's two pie widgets just outside it; dragging one sets its angle in one undo step and double-clicking one makes the ellipse whole again. A live polygon's Polygon Properties there: side count, angle, corner type and radius, radius, side length and Make Sides Equal once an uneven scale has made its sides differ (`object.setLiveShape {sides, polygonAngle, polygonRadius, sideLength, makeSidesEqual}`, part of #812); a star is a plain path, as in Illustrator. The Flare Tool Options last as the tool's options: the next flare dragged out uses them, a click's dialog shows them and double-clicking the tool opens them (part of #812).
|
||||
- **Shapes:** all shape tools (including Flare) and the line, arc, spiral and grid tools. Space held while dragging out a shape, line, arc, spiral or grid moves it at its current size. The Flare tool's center drag turns the rays by 0.1 radian at each drag update in which the pointer's document y grows, and back by as much at each one in which it falls, Shift held keeps their turn, and Space held during either of its drags moves the flare. While a grid is dragged out, Up/Down change its rows (concentric dividers) and Left/Right its columns (radial dividers). A click with a grid tool asks for the size, the divider counts and the grid options (#1377, in part): a skew for each set of dividers, Use Outside Rectangle As Frame or Create Compound Path From Ellipses, and Fill Grid; they are parameters of `shape.rectangularGrid` and `shape.polarGrid`, stay as the tool's options and apply to drags too. The curve a skew percentage follows and the direction of the radial skew are our own (the public documentation gives neither), and the dialogs have no reference point locator. An ellipse's Pie Start and End Angle and Invert Pie (Transform and Properties panels' Ellipse Properties, `object.setLiveShape {pieStart, pieEnd, invertPie}`) cut it as a pie (#812). With the bounding box showing, the Selection tool shows a selected ellipse's two pie widgets just outside it; dragging one sets its angle in one undo step and double-clicking one makes the ellipse whole again. A live polygon's Polygon Properties there: side count, angle, corner type and radius, radius, side length and Make Sides Equal once an uneven scale has made its sides differ (`object.setLiveShape {sides, polygonAngle, polygonRadius, sideLength, makeSidesEqual}`, part of #812); a star is a plain path, as in Illustrator. The Flare Tool Options last as the tool's options: the next flare dragged out uses them, a click's dialog shows them and double-clicking the tool opens them (part of #812).
|
||||
@@ -1090,7 +1097,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- **Blend spine Anchor Point tool (#2544):** on a selected blend, dragging a spine corner makes symmetric Smooth handles; the tool displays and picks existing spine handles when switched to, drags one independently or retracts it on click, and clicking a point with handles retracts both. The spine is edited live without moving its key objects. Windows native canvas checks and screenshots reviewed: symmetric and independent handles, corner/retraction, Shift constraints and perpendicular reshaping, tool switching, key preservation, Undo/Redo, save/reopen, hidden handles and overlapping Path/Blend priority (PR #2643). Behaviour reference: [public path-editing documentation](https://helpx.adobe.com/illustrator/using/adjust-path-segments.html).
|
||||
- **Blend steps of brushed strokes:** the steps interpolate the pen pressure, tilt, bearing and rotation recorded with the Paintbrush, so a Calligraphic, Scatter or Art brush that varies with the pen changes gradually from one key to the next. A key without a recording counts as half pressure, half tilt and 0°, as brushes read it, and angles turn the shorter way round. When the blend starts a key's path at another anchor (an open path run from its end, a closed one turned to another start), the key's recordings, width profile and arrowheads turn with the path. Different brushes still switch halfway (VectorCraft's own rule; strokes blend their options, as [Blended objects overview](https://helpx.adobe.com/illustrator/desktop/manage-colors/apply-transparency-and-blending/blended-objects-overview.html) describes; `crates/doc/src/blend.rs`, `pen_pressure_tilt_and_angles_interpolate_for_brushes`, `stroke_profiles_turn_with_a_key_path_started_elsewhere`).
|
||||
- **Path editing (#494):** the handles shown are the handles that drag: Direct Selection drags those of a path selected as a whole (as the Pen leaves it), the Anchor Point tool and Pen+Alt no longer grab handles that Show handles when multiple anchors are selected hides, a handle shorter than the tolerance leaves its anchor to be picked, and the anchor tools pick within Selection & Anchor Display › Tolerance. A dragged segment keeps a smooth anchor at either end smooth. With Direct Selection, the Pen, the Curvature and the anchor tools, a path selected as a whole shows all its anchors selected, and the Control bar and the Properties panel offer Convert (corner, smooth) for them too; Remove and Cut wait for anchors direct-selected (#504). A handle drag gathers its snap targets once per drag (it took 21 ms per pointer move on a 20,000-path document, now 1 ms; `vectorcraft-cli perf` measures handle and segment drags on a 5,000-anchor path). Join merges the selected anchor points that lie on one another, as after Average, into one anchor (#1582, fixes #1533), and removes the merged anchors in one pass over the path, so a long run of them no longer moves the anchors after it once per merge (`cmd::path::tests::a_long_run_before_many_other_anchors_merges_in_one_pass`); Object › Path › Average & Join… (`path.averageJoin`, Cmd+Alt+Shift+J, the "Create corner or smooth join" shortcut of [Default keyboard shortcuts](https://helpx.adobe.com/illustrator/using/default-keyboard-shortcuts.html)) moves two open path ends to their midpoint and joins them there, a corner or smooth point as its dialog's Points choice asks, in one undo step.
|
||||
- **Graphs:** Column, Stacked Column, Bar, Stacked Bar, Line, Area, Scatter, Pie and Radar graph tools with Graph Data and Graph Type. A series starts in greyscale; Group Selection's fill and stroke, the paint, weight, opacity and blend mode of a mark's top visible fill or stroke row after an Appearance command or a graphic style (each given a mark or its series picked with Group Selection), the Eyedropper, Default Fill and Stroke or Swap Fill and Stroke, the paint or stroke weight a stroke weight, gradient or recolor command changes there, and a mark's object opacity and blend mode, are kept separately on the graph and reapplied when its data, type or size changes, and through save, open and undo. Graph Type's Override Calculated Values (both `axisMin` and `axisMax`) uses exactly that value-axis range, split into the tick count (5 when automatic). Line graphs take Edge-to-Edge Lines (off by default: the points sit at the centres of their categories; graphs saved before the option keep their edge-to-edge lines), and radar graphs follow Mark Data Points and Connect Data Points. Blank cells (an empty CSV cell or `null`) are values left out, not zeros: columns, bars and stacked segments skip them, lines and scatter lines break around them and the value axis ignores them, while area, pie and radar draw them as 0; a number in straight quotes is a label, and the data window writes it back quoted. Graph types combine: Graph Type on series picked with Group Selection (or `series` indexes) draws them as their own type, with column, stacked column, line and area mixing on the vertical value axis and bar and stacked bar on the horizontal one; stacked columns take one slot of the cluster, lines draw in front of columns and areas behind. The value axis goes on the left, the right or both sides (column, stacked column, line, area and scatter graphs; bar graphs keep theirs along the bottom), and Separate Scales gives the series assigned to the right axis a scale of their own with its own tick values. Each value axis takes tick marks of no, short or full (across the plot) length and a count per division, and a prefix and suffix for its numbers; the category axis takes tick marks too (none by default), at or between its labels. Graph designs: Object › Graph › Design lists the designs with a preview of the selected one, and New Design (the selected art), Rename, Delete Design, Paste Design (a copy back to edit) and Select Unused, and Marker draws the data points and legend swatches of line, scatter and radar series with a design, scaled so its backmost object fills the default marker's square. Graph Data transposes rows and columns and switches a scatter graph's x and y, and a `|` in a category or series label starts a new line. Pie graphs take Legends in Wedges, Position (Even, Ratio sized by area, Stacked on one centre) and Sort (None, All, First). Graph Type takes column and cluster widths up to 1000% (overlapping past 100%) with First Row and First Column in Front (First Row orders each series' categories; across series the series order decides, so series stay one group each for Group Selection), draws filled lines, adds drop shadows behind columns, bars, lines and wedges, and puts the legend in rows across the top. Text formatted with the Character, Paragraph or Appearance controls, on the whole graph or on labels picked with Group Selection, is kept per kind of label (value axis numbers, category labels, legend labels) through the graph being drawn again. Object › Graph › Data opens a worksheet: cells picked with a click and edited above the sheet (Tab moves right, Enter down, the arrows between cells), Import Data from a tab-separated text file, Transpose, Switch x/y, Cell Style (decimals shown, column width), Revert and Apply. `graph.setData` returns and takes the data as CSV with each value written exactly, not rounded to two decimals, so applying the returned CSV changes nothing (#1485).
|
||||
- **Graphs:** Column, Stacked Column, Bar, Stacked Bar, Line, Area, Scatter, Pie and Radar graph tools with Graph Data and Graph Type. A series starts in greyscale; Group Selection's fill and stroke, the paint, weight, opacity and blend mode of a mark's top visible fill or stroke row after an Appearance command or a graphic style (each given a mark or its series picked with Group Selection), the Eyedropper, Default Fill and Stroke or Swap Fill and Stroke, the paint or stroke weight a stroke weight, gradient or recolor command changes there, and a mark's object opacity and blend mode, are kept separately on the graph and reapplied when its data, type or size changes, and through save, open and undo. A series that draws Filled Lines bands keeps no stroke paint or weight: its bands are drawn again with their 0.25 pt black outline. Graph Type's Override Calculated Values (both `axisMin` and `axisMax`) uses exactly that value-axis range, split into the tick count (5 when automatic). Line graphs take Edge-to-Edge Lines (off by default: the points sit at the centres of their categories; graphs saved before the option keep their edge-to-edge lines), and radar graphs follow Mark Data Points and Connect Data Points. Blank cells (an empty CSV cell or `null`) are values left out, not zeros: columns, bars and stacked segments skip them, lines and scatter lines break around them and the value axis ignores them, while area, pie and radar draw them as 0; a number in straight quotes is a label, and the data window writes it back quoted. Graph types combine: Graph Type on series picked with Group Selection (or `series` indexes) draws them as their own type, with column, stacked column, line and area mixing on the vertical value axis and bar and stacked bar on the horizontal one; stacked columns take one slot of the cluster, lines draw in front of columns and areas behind. The value axis goes on the left, the right or both sides (column, stacked column, line, area and scatter graphs; bar graphs keep theirs along the bottom), and Separate Scales gives the series assigned to the right axis a scale of their own with its own tick values. Each value axis takes tick marks of no, short or full (across the plot) length and a count per division, and a prefix and suffix for its numbers; the category axis takes tick marks too (none by default), at or between its labels. Graph designs: Object › Graph › Design lists the designs with a preview of the selected one, and New Design (the selected art), Rename, Delete Design, Paste Design (a copy back to edit) and Select Unused, and Marker draws the data points and legend swatches of line, scatter and radar series with a design, scaled so its backmost object fills the default marker's square. Graph Data transposes rows and columns and switches a scatter graph's x and y, and a `|` in a category or series label starts a new line. Pie graphs take Legends in Wedges, Position (Even, Ratio sized by area, Stacked on one centre) and Sort (None, All, First). Graph Type takes column and cluster widths up to 1000% (overlapping past 100%) with First Row and First Column in Front (First Row orders each series' categories; across series the series order decides, so series stay one group each for Group Selection), draws filled lines, adds drop shadows behind columns, bars, lines and wedges, and puts the legend in rows across the top. Text formatted with the Character, Paragraph, Appearance, Transparency or Graphic Styles controls or the Eyedropper, on the whole graph or on labels picked with Group Selection, is kept per kind of label (value axis numbers, category labels, legend labels) through the graph being drawn again, the paint, weight, opacity and blend mode of a label's topmost visible fill and stroke rows and its object opacity and blend mode included. Object › Graph › Data opens a worksheet: cells picked with a click and edited above the sheet (Tab moves right, Enter down, the arrows between cells), Import Data from a tab-separated text file, Transpose, Switch x/y, Cell Style (decimals shown, column width), Revert and Apply. `graph.setData` returns and takes the data as CSV with each value written exactly, not rounded to two decimals, so applying the returned CSV changes nothing (#1485).
|
||||
An Eyedropper pick that includes transparency and leaves a mark's top fill or stroke row without paint, or removes that row when the source has no row of that kind, where that row had paint before, also replaces the opacity and blend mode the graph keeps for that kind of row in the series; a row that had no paint before the pick leaves them as they are.
|
||||
- **Graph column designs:** Object › Graph › Column (`graph.column`) draws the columns, bars or stacked segments and the legend swatch of the series picked with Group Selection with a graph design: Vertically Scaled stretches it to each column's length, Uniformly Scaled scales it both ways and centers it, Repeating stacks a copy for each Each Design Represents value and chops or scales the last one (For Fractions), and Sliding keeps the part above the design's guide line in proportion and stretches the part below. The dialog lists the designs with a preview; the choice is saved with the graph and follows the design's rename and delete.
|
||||
Type in a column design that holds a `%` followed by two digits shows each column's value in place of the `%` and the digits: the first digit is the least number of places before the decimal point (zeros are added in front; 0 gives as many as the value needs), and the second digit sets the places after it, rounded. Unless it is inside a group that clips or has its own opacity or appearance, or inside a blend, compound shape, envelope, repeat or intertwined objects, the type keeps its size and is drawn once per column in a repeating design. The legend swatch leaves it out.
|
||||
@@ -1218,6 +1225,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- A 3D effect on one fill or stroke ([the help page](https://helpx.adobe.com/illustrator/using/effects.html)) leaves the object's other fills and strokes drawn with the path's or compound path's fill rule, so an even-odd compound path keeps its holes in them; this holds for Extrude & Bevel, Inflate, Rotate and Revolve, and for the Classic Extrude & Bevel, Rotate and Revolve. Tests: `solids::tests::a_fill_or_stroke_without_the_effect_keeps_the_even_odd_hole`, `revolve::tests::a_fill_without_the_revolve_keeps_the_even_odd_hole`.
|
||||
- With caps and opaque paint, Extrude & Bevel (both kinds) and Inflate draw each side face of the fill's solid before the faces of the same object's strokes that overlap it (strokes on closed paths without dashes, a width profile or a brush, in a solid color or an opaque gradient), so the stroke's walls cover the fill's walls at concave corners instead of showing stripes of the fill. Tests: `solids::tests::a_fills_walls_are_drawn_before_the_stroke_faces_over_them`, `solids::tests::the_draw_order_moves_a_fill_wall_before_the_stroke_faces_it_overlaps`, `solid::tests::facets_tell_the_sides_from_the_ends_and_the_faces_turned_away`.
|
||||
- When the fill and strokes are at full opacity with Normal blending, under a stroke that leaves parts of the fill's edge uncovered (dashed, with a width profile or a brush, on an open subpath, or in a paint that may show through), Extrude & Bevel (both kinds) and Inflate cut each stroke face that passes through a face of the fill's solid, or of another of the shape's strokes, where their depths meet, and draw the faces of the shape's fill and strokes that overlap in the order of their depths where they overlap, instead of by the depths of their centers. Inflate orders a plain stroke the same way, since its fill can rise in front of the stroke. The fill no longer paints over a nearer dash, and a dash's end no longer covers the fill wall in front of it; a fill wall in a gap between dashes stays visible. The same order applies inside a group member's own opacity mask or blending mode, to a gradient with transparent stops under a colored light with graphics on its caps, and to Inflate in gradients under a colored light. Tests: `solids::tests::fill_walls_and_strokes_that_leave_gaps_draw_in_the_order_of_their_depths_where_they_overlap`, `solids::tests::local_order_puts_overlapping_fill_walls_and_stroke_faces_in_depth_order`, `solids::tests::a_stroke_face_through_a_fill_wall_is_cut_where_their_depths_meet`, `solids::tests::a_masked_members_fill_and_stroke_faces_go_in_one_order`, `solids::tests::a_colored_inflate_in_gradients_draws_its_faces_in_one_order`, `solids::tests::a_depth_cycle_keeps_the_cap_last`, `solids::graphics::tests::a_transparent_gradient_with_a_graphic_keeps_the_shared_face_order`.
|
||||
- Without a twist, a tapered Extrude & Bevel wall (and each bevel band) is one flat face; only a twist cuts walls into slices, so no seam between slices paints a light tick or a light line on a tapered, untwisted wall (#7019). Test: `solid::tests::a_tapered_wall_is_one_flat_face_and_a_twisted_one_is_sliced`.
|
||||
- Extrude & Bevel, Inflate and Rotate apply to type: it makes a solid of its glyph outlines, painted with its own fills and strokes or, when it has none, its characters' colour (the first run's), and stays type, so editing the text reshapes the solid (#4715).
|
||||
- Extrude & Bevel, Inflate and Rotate (Effect › 3D and Materials): live effects in the `three-d` crate with depth, twist, taper, solid or hollow caps, five original bevel shapes (width, height, repeat, spacing, inside, both sides), Inflate's volume, both sides, twist, taper and cap, Rotate's turned fills and strokes, Position presets, the rotation and light gizmos, SVG/PDF vector output and Expand Appearance; one 3D effect per object; covered by geometry, effect, canvas-versus-export, command and dialog tests ([three-d.md](three-d.md)).
|
||||
- Extrude & Bevel and Inflate build detailed shapes: each solid takes up to 65,536 outline points and 163,840 faces (VectorCraft's own limits, was 2,048 points and 32,768 faces), counted before any point is sampled; when the faces do not fit, every curve takes fewer pieces, down to 4. A closed path of 2,000 curves extrudes with a bevel and inflates, and paths of 5,000 and 10,000 curves build at the default settings (`crates/three-d/src/solid/tests_limits.rs`).
|
||||
@@ -1273,6 +1281,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
The Character panel menu's Show Font Height Options shows a Set Font Height Reference dropdown under Font Size (`text.setFormat` or `text.setRangeStyle` `{fontHeightReference}`). Each reference shows an icon of the height it measures before its name, in the open list and in the closed field (#6304): a frame around a letter for Em Box, a bar from the baseline to the top of a capital for Cap Height and of a lowercase x for x-Height, and a frame inset in the em square for ICF Box. With Em Box, the default, the font size is the size of the em square; with Cap Height, x-Height or ICF Box, the characters are set at the em size at which the font's OS/2 cap height, its x height or the height of its ideographic character face equals the font size. With a font that has no such value, or one outside 0.1 to 2 em, the size measures the em box. SVG, PDF and legacy `.ai` export and the CSS Properties rules write the em size the characters are drawn at, and DXF export writes 0.7 times that em size as each TEXT entity's height (group 40, the height of its capitals). Behavior reference: [Vary font height](https://web.archive.org/web/20251118174722/https://helpx.adobe.com/illustrator/desktop/design-with-text/edit-format-text/vary-font-height.html).
|
||||
The Every-line Composer composes a paragraph whose characters differ in line metrics (type size, font, leading or vertical scale, or an inline graphic taller than the text) in area type of any shape, rows, columns and text wrap included. In a frame that is not a rectangle, or with text wrap, each line it tries is measured where the lines above it put it, across the line's own height, so a taller line gets the room of the narrower part of the frame, or of the span beside a wrap object, that it reaches. Such a paragraph is broken with the Single-line Composer when the frame has no room for all of it or when the search passes VectorCraft's own limits. Behavior reference: [the help page](https://helpx.adobe.com/illustrator/desktop/design-with-text/edit-format-text/set-hyphenation-and-line-breaks.html).
|
||||
In area type of a shape other than a rectangle, each line's whole band, ascent to descent, stays inside the frame: where an edge pinches in within the band, the line ends at the narrowest point, and a line runs beside a hole that starts and ends within its band, not across it. In area type of any shape, a line also stays clear of a text wrap object that reaches into any part of its band, and inside an Invert Wrap object over its whole band (`crates/text/src/layout/region.rs` tests).
|
||||
With Invert Wrap, the spans a line keeps inside a wrap shape of many parts (a comb of 500 teeth) are found by stepping through the line's spans and the shape's spans once for each piece of the band, so the work grows with the number of spans, not with its square (`crates/text/src/layout/region.rs` tests).
|
||||
The Character panel's Small Caps, Superscript and Subscript buttons and the panel menu's items of the same names turn small caps and the superscript or subscript position on and off for the selected type, or for the text the Type tool has selected (`text.setFormat` or `text.setRangeStyle` `{smallCaps, position}`), in Document Setup's proportions. Turning Superscript on turns Subscript off, and turning Subscript on turns Superscript off. A button or item shows as on when the first selected character (at a caret, the character before it) has its attribute.
|
||||
The Character panel's Anti-aliasing Method dropdown, under Character Rotation, sets how the edges of the selected type objects are drawn as pixels (`text.setFormat {antiAlias}`), for the whole object, with each frame of a thread keeping its own method and graph labels keeping it when the graph is drawn again, on the canvas, in raster exports and when the type is rasterized. VectorCraft defines the methods: Sharp, the default, draws edges as before; None paints a pixel only where the type covers at least half of it; Crisp shows a pixel covered by a share c at `2c - 0.5`, and Strong shows it at `2c`, each kept between 0 and 1. SVG, PDF and EPS export are unchanged. Scores and hours unchanged.
|
||||
The OpenType panel's Stylistic Alternates and Titling Alternates checkboxes turn `salt` and `titl` on and off for the selected type, and its Figure menu lists Default Figure, Tabular Lining, Proportional Lining, Proportional Oldstyle and Tabular Oldstyle; Proportional Lining sets `pnum` and `lnum` and turns `tnum` and `onum` off, Tabular Lining turns `pnum` off and keeps `lnum`, Proportional Oldstyle turns `lnum` off and keeps `pnum`, and Default Figure and Tabular Oldstyle turn `pnum` and `lnum` off. Behavior reference: [Format text with OpenType features](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/format-text-with-opentype-features.html) and [Use swashes, titling alternates, or stylistic alternates](https://helpx.adobe.com/illustrator/desktop/design-with-text/special-characters-glyphs/use-swashes-titling-alternates-or-stylistic-alternates.html) (public documentation). Tests: `panels::opentype::tests`.
|
||||
@@ -1286,7 +1295,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Exports to PDF, EPS, SVG, EMF, WMF and the raster formats warn about the area type and type on a path that they draw without the text that doesn't fit, and give their ids, as Print and Print Preview do.
|
||||
On a shaped area type frame, Inset Spacing keeps text that far from the frame's edge, holes included, measured from the edge itself rather than along the line; the archived help treats the inset as the space an area type object leaves between its text and the path that bounds it (<https://help.adobe.com/archive/en_US/illustrator/cs5/illustrator_cs5_help.pdf#page=317>, <https://web.archive.org/web/20220911143322/https://helpx.adobe.com/pdf/cs6/illustrator_reference.pdf#page=325>). A rectangular frame keeps its inset from each side as before, and a column's inner edges keep it once. Tests: `layout::region::inset_on_a_shaped_frame_is_measured_from_its_sloped_edge`, `inset_keeps_text_clear_of_a_hole_s_sloped_edges`, `inset_applies_once_at_a_column_s_edge_and_at_the_frame_s_edge`.
|
||||
An edit copies a thread's story only when it changes one of the thread's frames: with a story of 50,000 characters threaded through 8 frames with a style change at every word, moving another object took 7.8 ms and now takes 0.013 ms, and a frame of a drag took 7.2 ms and now takes 0.012 ms (release build, `threaded_story_edit_timing`).
|
||||
When a story flows through threaded area type, each frame is measured with the whole paragraphs of the story that it needs and a few more, not with the whole rest of the story, and it keeps the same text as before. A story of 1,500 one-line paragraphs (55,892 bytes) through 40 frames was laid out over 2,126,762 bytes of text while the frames were measured, and is now laid out over 21,035 (`thread::tests::many_frames_measure_about_the_text_they_take`). Area type with its lines aligned to the center, the bottom or justified vertically, and type on a path whose first paragraph is aligned Left, Justify Left or Auto, are measured the same way: the same story through 40 area frames aligned to the center was laid out over 2,126,762 bytes and is now laid out over 21,035, and through 40 paths aligned Left over 2,135,202 bytes and now over 20,583 (same test). Shrink Text to Fit, Dynamic Text, Optical Margin Alignment and Roman Hanging Punctuation on a path, a path aligned another way, horizontal type on a path whose first paragraph is set right to left or with right-to-left text in the rest of the story, and a frame whose share ends in the story's last paragraph are still measured with the whole rest.
|
||||
When a story flows through threaded area type, each frame is measured with the whole paragraphs of the story that it needs and a few more, not with the whole rest of the story, and it keeps the same text as before. A story of 1,500 one-line paragraphs (55,892 bytes) through 40 frames was laid out over 2,126,762 bytes of text while the frames were measured, and is now laid out over 21,035 (`thread::tests::many_frames_measure_about_the_text_they_take`). Area type with its lines aligned to the center, the bottom or justified vertically, and type on a path whose first paragraph is aligned Left, Justify Left, Justify All or Auto, are measured the same way: the same story through 40 area frames aligned to the center was laid out over 2,126,762 bytes and is now laid out over 21,035, through 40 paths aligned Left over 2,135,202 bytes and now over 20,583, and through 40 paths aligned Justify All over 2,135,202 bytes and now over 20,583 (same test). Shrink Text to Fit, Dynamic Text, Optical Margin Alignment and Roman Hanging Punctuation on a path, a path aligned to the center or the right, horizontal type on a path whose first paragraph is set right to left or with right-to-left text in the rest of the story, and a frame whose share ends in the story's last paragraph are still measured with the whole rest.
|
||||
A paragraph that continues from one threaded frame into the next has its first-line indent and bullet or number in the frame where it starts; in the next frame its first line starts where its wrapped lines start. In frames that are no longer threaded, copies of a frame and point type converted from one, the first paragraph has its indent and bullet or number again.
|
||||
In threaded text, a paragraph format given to the empty paragraph after a frame's last paragraph break stays after the story flows again, in that frame and in the frames the paragraph continues into, unless the same edit also formats the next frame's first paragraph, whose format then applies (VectorCraft's own rule; `thread::tests::restyled_empty_last_paragraph_wins_over_unedited_next_frame`, `cmd::threads::tests::editing_a_frames_empty_last_paragraph_survives_thread_reflow`).
|
||||
Type › Convert To Point Type on a frame of threaded text makes point type of the text that frame holds and takes it out of the thread; the story flows through the other frames without that text, so each character is in the document once.
|
||||
@@ -1415,6 +1424,8 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
View › Show Live Paint Gaps (`view.livePaintGaps`) draws the gaps of the selected Live Paint groups up to their Paint Stops At size, each in its group's Gap Preview Color, until Hide Live Paint Gaps or Hide Edges hides them ([Live Paint gaps](https://web.archive.org/web/20260105111201/https://helpx.adobe.com/illustrator/desktop/paint-and-fill/learn-painting-basics/find-and-close-gaps-in-live-paint-groups.html)).
|
||||
Double-clicking the Live Paint Selection tool opens its Tool Options ([Live Paint Selection tool options](https://web.archive.org/web/20250904012025/https://helpx.adobe.com/illustrator/using/selecting-objects.html)): with Select Fills off, a click selects an edge instead of a face; with Select Strokes off, Alt-click selects a face instead of an edge; Color and Width set the color and width of the highlight on the face or edge under the pointer (red and 4 px by default). The options last across tool switches and are saved with the preferences (`tool.setOption {tool: "livePaintSelection"}`).
|
||||
As VectorCraft's own rule, OK in Live Paint Selection Tool Options, Live Paint Bucket Options, Gap Options and Tile Edge Color gives an error for a color with an alpha part (`#rrggbbaa` or `#rgba`) and changes nothing.
|
||||
As VectorCraft's own rule, `tool.setOption` for the Live Paint Bucket and the Live Paint Selection tool, chosen or not, checks every value before it sets any: a switch that is not `true` or `false`, a `color` that is not an RGB color or a layer color's name, or that has an alpha part, a `width` that is not a number and an option the tool does not have give an error naming the option, and nothing is set or saved. A `width` outside 1 to 20 px is still set to the nearest end of that range. Saved settings that hold an invalid value still load, and the tool keeps its default for that option. Evidence: `tests::build::{live_paint_tool_options_refuse_invalid_values_and_change_nothing, live_paint_tool_options_take_rgb_colors_and_clamp_the_width, live_paint_tools_load_saved_settings_with_invalid_values}`.
|
||||
As VectorCraft's own rule, `tool.setOption` for the Shape Builder, chosen or not, checks every value the same way: a switch that is not `true` or `false`, a `pickColorFrom` or `selection` that is not one of its names, a `gapLength` that is not a number, a `highlightColor` that is not an RGB color or a layer color's name, or that has an alpha part, and an option the tool does not have give an error naming the option, and nothing is set or saved. A `gapLength` outside 0 to 72 pt is still set to the nearest end of that range. Evidence: `tests::build::{shape_builder_tool_options_refuse_invalid_values_and_change_nothing, shape_builder_tool_options_take_valid_values_and_clamp_the_gap}`.
|
||||
A drag of 3 screen pixels or more with the Live Paint Selection tool draws a marquee and selects the faces and edges it touches, partly enclosed ones included, and a Shift-drag adds them to the selection or removes them from it ([Modify Live Paint groups](https://web.archive.org/web/20261006115247/https://helpx.adobe.com/illustrator/desktop/paint-and-fill/learn-painting-basics/modify-live-paint-groups.html)). A click and a marquee change the selection on release, and Escape before the release leaves the selection as it was. Locked Live Paint groups, those on a locked layer or artboard, and in isolation mode those outside the isolated art are not highlighted or selected.
|
||||
A drag with the Live Paint Selection tool draws a marquee and selects the faces and edges it touches, partly enclosed ones included, and a Shift-drag adds them to the selection or removes them from it ([Modify Live Paint groups](https://web.archive.org/web/20261006115247/https://helpx.adobe.com/illustrator/desktop/paint-and-fill/learn-painting-basics/modify-live-paint-groups.html)). A click and a marquee change the selection on release, and Escape before the release leaves the selection as it was. Locked Live Paint groups, those on a locked layer or artboard, and in isolation mode those outside the isolated art are not highlighted or selected.
|
||||
When the object the Blend tool picked first is deleted or undone away before the second click, the next click on an object picks that object first instead of doing nothing. Regression tests: `blend_tool_picks_again_when_its_first_pick_is_gone` in `meshblend.rs` and `the_blend_tool_picks_again_when_its_first_pick_is_deleted` in `tests/blendopts.rs`.
|
||||
@@ -1547,6 +1558,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Create Object Mosaic (its columns and rows), Transform Each (its reference point and Random seed) and Rearrange All Artboards (its columns) refuse a fraction, a negative number or a string, such as 2.5, -1 or "4"; 4.0 counts as 4.
|
||||
Move, Rotate, Scale, Reflect, Shear, Transform Again, Nudge and the Transform panel's values (their copy, Scale Strokes & Effects, Scale Corners, Transform Patterns, Transform Objects and area type options), Align, Distribute and Distribute Spacing (Transform Patterns), Object Properties (visible, locked, Isolate Blending and Opacity & Mask Define Knockout Shape) and Live Shape Properties (Invert Pie, Make Sides Equal and relative rounding) refuse a value other than true, false or null, such as "false", and leave the document as it was.
|
||||
Object Properties (its opacity), Live Shape Properties (corner radius and polygon sides), the Transform panel's reference point and Align, Distribute and Distribute Spacing to an artboard (the artboard's number) refuse a value other than a number or null, such as "50", and leave the document as it was.
|
||||
Live Shape Properties refuses a key it does not take, at the top level or in one of its items, a polygon side count that is not a whole number from 3 to 1000 and a negative corner radius, and leaves the document as it was; the Transform panel's Sides field takes 3 to 1000.
|
||||
Transform Each (its scales, moves and rotation), Rasterize (its resolution), Create Object Mosaic (its new width and height and its spacing), Create Trim Marks (its offset, length, bleed and weight) and Rearrange All Artboards (its spacing) refuse a value other than a number or null, such as "50", and change nothing. Crop Image refuses a rectangle that is not four numbers, such as "0, 0, 20, 20".
|
||||
Transform Each (Reflect X, Reflect Y, Random, Copy, Scale Strokes & Effects, Scale Corners, Transform Objects and Transform Patterns), Create Object Mosaic (gray tiles and deleting the image), Crop Image (its trim), Create Trim Marks (all artboards) and Rearrange All Artboards (by column, Move Artwork with Artboard and Transform Patterns) refuse a value other than true, false or null, such as "false", and change nothing. Create Trim Marks refuses a style that is not text, such as 5.
|
||||
New Artboard refuses a position or size other than a number or null, such as "10", and New Artboard and Artboard Options refuse a name other than text or null, such as 5; each leaves the artboards and the undo history as they were.
|
||||
@@ -1574,6 +1586,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- `.vectorcraft` (lossless JSON, compressed, atomic saves, save down to v1), Save As with a format chooser, Save a Copy, Revert, templates, Data Recovery after a crash (browser tabs hold their copies with Web Locks too, so a background tab's copies are never taken for a crash's, and a tab repairs copies another removed when it resumes: #367), background save and export. The desktop app writes its warnings and errors (graphics adapter, a lost graphics device, panics the guard recovered from) to standard error and to `logs/vectorcraft.log` next to the preferences, the two previous runs kept and each file capped at 16 MiB, so a launch without a terminal still leaves something to attach to a bug report (#465). Native documents with a lot of path data (traced or generated art, in layers, symbols or patterns) are saved as compact JSON, about a fifth of the size; small documents stay pretty-printed (#1492). Saving to a network drive on macOS falls back to a plain fsync when the share refuses a full flush (#1625, part of #1620; not confirmed on a real share), and a save still succeeds when a folder refuses the temporary file, the rename over the document or copying permissions: the content is written elsewhere first and copied in, and a failed copy keeps the temporary file and names it (#1649, part of #1620). A document opened by a relative path finds its relatively linked images, and `vectorcraft-cli convert` lists what reading the input left out as `importWarnings` (#1606, fixes #1604).
|
||||
Preferences › File Handling › Data Recovery › Folder has a Choose… button on the desktop that picks the folder Data Recovery keeps its copies in ([Illustrator reference, Set Data Recovery preferences](https://web.archive.org/web/20210601162814/https://helpx.adobe.com/pdf/illustrator_reference.pdf)); a picked folder that Data Recovery cannot create its folders in or list is refused with a status message, and the field keeps its value. OK applies the same check to a folder typed into the field (VectorCraft's own rule): when it fails, the dialog stays open, the status bar says why and no preference changes; an empty field (the default folder) and the folder already saved are not checked. Preferences › Plug-ins & Scratch Disks is where additional plug-ins folders are set ([Illustrator preferences help](https://helpx.adobe.com/illustrator/desktop/get-started/preferences-and-settings/set-app-preferences.html)); its Additional Plug-ins Folder has a Choose… button on the desktop as well, VectorCraft's own, matching Data Recovery's, and VectorCraft's own rule refuses a picked or typed folder whose contents can't be listed. Additional Fonts Folder and Templates Folder stay typed only.
|
||||
`prefs.set` applies the dialog's check to `recoveryFolder` and `pluginsFolder` for every caller (VectorCraft's own rule): a folder that fails returns an error and no preference changes; an empty value and the folder already saved are not checked.
|
||||
When a Data Recovery copy can't be written, the status bar and the log show the error (with the document's title when one document's copy fails), the folder copies go to, whether that is the default recovery folder or the folder set in Preferences, and the preference that picks another folder (`recoveryFolder`; VectorCraft's own message).
|
||||
A name typed in the desktop save panel without the file type's extension gets it, and when a file of that name exists, which the panel did not ask about, Save, Save As, Save a Copy, Save as Template, the exports and every other write through a save panel ask before replacing it (dialog `replaceFile`; Cancel writes nothing).
|
||||
A name returned by the desktop save panel with the extension of a format the save does not write has it replaced with the saved format's: Save As of a new document saves `card.ait` and `card.png` as `card.vectorcraft`, and Save as Template saves `card.pdf` as `card.vctemplate`. An extension that names no format stays part of the name (`notes.v2` is saved as `notes.v2.vectorcraft`).
|
||||
Export As, Save as PDF, Save for Office Documents, Save for Web, Text Export Options, print to file, the presets' Export… and the library, swatch and Document Info saves replace a typed extension of another format than the one they write in the same way: Export As PNG writes `card.svg` as `card.png`, Save as PDF writes `card.png` as `card.pdf`, and `document.exportSelection` with a `format` suggests and adds that format's extension. An extension of the written format stays as typed in any letter case (`photo.JPEG` for JPEG), Export As SVG writes `art.svgz` compressed, and `document.exportSelection` without a `format` writes the format the typed extension names (`tests/saveext.rs`).
|
||||
@@ -1598,6 +1611,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
A PDF-compatible `.ai` saved with Include Editing Data for Other Apps defines every symbol in its editing copy with its art, registration point and place in the Symbols panel's order, and writes its instances as symbol instances, which VectorCraft's `.ai` reader opens as symbols and instances again (`symbols_and_their_instances_are_read_back` in `crates/eps/src/ai_editing/tests.rs`; [file-format-parity.md](file-format-parity.md) lists the instances written as their art).
|
||||
A PDF-compatible `.ai` saved with Include Editing Data for Other Apps keeps envelopes made with a warp, a mesh or a top object editable: its editing copy holds each envelope's contents, shape, Fidelity, Envelope Options and Edit Contents state in the form VectorCraft's `.ai` envelope reader reads, beside its distorted art, so the file opens with the same live envelope, Edit Contents still switching between the contents and the envelope ([Edit the contents of envelopes](https://helpx.adobe.com/illustrator/desktop/manage-objects/reshape-transform-objects/edit-the-contents-of-envelopes.html)). Envelopes of type, envelopes in opacity masks, pattern tiles or another envelope's contents, and envelopes the reader would open with another shape or other settings (a Fidelity that isn't a whole number, bounds margins kept with Distort Appearance off), and envelopes after the first 256 in a file are written as their distorted art, with a warning (`envelopes_are_read_back_live` and `envelopes_the_reader_cannot_open_live_are_written_as_their_art` in `crates/eps/src/ai_editing/tests.rs`).
|
||||
A PDF-compatible `.ai` saved with Include Editing Data for Other Apps writes eligible paths, compound paths and groups with live effects with an art style when the writer supports their appearance and effects (not a filled path that uses the even-odd rule, and none on a large canvas), which VectorCraft's `.ai` reader opens as the same appearance with its effects live (`objects_with_live_effects_are_read_back` and `every_effect_setting_written_on_an_object_is_read_back` in `crates/eps/src/ai_editing/tests.rs`; [file-format-parity.md](file-format-parity.md) lists the objects written without one and the effects they lose).
|
||||
The same holds for the objects of an opacity mask's art, a mask inside another mask's art and a hidden art root included, so a mask whose art has Offset Path opens drawing the image it masks as it did, with the effect live; geometry effects that no art style holds on a mask's art, such as Roughen, are written applied to the art, which opens drawing what it drew (`a_masked_image_with_live_offset_path_round_trips`, `hidden_and_nested_mask_art_keep_live_offset_path` and `a_masks_art_with_an_effect_no_style_holds_is_written_as_it_draws` in `crates/eps/src/ai_editing/tests.rs`).
|
||||
A PDF-compatible `.ai` saved with Include Editing Data for Other Apps writes point type, area type and type on a path as type in its editing copy, and objects next to it keep their own transparency (`crates/eps/src/ai_editing/tests.rs`, `cmd::fileio::tests_pdfedit::type_comes_back_from_the_editing_copy`; [file-format-parity.md](file-format-parity.md) lists what is written as outlines).
|
||||
A PDF-compatible `.ai` saved with Include Editing Data for Other Apps keeps the document's variables, data sets and the bindings of objects to variables in its editing copy, in the form the variable library reader above reads, so they come back when the file is opened. Bindings to layers, to type written as outlines, to graphs and to linked images written as other objects, data set values of graphs, and variables, data sets, bindings and values past the writer's limits are left out with a warning (#6024; `crates/eps/src/ai_editing/tests.rs` `variables_data_sets_and_bindings_are_read_back`; `crates/eps/src/ai_editing/writer/variables.rs` lists what is left out).
|
||||
In a `.ai` or EPS opened from its editing data, type has its text object's opacity, blend mode and knockout shape flag, whether it is made from the file's text document or taken from the page, and type made from the text document takes its text object's lock. Where such type has transparency and comes in with other art (the rest of its look, or page type and strokes that go with it), a group of them has it. Where the page draws its type, or the strokes around it, with transparency that is neither its text object's nor its text object's combined with that of the objects around it, the page's type and strokes keep their own instead (`crates/eps/src/import/tests_native.rs`). Where the page draws type of no text object over text objects made from the text document, with their words in any case, that type is theirs as the page draws it and is left out; the page's other type of no text object goes only to text objects whose type the text document can't make, or else is left out with a warning.
|
||||
@@ -1640,6 +1654,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Export As PDF with Use Artboards off also opens the Save PDF dialog, without its Artboards section, and writes one page of the visible art's bounds with the dialog's options (`document.exportPdf {useArtboards: false}`; `crates/ui-egui/src/dialogs/tests_export.rs`, `crates/engine/src/cmd/fileio/tests_pdf.rs`).
|
||||
A `.ai` export with Use Artboards off writes one page of the visible art's bounds without the native document or the editing copy for other apps, with a warning, so the file does not reopen with one artboard in place of the document's; without PDF content it is refused (`crates/engine/src/cmd/fileio/tests_pdfedit.rs`).
|
||||
PDF export warns when a PDF/X file has no bleed on a side where the document's bleed has one, and writes the file as asked.
|
||||
In a PDF without a standard, the warning for a page longer than 14,400 pt written with a `UserUnit` names "Write pages longer than 200 in at full size in points" (`crates/engine/src/cmd/fileio/tests_pdf.rs`).
|
||||
A PDF/A-2b export at PDF 1.4 with a page longer than 14,400 pt is written as PDF 1.6 with a `UserUnit` and a warning, whether or not `longPagesInPoints` is on, so its page boundaries stay within PDF/A-2's limit of 14,400 units (ISO 19005-2, 6.1.13) unless the page is too narrow for that (`crates/pdf/src/tests/marks.rs`).
|
||||
PDF/X-1a, PDF/X-3 and PDF 1.3 files keep the art under the hidden part of a picture, gradient, pattern, mesh or raster effect that a clipping mask or clipping layer crops: flattening rasterizes only the part of such art that its clipping path shows, on its own page and on the next one. Layers the file leaves out are left out of the flattening, and transparent art that a clipping path hides entirely is removed (`crates/engine/src/cmd/fileio/tests_pdfx.rs`).
|
||||
Placed (linked) files in a `.ai`'s editing data come in as linked images in their place, each showing the low-resolution preview the file keeps of it until its file is found or relinked in the Links panel (a file found next to the document, at its path, or in the folder the editing data names relative to the document's, such as `src/`, is read as the document opens, and its link takes that file's size, modification time and hash). A file with them no longer falls back to its PDF part, so its guides, sublayers and hidden objects open (#1264; `crates/eps/src/import/ai/tests.rs`, `crates/engine/src/tests/links.rs`). In a file opened that way, a gradient with stops in the middle runs its whole ramp across its shape and a gradient object no longer passes its fill to the next path (#1390); text objects with an appearance keep their own text and frame, type of hidden layers stays hidden, and type on later artboards lands on its text objects (#1391); area type whose frame is too short for a line of the fallback font shows its first line, the frame made taller with a warning in the open result (#1392).
|
||||
@@ -1709,6 +1724,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
- A photo whose EXIF orientation turns or flips it (a camera held upright or upside down) is placed and opened upright, as it was taken; the image is stored as it is seen (#4284). A quarter turn swaps the resolution's axes, so the image keeps its physical size. TIFFs read without the image decoder (grayscale with extra channels, CCITT Group 3, CMYK with one plane per ink) follow their Orientation tag too, and a turned CMYK JPEG or TIFF keeps its inks, at the 8 or 16 bits the file has, as a CMYK TIFF.
|
||||
- An image that Open and Place store again keeps the ICC profile its file embeds and its 16-bit samples. A turned PNG, JPEG, WebP or TIFF stored as PNG, and a TIFF the image decoder reads, keep their gray or RGB samples at 8 or 16 bits with their gray or RGB profile in the PNG's `iCCP` chunk ([PNG specification, iCCP](https://www.w3.org/TR/png-3/#11iCCP)). A CMYK TIFF stored with one plane per ink and a turned CMYK JPEG or TIFF keep their CMYK profile as TIFF tag 34675, a JPEG's put together from all its APP2 segments ([ICC image-format guide](https://github.com/InternationalColorConsortium/iccDEV/blob/master/iccdev-mcp/docs/icc-format-guide.md)). A profile whose color space differs from the stored samples' is left out. The profile is kept in the stored image; how CMYK inks are drawn and exported to PDF does not change (`crates/engine/src/cmd/fileio/tests.rs`).
|
||||
- SVG import shows a raster `<image>` whose EXIF orientation or TIFF Orientation tag turns or flips it upright, linked or as a data URL, and inside an SVG shown as an image: the pixels are stored turned, the width and height swap, and the `<image>` box fits the turned image under `preserveAspectRatio`, as CSS `image-orientation: from-image` describes (<https://www.w3.org/TR/css-images-3/#the-image-orientation>). A turned CMYK JPEG or TIFF keeps its inks as a CMYK TIFF, as does a CMYK TIFF that is not turned. TIFF data URLs (`image/tiff`, or untyped TIFF bytes) are read, and TIFFs with an alpha or other extra channel, CCITT Group 3 TIFFs and CMYK TIFFs stored one plane per ink are read as Open and Place read them. The pixels are decoded within the decode allowance, and a TIFF claiming more strips or tiles than the decoder can count is refused before it is decoded (`crates/svg/tests/it/image_orientation.rs`).
|
||||
- SVG import leaves out an SVG shown as an image that it can't read (text that isn't XML, an SVG without a size) and goes on with the images after it, as SVG 2's error processing describes (<https://www.w3.org/TR/SVG2/conform.html>). Only images that decode count toward the 256 nested SVG images an SVG may show, so an image after many broken ones is imported. Every nested SVG image read, decoded or not, counts toward VectorCraft's own limits of 1,024 reads and 512 MB of text per import; past them, nested SVG images are left out with a warning (`crates/svg/tests/it/import_details.rs`).
|
||||
- File › Place and a file dropped on the canvas refuse a PNG, JPEG, GIF or WebP file whose pixels can't be read, such as one cut short by a download or a sync still running, and the status bar shows "Couldn't place <name>: the image's pixels can't be read". Paste and Relink refuse such an image too, and Update Links, or Open when it reads the file again, counts it as missing. A JPEG cut short still places when its pixels can be decoded (`file.place`, `crates/engine/src/tests_place.rs`).
|
||||
- On the desktop, Copy and Cut make the system clipboard's formats (text, SVG, PDF, PNG) from a copy of the clipboard on the thread that writes background saves and exports, and write them when they are ready; while that thread has a save, an export, a print or a recovery copy to finish, they are made and written at once. Until they are written, Paste in VectorCraft takes the internal clipboard, and while a text field or the Type tool has the keyboard the app waits for them. Another Copy or Cut, or a copy of text in VectorCraft, drops them.
|
||||
- In the Linux Flatpak on GNOME, where the clipboard goes through the compositor's core Wayland protocol, one Copy offers the PNG (`image/png`), the SVG (`image/svg+xml`, with Include SVG Code on) and the text, and Paste takes another app's SVG, text or PNG in that order, a picture over blank text or text that only names it; the Paste menu item is enabled by the types offered (`clipboard::wayland` tests in `apps/vectorcraft/src/clipboard.rs`; not yet run in the Flatpak on a GNOME session).
|
||||
@@ -1754,6 +1770,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
Pathfinder › Merge and the `pathfinder.merge` group effect find the faces of every fill in a few contour passes over the arrangement, as Trim and Crop do, instead of one pass for each distinct fill. The output paths and their order are the same. With 8,000 squares that do not touch, each with its own fill, Merge takes 72 to 107 ms instead of 17 to 32 s (release build).
|
||||
The Pathfinder panel, Offset Path, Clean Up, Divide Objects Below, Make and Release Blend, Envelope Distort's Make and Release, Repeat (Radial, Grid, Mirror and Release), Vector Halftone, New and Redefine Symbol, Delete Symbol, erasing with the Symbol Sprayer, Rasterize, Convert to Artboards, Flatten Transparency, Clear Guides, Shape Builder, Live Paint, Release Image Trace, Make and Release Opacity Mask, Delete with direct-selected anchor points, Remove Anchor Points, Cut Path, and the Shaper, Knife, Eraser, Path Eraser, Line Cut, Rectangle Cut, Mirror & Cut and Blob Brush tools add and remove objects in one pass over each layer or group they change, and Outline Stroke and Expand write each new object in the place of the object it replaces (#1429).
|
||||
Offset Path looks up the segments near each candidate hole or island in a tree of the source path's segment bounds when it decides whether to drop that contour, instead of testing the bounds of every segment. The output paths are the same. On compound and open paths of 25,000 to 40,000 anchors with 6,400 to 11,976 candidate contours, that check takes 11 to 13 ms instead of 140 to 649 ms (medians of five interleaved runs). The limit on overlapping segment pairs is the same, so a path that stops with "Offset Path: the path is too complex to offset" still stops there.
|
||||
Offset Path on several selected paths, or on a group of them, works out their offsets on as many threads as the computer has logical CPUs (one thread on the web and for a single path), and then makes the new objects one after another in the selection's order. The new objects, their ids, their stacking, the selection and the undo step are the same as when the paths were offset one at a time, and when more than one path fails, the error is the one for the first of them in that order (`tests::pathops::offset_path_of_several_objects_keeps_their_order`, `tests::pathops::offset_path_works_on_several_threads_in_order`, `tests::pathops::offset_path_stops_after_the_first_failure`).
|
||||
Finding the distinct regions of an arrangement lists the shapes that cover each region instead of keeping a flag for every shape, so that step's time follows how many shapes cover each region rather than how many shapes there are. Divide, Hard Mix, Soft Mix, Shape Builder, Flatten Transparency, trapping, Intertwine and the Pathfinder effects are among the commands that use that step. The regions, their order and the output are the same. Divide on 3,000 overlapping rectangles takes 0.84 to 1.13 billion CPU cycles on its thread instead of 1.25 to 1.46 billion (dev build, six runs of each, alternating, while other builds were running).
|
||||
The contour passes of the two-path boolean operations, Offset Path, compound shapes and Intertwine test the list of shapes that cover each face instead of a flag for every shape, so each test's time follows how many shapes cover the face rather than how many shapes there are. The contours, their order and the output are the same. The many-shape boolean that compound shapes use takes 0.75 to 0.83 billion CPU cycles on its thread instead of 1.28 to 1.33 billion to unite 10,000 squares that do not touch, and 2.27 to 2.30 billion instead of 2.43 to 2.47 billion for 1,500 members of two squares each over 3,000 overlapping squares (dev build, six runs of each, alternating, while other builds were running).
|
||||
Pathfinder › Unite and the other commands that unite filled paths sweep a single input once instead of twice when its own sweep neither splits nor drops any of its segments and no two of its segments lie within twice the sweep tolerance. The output is the same. Unite on one compound path of 4,000 rings takes 485 to 542 ms instead of 872 to 1,008 ms, and on one zigzag polygon of 20,000 teeth 70 to 76 ms instead of 118 to 130 ms (release build, medians of three alternating rounds of five runs, while other builds were running).
|
||||
@@ -1874,6 +1891,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
|
||||
|
||||
- **Plug-in parameters as their manifest presents them (G17):** each parameter may have a `label`, a `unit` shown after its value, `help` on its label and a `helpUrl` page opened from a button, a `group` (sections that fold, after the parameters outside any group) and a `visibleWhen` that shows it only while the checkboxes and choices it names have one of the listed values (a hidden parameter still goes to the plug-in). `string` and `numberList` parameters join number, int, bool and choice, and a plug-in declares up to 256 parameters, at most 64 outside groups. The filter, live-effect and exporter dialogs use these keys, and the Appearance panel's effect editor the labels, units, help and conditions; hosts from before them ignore them. Regressions: `crates/plugins/src/dialog.rs`, `crates/plugins/src/manifest.rs`, `crates/ui-egui/src/dialogs/tests_plugin_fields.rs`, `crates/ui-egui/src/panels/appearance.rs`. Scores and hours unchanged.
|
||||
- **Live-effect plug-ins read their object's paints (G17):** a live effect is given the object's `fills` and `strokes` as a filter gets them, read only, and `_context.item` (`"object"`, or the fill or stroke whose own effects hold it); the result is cached by paint too, so a change of paint runs it again. Regressions: `crates/engine/src/tests/plugins.rs`, `crates/plugins/src/effect.rs`. Scores and hours unchanged.
|
||||
- **Live-effect plug-ins before a fill's or stroke's own 3D effect:** a live effect listed before a fill's or stroke's own Extrude & Bevel, Inflate or Rotate effect is given `_context.item` for that fill or stroke (`{"fill": i}` or `{"stroke": i}`), not `"object"`, in the drawn art, in the 3D meshes and in Expand as Wireframes; a deferred stage there is listed at that fill's or stroke's place. Regressions: `crates/effects/src/tests/solidcontext.rs`. Scores and hours unchanged.
|
||||
- **Filter plug-ins set effects and stroke styles (G17):** a filter is given each object's effect records and its strokes' `join`, `cap` and `miterLimit`, and may return them; the records are admitted as `effect.apply` admits them (a known effect or installed live-effect plug-in, parameters it takes, one 3D effect that fits, no texture read from a file), and one refused refuses the output. Regressions: `crates/engine/src/tests/plugins.rs`, `crates/plugins/src/objects/tests.rs`. Scores and hours unchanged.
|
||||
- **Gradient stop plates from filter plug-ins are clamped (G17):** the four process `plates` of a gradient stop in a filter's or importer's output are clamped to 0–1, as its other colors are; a value that is not a number becomes 0, and an infinite one becomes 0 or 1 by its sign. Painted live effects still refuse such a stop. Regressions: `crates/plugins/src/objects/tests.rs`. Scores and hours unchanged.
|
||||
- **Plug-in data kept with the document (G17):** a filter writes JSON of at most 1 MiB with `documentData` (one undo step with its objects; `null` removes it) and reads it back in `_context.documentData`, which no other filter is given. It is the document's foreign data (`unknown.pluginData`, by plug-in id), as the perspective grid is, so the native file keeps it with no section of its own; an exporter is given the whole document, so it can read every plug-in's. Regressions: `crates/engine/src/tests/plugins.rs`, `crates/engine/tests/plugin_export.rs` (the exporter), `crates/doc/src/plugin_data.rs`, `crates/plugins/src/objects/tests.rs`. Scores and hours unchanged.
|
||||
@@ -2151,6 +2169,10 @@ A VectorCraft addition, so no area score moves. Object › Plug-ins › Cutting
|
||||
|
||||
A VectorCraft addition, not a feature of the reference app, so no area score moves. Object › Plug-ins › Cutting Tools › Weed Box and Lines… (`addon.cutting.weed`) adds a weed box and weeding lines around the selected art for vinyl cutting ([what a weeding border is](https://help.arlon.com/what-is-a-weeding-border)). The rest is VectorCraft's own: the box is a rectangle at a margin around the art, and the lines run across it horizontally, vertically or both ways, by count or by spacing, and stop at the art's outlines or at a gap from them. The box and the lines are straight paths stroked in a chosen swatch ([Registration] by default), in one group named Weeding on top of the current layer, added as one undo step. The art is measured by the outlines a cutter cuts: compound paths by their fill rule, type by its glyph outlines, clip groups by what shows, images by their frames, placed files by the art they show, symbol instances by their art, and blends and other live objects by the art they draw. The dialog has Preview. Tests: `cmd::addons::cutting::weed::tests` in `vectorcraft-engine`, `weed_box_and_lines_previews_cancels_and_runs_on_ok` in `vectorcraft-ui-egui` and `command_sweep`. Commands: `docs/mcp.md` › Cutting Tools add-on › Weed Box and Lines.
|
||||
|
||||
## Cutting Tools add-on: Banner Hems and Grommets (2026-11-13)
|
||||
|
||||
A VectorCraft addition, so no area score moves. Object › Plug-ins › Cutting Tools › Banner Hems and Grommets… (`addon.cutting.banner`) marks where a printed banner is hemmed ([hem](https://en.wikipedia.org/wiki/Hem)) and where its grommets go ([grommet](https://en.wikipedia.org/wiki/Grommet)). The rest is VectorCraft's own: the banner is the selected art's bounds or each artboard; each chosen side gets a hem line at a set depth inside its edge (1 in by default) and grommet marks at a set inset (0.5 in), one at each end of the side and the rest spread evenly at most a set spacing apart (24 in), with one grommet at a shared corner. Each grommet mark is a circle with a cross through its center. The marks are stroked in a chosen swatch ([Registration] by default), in one group named Banner Marks per banner on top of the current layer, added as one undo step. The dialog has Preview. Tests: `cmd::addons::cutting::banner::tests` in `vectorcraft-engine`, `banner_hems_and_grommets_previews_cancels_and_runs_on_ok` in `vectorcraft-ui-egui` and `command_sweep`. Commands: `docs/mcp.md` › Cutting Tools add-on › Banner Hems and Grommets.
|
||||
|
||||
## Path Precision Tools add-on: Divide into Dashes (2026-11-01)
|
||||
|
||||
A VectorCraft addition, not a feature of the reference app, so no area score moves. Object › Plug-ins › Path Precision Tools › Divide into Dashes… cuts the selected paths into separate open paths along the curve (arc length, not straight distance): each `dash` long (0.01 to 1000000 pt, 10 by default) with `gap` between them (0 by default: the pieces touch); the gap pieces are left out unless Remove Gaps is off. With direct-selected segments (or anchors) only those runs are divided, the pattern running on across segments that follow one another, and the rest of such a path stays as pieces of its own. Fit to Corners and Ends gives every run between corners and ends a whole number of dashes, all stretched or squeezed alike so it starts and ends on a dash (a closed path without corners holds whole periods); otherwise the lengths are exact and each run's last piece is what is left. Every piece keeps the path's appearance and is selected; one undo step; at most 100000 pieces (more is refused). The dialog takes lengths in any unit and previews on the canvas. Tests: `dashes::tests` in `vectorcraft-pathops` (exact and fitted lengths, curves measured along them, picked segments on open and closed paths, the piece cap and bad patterns), `divide_into_dashes_*` in `cmd::addons::pathtools::tests` in `vectorcraft-engine` (gaps removed or kept, fitted lengths, the stroke kept, one undo step, selected segments only, bad params and too many pieces refused), `divide_into_dashes_opens_its_dialog_previews_and_runs_on_ok` in `vectorcraft-ui-egui` and `command_sweep`. Commands: `docs/mcp.md` › Path Precision Tools add-on.
|
||||
|
||||
+2
-1
@@ -77,7 +77,7 @@ object is where the art was.
|
||||
|---|---|
|
||||
| Depth | 0–2,000 pt. At 0 the object is flat (the art turned like Rotate). |
|
||||
| Twist | 0° to 360°: the back face turned against the front, the walls following in slices. |
|
||||
| Taper | 1–100 %: the back face's size against the front's. |
|
||||
| Taper | 1–100 %: the back face's size against the front's. Without a twist, each wall (and each bevel band) stays flat, so it is one face, not cut into slices. |
|
||||
| Cap | **Solid** closes the front and back; **Hollow** leaves them open, showing the insides of the walls. |
|
||||
| Bevel Shape | **None**, **Classic** (a straight chamfer), **Rounded** (convex quarter round), **Cove** (concave), **Step** (two steps) or **Ogee** (an S curve). Our own cross-sections. |
|
||||
| Width, Height | How far the bevel reaches across the face and along the depth (0–1,000 pt each). The height is limited to the depth (half of it on each side with Bevel both sides). |
|
||||
@@ -491,6 +491,7 @@ Release measurements and a repeatable CLI scene are in [3D lighting performance]
|
||||
|
||||
| Date | Change |
|
||||
|---|---|
|
||||
| 2026-11-13 | Extrude & Bevel cuts its walls into slices only for a twist. A taper alone keeps each wall flat, so it is one face, without the light ticks at the joints between slices or the light line down a wall (#7019). Inflate still slices its sides for a taper. |
|
||||
| 2026-11-12 | The seams of Extrude & Bevel, Inflate and Rotate under a white light, and of the faces of Extrude & Bevel (Classic), Revolve (Classic) and Rotate (Classic), went from miter to round joins (the seams of Revolve and of colored lights, and 3D (Classic) Wireframe edges, were already round): no thorns on edge-on facets, and facets with no neighbor now have rounded convex corners ([Seams](#seams)). |
|
||||
| 2026-11-08 | Contours that cross, touch or overlap are merged by vectorcraft-pathops before Extrude & Bevel, Inflate and Rotate build a solid, sharing its limits; others are built as drawn. |
|
||||
| 2026-11-06 | Extrude & Bevel, Inflate and Rotate apply to groups and layers: every path, compound path and type in them turns about one shared axis (#4506). |
|
||||
|
||||
Reference in New Issue
Block a user