Commit Graph
4884 Commits
Author SHA1 Message Date
BFlat 0c976db26c Merge pull request #7319 from dotCooCoo/fix/ai-wrap-options-saved
.ai save: the editing copy keeps text wrap Offset and Invert Wrap
2026-11-14 07:33:50 +07:00
BFlat 8009ea8e6d Merge pull request #7313 from dotCooCoo/fix/background-document-bounds
Type: a document replaced in the back measures its type when it is replaced
2026-11-14 07:33:42 +07:00
BFlat c6d580af4b Merge pull request #7280 from dotCooCoo/fix/colored-solid-faces-one-order-limit
3D: solid-color fills and strokes under colored lights draw their faces in one depth order
2026-11-14 07:33:34 +07:00
BFlat 13abf355c6 Merge pull request #7323 from dotCooCoo/fix/trace-palette-flat-ground
Image Trace: a nearly flat dark ground keeps one color in a Limited palette
2026-11-14 07:33:05 +07:00
BFlat 239152b6c8 Merge pull request #7303 from dotCooCoo/fix/slanted-seam-tolerance
Area type: lines stop at a gap between slanted contours however narrow
2026-11-14 07:32:55 +07:00
BFlat 0b29b2b1f6 Merge pull request #7267 from dotCooCoo/fix/doc-info-values-translated
Document Info: values show in the interface language
2026-11-14 06:27:27 +07:00
BFlat 4a0f4b924e Merge pull request #7305 from dotCooCoo/fix/one-anchor-edit-no-remeasure
Path: anchor edits on a long selected path skip measuring it for the canvas check
2026-11-14 06:27:14 +07:00
BFlat f6e84df143 Merge pull request #7306 from dotCooCoo/fix/path-type-rtl-fit
Type on a path: overflowing right-to-left type shows the longest start that fits
2026-11-14 06:26:48 +07:00
BFlat efba8bfd89 Merge pull request #7295 from dotCooCoo/fix/negative-wrap-offset
Text Wrap: a negative Offset lets text run into the wrap object
2026-11-14 06:26:39 +07:00
BFlat be1810e0c9 Merge pull request #7263 from dotCooCoo/feat/smooth-free-end-tangent
Smooth tool: an open path's end turns with the smoothing when a drag reaches it
2026-11-14 06:26:31 +07:00
BFlat 6fa41d4f76 Merge pull request #7304 from dotCooCoo/fix/graph-series-object-opacity-other-commands
Graphs: Global Edit, Randomize Opacity and Sort Objects keep what they give a series
2026-11-14 06:26:22 +07:00
BFlat 2beda0487e Merge pull request #7251 from ncic/snap-labels
Snap to Point draws no Smart Guides labels or lines with Smart Guides off
2026-11-14 06:26:14 +07:00
dotCooCoo 0fc37a0ddf Merge main into fix/slanted-seam-tolerance 2026-11-13 15:17:12 -08:00
dotCooCoo 9d3717b0c0 Merge main into fix/colored-solid-faces-one-order-limit 2026-11-13 15:16:25 -08:00
dotCooCoo aab26c2b31 Image Trace: a nearly flat dark ground keeps one color in a Limited palette
The Limited palette's median cut ranks cuts by pixel-weighted gain. A
large near-black ground with faint noise therefore took two colors less
than 0.02 apart in Oklab, and the trace drew blotches of one over the
other.

With 9 to 16 colors, a cut whose two sides both have a dark gray mean
(Oklab lightness under 0.30, chroma under 0.03) and lie less than 0.03
apart now has its gain scaled by (distance / 0.03)^2 while the cut is
chosen. The ground keeps one color, and the color it would have taken
goes to another cut. Document Library without swatches follows Limited.
Other color counts, Full Tone and Automatic choose the same cuts as
before.
2026-11-13 15:13:54 -08:00
dotCooCoo aa5d142bd8 .ai save: the editing copy keeps text wrap Offset and Invert Wrap
A PDF-compatible .ai saved with Include Editing Data for Other Apps
wrote no text wrap options, so a wrap object opened from the file no
longer wrapped type. An object with only wrap options got no
dictionary at all.

