Merge main into feat/smooth-keeps-corners

This commit is contained in:
dotCooCoo
2026-11-14 09:42:14 -08:00
117 changed files with 9643 additions and 478 deletions
+9 -5
View File
@@ -15,13 +15,17 @@ The **Dimension Tool** is in the Modify section of the toolbar. Its strip offers
path's length. A press on an anchor picks it when the pointer moves less than 8 pixels
before the release; a longer drag drags out the dimension of the segment under the pointer. A
curved segment is measured from end to end. With Smart Guides on, both points also snap into line with other objects'
anchors and centres, and the second onto the construction guides through the first; the guides
anchors and centres. With Snap to Perpendicular or Snap to Tangent on, the second point also
snaps onto a segment where the line from the first meets it square or grazes a curve. When the
first point was picked on an anchor, the second also snaps onto the construction guides through
it; any other first point has no construction guides through it. The guides
show while hovering, before each click. VectorCraft's own rules decide where a point lands: an
anchor within 8 pixels takes it first; a point on a guide stays on the guide where the pointer
is, except that it moves onto a segment within the Smart Guides snapping tolerance, or onto the
place where a construction guide crosses another object's alignment line within twice that
tolerance; a point that no anchor, guide, grid or pixel snapping places lands on the closest
point of a segment within 8 pixels.
is, except that it moves onto a segment within the Smart Guides snapping tolerance, or, on a
construction guide or a Snap to Glyph guide that runs at an angle, onto the place where that
guide crosses another object's alignment line within twice that tolerance; a point that no
anchor, guide, grid or pixel snapping places lands on the closest point of a segment within 8
pixels.
A linear dimension is aligned, horizontal or vertical, as the
[linear dimensions help](https://helpx.adobe.com/illustrator/desktop/measure-and-align/plot-and-measure/plot-linear-dimensions-of-objects.html)
describes: after the second click, clicking again places an aligned dimension, and moving the
+6 -2
View File
@@ -98,8 +98,12 @@ main added paragraph labels, spine-index validation and two error messages: six
Main's workspace version is still 0.21.0; this PR does not change release versioning.
`cargo test -p vectorcraft-ui-egui --lib i18n::tests` passes all 55 tests in Ubuntu 24.04 (WSL).
The untranslated report has no Hindi section, meaning it found no missing Hindi rows among the
categories it checks. This does not check dynamically assembled strings that the scanners miss.
On 2026-11-14 the untranslated report on main (`f793044f83`) has a Hindi section with 608
missing rows: 28 menu strings, 30 `tl!` strings, 11 undo labels and 539 messages. Its
`every language` section lists 68 more that every checked language lacks, Hindi included: 10 menu
strings, 2 undo labels and 56 messages. These include labels for newer features and command
parameter, script and file import or export errors, which show in English until a catalog row
is added. The report does not check dynamically assembled strings that the scanners miss.
Additional checks compare placeholders, backtick-delimited identifiers and numeric values.
The native Hindi UI fallback test also passes with the installed Nirmala UI font. A running
desktop preview was checked in Hindi, including the New Document dialog and File menu.
+5 -5
View File
@@ -31,7 +31,7 @@ Chinese by `imachus`). Georgian and the original Gujarati catalog are recorded a
| English | `en` | source, 100% | all | Latin | — | full | — |
| Simplified Chinese (Mandarin) | `zh-hans` | 5,102 rows, 791 of them `@msg` (counted 2026-10-21): menus, `tl!` literals and messages complete when counted | all (3,554 `@msg` and 48 `@msgplural` rows, counted 2026-11-13: the untranslated report lists 55 missing messages for it, which open #7116, #7211, #7330, #7378 and #7405 translate) | CJK UI font from craft-fonts (BIZ UDPGothic) when embedded, else a system font; IME with marked text at the caret; vertical type partial ([type-parity.md](type-parity.md)) | no | full | — (review) |
| Spanish | `es` | 4,009 / 4,020 (99.7%) | all (604 messages) | Latin | no | full | — (review) |
| Hindi | `hi` | 8,782 rows (2026-11-13): 3,014 `@msg`, 47 `@msgplural`, 41 `@plural`; no gaps in the untranslated report | menus, dialogs, tooltips and scanned messages; contributor-approved loanword terminology; agent wording pass | UI and document text shape with HarfRust; installed desktop Devanagari fallback, or a `Deva` craft-fonts face; web font still needed | contributor terminology review; 2026-11-13 wording pass on messages and longer labels, with a glossary-term test; wider proofread welcome | complete catalog, machine-assisted draft | native review, layout and web font |
| Hindi | `hi` | 8,782 rows (2026-11-13): 3,014 `@msg`, 47 `@msgplural`, 41 `@plural`; the untranslated report on main `f793044f83` (2026-11-14) lists 676 missing rows for it: 608 in its own section and 68 that every checked language lacks | menus, dialogs, tooltips and scanned messages; contributor-approved loanword terminology; agent wording pass | UI and document text shape with HarfRust; installed desktop Devanagari fallback, or a `Deva` craft-fonts face; web font still needed | contributor terminology review; 2026-11-13 wording pass on messages and longer labels, with a glossary-term test; wider proofread welcome | complete catalog, machine-assisted draft | reported missing rows, native review, layout and web font |
| Gujarati | `gu` | 4,673 rows (2026-11-14): original 4,286 unchanged; all 387 additions contributor-reviewed and approved | menus and dialogs; status/error messages partial | installed Gujarati fonts on desktop; optional `Gujr` craft-fonts fallback; no Gujarati face in the pinned CI/release fonts or web startup list | original catalog reviewed by a native speaker; all 387 later additions approved by the contributor, with 11 wording corrections | contributor-reviewed catalog | remaining messages and a bundled Gujarati web font |
| Arabic | `ar` | 0 | none | document text: bidi layout and Paragraph Direction; interface: no right-to-left layout, no Arabic shaping in egui | no | none | 25–40 |
| French | `fr` | 9,166 rows, 3,436 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 178 missing messages for it | all | Latin | no | full | — (review) |
@@ -44,8 +44,8 @@ Chinese by `imachus`). Georgian and the original Gujarati catalog are recorded a
**Historical 12-language score: ~82%** (equal weights: 100 + 85 + 100 + 0 + 0 + 100 + 100 + 100 + 100 + 98 + 100 + 100, over 12).
**To `full` for all twelve: ~50–85 h** (historical estimate, not re-scored here). Hindi now has
a complete catalog and UI shaping; its remaining work is native review, layout checking and the
web font. Arabic still needs its catalog and right-to-left interface. Each new Latin-script catalog is ~4,000 rows; the existing ones were written in a few agent hours each
a catalog that the tests count as complete, and UI shaping; its remaining work is the rows the
untranslated report lists for it, native review, layout checking and the web font. Arabic still needs its catalog and right-to-left interface. Each new Latin-script catalog is ~4,000 rows; the existing ones were written in a few agent hours each
plus review. Native-speaker review is human work and isn't in the hours.
## Other shipped languages
@@ -53,12 +53,12 @@ plus review. Native-speaker review is human work and isn't in the hours.
| Language | Code | Translated | Status |
|---|---|---|---|
| Traditional Chinese (Taiwan) | `zh-hant` | 8,820 rows, 3,438 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 40 missing messages for it; menus, `tl!` literals and messages were complete when counted on 2026-10-21 (80% overall) | partial |
| Italian | `it` | 8,757 rows, 3,422 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 40 missing messages for it | full |
| Italian | `it` | 8,924 rows, 3,560 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 54 missing messages for it, which open #7116, #7211, #7378 and #7405 translate | full |
| Dutch | `nl` | 3,447 `@msg` and 48 `@msgplural` rows (counted 2026-11-13): in `COMPLETE_MESSAGES`, and the untranslated report lists 41 missing messages for it; one/other plurals | full |
| Danish | `da` | 5,279 rows, 750 of them `@msg` (counted 2026-10-21): menus and `tl!` literals complete when counted; its messages are partial; one/other plurals | full |
| Russian | `ru` | 4,009 / 4,020 | full |
| Ukrainian | `uk` | 8,802 rows, 3,439 of them `@msg` and 48 `@msgplural` (counted 2026-11-13); one/few/many plurals | full |
| Hungarian | `hu` | 5,253 rows (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one plural form | full |
| Hungarian | `hu` | 9,166 rows, 3,444 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 40 missing messages for it, and lists 47 menu strings, 25 `tl!` strings, 11 undo labels and 45 swatch names without a row; one plural form | full |
| Polish | `pl` | 9,044 rows, 3,439 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 46 missing messages for it, and 47 menu strings, 26 `tl!` literals, 11 undo labels and 45 swatch names; one/few/many plurals | full; native review pending |
| Finnish | `fi` | 5,318 rows (counted 2026-10-21): menus, `tl!` literals and messages complete when counted; one/other plurals, 797 `@msg` rows | full; AI-assisted, native proofreading pending |
| Czech | `cs` | 9,273 rows, 3,560 of them `@msg` and 48 `@msgplural` (counted 2026-11-13): the untranslated report lists 2 missing Czech messages, and 54 messages that no language has a row for | catalog complete; render-site gaps reduced; native review pending |
+41 -10
View File
@@ -1,6 +1,6 @@
# VectorCraft MCP server
> **Last updated:** 2026-11-13 · **Change:** Snap to Point with Smart Guides off draws no Smart Guides labels or lines, #7250; no response-shape change. Previously: Envelopes: a top object's side whose pieces are all one curve split at anchors follows that curve's parameter (#7097); existing response shapes retained.
> **Last updated:** 2026-11-14 · **Change:** Pencil continuation, straight-line and closing cursors; scores and estimates unchanged; no response-shape change. Previously: Snap to Point with Smart Guides off draws no Smart Guides labels or lines, #7250; no response-shape change. Previously: Envelopes: a top object's side whose pieces are all one curve split at anchors follows that curve's parameter (#7097); existing response shapes retained.
`vectorcraft-cli mcp` runs a [Model Context Protocol](https://modelcontextprotocol.io) server on stdio
(newline-delimited JSON-RPC 2.0; see [Protocol](#protocol) for version negotiation). Agents use it to
@@ -3224,8 +3224,12 @@ already walks Image Trace. Short agent entry points:
is rejected with an error. The Pencil and the Paintbrush give Fidelity in screen pixels, 0.01 to 100 px, and send it
divided by the zoom (0.0313 to 640) and kept within that range, so a stroke is fitted at the same tolerance on screen
at every zoom. A stroke
that continues a path (`extend`) closes it when it ends within four times the Fidelity of the path's other end, at
least 6 pt and at most 400 pt. The Blob Brush's `path.blob` Fidelity stays in points, 0.01 to 100 pt.
that continues a path (`extend`) closes it when `closed` is true: the Pencil and the Paintbrush send it when the
stroke ends within Close Paths When Ends Are Within of the path's other end (the cursor shows the closing ring there),
a straight Pencil line too, or with Alt held at the release. The stroke's end then joins the other end when it is
within four times the Fidelity of it (at least 6 pt and at most 400 pt), and a straight segment closes the path from
farther away. Without `closed`, the stroke closes the path when it ends within that four-times-Fidelity distance. The
Blob Brush's `path.blob` Fidelity stays in points, 0.01 to 100 pt.
- Variables: `variable.list`, `variable.define {name, kind: text|visibility|image|graph}`, `variable.bind {variable, ids?}`,
`variable.makeTextDynamic`, `variable.makeVisibilityDynamic`, `variable.makeImageDynamic`, `variable.makeGraphDynamic`
(`variable.bind` and `variable.makeTextDynamic` refuse type that already has another text variable and name it),
@@ -3269,8 +3273,9 @@ already walks Image Trace. Short agent entry points:
byte order that reads a line break (`\n` or `\r`). It is refused when fewer of its units hold a NUL byte (UTF-8 or
Windows-1252 text with stray NUL bytes, or UTF-16 text made mostly of other characters, which needs a byte-order
mark), when both byte orders read a line break (the text holds U+0A00 or U+0D00), when it has an odd length, and
when it isn't valid UTF-16 in that order or holds a NUL character. A file with no line break has no data rows and is
refused for that. `csv` and `data` are read as the text they hold.
when it isn't valid UTF-16 in that order or holds a NUL character. A file with no line break is read big-endian when
more of its two-byte units start with a NUL byte than end with one, and little-endian otherwise; it has no data rows,
so the import is refused. `csv` and `data` are read as the text they hold.
- Variable libraries: `variable.loadLibrary {path|xml|dataBase64}` (the Variables panel menu's Load Variable
Library…) replaces the document's variables and data sets with a variable library's in one undo step. A load, like a
`dataset.import`, adds no undo step when it leaves the variables and data sets as they were. The library
@@ -3646,6 +3651,16 @@ already walks Image Trace. Short agent entry points:
a locked artboard, or in isolation mode outside the isolated art. In the app, the tool's cursor shows what a click
at the pointer selects under these rules: the arrow with a filled square for a face, with a short line for an edge,
and with an x for nothing. It keeps the look it had at the press until the release.
A double-click (`pointer_gesture` kind `doubleclick`, after the two clicks' `down` and `up`) on the face a click there
picks runs `select.set {ids}` with that face and the faces of its group that a flood from it reaches across edges
that are hidden or draw no stroke (an edge that is fully transparent, or whose strokes are each hidden, without
paint, 0 pt wide or fully transparent); a stroked edge and a Gap Detection gap stop the flood, and hidden faces are
left out. On the edge a click
there picks, it runs `select.set {ids}` with that edge and the edges of its group, not hidden, joined to it end to
end through edges that draw with the stroke paint it draws with (the paint of an edge's topmost stroke that is
shown, with paint, above 0 pt and not fully transparent; none for an edge that draws no stroke). With Shift held it runs `select.toggle {ids}` with the same faces or edges,
and where a click selects no face or edge it runs nothing. The same options, locks and isolation rules apply as for
a click.
The Live Paint Bucket's options (`tool.setOption {tool: "livePaintBucket", values}`; double-clicking the tool opens
them, dialog `livePaintBucketOptions`) are `paintFills` (on), `paintStrokes` (off), `cursorSwatchPreview` (on),
`highlight` (on), `color` (the
@@ -5135,7 +5150,8 @@ The Attributes panel (`window.panel {panel: "attributes"}`, Cmd+F11) reads `attr
objects differ) and `recentUrls`. `attributes.set {overprintFill?, overprintStroke?, showCenter?, imageMap?, url?,
note?, ids?}` sets them in one undo step; `path.setFillRule {rule: "nonZero"|"evenOdd"}` sets the fill rule of the
paths and compound paths, and `path.reverse {reversed?}` makes subpaths run counter-clockwise (true) or clockwise
(false). SVG export wraps an object with a URL in `<a xlink:href>`, and SVG import reads `<a href>` links back.
(false). When every subpath of a path turns alike, its strokes' width profiles (left and right swapped) and pen
pressure, tilt, bearing and rotation turn with it, so the strokes draw as before. SVG export wraps an object with a URL in `<a xlink:href>`, and SVG import reads `<a href>` links back.
```json
{"name":"run_command","arguments":{"command":"attributes.set","params":{"ids":[12],"url":"https://example.com","imageMap":"rectangle"}}}
@@ -7235,9 +7251,14 @@ the document; so does `object.expand`.
Placing a text file (`.txt`) sets it as area type: `file.place {path | name+dataBase64, text?: {characterSet?:
"unicode" | "ansi", platform?: "windows" | "mac", removeLineReturns?, removeParagraphReturns?, replaceSpaces?: n}}`
(Text Import Options). Unicode reads UTF-8, or UTF-16 with a byte-order mark; ANSI reads Windows-1252 (Mac Roman on
`mac`). `removeLineReturns` joins the lines of each block into one paragraph, `removeParagraphReturns` drops blank
lines, `replaceSpaces: 3` turns runs of 3 or more spaces into tabs. The frame fills `rect`, the replaced object's
bounds, or the artboard less a 36 pt margin.
`mac`). Unicode reads a file without a byte-order mark as UTF-16 by the rule `dataset.import` uses: at least half of
its two-byte units hold a NUL byte, in the byte order that reads a line break, or for a file with one line, big-endian
when more of its units start with a NUL byte than end with one, and little-endian otherwise. Any other file is read as
UTF-8, else as the platform's 8-bit set: one with fewer NUL bytes, one with an odd length, one where both byte orders
read a line break, and one that isn't valid UTF-16 in that order or holds a NUL character. `removeLineReturns` joins
the lines of each block into one paragraph, `removeParagraphReturns` drops blank lines, `replaceSpaces: 3` turns runs
of 3 or more spaces into tabs. The frame fills `rect`, the replaced object's bounds, or the artboard less a 36 pt
margin.
```json
{"name":"run_command","arguments":{"command":"file.place","params":{"path":"/tmp/notes.txt","text":{"removeLineReturns":true,"removeParagraphReturns":true}}}}
@@ -10662,6 +10683,10 @@ threaded frame, which composes them again at its own widths. Such a paragraph fa
frame has no room for its first line, or when the search for its breaks passes VectorCraft's own limits (1,000,000
lines tried and 2,000,000 baseline steps for one paragraph, 2,000,000 lines and 4,000,000 steps for all the
paragraphs of a frame).
Single-line measures each line's room the same way: a line that takes in a taller character is placed again across its
new height and broken again in the room there. When that leaves the taller character for the next line, the line is
set at its own height where the room there is no narrower, with the words before that character that fit there, and
otherwise stays where it was placed.
The UI command `type.lineComposer` (Cmd+Alt+Shift+C, in remote mode `press_key {key: "C", mods: {cmd: true, alt: true,
shift: true}}` or `invoke_menu`) sets `singleLine` when every paragraph of the selected type (or every paragraph the
Type tool's selection touches) uses Every-line, else `everyLine`, and returns the composer it set.
@@ -10720,7 +10745,12 @@ and the arrow keys nudge them by the keyboard increment. The active tool lists t
(`tool.setOption {}` returns them as `meshPoints: [{id, index}…]`). On gradient meshes a solid fill colour (`paint.setFill`, from the
Color panel, Swatches or the Eyedropper) recolours just the picked points, and when every target of
`transparency.set` is a gradient mesh with points picked, its `opacity` fades those points instead of the objects
(`transparency.info` then shows their opacity, `null` when it differs). Both are one undo step.
(`transparency.info` then shows their opacity, `null` when it differs). Both are one undo step, and neither goes to the
points while the Appearance panel's active row takes the fill or the opacity. When the first selected object is a
gradient mesh with points picked, the Fill proxy, the Color panel, the Color Wheel and `paint.proxies` show its first
picked point's color, and `fillMixed` compares the picked points' colors with each other and with the fills of the other
selected objects. The Transparency panel shows the picked points' opacity (blank when it differs), and the Control
bar shows the first picked point's opacity.
`object.mesh.movePoints {id, points: [index…], dx, dy}` (or `{items: [{id, points}…], dx, dy}` over several meshes)
moves points by (dx, dy), their handles with them; `object.mesh.setPointColor` takes `points` or `items` the same
@@ -11849,6 +11879,7 @@ the error text. The interactive fallback applies only to ordinary File > Save, n
| Date | Change |
|---|---|
| 2026-11-13 | `path.freehand`: `closed`, when given, decides whether a stroke that continues a path (`extend`) closes it; the Pencil and the Paintbrush send it by Close Paths When Ends Are Within. |
| 2026-11-13 | Snap to Point with Smart Guides off draws no Smart Guides labels or lines (#7250). |
| 2026-11-13 | Envelopes: a top object's side whose pieces are all one curve split at anchors follows that curve's parameter (#7097). |
| 2026-11-11 | Document READ_ONLY_LOCATION for saves (#6146); no response-shape change. |
File diff suppressed because one or more lines are too long
+12
View File
@@ -121,6 +121,14 @@ How a facet carries its seam depends on the lights and the paint:
groups clipped to the union of its facets, so no seam reaches past the surface; a gradient fill, and a solid-color
fill or stroke whose faces share one depth order with another solid's, fills each facet's ramps through a clip of
the facet and its seam, outlined with round joins.
The facets of a surface drawn this way lie over an underlay
of themselves whose seams are 2 pt wide, reaching 1 pt past each edge, and one clip to the union of the facets and
their seams removes what the underlay paints past the surface. Where two facets' antialiased edges meet, the
underlay fills the pixels they leave partly uncovered with the neighbors' own light, so no black channel backdrop
or background shows there. Compared with the same art drawn at 3x and averaged down, away from the surface's outline
and from places where the light changes sharply, a pixel drawn at 1:1 is opaque where the 3x art is opaque, and
otherwise its alpha is within 3 levels. Inflate seen straight on with an opaque fill also has each color channel
within 3 levels (VectorCraft's own measure).
- Extrude & Bevel (Classic), Rotate (Classic) and Revolve (Classic): a path and a seam for every face; gradient and
pattern faces seam only the base paint, and the shading and highlight layers cover the face alone. The Wireframe
surface draws edges only, with no seam.
@@ -171,6 +179,10 @@ The rest is our reading:
once their faces pass it no later solid is built: the object draws its source art, and applying or editing the
effect, Export 3D Object and **Expand as Wireframes** report that the 3D surface is too complex. A stroke left
out for its own limits does not count.
- Inflate works out how high every shape puffs before it builds the first solid, because the highest puff sets
how far away the eye is. At a Volume of 0 % no shape puffs, so each shape's puff is worked out only when its
solid is built, and none is worked out for the solids after the limit stops. The shadow builds no solid for a
fill or stroke that is fully transparent.
## Groups
+3 -2
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-13 · **Change:** minor (Graphic Styles list fills a taller panel, #2992; scores and estimates unchanged; previously: library panels' lists fill a taller panel, #2992; scores and estimates unchanged; previously: Swatches list fills a taller panel, #1638; scores and estimates unchanged; previously: icon-strip flyouts also resize from the top edge and the canvas-side top corner, keeping the moved top in workspaces (storytold/craft-libs#1094); scores and estimates unchanged; previously: macOS: the canvas cursor stays after the pointer moves, #6362; scores and estimates unchanged; previously minor: Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar; previously minor: Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-13 · **Change:** minor (Pencil continuation, straight-line and closing cursors; scores and estimates unchanged; previously: Graphic Styles list fills a taller panel, #2992; scores and estimates unchanged; previously: library panels' lists fill a taller panel, #2992; scores and estimates unchanged; previously: Swatches list fills a taller panel, #1638; scores and estimates unchanged; previously: icon-strip flyouts also resize from the top edge and the canvas-side top corner, keeping the moved top in workspaces (storytold/craft-libs#1094); scores and estimates unchanged; previously: macOS: the canvas cursor stays after the pointer moves, #6362; scores and estimates unchanged; previously minor: Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar; previously minor: Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
>
> Vector Halftone preview update (2026-11-10): temporary dot selection marks are hidden, and the bounding box stays available (#6369).
>
@@ -52,6 +52,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-11-14 | minor | Layers panel: right-clicking a layer/group/object row shows a context menu with Options…, Duplicate, Delete, Lock/Hide Others, Locate Object, and Collect for Export — matching standard desktop layer panel conventions. Scores unchanged. |
| 2026-11-13 | minor | Pencil cursors: the continuation cursor (a short rising line) shows over an open end of a selected path before any press, freehand too, and while a continuing stroke nears another selected path's open end it connects to; the straight-line cursor is a short level line; a continued path, a straight line too, shows the closing cursor and closes within Close Paths When Ends Are Within of its other end, and with Alt at the release. Scores and estimates unchanged. |
| 2026-11-13 | minor | Graphic Styles: in a panel made taller the list fills the space above the footer instead of stopping at 220 pt (#2992; `the_list_fills_a_tall_panel_above_its_footer` in `crates/ui-egui/src/panels/graphic_styles.rs`). Scores and estimates unchanged. |
| 2026-11-13 | minor | Library panels (swatch, Color Book, brush, symbol and graphic style libraries): in a panel made taller the list fills the space above the footer instead of scrolling inside 220 or 280 pt (#2992; `the_list_fills_a_tall_panel_above_its_footer` in `crates/ui-egui/src/panels/library_panel/tests.rs`). Scores and estimates unchanged. |
| 2026-11-13 | minor | Swatches: in a panel made taller the swatch list fills the space above the footer instead of scrolling inside 150 or 200 pt (#1638). Scores unchanged. |
@@ -178,7 +179,7 @@ tools, never checked side by side) isn't captured row by row.
| Blend spine Anchor Point conversion and handle editing (#2544) | implemented | symmetric handles, independent drag/retraction, visible-handle policy and selection/stacking covered by tool and engine regressions; Windows native canvas checks and screenshots reviewed in PR #2643 |
| Several blend spine points picked and dragged together (#5285) | done | with Direct Selection, Shift-click picks more points of a selected blend's spine or takes one away, as on a path; dragging any picked point moves them all, and the key objects on them, in one undo step (`object.blend.spine.moveAnchor {with}`); a marquee doesn't pick spine points yet |
| Add/Delete/Anchor Point tools; Anchor Point tool drags segments to reshape | done | #2267: a click on a handle end retracts that handle and leaves the anchor a corner with the other one; Shift held at the press on an anchor moves it, handles and all (Shift kept down: at 45° steps) instead of pulling out handles |
| Pencil: Fidelity, Keep selected, Alt to Smooth, edit selected paths, close by proximity | done | Fidelity is in screen pixels, the same at any zoom, and goes down to 0.01 px in the dialog and the tool, which sends `path.freehand` the value in points at the current zoom (#5729; the Smooth tool keeps 0.05 pt); its slider runs across the Tool Options row on a logarithmic rail from 0.01 to 20 px, the field shows hundredths, and the slider's and the field's arrow keys step hundredths up to 0.1 px, tenths up to 1 px and whole pixels above (Shift ×10) (#3328); Alt key toggles to Smooth Tool (#2001); Shift held at the press draws a straight line at 45° steps from the Constrain Angle, and Alt held at the press (with Alt key toggles to Smooth Tool off) a straight line at any angle (#3799), with a straight-line cursor while Shift or Alt is held before the press, and a path-continuation cursor over an end of a selected open path, where the line continues the path; Edit Selected Paths continues a selected path from an end and, from a stroke that starts and ends on a selected path, redraws the section between (the shorter way round a closed path, #2850); with Keep selected (Pencil and Paintbrush, on by default) on, a stroke selects the path it draws or continues and replaces the earlier selection, and off a new stroke leaves nothing selected, the earlier selection included, while a continued or redrawn path is deselected and the rest of the selection stays; a filled Pencil path keeps a stroke of None (#1804, part of #1679); while a freehand stroke is drawn back to within Close Paths When Ends Are Within of its start, the Pencil and the Paintbrush show the closing cursor, and a release there closes the path; a Pencil stroke from an end of one selected open path to an end of another connects the two into one path |
| Pencil: Fidelity, Keep selected, Alt to Smooth, edit selected paths, close by proximity | done | Fidelity is in screen pixels, the same at any zoom, and goes down to 0.01 px in the dialog and the tool, which sends `path.freehand` the value in points at the current zoom (#5729; the Smooth tool keeps 0.05 pt); its slider runs across the Tool Options row on a logarithmic rail from 0.01 to 20 px, the field shows hundredths, and the slider's and the field's arrow keys step hundredths up to 0.1 px, tenths up to 1 px and whole pixels above (Shift ×10) (#3328); Alt key toggles to Smooth Tool (#2001); Shift held at the press draws a straight line at 45° steps from the Constrain Angle, and Alt held at the press (with Alt key toggles to Smooth Tool off) a straight line at any angle (#3799), with a straight-line cursor (a short level line) while Shift or Alt is held before the press, and a path-continuation cursor (a short rising line) over an end of a selected open path, where the stroke continues the path, freehand or straight, and while a continuing stroke ends near an open end of another selected path it connects to; Edit Selected Paths continues a selected path from an end and, from a stroke that starts and ends on a selected path, redraws the section between (the shorter way round a closed path, #2850); with Keep selected (Pencil and Paintbrush, on by default) on, a stroke selects the path it draws or continues and replaces the earlier selection, and off a new stroke leaves nothing selected, the earlier selection included, while a continued or redrawn path is deselected and the rest of the selection stays; a filled Pencil path keeps a stroke of None (#1804, part of #1679); while a freehand stroke is drawn back to within Close Paths When Ends Are Within of its start, or a stroke continuing a selected path (a straight line too) to within it of that path's other end, the Pencil and the Paintbrush show the closing cursor, and a release there closes the path; a Pencil stroke from an end of one selected open path to an end of another connects the two into one path |
| Drop Shadow, Outer Glow and Inner Glow: Opacity, the offsets, Blur and Darkness have spinner arrows that step by one (a unit for distances), repeat when held and stop at the fields' ends (#5367, #5368) | done | dialogs::effect test drop_shadow_and_outer_glow_fields_have_spinner_arrows; other effect dialogs' number fields still have none |
| Effect dialogs' colour fields: a swatch beside the hex follows typed values, and a double-click opens the Color Picker over the dialog, whose OK fills it and Cancel comes back unchanged (#5365) | done | dialogs::effect tests outer_glow_colour_swatch_opens_the_color_picker and drop_shadow_colour_swatch_opens_the_color_picker (Drop Shadow's Color, #5364); the picker previews nothing itself, the effect dialog previews the returned colour |
| Join tool scrubbing, Average, Join | done | Join merges the direct-selected anchors lying on one another along a path, as after Average, into one (#1533); the Join tool trims two crossing open paths whose overhanging ends it scrubs over and joins them at the crossing, instead of drawing a segment between their ends (#5844) |