Commit Graph
6859 Commits
Author SHA1 Message Date
BFlat 58de20a4b1 Merge pull request #4846 from dotCooCoo/fix/homography-apply-finite
Geometry: a perspective point that overflows maps to nothing instead of infinity
2026-10-31 20:13:06 +07:00
BFlat 969f7f66c3 Merge pull request #4804 from dotCooCoo/feat/perspective-shift-constrains-move
Perspective Selection: Shift constrains a move to the plane's axes and diagonals
2026-10-31 20:12:52 +07:00
BFlat 9269e83b27 Merge pull request #4858 from dotCooCoo/fix/reduce-basic-keeps-selected-fill
Appearance: Reduce to Basic Appearance keeps the selected fill or stroke row
2026-10-31 20:12:37 +07:00
BFlat 62f2f327d4 Merge pull request #4863 from dotCooCoo/fix/add-new-fill-above-selected
Appearance: Add New Fill copies the selected fill row right above it
2026-10-31 20:12:22 +07:00
BFlat 73627d806b Merge pull request #4866 from dotCooCoo/fix/issue-3229
Part of #3229: setting type in a font or style that isn't available warns
2026-10-31 20:12:08 +07:00
BFlat f19e4ff806 Merge pull request #4852 from dotCooCoo/fix/replace-font-hidden-locked
Find Font: Change and Change All leave hidden and locked text alone
2026-10-31 20:11:51 +07:00
BFlat ec40a39749 Merge pull request #4853 from dotCooCoo/fix/opacity-mask-layers
Transparency: Make Opacity Mask over several layers masks their art
2026-10-31 20:11:36 +07:00
BFlat 4992600f0e Merge pull request #4787 from dotCooCoo/fix/pattern-undecoded-marks
Render: pattern tiles draw undecoded-image marks when the view does
2026-10-31 20:11:22 +07:00
BFlat 9fe12a7264 Merge pull request #4789 from dotCooCoo/fix/mask-root-node-mask
Render: an object used as an opacity mask keeps its own opacity mask
2026-10-31 20:11:06 +07:00
BFlat 94d2d068a9 Merge pull request #4828 from dotCooCoo/fix/brush-warp-mask
Brushes: opacity masks on art brush pieces bend with the art
2026-10-31 20:10:52 +07:00
BFlat 72a5442313 Merge pull request #4838 from dotCooCoo/feat/blob-brush-angle-roundness
Blob Brush: Tool Options set the brush's Angle and Roundness
2026-10-31 20:10:37 +07:00
BFlat 52a33d3d8d Merge pull request #4840 from dotCooCoo/fix/dxf-dxf-alter-paths-if-necessary
DXF export: Alter Paths for Appearance outlines only strokes a CAD line can't draw
2026-10-31 20:10:21 +07:00
BFlat 6dff0095ea Merge pull request #4841 from dotCooCoo/fix/dxf-dxf-ellipse
DXF export: ellipses and unevenly scaled circles are written as ELLIPSE
2026-10-31 20:10:07 +07:00
BFlat 6612400fb9 Merge pull request #4839 from dotCooCoo/fix/dxf-dxf-line-entity
DXF export: an open path of one straight segment is written as a LINE
2026-10-31 20:09:52 +07:00
BFlat 40c3519af1 Merge pull request #4842 from dotCooCoo/fix/assemble-keeps-visibility
Outline Stroke, Expand: hidden and locked objects stay hidden and locked
2026-10-31 20:09:38 +07:00
BFlat ce2ca3c017 Merge pull request #4843 from dotCooCoo/fix/select-font-hidden-locked
Find Font: Find leaves out hidden and locked text
2026-10-31 20:09:23 +07:00
BFlat 4094658641 Merge pull request #4844 from dotCooCoo/fix/swatch-delete-plural
Swatches: the delete prompt for several swatches uses each language's plural forms
2026-10-31 20:09:07 +07:00
BFlat 5796c886a4 Merge pull request #4847 from dotCooCoo/fix/docs-mcp-type-underline-fragment
Docs: the type.underline line no longer repeats the end of the sentence before it
2026-10-31 20:08:51 +07:00
BFlat 800c9b9f18 Merge pull request #4848 from dotCooCoo/fix/issue-4837
Fix #4837: the saved color scheme, accent and canvas color show at launch
2026-10-31 20:08:36 +07:00
BFlat d4f8733176 Merge pull request #4859 from dotCooCoo/fix/select-same-fill-live-paint
Select Same: Fill Color from a Live Paint face stays in its Live Paint group
2026-10-31 20:08:22 +07:00
BFlat 40eceb422c Merge pull request #4857 from dotCooCoo/fix/issue-4819
Fix #4819: Convert to Smooth and Corner convert a selected blend's spine
2026-10-31 20:08:07 +07:00
BFlat 31c51b7f45 Merge pull request #4874 from dotCooCoo/fix/issue-4516
Part of #4516: Windows renders start workers only for the cores the process may use
2026-10-31 20:07:53 +07:00
BFlat 2f2b731f03 Merge pull request #4869 from dotCooCoo/fix/issue-4864
Fix #4864: a search pick of an Asset Export command opens the panel
2026-10-31 20:07:37 +07:00
BFlat 257aa3e1f9 Merge pull request #4867 from dotCooCoo/fix/web-shortcut-key-before-text
Shortcuts: in the web build a key-position shortcut uses the key of the same press
2026-10-31 20:07:23 +07:00
dotCooCoo 8363c815ec Perspective: a transform's overflow fallback keeps each entry's powers of two apart
When the conjugate a ∘ self ∘ a⁻¹ overflows, conjugated now forms every
entry of the product as a sum of terms whose factors are split into a
mantissa and a power of two, and scales the whole product by one power of
two from its w row at the end. Scaling each partial product to a largest
entry of 1 could round an entry to 0 that the next factor would restore,
so a projection with entries far apart in size, such as a scale by
(1e160, 1e-160) seen through the same scale, was removed and the art drew
flat.
2026-10-31 19:43:16 +07:00
dotCooCoo ae76455723 Perspective Selection: a move of loose art keeps its plane when 4 clears the active plane
The move drag remembers the plane it places loose art on. Pressing 4
during the drag, or dragging on after it, previews and commits the move
on that plane instead of dropping it. A 1-3 key pressed before the drag
threshold also sets the plane the move uses.
2026-10-31 19:43:16 +07:00
dotCooCoo c711ad42f0 Perspective: a transform's overflow fallback scales each partial product
When the conjugate of a projection overflows, it is now formed one factor
at a time, and each partial product is divided by its largest entry
magnitude. Scaling the affine factors up front let the w row underflow to
0, so a scale by 2 seen through a move by 1e308 returned None and the
projection was removed, though its conjugate is finite.
2026-10-31 19:43:16 +07:00
dotCooCoo c15874ba6e Perspective Selection: Shift constrains each object in its own plane
perspective.move takes constrain: true instead of a plane-space
direction. For each object, the command snaps the move to the nearest
axis or 45-degree diagonal of that object's own plane, so a selection on
several planes keeps every object on a line of its plane. The tool sends
the raw pointer with the flag.

