Commit Graph
2578 Commits
Author SHA1 Message Date
theironchefandClaude Opus 5.5 bef928bf17 Fix #309: Pen: Alt pressed mid-drag keeps the curve into the new anchor
Pressing Alt while dragging out a smooth point set its incoming handle to
the anchor itself, so the segment just shaped turned straight. The Pen
now remembers the incoming handle it last previewed and keeps it while
Alt is held, so only the outgoing handle follows the pointer: a corner
with curves on both sides, as in the reference app. Alt held from the
start of the drag still gives an outgoing handle only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 03:22:31 +07:00
Fabian GrajalesandClaude Opus 5.5 3bc4365ee2 Smart Guides: a turned bounding box snaps while it is resized
The resize snap skipped a bounding box standing at an angle. It now works
on the page whatever the angle: a corner handle takes the target's x, y or
both, and a side handle (or a proportional corner) slides along its own
direction until the handle or an end of its side is on a target. A target
the side runs almost along is skipped, so the handle stays near the pointer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013j16ENkbsNYyHSCDhxYkYR
2026-10-07 14:32:11 -05:00
haven 364c579c04 M11: artboards snap by their bleed; transform panel edits an active artboard 2026-10-07 11:42:00 -07:00
haven 9cd91deafa M11: Artboard tool snaps artboards while moving and resizing 2026-10-07 11:41:33 -07:00
Fabian GrajalesandClaude Opus 5.5 7de04544e4 Smart Guides: bounding-box resizes snap to the other objects
Dragging a bounding-box handle with the Selection or Free Transform tool
now lands the edges it moves on the edges and centres of the other objects
and artboards, with the guide line, as a move already did. A proportional
scale snaps the closer axis only; a turned bounding box doesn't snap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013j16ENkbsNYyHSCDhxYkYR
2026-10-07 13:05:37 -05:00
BFlatandClaude Opus 5.5 0648e99fc4 Layers: keep clippy happy (menu item type, no unreachable in tests)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:06:31 +07:00
BFlatandClaude Opus 5.5 ccdb4d89c1 Layers: the panel's rows work in the collapsed dock's flyout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:54:34 +07:00
imachusandClaude Opus 5.5 a92905a816 Type: mojikumi — Line-end Punctuation Half Width for Japanese punctuation
Japanese full-width punctuation is half a mark and half a space (an
opening bracket's space before it; a closing bracket's, comma's or full
stop's after it). Set solid, 」「 or 。」 show a full em of air between
the marks, and a line ending in 。 stops half an em short of the edge.

- `ParaStyle.mojikumi` (Paragraph panel › Mojikumi): None, or Line-end
  Punctuation Half Width, which (JLREQ 3.1.4) lets consecutive
  punctuation share one half-em space — a closing mark followed by
  punctuation loses the space after it, an opening bracket after another
  the space before it — and sets a closing mark ending a line half
  width. Only full-width marks (advance an em) are touched, never inside
  a tate-chu-yoko block; vertical type the same way down the column.
- New type (`text.create`, Area/Path Type) takes Line-end Punctuation
  Half Width, the usual default of Japanese layout; documents from
  before it and imported text keep None (written only when set, so
  older files and older apps are unaffected). `text.setFormat
  {mojikumi: "none"|"lineEndHalf"}`.
- Builds on #344: on justified lines the room it frees is spread
  between the characters.
- Catalog rows in ja and zh-hant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 00:46:07 +09:00
Fahri Meral 6f54843d5a Merge upstream/main: keep panel normalization alongside dock collapse behavior 2026-10-07 18:44:42 +03:00
BFlatandClaude Opus 5.5 7eb3f25f1f Layers: sublayers, groups and objects are clickable rows in the panel
Rows at every depth highlight on click (Shift range, Ctrl toggle) and make
their layer current; selection squares select a row's art and drag the
selection to another row; eye and lock on every row with drag-down-the-column
in one undo step and Ctrl-click for Outline; Alt-click triangles; drag and drop
rows above, below or into layers and groups with a drop line (Alt copies);
Delete key; the full panel menu, Layer Options and Panel Options dialogs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:29:15 +07:00
BFlatandClaude Opus 5.5 27a1a48176 Layers: sublayers are layers, not objects, and every row has a command
Art in a sublayer is now selected as objects (clicks, marquee, Select All, the
Select menu), sublayers select in their own colour, and hidden, locked or
template sublayers block clicks. Layer Options gain Preview (per-layer outline)
and Dim Images. New and fixed layer.* commands for the Layers panel: setCurrent
and highlight (rows at any depth), selectAll, move (reparent with cycle and
nesting checks, Alt copies), delete/duplicate rows, merge, flatten, collect,
release to layers, reverse, template, hide/outline/lock others and their
show/preview/unlock all, locate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:29:15 +07:00
BFlatandClaude Opus 5.5 f16403a851 Fix #293: the dock's double arrow collapses its panels to icons
The » at the top of the right dock was only painted. Its header strip is
now a click target (hover highlight, "Collapse to Icons" tooltip) that
runs the new window.collapseDock UI command: the Properties | Layers |
Libraries group hides and its three panels become icons at the top of
the icon column, under a « strip ("Expand Panels") that expands them
again. While collapsed, those icons and window.panel pop the panel out
next to the column like the other icon panels (dock-width flyout, Layers
and Properties given a height that keeps them on screen); expanding with
one popped out shows its tab.

The flyout now follows the icon column's real left edge (recorded each
frame) instead of assuming a 300-point dock, so it also tracks a resized
or collapsed dock. The collapsed state is kept with the UI preferences
and in user workspaces; the built-in workspaces expand the dock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 22:21:59 +07:00
imachusandClaude Opus 5.5 5623f90ef7 Type: justified Japanese lines spread between their characters
Justify (last line left, centred or right) widened only word spaces, so
a Japanese line, which has none, stayed set solid and the right edge of
a justified Japanese paragraph was ragged by up to almost a character
(only Justify All spread the characters). Following JLREQ 3.8, the room
left on a line now goes to the gaps next to a CJK character, shared
with any word spaces:

- not inside a Latin word or a tate-chu-yoko block, nor next to a tab;
- lines without CJK characters are justified as before;
- vertical type too (the same code, in line space).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 00:20:18 +09:00
imachusandClaude Opus 5.5 681d18a08f Type: vertical type takes upright glyphs' cells from the font's vertical metrics
Upright glyphs in vertical type advanced one em (or their horizontal
advance, if wider) and turned about a fixed point 0.38 em above the
baseline. Fonts that carry vertical metrics now place them as they ask:

- `FontFace::vertical_glyph`: a glyph's advance down the column (`vmtx`)
  and the height of its vertical origin (`VORG`, else the glyph's top
  plus its top side bearing, as in TrueType fonts); `None` without
  `vhea`/`vmtx` or with values outside a few ems.
  `FontFace::ideographic_centre`: the em box centre from an ideograph's
  cell, else 0.38.
- The layout advances an upright glyph by its vertical advance and hangs
  it from its vertical origin; tate-chu-yoko blocks and point type's
  anchor use the font's em box centre. Fonts without vertical metrics
  are laid out exactly as before.
- Hiragino's tables give the values the layout assumed (one em, origin
  0.88 em), so Japanese vertical type in it renders pixel for pixel the
  same; this is the base for proportional vertical metrics (`vpal`) and
  for fonts whose em box sits elsewhere.
- `test_fonts::vertical_font`: Source Sans 3 with `vhea`/`vmtx` (and
  optionally `VORG`) built in code, one glyph 1.4 em tall hanging from
  1.1 em; tested with and without `VORG`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 00:12:44 +09:00