The writer now writes each wrap object's options in its dictionary as
`AI11TextWrapOffset` (`/Real`) and `AI11TextWrapInvert` (`/Bool`, 1 or
0), the entries `text_wrap` in crates/eps/src/import/ai/read/document.rs
reads, beside the object's name, variables and opacity mask.

- The offset is the one in the art's space, so on a large canvas it is
  written at 1/10 and read back at its size. An offset that is not
  finite is written as the default 6 pt, and one past the -1000 to
  1000 pt the reader keeps as the nearer end of that range.
- Art the writer draws for an object (a blend's steps, a symbol
  instance written as its art, a brushed stroke's pieces, pattern
  tiles, an object's drawn look) is written without the options of the
  objects it is made from. The object itself and a symbol's own art
  keep theirs.
- A clipping path written as its fills and its strokes has its options
  once.

Docs: docs/file-format-parity.md, docs/target-app-parity.md.
2026-11-13 14:48:16 -08:00
BFlat 28bd9c9292 Merge pull request #7298 from dotCooCoo/fix/hi-message-rows
i18n: Hindi rows no longer keep English words or garble their sentences
2026-11-14 05:42:51 +07:00
BFlat 517b725be5 Merge pull request #7089 from dotCooCoo/fix/smooth-fidelity-screen-pixels
Smooth: Fidelity is in screen pixels, so a drag smooths as much at any zoom
2026-11-14 05:42:42 +07:00
BFlat 64c6387b84 Merge pull request #7260 from dotCooCoo/fix/tool-options-refuse-invalid
Live Paint and Shape Builder: tool.setOption refuses invalid options
2026-11-14 05:42:33 +07:00
BFlat 0899d4026a Merge pull request #7302 from dotCooCoo/fix/plugin-before-item-3d-context
Effects: a plug-in before a fill's or stroke's own 3D effect is told its fill or stroke
2026-11-14 05:42:24 +07:00
BFlat 39027eb42e Merge pull request #7292 from dotCooCoo/fix/ai-mask-art-live-effect
.ai export: opacity mask art keeps its live effects in the editing data
2026-11-14 05:42:16 +07:00
BFlat 2fe70b2483 Merge pull request #7258 from dotCooCoo/fix/graph-label-appearance-kept
Graphs: Appearance edits on a label are kept for every label of its kind
2026-11-14 05:42:08 +07:00
BFlat c36aaec289 Merge pull request #7296 from dotCooCoo/fix/delete-artboards-one-pass
Artboards: delete several artboards and their guides in one pass
2026-11-14 05:41:59 +07:00
BFlat 1b039350a3 Merge pull request #7297 from dotCooCoo/fix/global-edit-enabled-for-supported-groups
Global Edit: Start Global Edit is offered only for a group it can start on
2026-11-14 05:41:50 +07:00
BFlat 5fd9ef537a Merge pull request #7294 from dotCooCoo/fix/live-shape-unknown-keys
Live Shapes: object.setLiveShape refuses unknown keys and invalid sides or radius
2026-11-14 05:41:41 +07:00
BFlat 7b992a416e Merge pull request #7287 from dotCooCoo/fix/recovery-error-guidance
Data Recovery: a failed copy names the folder in use and how to change it
2026-11-14 05:41:33 +07:00
BFlat 795f01782f Merge pull request #7272 from dotCooCoo/fix/invert-wrap-one-pass
Text Wrap: Invert Wrap intersects a line's spans in one pass
2026-11-14 05:41:20 +07:00
BFlat df581b2521 Merge pull request #7282 from dotCooCoo/feat/banner-hems-grommets
Cutting Tools: Banner Hems and Grommets marks a banner's hems and grommet holes
2026-11-14 05:41:10 +07:00
BFlat 64b4cb1ad6 Merge pull request #7300 from dotCooCoo/fix/composite-fonts-per-document
Type: documents that define one composite font name differently each draw in their own
2026-11-14 05:40:49 +07:00
BFlat c135ba1f9b Merge pull request #7279 from dotCooCoo/fix/path-type-probe-wider
Type: threaded type on a path aligned Justify All is measured by paragraphs
2026-11-14 05:40:38 +07:00
BFlat 35d7c5d523 Merge pull request #7271 from dotCooCoo/fix/pdf-long-page-warning-names-option
PDF: the long-page warning names the in-points option
2026-11-14 05:40:30 +07:00
BFlat e244a65981 Merge pull request #7293 from dotCooCoo/fix/offset-path-parallel
Offset Path: offsets several selected paths on several threads
2026-11-14 05:40:00 +07:00
BFlat 55fe8b62d4 Merge pull request #7278 from dotCooCoo/fix/rtl-tab-line-hyphenation
Type: right-to-left lines with tabs are measured as they are drawn
2026-11-14 05:39:52 +07:00
BFlat 00d2f6d24b Merge pull request #7283 from dotCooCoo/fix/nested-svg-image-count
SVG import: broken nested SVG images do not use up the image allowance
2026-11-14 05:39:43 +07:00
BFlat 31eb3b0d1e Merge pull request #7285 from dotCooCoo/fix/pdf-warped-image-written-once
PDF export: a warped image writes its pixels once for all its pieces
2026-11-14 05:39:34 +07:00
BFlat 2f44c32060 Merge pull request #7032 from addibble/taper-one-face
3D: a tapered Extrude & Bevel wall is one face
2026-11-14 05:39:24 +07:00
dotCooCoo a8833442dd Type: a document replaced in the back measures its type when it is replaced
Session::replace_document on a tab other than the current one cleared
the bounds of type set in a font named like a composite font and left
that type with estimated bounds until the document came to the front.

- The replacement's type without bounds is measured at once, in the
  document's own composite fonts, lent for the measuring. The front
  document stays the one whose composite fonts are registered.
- When the document then comes to the front unchanged, its type in its
  own composite fonts is not measured again. Type set in a composite
  font only another document defines is still measured again, as
  missing, and so is type set in a composite font name that another
  thread's loan held with a different definition.
2026-11-13 14:29:46 -08:00
dotCooCoo e914d8abdd Merge main into fix/doc-info-values-translated 2026-11-13 14:13:45 -08:00
dotCooCoo 77e4dceb9d Type on a path: overflowing right-to-left type shows the longest start that fits
Right-to-left type on a path that overflows searched for the start of its
text that fits with a binary search, which assumed that a longer start
never fits once a shorter one does not. A letter tracked to a negative
advance breaks that: with steps of 6, 6, -3 and 6 points in a 10 point
span, the first three letters fit while the first two do not, and the
search showed only the first letter.

- Without hanging punctuation, and with no spacing or on a path of one
  straight segment, every start is measured in O(n log n): each glyph
  keeps its place in the whole text's visual order, except the trailing
  whitespace and controls that UAX #9 rule L1 sets to the paragraph's
  level.
- With hanging punctuation, or spacing on a curve, when a letter has a
  negative advance, a start is a candidate only when its glyphs, in its
  own visual order and each at the least step it can take, reach no
  farther than the path's length. This lower bound holds with negative
  advances.
- At most 32 candidates are arranged from the longest. When none of
  them fits, a binary search over the rest shows a start that fits,
  which is not always the longest.
- With hanging punctuation, or spacing on a curve, text with no negative
  advance keeps the binary search.

Right-aligned and centered type on a curve with Spacing was placed using
the width its glyphs have at the start bracket, while the steps were
measured where the line was placed, so a line that fits could end past
the end bracket and lose glyphs. It is now placed using the width of the
steps it has where it is placed.
2026-11-13 14:04:05 -08:00
dotCooCoo 380f03345f Merge main into feat/smooth-free-end-tangent 2026-11-13 14:01:37 -08:00
dotCooCoo 6e308c4e54 Graphs: Global Edit, Randomize Opacity and Sort Objects keep what they give a series
A path directly in a graph series lost what these commands gave it when
the graph was drawn again, for example after graph.setData:

- While Global Edit is on in an isolated graph, a match that is a series
  path, or a series group whose paths take the edit, now has what
  changed on its paths stored for their series: the paint, weight,
  opacity and blend mode of the topmost visible fill and stroke, and the
  object's opacity and blend mode. The edited match is stored by its own
  command as before.
- addon.arrange.randomizeOpacity and addon.arrange.sort with apply
  "opacity" now store the object opacity, with the blend mode, of the
  series paths whose opacity they change. When they change several
  paths of one series, the frontmost of them sets what the graph
  stores, as for the other commands.

The graph stores them in the same undo step as the edit. The params
text of addon.arrange.randomizeOpacity and addon.arrange.sort,
docs/mcp.md and docs/target-app-parity.md describe the new behavior.
2026-11-13 13:53:55 -08:00
ncic 1b3454b4f8 Merge upstream main into snap-labels
# Conflicts:
#	docs/target-app-parity.md
2026-11-13 22:48:42 +01:00
dotCooCoo e51e67116d Path: anchor edits on a long selected path skip measuring it for the canvas check
The check after each edit that the selected objects stay within the
canvas measured the whole of every selected path. Moving one anchor of
a 10,000-anchor path measured all 9,999 segments. A path or compound
path whose anchors and handles are all finite and inside the canvas
range now passes without being measured, because its curves stay inside
their control points. A path with a point outside that range is still
measured, so the check accepts and refuses the same edits as before.

path.moveAnchor to the point the anchor is already at, and
path.setHandle to the point the handle is already at, now leave the
document as it is and record no undo step.

vectorcraft_geom::path::measured_segments counts the segments that
PathData::bounds measures, and the new engine tests use it.
2026-11-13 13:46:30 -08:00
dotCooCoo 08f7ce6670 Area type: lines stop at a gap between slanted contours however narrow
Two contours of an area-type frame now count as meeting along a slanted
edge only when their edges lie exactly on one line, checked with an exact
cross product, and the intervals on either side of a seam join only
where both edges cross the middle of the band at the same x, found along
the same line. Before, both checks allowed a few units in the last place
of the coordinates, which near the edge of the canvas (x = 3,999,000)
is wider than a real gap of one to four units, so a line ran across the
gap outside the frame.

An edge divided by an anchor exactly on it still joins, including where
the divided edge's own crossing would round to another x.
2026-11-13 13:42:05 -08:00
dotCooCoo c8177dc7e8 Effects: a plug-in before a fill's or stroke's own 3D effect is told its fill or stroke
A 3D effect on a fill or stroke worked on copies of the object's fills
and strokes, and the copies were looked up among the object's items by
identity, so a live-effect plug-in before that 3D effect was given
`_context.item` "object" and a deferred stage there was listed with no
item. The drawn art, the 3D meshes and Expand as Wireframes now pass the
original item, so the plug-in is given `{"fill": i}` or `{"stroke": i}`
as docs/plugins.md describes. The paints of a type's first run still have
no item.
2026-11-13 13:33:01 -08:00
BFlat 4558196e16 Merge pull request #7053 from dotCooCoo/feat/warichu
Type: Warichu stacks selected characters on lines inside their line
2026-11-14 04:32:40 +07:00
BFlat ce1e688c7c Merge pull request #7138 from dotCooCoo/fix/status-linked-files-keeps-notes
Status bar: a line about linked files keeps the open's notes listed
2026-11-14 04:32:29 +07:00
BFlat f8751a8c0c Merge pull request #7221 from dotCooCoo/fix/space-in-text-edit
Type: Space types a space while editing text instead of panning
2026-11-14 04:32:17 +07:00
BFlat a0e8701256 Merge pull request #7248 from dotCooCoo/fix/ai-twist-past-180-keeps-look
.ai import: straight paths twisted past 180° keep the drawn look
2026-11-14 04:32:07 +07:00
BFlat e5913e30e1 Merge pull request #7204 from dotCooCoo/fix/trace-overlapping-two-pass
Image Trace: Overlapping fills each shape whole and stacks what it encloses above it
2026-11-14 04:31:56 +07:00