On a diagonal, Snap to Grid now moves along the diagonal by the nearer
per-axis correction, so that edge lands on its gridline.
2026-10-31 19:43:16 +07:00
dotCooCoo 375b413ba6 Perspective: a projection that a transform overflows keeps a w row of 1
When conjugating a projection overflows, the scaled-down result is now divided by the largest entry in its w row. A valid conjugate is no longer dropped by the determinant cutoff at the arbitrary scale, and every point of a kept projection passes the horizon test in apply instead of none.
2026-10-31 19:43:16 +07:00
dotCooCoo 9f64452303 Perspective Selection: Snap to Grid keeps a Shift-constrained move on its axis or diagonal
perspective.move takes an optional constrain: [dx, dy], a plane-space
direction. For an in-plane move, Snap to Grid's correction is projected
onto that direction, so a move the Shift key constrains to a plane axis
or a 45-degree diagonal stays on that line when an object edge lies near
a gridline. The Perspective Selection tool sends the direction for
Shift moves and copies. Moves without the param behave as before.
2026-10-31 19:43:16 +07:00
dotCooCoo db38e2e114 Perspective: a projection that a transform overflows is scaled down or removed
When moving type or a symbol instance in perspective makes the
conjugated projection overflow, Homography::conjugated now forms the
product from factors scaled to a largest entry of 1 and returns it at
that scale, which maps every point to the same place. When even the
scaled result is not invertible, the transform removes the projection
and the art is drawn flat, instead of keeping the old projection while
the flat art moves.
2026-10-31 19:43:16 +07:00
dotCooCoo 3d345ff95b Geometry: a perspective point that overflows maps to nothing instead of infinity
Homography::apply checked that w is in front of the horizon but not the quotients, so a point with w just above 1e-9 and a large x or y, or a NaN w, mapped to an infinite or NaN point. apply now returns None unless the mapped point is finite. inverse, conjugated and affine_at return None when their result has an entry that is not finite.
2026-10-31 19:43:16 +07:00
dotCooCoo 45b266c805 Appearance: Reduce to Basic Appearance finds the active row in the first selected object
The targets are in paint order, so the first selected object is not always the first target. The active row is now matched against the first selected object wherever it is among them.
2026-10-31 19:43:15 +07:00
dotCooCoo 3a7e81e6c3 Appearance: Add New Fill copies the selected fill row right above it
With a fill row selected in the Appearance panel, Add New Fill now
inserts a copy of that row directly above it and selects the new fill.
Rows already above the selected one stay where they are. Before, the
new fill was always a copy of the topmost fill, added at the top.