imachusandClaude Opus 5.5 52e1c0eca0 Type: a font menu with samples, live preview, script and kind filters, styles and favourites
The Character and Properties panels' font menu was a plain searchable
list of names. With hundreds of installed families (and Japanese names
that say little to someone who can't read them) a name isn't enough.

- Each row shows the family's name and a sample of the selected text set
  in it (a generic sample when the font lacks its characters). Samples
  are rendered off the UI thread, a few per frame, and only for the rows
  in view (the list is virtualised).
- The row under the pointer or reached with ↑/↓ previews its font on the
  selected text, as one live interaction with nothing in the history; a
  click or Enter applies it as one step, Escape or closing the menu puts
  the text back. The current family is highlighted and scrolled into
  view, also when the document names it in another language.
- Filters by script (Japanese, Latin) and kind (serif/Mincho, sans
  serif/Gothic, rounded, script/brush, monospaced, decorative), from the
  font's OS/2 classification and, for CJK fonts whose tables seldom say,
  its names. `FontTraits`/`FontClass` in the text crate; installed
  families get them from the same scan as their names.
- ▸ (or →/←) lists a family's styles; a style row previews and applies
  that style.
- ☆ stars a family; the ★ filter shows only the favourites (kept with
  the UI state).
- Preferences › Type › Enable in-menu font previews and Font Preview
  Size now turn the samples off and size the rows; the in-window Type ›
  Font menu (Windows, Linux) shows a sample beside each name.
- Families whose name starts with a dot (the system's own) are hidden.
- Catalog rows for the new labels in zh-hant (complete) and ja.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:51:33 +09:00
imachusandClaude Opus 5.5 fcaeaa74a7 PDF/.ai import: Japanese text as live type (CID fonts, vertical columns, missing fonts)
Japanese PDFs and PDF-compatible .ai files often set text in CID fonts
with no ToUnicode map, in vertical columns, and in fonts the reader
doesn't have. They came in as outlines (or as the wrong characters).

- CID fonts without ToUnicode: the character comes from the font's CFF
  charset through the standard CMaps (hayro's `embed-cmaps`); Kangxi
  radicals that some generators map to are unified with their ideographs
  (⿓ → 龍).
- A glyph becomes live type only when the installed font draws the same
  glyph: compared by box with the font of the PDF's PostScript name, or
  the closest style of its family (a variable font's named instances),
  whose style the type then takes. Otherwise it keeps its outline.
- Vertical columns (WMode 1, glyphs with no horizontal advance) come back
  as vertical type, letter spacing as tracking; a single upright glyph is
  vertical type too. Horizontal lines get tracking from the glyph
  positions the same way.
- Text in a font that isn't installed keeps its outlines (what prints),
  with an editable copy in a substitute font, drawn pink, on a
  non-printing layer named after the missing fonts (stroke-only glyphs
  included).
- Marked content other than a layer's (spans with actual text,
  artifacts) no longer ends a line of type: 篳篥・龍笛・笙 came back as
  three objects when one character was in a span.
- Tests in tests_live_text.rs and tests_realtext.rs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 23:45:31 +09:00
BFlatandClaude Opus 5.5 406c27ebd8 Fix #306: render on the power-saving GPU by default, with a preference for the discrete one
On hybrid-graphics laptops (an integrated GPU driving the display plus a
discrete one), egui-wgpu's default power preference is HighPerformance, so
VectorCraft rendered on the discrete GPU and its frames were copied to the
display through the integrated one. On an Asus ZenBook with Intel Iris + Arc
the window flickered whenever the mouse moved over it (#306, #305).

The canvas is rasterized on the CPU (vello_cpu) and the GPU only composites
the canvas texture and draws the UI, so the integrated GPU is plenty. The
desktop app now asks wgpu for the power-saving adapter by default.
Single-GPU machines are unaffected.

- Preferences > Performance > Graphics Processor (`gpuPreference`:
  powerSaving, the default, or highPerformance), with a note that it
  applies after a restart. The app reads it from the saved preferences
  before the window opens. WGPU_POWER_PREF still overrides it.
- Help > About and `ui.inspect` (`graphicsAdapter`) name the adapter in
  use, and it is logged at startup, for future GPU bug reports.
- Docs (README, docs/development.md) and ROADMAP updated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:10:17 +07:00
EthanSuquetandClaude Opus 5.5 7e0ed6b183 EPS import: EPS files from the reference app open as vectors
#249 made the reduced repros of #234 open, but a real file saved by the
reference app (version 30) still fell back to its screen-resolution preview
with "typecheck in `a dictionary`". Running its prolog to the end needed:

- The standard dictionaries (systemdict, userdict, globaldict, statusdict,
  errordict, $error) as values in systemdict, so `/globaldict where
  { /globaldict get begin } if` gets a dictionary, not an operator.
  SharedFontDirectory names the font directory too. errordict has a
  handleerror for prologs that wrap it.
- `dictstack`, `internaldict`, `currentsystemparams` and
  `currentuserparams` (with the cache sizes programs `get`), and `cshow`.
- Executable files: `cvx` and `cvlit` set a file's attribute, `xcheck`
  reads it, and executing one runs its data as a program, as the prolog
  does with `(...) 0 () /SubFileDecode filter cvx exec`.
- SubFileDecode with a count of 0 and an empty end string passes its
  whole source through instead of nothing.
- `flushfile` on a filter over the program's data skips that data (the
  file's XMP packet). A filter chained from a pending one leaves it
  nothing to skip, so the writer's own `VCsrc flushfile` is unchanged.

The interpreter empties its standard dictionaries when it finishes, since
systemdict now holds itself. Both real files tested now import as 15
vector paths in CMYK with no warnings, and round-trip through SVG and PDF
pixel for pixel. The EPS fuzzer exercises the new operators.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:06:56 -04:00
BFlatandClaude Opus 5.5 079f9a8b9a Fix #296: variable fonts list and draw every named style
The font database made one style per font file, so a variable font
such as Figtree[wght].ttf listed only its default instance (Light).
Faces now also yield their fvar named instances, each a style of the
family named by its subfamily name (the default instance is the face
itself; unnamed or duplicate instances are left out; axes and
instances read are capped). The system font scan reads the fvar table
beside the name table, so installed instances are listed before the
file is loaded and found by name and by PostScript name.

An instance face carries its axis settings: skrifa draws its outlines
and reads its metrics and advances at that location, harfrust shapes
with a ShaperInstance, so layout, the canvas, Create Outlines and hit
testing all use the instance. PDF export embeds it through krilla's
Font::new_variable, SVG @font-face through subsetter's
subset_with_variations: both write a static font of that instance.

Tests build a small variable font in code (test_fonts, via
write-fonts; no font file is committed) and check listing, resolving,
glyphs and advances, PDF and SVG export and damaged fvar/gvar tables;
Bahnschrift and Segoe UI Variable are checked where installed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:01:26 +07:00
Fahri Meral 6f9b160038 Merge branch 'main' of https://github.com/storytold/vectorcraft into mcp-small-wins 2026-10-07 16:58:14 +03:00
Fahri Meral e5e09d5d48 mcp: read object template via document.node summary flag 2026-10-07 16:39:06 +03:00
Fahri Meral d9136c46b9 mcp: accept panel ids case-insensitively and by display label 2026-10-07 16:39:06 +03:00
BFlatandClaude Opus 5.5 ee7a7ebfac Fix #290: hovering another menu title switches the open menu
On the in-window menu bar (Windows and Linux) each top-level menu needed
its own click: with File open, moving the pointer onto Edit or Object did
nothing. Now, as on a native menu bar, while one menu is open a moving
pointer that reaches another title opens that menu instead (ported from
PhotoCraft). A pointer resting on a title doesn't switch, and a tall menu
that covers the bar doesn't switch to the title underneath it. The native
macOS menu bar is unchanged.

Also adds a regression test for #292: the Simplify, Offset Path, Move,
Rotate, Split Into Grid and Average dialogs are 366 pt wide in a 1600 pt
window (already fixed by #239).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:32:03 +07:00
BFlatandClaude Opus 5.5 deaec7fc71 Fix #291: live corners stay circular when a rectangle is scaled unevenly
A live rectangle kept every transform in its `xf`, so a non-uniform scale
(a bounding-box drag, Object > Transform > Scale) stretched the rounded
corners built in untransformed space into elliptical arcs. Scale Corners
off divided the radii by the mean scale, which only compensated uniform
scales.

LiveShape::transform now folds a scale along the rectangle's own sides
(any rotation or reflection, no shear) into w/h and keeps only rotation,
reflection and position in `xf`, so the radii are document lengths and the
path is regenerated with circular corners. Radii scale by the mean scale
(sqrt|det|), which keep_corners undoes for Scale Corners off. Shears and
plain moves keep composing into `xf` as before, so files saved with a
scale in `xf` keep their exact geometry until next scaled or rotated.
A corner-widget drag starts from the radius as drawn (clamped to fit).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 20:25:41 +07:00
Sarah Wesker a40260a441 Select: saved selections live in the document, are listed in the Select menu and can be edited
Save Selection… asks for a name and keeps the selection in the document (saved with
the file, undoable, at most 25) instead of in session memory keyed by the title.
Each saved selection is listed at the bottom of the Select menu and a click selects
its objects again. Edit Selection… opens a dialog with the list to rename or delete
them, applied together on OK as one undo step (select.editSaved takes `edits`).

The menu stub count in the ROADMAP goes from 16 to 15.
2026-10-07 08:58:33 -04:00
imachusandClaude Opus 5.5 ef167a1345 i18n: Japanese for the whole interface (panels, dialogs, tooltips, hints)
Closes #217. The Japanese catalog now covers every menu string and every
tl! literal, so `complete_menus` is on for `ja` and the tests keep it
complete.

- ja.tsv: about 2,300 rows added after the existing menu rows, which are
  unchanged: panels, dialogs, tooltips, the hint bar, document tabs,
  status messages and the strings built at run time (section lists,
  counts, `@plural` rows). Written from the meaning of the English
  labels in the vocabulary Japanese users of vector illustration
  software know; product and format names stay in Latin letters, the
  trailing "…" is kept, and placeholders appear in both columns.
- Kept in English, as before: the product name, OpenType, the built-in
  workspace names and the bracketed perspective preset names.
- tests: the languages that keep those names in English (`cs`, `ja`) are
  listed once (`KEEPS_MENU_NAMES`), and the completeness test skips the
  kept names for them, so a language can keep them and still be
  complete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:36:51 +09:00
Hiroshi InukaiandClaude Opus 5.5 539dcb84b7 Tests: Japanese file and folder names save, open, export and title documents
A regression test for non-ASCII paths. It saves to a Japanese file name, with
full-width brackets and a middle dot, inside a Japanese folder. It checks the
document's title, reopens the file with its Japanese text, and exports SVG, PNG
and PDF to Japanese names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:07 +07:00
Hiroshi InukaiandClaude Opus 5.5 d5e21cc735 PDF/.ai import: art of a neighbouring artboard stays on its own page
A file with several artboards writes, on each page, the art of its
neighbours that reaches the page's box, shifted by its own artboard
spacing. Kept, those copies drew over the art of the page they came from
(a hologram over its card's stripes and title). With several pages, art
wholly outside a page's box now stays with the page it belongs to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:07 +07:00
theironchefandClaude Opus 5.5 bc688bd1b5 Fix #285: the Symbols panel takes drag and drop both ways
Art dragged off the canvas and released over the Symbols panel's list
becomes a new symbol (symbol.new with the dragged ids), and a symbol
dragged out of the panel (PanelDrag::Symbol) is placed on the canvas
centred where it is dropped (symbol.place), showing its thumbnail at
the pointer on the way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:20:07 +07:00
theironchefandClaude Opus 5.5 11799fa0cc Fix #283: double-clicking type with a selection tool puts the caret there
The Selection tool's double-click on text only switched to the Type
tool, which then had nothing being edited, so typing went to the tool
shortcuts (X swapped the text's fill and stroke). After such a switch
the canvas passes the double-click on to the Type tool as a click, which
starts editing the type with the caret where it was clicked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:19:27 +07:00
theironchefandClaude Opus 5.5 b6649a3fad Fix #280: shortcuts with Shift and a punctuation key fire as typed
egui reports the character a key types, so Cmd+Shift+[ arrives as
Cmd+Shift+{ (], / likewise as }, ?) and Shift+` as the text ~, and these
default shortcuts never matched: Bring to Front, Send to Back, Search
Commands and the Curvature tool. Command chords now also take the
shifted character, single-key tool and command shortcuts also look up
Shift+<typed text>, and the Keyboard Shortcuts editor records such a
chord as its key (Cmd+Shift+], not Cmd+Shift+}), so conflicts show.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:19:25 +07:00
Hiroshi InukaiandClaude Opus 5.5 e2227849a1 PDF/.ai import: the last glyph of type on a path stays on its path
The path rebuilt through the glyphs ended where the last glyph ends, so
rounding in the spacing could push that glyph past the end, where type on
a path stops ("OFFICIAL ISSUED" lost its D). The path now runs an em
further.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:03:00 +07:00
Hiroshi InukaiandClaude Opus 5.5 ea5a04504a PDF/.ai import: type set on a path comes back as type on a path
Apps write type on a path one glyph at a time, each placed and turned along the
curve. The importer joined glyphs into a line only while they kept the first
glyph's direction. Type on a gentle curve was flattened into straight lines, and
type on a tighter curve fell apart into one object per glyph.

A glyph that starts about where the previous one ends, turned a little from it
(under about 20°), now continues the line. A line whose baseline turned more than
about 3° becomes type on a path: its path is a smooth curve (Catmull-Rom as cubic
Béziers) through the glyphs' baseline origins and the end of the last glyph.
Spaces between words are measured along the last glyph. Straight type, rotated or
not, imports as before.

Test: "ARCHING" written glyph by glyph along an arc imports as one
type-on-a-path object with that text and a curved path; slightly rotated straight
type stays point type.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:03:00 +07:00
theironchefandClaude Opus 5.5 3c096da84d Fix #277: Ctrl+Space zooms (Ctrl+Alt+Space out), Space alone pans
Held Space always panned, whatever else was held, so the temporary Zoom
tool keys did nothing. Held Space is now the Hand tool and Cmd+Space the
Zoom tool (Alt: out), whatever the active tool, for the press and the
cursor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:03:00 +07:00
theironchefandClaude Opus 5.5 47104f5f4c Fix #270: Ctrl with another tool drags with the selection tool used last
The canvas always switched to the Selection tool for a Cmd press with a
non-selection tool. The UI state now remembers which of Selection,
Direct Selection and Group Selection was used last, and the temporary
switch uses it, so Cmd-dragging an anchor while drawing with the Pen
after using Direct Selection moves that anchor, not the whole path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:03:00 +07:00
bflatasticandClaude Opus 5.5 d6eb526186 Fix #252: area type resizes its frame with the mouse
Dragging a bounding-box handle of area type with the Selection tool now
resizes the type area: the text reflows at its own size (threads too)
instead of being scaled, and History says "Resize Type Area". With other
objects selected they scale as before while the area type resizes its
frame. Direct Selection picks the frame's corners and edges and reshapes
the area ("Reshape Type Area", new command text.reshapeArea), and the
selected frame's anchors and outline show. Area Type Options gains Width
and Height. Point type, rotation, Object > Transform > Scale, the Scale
tool and the Transform panel still transform the type.

Root cause: every handle drag previewed object.transform, which folds the
matrix into the text's xf (TextObject::transform), so area type scaled its
glyphs; and Direct Selection's anchor hit test only looked at paths, so the
frame's corners could not be picked. object.transform now takes
typeAreas, which reshapes the frame in text space (xf^-1 * m * xf), and
the tools use it and text.reshapeArea.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 13:02:55 +07:00
bflatasticandClaude Opus 5.5 dd595cf2e8 Fix #260: tate-chu-yoko numbers and upright glyphs keep their own cell in vertical text
In vertical type every character now sits in its own cell down the column:
"10" and "22" in 「10月22日」 stand side by side in one em, centred on the
column, and 月/日 start right after them. Justified (Justify All) columns
no longer split a tate-chu-yoko block, and tracked or justified upright
characters stay on the column's centre line instead of drifting across it.

Root cause: in 0.3.1 (the reporter's build) upright glyphs were placed by
the font's ascent rather than the ideographic em box, so a font with a tall
ascent (Noto Sans CJK JP, 1.16 em) drew each upright character ~0.28 em
down into the next cell, onto the sideways digits; #208 (after 0.3.1)
replaced that with em-box placement and tate-chu-yoko, which this commit
locks in with regression tests. Two defects of the same kind remained:
Justify All added its inter-character gap inside a tate-chu-yoko block
(the block's second digit slid down the column, away from the first), and
upright glyphs turned about the middle of their advance, which tracking and
justification lengthen, instead of the middle of their own cell.

Tests: the issue's layout with bundled glyphs (cells one after the other,
every ink inside its cell and no overlaps, 2-3 digit blocks one em and
centred, single digits and 2026 on their side advancing by their length,
spaces), the issue's string with craft-fonts' Japanese face (skips without
craft-fonts), Justify All with a block, tracking.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:16:44 +07:00
theironchefandClaude Opus 5.5 614606cc48 Fix #268: Free Transform follows the modifiers held during a handle drag
The tool chose scale, distort, perspective or shear from the modifiers at
the press only, but a Cmd press on the canvas is the temporary Selection
tool, and the documented gesture is to start dragging and then hold Cmd.
A handle drag now follows the modifiers held during the drag; when the
operation changes, the interaction restarts so the undo step is named
after what was done.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:15:46 +07:00
theironchefandClaude Opus 5.5 13f65ce6d4 Fix #266: the status bar's artboard navigator works, and fitting shows its artboard
The navigator's buttons were painted only and its number was always 1,
and Fit Artboard in Window and Actual Size always used the first
artboard. The per-document View now keeps the navigator's artboard; the
new view.goToArtboard UI command (an index, or first / previous / next /
last) sets it and fits it in the window, and the four buttons call it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:15:46 +07:00
theironchefandClaude Opus 5.5 308c096889 Fix #264: double-clicking Hand, Zoom and the transform tools works
A double-click on a tool button runs tool.options, which only knew a few
tools, so the common double-clicks did nothing: the Hand tool now fits
the artboard in the window, the Zoom tool shows 100%, and Rotate, Scale,
Reflect and Shear open their Object > Transform dialog (when something
is selected, like the menu items).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:15:45 +07:00
bflatasticandClaude Opus 5.5 926cdc80a5 Fix #257: format lists name every format the engine reads and writes
The export tool's description, the docs' open_file and export rows and the
CLI's run/convert usage listed only some formats. The CLI usage now prints
the writable extensions next to the readable ones, both generated from the
format table (export_extensions), the export tool points to its generated
format enum, and the docs name EPS, DXF, EMF, WMF, SVGZ and templates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:10:12 +07:00
bflatasticandClaude Opus 5.5 b55e3ad70a Fix #258: the save_file tool says what it saves
It ran document.save, which keeps the document's own file and format (or
takes the format the path's extension picks), but described itself as a
native .vectorcraft save. The description now says so, with the formats
generated from SAVE_FORMATS, and points to export for the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:09:42 +07:00
bflatasticandClaude Opus 5.5 2e134e56be Fix #256: inspect_document reports the paint type's characters show
A type node's fill, stroke and strokeWidth now come from its first run, as
paint.proxies and its strokeOptions already did; fills and strokes of the
type object itself are reported apart as objectFill, objectStroke and
objectStrokeWidth.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:48:54 +07:00
bflatasticandClaude Opus 5.5 a01e045905 Fix #255: selection exports report the encoder's warnings
document.exportSelection (the MCP export tool's `selection: true`) now
replies with `format` and the encoder's `warnings`, the same list a
whole-document export gives: lossy WebP written lossless, blend modes left
out of SVG Tiny 1.2, PDF layers at 1.4 and the rest. A selection export
that approximates nothing replies with an empty list.

Root cause: export_selection encoded with `encode`, which drops the
warnings encode_with_warnings returns, and its reply carried only path,
bytes and bounds. The params doc and docs/mcp.md now describe the reply.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:42:05 +07:00
BFlat eac383d5af Merge pull request #262 from p0lyg0n/i18n/japanese-menus
i18n: Japanese translates every menu label
2026-10-07 11:39:13 +07:00
theironchefandClaude Opus 5.5 c6ac2bf3c5 Fix #247: dragging from a ruler onto the canvas makes a guide
The rulers were only painted. A drag from the top ruler now previews a
horizontal guide and adds it with guide.add where the button is released
on the canvas; the left ruler makes a vertical one. Released anywhere
else, nothing is added. Guides are shown when one is made this way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:34:27 +07:00
Hiroshi InukaiandClaude Opus 5.5 198725ed38 i18n: Japanese translates every menu label
Japanese covered 36 menu labels after #145; every other label stayed
English. ja.tsv now holds all 556 interface menu labels, in menu order,
including both readings of every toggle, plus the labels added since: the
Language menu's Automatic and the canvas context menu's. #145's 36 entries
are unchanged. Kept in English, as for Czech: the product name, language
names, OpenType, the built-in workspace names and the bracketed perspective
grid presets.

The Czech coverage test becomes menu_catalogs_translate_every_menu_label,
run for Czech and Japanese. ROADMAP and docs/development.md say both cover
every menu label.

Ported by the maintainers from the Rust table of the original PR onto the
catalog framework (#205): the placeholder labels of recent-file, recent-font,
user-preset and user-library slots are left out (the menus show the names).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 11:33:45 +07:00
c91ca3634f Palette: entries rebuild when keyboard shortcuts change
The command palette caches its entries per language and plug-in set
(#243), but each entry also shows its shortcut: after editing shortcuts
the palette kept showing the old ones until the language changed. The
cache key now includes the shortcut editor's generation. From #242.

Co-authored-by: WildfootW <wildfootw@wildfoo.tw>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 10:55:55 +07:00
BFlat 24f7d5fba5 Merge pull request #253 from theironchef/fix/area-type-frame-offset
Type tools: a dragged area-type frame is the dragged rectangle
2026-10-07 10:55:41 +07:00
BFlat cc4992172a Merge pull request #246 from theironchef/fix/type-drag-select
Type tool: a drag across text that isn't being edited selects it
2026-10-07 10:55:36 +07:00