Commit Graph
1617 Commits
Author SHA1 Message Date
KnottyDyesandClaude Opus 5.5 5cd8d99db7 Package: report PDF warnings and keep hyperlinks on rasterized frames
Include the PDF export warnings in the package result and report. Cover
shadow and feather output in packaged PDFs with a synthetic regression test.

Preserve frame and text-range hyperlinks on rasterized frames, including
inside groups, at their original source bounds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 18:20:58 -07:00
Tex Jernigan e1910529a7 Frames with a nested image: hit inside the frame, take a placed graphic; replacing keeps the crop; open on a usable layer (#2226)
* Frames holding pasted-in images are hit inside the frame, take a placed graphic; documents open on a usable layer

A frame with items pasted into it (how a document from InDesign keeps a cropped photo) was hit
through its children like a group, so the whole uncropped image counted: a click on the empty
page beside such a photo selected it, and nothing could be deselected there. It is now hit by
its own area, as it is drawn clipped. Such a frame holding only graphics also takes a placed or
dropped graphic (Item::takes_graphic), which fills it as an empty or graphic frame is filled.

A document opened with new objects going to its top layer even when that layer was hidden and
locked (a dieline), so a placed graphic showed as an empty frame outline. It now opens on the
topmost layer that is shown and unlocked (Document::working_layer).

* Place: a graphic replacing the one a frame shows keeps the frame's crop and zoom

Placing or dropping into a frame that shows a graphic (in it, or as the one graphic pasted into
it) filled the frame afresh, so the crop and zoom chosen for the old picture were lost. The new
graphic now covers the old one's area, centred on it: an edited copy of the same picture lands
exactly where the old one was.

* Move the replace-keeps-crop and open-on-a-usable-layer changes to their own PRs

Review asked for them to be checked against reference app behaviour on their own. This PR keeps
the frame hit area and Item::takes_graphic. Reverts 8ea0bc16 and drops Document::working_layer.

* Move Document::working_layer and its test to #2267
2026-11-03 17:21:35 -05:00
Tex Jernigan ae5be94865 Layers: a document opens on its topmost shown, unlocked layer (#2267)
A document opened with new objects going to its top layer even when that layer was hidden and
locked (a dieline), so a placed graphic showed as an empty frame outline. Document::working_layer
picks the topmost layer that is shown and unlocked (the top layer when there is none); DocState::new
and the fallback after the active layer is deleted use it.
2026-11-03 17:15:53 -05:00
aiongg 0867f82961 Merge pull request #1666 from MarekSpodBiedry/issue-1646
Fill the empty or graphic frame under the pointer when a file is dropped on it (#1646)
2026-11-03 17:00:02 -05:00
aiongg c1bf2c769b Merge pull request #1968 from VoiceLessQ/fix/1522-anchored-copy-ids
Give anchored objects fresh ids when copying text frames (fixes #1522)
2026-11-03 16:48:53 -05:00
aiongg d400167537 Apply review fixes
- crates/engine/src/cmd/file/place.rs
2026-11-03 21:46:56 +00:00
aiongg 6c4723e1e8 Merge pull request #184 from storybored379/feat/mcp-conventions
MCP: complete tool hints and check nested argument keys
2026-11-03 16:35:55 -05:00
aiongg cb5c7ca309 Merge main into feat/mcp-conventions 2026-11-03 21:23:14 +00:00
aiongg c10bba5f4d Merge pull request #1900 2026-11-03 21:15:06 +00:00
aiongg 1967903244 Merge pull request #2102 2026-11-03 20:24:26 +00:00
aiongg 1da269b7f5 Merge main into feat/mcp-conventions 2026-11-03 19:40:25 +00:00
aiongg 6914f12209 Apply review fixes
- crates/engine/src/script.rs
2026-11-03 19:08:01 +00:00
aiongg 78139b693e Merge pull request #2193 2026-11-03 19:07:43 +00:00
aiongg 671114f5fc Merge pull request #2024 2026-11-03 19:07:43 +00:00
aiongg 474ecd61d4 Merge main into fix/1522-anchored-copy-ids 2026-11-03 19:01:23 +00:00
aiongg 1e3c5fb0ef Apply review fixes
- crates/engine/src/cmd/file/open.rs
2026-11-03 17:56:11 +00:00
JonRC 7bc3a26e4a type.char: warn about the font the text resolves to (follow-up to #2190)
The warning from #2190 looked only at the attributes passed. A composite
font made by style.compositeFont.set isn't an installed family, so
applying one warned "Missing font: Mixed" even when its entries were
installed. And a fontStyle-only call, or a family change that kept a
style the new family lacks, said nothing.

After a call that sets or clears fontFamily or fontStyle, type.char now
tallies the fonts the formatted text resolves to, with the code
font.list uses (composite entries per character), and warns about the
missing ones and substitute styles. At a caret it checks the font the
next typing gets. tally_story becomes tally_range over a byte range,
and describe_fonts is the part of used_fonts that type.char reuses.
2026-11-03 01:51:54 -03:00
Brandon Thomas 312eefac9b Merge pull request #1493 from Hamza0101/fix/overset-export-warnings
An export says what text its pages had no room for (#1465)
2026-11-02 23:24:29 -05:00
Brandon Thomas 1e2d75d0b0 Merge pull request #2125 from Tom-R-Main/openbytes-title
File import: keep native and IDML bytes out of the INDD converter
2026-11-02 23:24:12 -05:00
Brandon Thomas a4a4cd6ee9 Merge pull request #2141 from Silvertree2010/fix/h5392-data-merge-record-range-accepts
Reject signed record numbers in data merge record ranges
2026-11-02 23:24:08 -05:00
Brandon Thomas 3eb8091bac Merge pull request #2142 from TrevorBrown-dev/fix/variables-numeric-text
M3: a Custom text variable defined with a number shows its digits (#2093)
2026-11-02 23:23:59 -05:00
Brandon Thomas af9706176a Merge pull request #2165 from 4waymedia/fix/links-status-by-date
Links: an unchanged linked image is not read again on every poll (#2164)
2026-11-02 23:23:46 -05:00
Brandon ThomasandClaude Opus 5.5 4c2296491e Links: key the image check cache on the resolved file, not the link text
A relative link names another file once the document is saved elsewhere,
so a status remembered for the old file must not answer for the new one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:09:34 -05:00
JonRC 6abeb8a1ca type.char: warn when the font family or style isn't available (#2189)
A fontFamily the app doesn't have was applied with a null result, so a
script that asked for Courier Prime exported the PDF in the substitute
and exited 0. The font is still applied, since documents can carry
missing fonts and Find Font and preflight list them, but type.char now
returns {"warnings": ["Missing font: Courier Prime (using Source Sans 3)"]},
or "Missing font style: ..." for a style the family doesn't have, in
preflight's words. Other calls still return null.
2026-11-03 01:00:19 -03:00
Paul Gemignani 7d0f141b52 Links: an unchanged linked image is not read again on every poll (#2164)
links.list decided a placed graphic's status by reading the whole file and comparing it with the asset's bytes whenever the sizes matched, and the Links panel polls it twice a second, so a document of press-size images read every one of them in full on every poll. Image links now have the size-and-time fast path linked text files already had: a file of the remembered size and time isn't read, a new time is read once and remembered (unless the file changed in the last two seconds), a different size is modified without a read. The answer is keyed by the asset's bytes' identity, so a relink, update or undo can never be served a stale one; status() stays as the exact check for callers that want it.

Verified locally on a288a87b: fmt, clippy, engine link tests including the new unchanged_linked_images_are_not_read_again.
2026-11-02 16:40:46 -08:00
FredApps f704f481d5 Merge remote-tracking branch 'origin/main' into pr1654
# Conflicts:
#	ROADMAP.md
2026-11-02 18:25:00 +01:00
Hamza 2d5af1bd0d A frame that crosses into an exported page is checked on it
A sheet draws its spread's items without asking which page each one sits on, so
a frame straddling two pages is drawn, in part, on both. The warning chose the
page from the frame's centre alone (`page_at_x(bounds.center().x)`), so a frame
centred on a page the export leaves out had its warning dropped while the part
on an exported page went into the file (noted in review).

`pages_of` gives every page of the spread the frame's bounds overlap, and the
story is kept when any of them is exported.

The page named is one the export has: the centre page when that is exported, so
an ordinary frame reads exactly as before, otherwise the first exported page the
frame reaches. A frame wholly on the pasteboard overlaps no page's span and
falls back to `page_of`, so the two cannot disagree about where such a frame is.

`overset_location` returns the reached pages beside the centre page, which is
what made it worth a named type.

The test exports a frame centred on page 3 and reaching back into page 2, four
ways: the whole document, page 3 alone, page 2 alone -- which used to report
nothing -- and page 4, which the frame never reaches and which still reports
nothing.
2026-11-02 18:40:39 +05:00
Trevor BrownandClaude Fable 5.1 5de0a0b806 M3: variables.define refuses a text that is neither a string, a number nor a boolean (#2093)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 04:13:40 -05:00
Trevor BrownandClaude Fable 5.1 485a94673f M3: a Custom text variable defined with a number shows its digits (#2093)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-11-02 02:40:43 -05:00
NetterSilverandClaude Haiku 5.5 633bdb66bf Reject signed record numbers in data merge record ranges
Found while testing crates/engine/src/cmd/datamerge/parse.rs:212 (parse_record_no, used by select_range)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 05:10:06 +01:00
Tom MainandOpenAI Codex 6e1b6e7754 #2125: integrate upstream v0.16.0
Merge origin/main at a288a87b. Preserve the font.list progress entry and the content-first routing note. The feature diff remains the same four reviewed files.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-11-01 16:30:57 -05:00
Tom MainandOpenAI Codex 60584e3221 #2108: prefer document content over InDesign filename extensions
Keep native ZIP, legacy JSON and IDML bytes out of the INDD converter even when a browser supplies a misleading .indd or .indt name. Preserve signature and unknown-data routing to the converter. Check that every browser delivery adds a document before asserting its title.

Co-Authored-By: OpenAI Codex <noreply@openai.com>
2026-11-01 15:08:46 -05:00
Brandon Thomas 1b02e5427f Merge remote-tracking branch 'origin/main' into land-2109 2026-11-01 14:50:36 -05:00
Brandon Thomas 3bd5adfb19 Merge pull request #2108 from Tom-R-Main/openbytes-title
file.openBytes: title a .designcraft file without its extension
2026-11-01 14:49:27 -05:00
Brandon Thomas d2045c4a82 Merge pull request #2081 from Silvertree2010/fix/h4609-script-parse-errors-report-the-w
Report script parse error line numbers from the original text
2026-11-01 14:49:20 -05:00
Brandon Thomas e3aea68cca Merge pull request #2084 from Silvertree2010/fix/h4663-math-svg-does-not-clamp-the-size
Clamp math.svg size to the same range as math.insert
2026-11-01 14:49:13 -05:00
Brandon ThomasandClaude Opus 5.5 9e12d58887 Math SVG: drop XML-forbidden characters before layout so they take no width
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 14:37:27 -05:00
Tom MainandClaude Opus 5.5 700c4bb344 file.openBytes: test titles that aren't ASCII
Names with characters outside ASCII, one shorter than the extension,
lose a trailing .designcraft or keep their names like the others.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
2026-11-01 13:47:00 -05:00
Tom MainandClaude Opus 5.5 472869598f font.list: a face without an OS/2 table reports a null fsType
A font with no readable OS/2 table doesn't say what its licence allows,
and reporting fsType 0 made it look installable. FontFace::fs_type() now
returns None for it, and font.list reports fsType and the five flags as
null. restricted_licence() and bitmap_only() still treat it as
unrestricted, so export behaviour doesn't change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
2026-11-01 13:31:06 -05:00
MarekSpodBiedry 84348b24c0 Skip locked frames and fill a frame with only the first file of a drop (#1646) 2026-11-01 07:40:55 +01:00
makesomethingshit 5c364f9897 #1620: Port parent resizing to current layout modules 2026-11-01 15:18:55 +09:00
midasmatterhorn e8e51337fa mcp: the page bases state each other - render_page's 0 is exportPdf's position 1 2026-11-01 05:38:05 +03:00
NetterSilverandClaude Haiku 5.5 8b9f297181 Require object params in compact script lines
Found while testing crates/engine/src/script.rs:50-54 (parse, compact `command {json}` branch)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 01:19:16 +01:00
Tom MainandClaude Opus 5.5 f0c86e77e0 file.openBytes: title a .designcraft file without its extension
file.openBytes used the name it was given as the document's title as is. The
IDML path strips .idml/.indd/.indt, but a native document opened as
"Brochure.designcraft" kept the extension, and everything that adds it back
doubled it: Save in the browser downloaded Brochure.designcraft.designcraft,
Save As suggested that name, and the File Name variable showed it. The app's
own drop and open paths strip the extension before calling, so only hosts and
scripts that pass a file name hit it.

The title now drops one trailing .designcraft (any case). Other names are
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
2026-10-31 11:33:13 -04:00
Tom MainandClaude Opus 5.5 1d9e577e36 font.list: report each face's fsType embedding bits
font.list now gives, for the face that sets the text, its raw OS/2 fsType
and what the bits mean: restrictedLicence, bitmapOnly, noSubsetting,
editable and previewPrint (null when the face is missing). A host that
makes print PDFs can then refuse a face whose licence doesn't allow the
export, including system fonts and the bundled fonts, without reading the
font files itself. PDF export subsets every font, so a caller needs
noSubsetting as well as the restricted and bitmap-only bits.

FontFace gains fs_type(); restricted_licence() and bitmap_only() read it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ApvpyStzzHbKyDBNxpzn2Y
2026-10-31 11:23:21 -04:00
NetterSilverandClaude Haiku 5.5 9caae9c542 Drop XML-forbidden control characters from math SVG text
Found while testing crates/engine/src/math.rs:909 (to_svg, the `esc` closure used for each <text> glyph)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-31 14:07:33 +01:00
NetterSilverandClaude Haiku 5.5 c128548111 Clamp math.svg size to the same range as math.insert
Found while testing crates/engine/src/cmd/mathexpr.rs:~50 (the math.svg query) vs insert at ~64

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-31 10:52:55 +01:00
NetterSilverandClaude Haiku 5.5 4b9a800899 Report script parse error line numbers from the original text
Found while testing crates/engine/src/script.rs:30-47 (parse: `t.lines().enumerate()` runs over the trimmed text)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-31 08:41:28 +01:00
Dylan M. Taylor ea214dd44d Merge pull request #2070 from aiongg/docs-tidy
docs: tidy agent, contributor and asset docs
2026-10-31 01:06:18 -04:00
Brandon Thomas 99f90cbe2b Merge storytold/main into PR #2052 2026-10-31 01:02:00 -04:00