The selected row belongs to the first selected object. In a mixed
selection, an object that shares that row gets the copy above its own
equal row; an object that does not share it gets a copy of its top
fill on top, as before. With a stroke row selected, or with `ids` or
`target: "contents"`, Add New Fill works as before.

The panel drops rows that were Cmd- or Shift-clicked together when the
active row changes outside the panel, so after Add New Fill (button,
menu or shortcut) only the new fill is selected.
2026-10-31 19:43:15 +07:00
dotCooCoo 65b6606d90 Part of #3229: setting type in a font or style that isn't available warns
Squashed from #4866 onto main.
2026-10-31 19:43:15 +07:00
dotCooCoo 1f31b6ed4a Find Font: Change and Change All leave hidden and locked text alone
Squashed from #4852 onto main.
2026-10-31 19:43:15 +07:00
dotCooCoo 875d3301f5 Transparency: Make Opacity Mask over several layers masks their art
transparency.makeOpacityMask with two or more layers below the mask
object (or a layer and objects of other layers) wrapped the layers
themselves in a new top-level group, so a layer ended up inside a
group. A layer among several masked items now stands for its art: the
masked group takes the layer's visible, unlocked objects, a hidden,
locked or template layer gives none, and the layers stay where they
are. One layer under a mask object, or one layer alone, is masked as
before.
2026-10-31 19:43:15 +07:00
dotCooCoo dd83e063a4 Render: pattern tiles draw undecoded-image marks when the view does
Pattern tiles were drawn with the default render options, so an image
whose pixels cannot be decoded drew nothing inside a pattern fill even
when the render marks undecoded images, as the canvas does. Tiles now
follow the caller's mark_undecoded_images setting, and the tile cache
keys on it.

An opacity mask with such a pattern now treats the mark as part of the
mask, as it does for an undecodable image outside a pattern.
2026-10-31 19:43:15 +07:00
dotCooCoo 8aa8bb4d9d Render: a mask art root, symbol art root or thumbnail keeps its own opacity mask
The renderer drew the root node of an opacity mask's art, of placed symbol
art, of an art brush piece, of an Image Trace source image and of a node
thumbnail without its own opacity mask. Make Opacity Mask uses the top
object as the mask art, so a mask made from an object that already had an
opacity mask ignored that inner mask. These roots now draw through the
same masked group as any other node, still drawn whatever their visibility
and bounds, and an incomplete inner mask still leaves out the outer object.
2026-10-31 19:43:15 +07:00
dotCooCoo b1ed0a512b Brushes: opacity masks on art brush pieces bend with the art
An art, scatter or pattern brush piece whose art carries a linked opacity
mask was bent along the path while the mask's art kept its place in the
brush's own coordinates, so the mask no longer covered the piece. The
mask's art now bends and has its strokes scaled with the object it
masks, on bent runs, on straight runs and where the brush narrows along
the path. A mask whose art cannot bend becomes an empty group. The
anchor budget for a brushed stroke counts the mask's art as well.
2026-10-31 19:43:15 +07:00
dotCooCoo 2a5e2e8588 Blob Brush: the tip preview draws 0% Roundness as thin as the brush
The Tool Options tip preview floored the short axis at 1% of the long one, while the brush draws 0% Roundness at 0.1%. The preview now uses the same 0.1% minimum, with a test that compares it with the tip the brush draws.
2026-10-31 19:43:15 +07:00
dotCooCoo 958566468a DXF export: dashed polylines continue their linetype around vertices
A polyline with a linetype now sets group 70 bit 128, so the dash pattern runs on through its vertices instead of restarting at each corner. This applies to LWPOLYLINE and the R12 POLYLINE.
2026-10-31 19:43:15 +07:00
dotCooCoo b493e601a9 Docs: leave the DXF row of file-format-parity.md to #4796
The ELLIPSE note stays in docs/gaps.md; the open #4796 rewrites the same file-format-parity.md row.
2026-10-31 19:43:15 +07:00
dotCooCoo 06e8d711ae DXF export: an open path of one straight segment is written as a LINE
An open path with a single straight segment was written as a two-vertex
LWPOLYLINE (POLYLINE before R14). It is now a LINE entity from its start
to its end point. A stroke with a weight in R12, R13 and R14 keeps its
polyline, since a LINE has no width. Closed paths and paths with more
than one segment are unchanged.

