Commit Graph
2197 Commits
Author SHA1 Message Date
dotCooCoo 55b1421dca Merge main into feat/dynamic-text-point-type 2026-11-12 01:13:39 -08:00
dotCooCoo ae802feb58 Merge main into fix/read-roots-document-replies 2026-11-12 01:13:38 -08:00
dotCooCoo e6d5c8846e Color: Sample Color from Screen works on Linux through the desktop portal
On Linux, ui.sampleScreenColor and the Color Picker's eyedropper button
now show the XDG desktop portal's color sampler (Screenshot.PickColor,
https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Screenshot.html).
A thread of its own makes the call and waits for the person, and the
picked sRGB color goes through the same conversion into the working RGB
space as on macOS and the web. A cancel leaves the colors as they were.

A session without a portal that has PickColor, a portal that does not
return from the call within 25 seconds (VectorCraft's own limit) or
leaves the bus before it answers, and a portal that ends the request in
another way each show a status message and end the wait. The two new
messages are translated in every catalog that has the sampler's other
messages. The request token is random, as the Request documentation
asks (https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Request.html).

The window is named for the portal on the UI thread, as for the save
dialog, and the sampler's thread keeps the window and its export until
the portal answers.
2026-11-12 01:12:13 -08:00
dotCooCoo c35d5f5b34 Read roots: links.findFiles and image.info follow the configured read roots
With automation read roots in force, links.findFiles and text.findFontFiles
replies, including later polls and stops of a search another client started,
leave out the files found outside the caller's read roots, a sought link's
saved path outside them and the folder searched when it is outside them. A
failed search then gives its reason without the path. The rows keep their
names, ids and status, and the counts stay.

image.info gives link: null for a linked file outside the read roots, as
links.info does. text.addFontFiles gives folder: null when the Fonts folder
is outside the read roots and names the copies there by their file names;
the fonts are still copied.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-12 01:03:41 -08:00
BFlat 61650e44a2 Merge pull request #6814 from dotCooCoo/feat/brush-replace-art
Brushes: Alt-drag art onto a brush to replace its art
2026-11-12 16:02:52 +07:00
BFlat 87c0d5cb5e Merge pull request #6826 from dotCooCoo/feat/3d-classic-rotate
3D (Classic): Rotate (Classic) turns flat art in 3D with the No Shading and Diffuse surfaces
2026-11-12 16:02:41 +07:00
BFlat 744c37d12f Merge pull request #6669 from dotCooCoo/feat/dynamic-text-release-path
Type: Release Type on a Path keeps the size Dynamic Text drew the type at
2026-11-12 16:02:25 +07:00
BFlat 183b2ed7e4 Merge pull request #6770 from dotCooCoo/feat/learn-panel
Learn: a Learn panel lists tutorials by skill, opened from Explore tutorials on the app bar
2026-11-12 16:02:15 +07:00
BFlat 3ed0dc64a8 Merge pull request #6656 from dotCooCoo/fix/inspect-library-ids-whole
MCP: a hidden library's shown id names it in requests, and replies hide its path wherever it appears
2026-11-12 16:01:54 +07:00
dotCooCoo 1d7690029f Document Info: Spot Color Objects lists the objects that use spot colors
The spotColors category is now titled Spot Color Objects and lists each
object filled or stroked with a spot color, by name with the spot colors
it uses, instead of the spot swatch names. A solid color or a gradient
stop linked to a spot swatch at a tint above 0 counts; process colors
that look the same and Registration do not. Paint that draws nothing is
left out by the rules Pattern Objects and Gradient Objects follow, and
type whose characters use a spot color is listed. Objects counts the
listed objects as Spot Color Objects.

document.info returns spotObjects, spotColorNames and objects.spots;
spotColors now holds the spot colors those objects use. The report that
Document Info > Save... and Package write lists the same rows.

The Spot Color Objects, Pattern Objects and Gradient Objects titles have
a row in each of the 27 complete catalogs, and a test checks that every
complete catalog has the three.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-12 00:59:50 -08:00
dotCooCoo e7f2601847 Blend: arrow keys step from the widget's shown value; a double-click on a widget leaves the art alone
- After a drag past either end of the range, the first arrow key now
  steps back from the value shown instead of doing nothing.
- With the Selection tool, a plain double-click on a blend widget no
  longer edits or isolates the artwork under it, or leaves isolation.
  Ctrl/Cmd+Shift double-click still releases a guide there.
- docs/mcp.md says the lower widget shows only when the steps follow
  the spine, and the G13 blend easing entry in docs/gaps.md no longer
  lists on-canvas easing handles as missing.
2026-11-12 00:54:15 -08:00
dotCooCoo 2bb8cd0b92 Swatch libraries: Patterns › Optical Effects adds wave, moiré and op-art patterns
Window › Swatch Libraries › Patterns and the Swatches panel's library
menu gain Optical Effects (`optical-effects`), a built-in pattern library
of eight black tiles drawn in code: Sine Bands, Ripple Lines,
Interference Rings, Offset Rings, Warped Checks, Pinched Stripes,
Chevron Pulse and Radiating Lenses. The names and designs are
VectorCraft's own. Each tile is 32 to 48 pt, one period of its design,
with fixed sample counts (at most 600 paths and 20,000 segments), so a
band that leaves one edge comes back at the same place on the opposite
edge, and rings and lenses that cross an edge are kept whole for the
tiling to draw on the next tile. Clicking a swatch adds its pattern and
swatch once and applies it, as with Geometric Patterns
(`swatch.library.add`).

The menu label has a row in every catalog; docs/mcp.md, the parity doc
and ROADMAP name the library.
2026-11-12 00:48:41 -08:00
dotCooCoo 0c758f6f06 Merge main into feat/brushes-ink-wash-library 2026-11-12 00:41:01 -08:00
dotCooCoo fdbf49d73a Merge main into feat/korean-line-break-anywhere 2026-11-12 00:40:59 -08:00
dotCooCoo 682971a154 Merge main into feat/brushes-dry-media-library 2026-11-12 00:40:55 -08:00
dotCooCoo aba45b7249 Merge main into feat/brushes-bristle-library 2026-11-12 00:40:51 -08:00
dotCooCoo 044c8047f6 Scripts: an error in code an earlier #targetengine run compiled names that run's file and line
A function an earlier run of a named engine defined was reported without
a line, column or file when it threw in a later run. The realm now gives
each source a tag that stays the same from run to run (Realm::error_tag,
Realm::script_tag), and no two sources share one once the tags run out.
Each named engine keeps the source maps of its runs' scripts, included
files and $.evalFile files, within 8 MiB, dropping the oldest first, and
an error in kept code is reported at that file, line and column. The
report's name and the console line keep the calling run's name. For an
earlier script given as source, file is that run's name.

Docs: docs/mcp.md (Script engines), script.run params text,
docs/target-app-parity.md.
2026-11-12 00:39:41 -08:00
dotCooCoo 2a55fff1a8 Merge feat/hpgl-export into feat/cut-order
# Conflicts:
#	docs/mcp.md
2026-11-12 00:34:03 -08:00
Sven Lafebre f757f9ef43 Merge remote-tracking branch 'origin/main' into fix/5111-kern-paragraph-start
# Conflicts:
#	docs/target-app-parity.md
2026-11-12 09:29:30 +01:00
Sven Lafebre ab17837cba Merge remote-tracking branch 'origin/main' into fix/5111-kern-paragraph-start
# Conflicts:
#	docs/target-app-parity.md
2026-11-12 09:24:22 +01:00
dotCooCoo ee524f06c9 Tabs: text.tabs.set can shrink a paragraph that holds more than 256 stops
text.tabs.set takes a list of more than 256 stops when every paragraph it
targets already holds at least that many, so a paragraph loaded with more
stops can lose them one at a time (the Tabs panel's Delete Tab). Any
other list of more than 256 stops is still refused, counted as supplied
before stops at one position merge.

Docs: docs/mcp.md.
2026-11-12 00:19:39 -08:00
dotCooCoo 175f51827d Symbols: redefining a dynamic symbol drops paints its new objects do not draw
When a dynamic symbol is redefined or edited, each instance kept every
appearance change whose path still named an object, even when that
object is now one that draws no fill or stroke of its own (an image, a
blend, a mesh) or a symbol instance given a gradient or pattern fill.
symbol.instance.setAppearance refuses such a paint, but the change stayed
on the instance and still counted as a color the document uses.

Fitting the changes to the new art now also clears a fill or stroke the
object at that path does not draw, and drops a change left empty.
2026-11-12 00:18:05 -08:00
BFlat eb608bb8b5 Merge pull request #6813 from dotCooCoo/feat/brush-place-art
Brushes: drag a brush onto the canvas to place a copy of its art
2026-11-12 15:14:18 +07:00
BFlat edeca27469 Merge pull request #6785 from dotCooCoo/fix/read-roots-save-export-results
MCP: save, export and package replies leave out paths outside a confined client's read roots
2026-11-12 15:14:09 +07:00
BFlat 1a7aa834db Merge pull request #6786 from dotCooCoo/fix/save-export-show-every-note
Save and Export: the status bar's hover lists every note
2026-11-12 15:13:51 +07:00
BFlat dcab893acd Merge pull request #6791 from dotCooCoo/feat/styles-painted-sketched-library
Graphic Styles: a built-in Painted and Sketched library adds watercolor, charcoal and ink styles
2026-11-12 15:13:39 +07:00
BFlat 0d550c6e6d Merge pull request #6796 from dotCooCoo/feat/patterns-grit-textures
Swatch libraries: Patterns › Grit Textures adds seamless grain, speckle and stipple patterns
2026-11-12 15:13:22 +07:00
BFlat 0ad57dc872 Merge pull request #6811 from dotCooCoo/fix/effect-refresh-deferred-nested
MCP: effect.refreshDeferred takes objects in symbol, pattern, brush and mask art
2026-11-12 15:13:13 +07:00
BFlat c8f31dd8a9 Merge pull request #6804 from dotCooCoo/fix/script-checker-name-escapes
Script checker: names with escaped characters are read as names
2026-11-12 15:13:04 +07:00
BFlat ba2aefb5dd Merge pull request #6815 from dotCooCoo/feat/para-style-options-tabs
Paragraph Styles: Style Options edits a style's tab stops
2026-11-12 15:12:55 +07:00
dotCooCoo 2c9f5a6a11 HP-GL export: an HP-GL plot past 16-bit coordinates gets a warning
Coordinates outside -32,768 to 32,767 plotter units (about 82 cm from the origin) are written as they are, with a warning that older devices may not read them. HP-GL/2 plots are not checked against this range.
2026-11-12 00:12:54 -08:00
dotCooCoo bd82a598dd Blend: on-canvas widgets set a selected blend's color shift and easing
With one whole blend selected, the Selection and Blend tools show two
widgets at the halfway point of its spine. Dragging the upper widget
along the spine sets the color shift (-100 to 100), and dragging the
lower one sets the easing strength (0 to 100). The lower widget shows
only when the steps follow a spine (a replaced spine or Align to Path),
the rule the step placement uses; a blend made without a spine shows
neither. When the boxes of three or more other visible objects hold a
widget's spot, the widget moves out in 16 px steps, up to 144 px, and
its line to the halfway point grows with it. While a widget is held,
the arrow keys step its value by 1 (Shift: by 10), and Escape or a
switch to another tool cancels the drag. A drag is one undo step; a
click or a drag that ends where it started records none.

- object.blend.setEasing sets easingType, ramp and colorShift on one
  blend, refuses a hidden or locked blend and easing on a blend without
  a spine, and records no undo step when nothing changes.
- BlendSpec::eases_along_spine holds the rule the step placement and
  the widget share.
- While a tool is busy, an arrow it claims arrives with the press's
  Shift and Alt; before, it always arrived plain.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-12 00:07:35 -08:00
Taha-Mahmoodi 5144f22976 Merge main 48e066f47 into glyph alternates #6084 2026-11-12 12:34:54 +04:30
dotCooCoo e6f330afd2 Automation: ui.dialog.set cannot change the command a dialog runs
ui.dialog.set took every field whose name starts with `__`, so a control
request (or MCP's answer_dialog, which goes through it) could rewrite the
`__command` and `__params` of a confirmation or the generic parameter
dialog, a plug-in command dialog's `__command`, or the paste a swatch
conflict waits to finish, after a person opened the dialog. The person's
OK then ran something else.

A `__` field is now settable only when it is a control of that kind of
dialog: a section or tab shown, a link between two fields, a name or
search being typed (for example Save PDF's `__section`, Transform Each's
`__constrain`, the Preferences `__search`). Every other `__` field, held
or not, is refused with "the `<kind>` dialog cannot set protected field
`<field>`". The request sets no field, and with `action: "confirm"` OK
does not run. Flags a button sets together with other fields are refused
too: the style dialogs' `__reset*`, Artboard Options' `__fit`,
`__sizeChoice`, `__refx` and `__refy`, and Scribble's `__scribbleSetting`.

Recolor's Merge takes a row listed twice in the selection once, and
Randomize keeps a seed at u64::MAX instead of overflowing it.

Docs: docs/control-protocol.md, docs/mcp.md, docs/target-app-parity.md.
2026-11-11 23:59:18 -08:00
dotCooCoo 08de741ca9 3D (Classic): Rotate (Classic) turns flat art in 3D with the No Shading and Diffuse surfaces
Effect › 3D and Materials › 3D (Classic) › Rotate (Classic)… turns every
fill and stroke as one flat plane, as Rotate does, and shades it with the
classic No Shading or Diffuse surface.

- `effect.apply` with `threeD.classicRotate`: the Position rotation and
  Perspective, `surface` (`none` or `diffuse`), the classic lights,
  Ambient Light, Blend Steps and Shading Color. It has no highlight, no
  Draw Hidden Faces and no shadow.
- The dialog shows Position on the Rotation tab and the surface and
  lights on the Lighting tab, with no Object tab.
- Groups and layers turn about one shared center, and the effect also
  goes on a fill or stroke, as Rotate's does.
- `effect.lightingPreset` refuses it, as it refuses the other classic
  3D effects.
- Unknown parameters, numbers out of range, bad flags, a surface other
  than No Shading or Diffuse and bad shading colors are refused with an
  error.
2026-11-11 23:44:11 -08:00
dotCooCoo a2b9588217 Docs: Paragraph Style Options lists the East Asian Composition Settings section 2026-11-11 23:42:32 -08:00
dotCooCoo 46ce6364c5 MCP: document.inspect and document.json leave out paths outside a confined client's read roots
Under --automation-read-root, document.inspect gives `path` as null when
the document's file is outside the read roots. document.json names a
linked image or placed file outside them by its file name alone, without
its relative path, size or date, in the layers, symbols, graph designs,
patterns, the pattern being edited and opacity masks. It also names a
data set's image value outside them by its file name, and leaves the
Export for Screens folder outside them out of export_settings. The
document is not changed, and unconfined callers see the same replies as
before.
2026-11-11 23:36:11 -08:00
dotCooCoo f8c234e670 Type: Dynamic Text turns point type into area type with Block on
Type > Dynamic Text and the Contextual Task Bar now also take point
type. Turning it on makes the point type area type with Block on, in
the same undo step:

- Along the lines, the frame is as wide as the widest line as typed
  with its paragraph's indents, measured with the word gap, so that
  line keeps its size and stays where it was across the page by its
  own alignment. The other lines are set to that width. When negative
  indents take more than that line's width, the frame is as wide as
  the line, placed so the line keeps its aligned point, and Block makes
  the line larger.
- The frame starts at the top of the text and grows down (to the left
  for vertical type) to hold every fitted line, around any Text Wrap
  objects above it, so nothing overflows.
- The new frame takes the default Area Type Options and keeps only the
  gaps; options kept from an earlier frame do not carry over.
- Point type with no line to fit (empty, or only spaces and breaks) is
  left as it is, and so is point type when `on` is false. Without `on`,
  point type counts as off, and the Type menu item is unchecked when
  point type comes first in the selection. A gap given with nothing it
  can apply to is an error.

Block now subtracts a list level's indent from the room it sets each
line to, as the layout does. Before, a nested list item was first set
too large for its line and then made smaller on a later pass.

Docs: docs/mcp.md, docs/target-app-parity.md.
2026-11-11 23:33:22 -08:00
dotCooCoo b42a3d4869 Stroke: stroke.set refuses a custom arrowhead path that fills no area
A {Custom: {name, path}} head is refused when its path fills no area under the
non-zero rule: a single anchor, points on one line, or contours that cancel out.
A bow tie and a thin bar are taken. The params text and docs/mcp.md state the rule.
2026-11-11 23:33:02 -08:00
dotCooCoo 656d63e4d2 Merge main into feat/learn-panel 2026-11-11 23:31:06 -08:00
dotCooCoo 96ad9344ee Merge main into fix/warp-styles-map 2026-11-11 23:31:05 -08:00
dotCooCoo 9c5d22bccc Merge main into feat/hpgl-export 2026-11-11 23:31:04 -08:00
dotCooCoo 55570c10d1 Merge main into fix/inspect-library-ids-whole 2026-11-11 23:31:03 -08:00
dotCooCoo 19d2778337 Merge main into fix/malformed-id-not-missing 2026-11-11 23:31:01 -08:00
dotCooCoo 2c6bd2826b Merge main into feat/dynamic-text-release-path 2026-11-11 23:31:01 -08:00
dotCooCoo d4e438273f Merge main into feat/cut-order 2026-11-11 23:30:59 -08:00
dotCooCoo c95a4d901f Brushes: built-in Ink and Wash library with tapered ink, brush pen and wash brushes
Window › Brush Libraries gains Ink and Wash after Art Ribbons: Tapered Ink, an art brush broad near its start that thins to a fine tip; Brush Pen, a calligraphic brush whose size follows the pen pressure; and Soft Wash and Pooling Wash, art brushes of translucent gray layers. The art brushes take the stroke color as tints. The names, shapes and opacities are VectorCraft's own.

Docs: docs/mcp.md, docs/gaps.md, docs/roadmap.md, docs/target-app-parity.md.
2026-11-11 23:17:31 -08:00
BFlat 48e066f475 Merge pull request #6755 from dotCooCoo/fix/ui-params-wrong-type
Commands: app and control channel params of the wrong type are refused
2026-11-12 14:17:29 +07:00
BFlat 8782f6c697 Merge pull request #6794 from dotCooCoo/feat/blend-create-spine
Blend: the Blend panel's Create Spine menu sets whether new blends get a spine
2026-11-12 14:17:20 +07:00
BFlat 5e63104d88 Merge pull request #6800 from dotCooCoo/fix/plugin-automation-install-approval
Plug-ins: an install that automation asked for is not approved in its dialog
2026-11-12 14:16:59 +07:00