Part of #1299.
2026-10-31 19:43:15 +07:00
dotCooCoo 9571ae0a46 Outline Stroke, Expand: hidden and locked objects stay hidden and locked
The art that replaces an outlined or expanded path did not take the
path's hidden, locked or Knockout Shape state. Outline Stroke on a
hidden path, or Expand on a group with a hidden member, made the new art
visible (a filled and stroked path became half visible: the outline
shown, the fill copy hidden), and a locked member's art was unlocked.

The replacement now takes the path's visibility, lock and Knockout Shape
state, and the fill copies and clipping paths inside it are shown and
unlocked, so showing or unlocking the new art shows or unlocks all of it.
This covers Outline Stroke, and Expand's strokes, gradient fills and
pattern fills.
2026-10-31 19:43:15 +07:00
dotCooCoo 9e8e091c86 Find Font: Find leaves out hidden and locked text
select.font (the Find Font dialog's Find button) selected every text
object using the font, including hidden or locked text and text in a
hidden or locked group or layer. It now selects only text that is
visible and unlocked through every group and layer, and not on a locked
artboard. Text on a visible, unlocked template layer is still found. A
font used only by hidden or locked text selects nothing.
2026-10-31 19:43:15 +07:00
dotCooCoo 9dcbe3688e Swatches: the French one-item delete prompt keeps the no-break space before ? 2026-10-31 19:43:15 +07:00
dotCooCoo f677c60aba Perspective Selection: Shift constrains a move to the plane's axes and diagonals
Holding Shift while dragging objects with the Perspective Selection tool
snaps the move, in the plane's own coordinates, to the nearest plane axis
or 45 degree diagonal. This applies to plain moves and to Alt and
Ctrl+Alt copies. The preview, the final move and the measurement label
use the snapped point. Pressing or releasing Shift, pressing 5 and
pressing 1 to 4 during the drag recompute the preview from the pointer;
a move perpendicular to the plane is not constrained.
2026-10-31 19:43:15 +07:00
dotCooCoo d9fefde061 Appearance: Reduce to Basic Appearance keeps the selected fill or stroke row
Reduce to Basic Appearance kept the topmost visible fill and stroke even
when another fill or stroke row was selected in the Appearance panel.
It now keeps the selected row in place of the topmost one of its kind,
and in each other selected object the row equal to it. With ids, or
with no selected row, it keeps the topmost ones as before.
2026-10-31 19:43:15 +07:00
dotCooCoo baaffd63e7 Blob Brush: Tool Options set the brush's Angle and Roundness
Blob Brush Tool Options gain Angle (-180 to 180 degrees, 0 by default)
and Roundness (0 to 100 percent, 100 by default), with a preview of the
tip and three dabs; a drag in the preview square sets the Angle. The
elliptical tip keeps its angle on the page along a stroke, a 0 percent
tip is drawn 0.1 percent as wide as it is long, and Size set to
Pressure still varies its size. path.blob takes angle and roundness,
and both values are kept with the tool's options.

While a non-round tip drags, the Blob Brush shows the outline of the
area it covers with its length label, and an Alt drag that smooths
shows the Smooth tool's thin line.
2026-10-31 19:43:15 +07:00