230 Commits
Author SHA1 Message Date
aiongg 7d16fffb39 Integration: #1451 screened outer glows and blended shadows isolate the spread from the paper 2026-10-31 00:35:26 +00:00
moppeeerandClaude Opus 5.5 8c89bf5f1a rustfmt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 22:40:44 +01:00
moppeeer 3711ac05ba Merge remote-tracking branch 'origin/main' into effect-blend-modes
# Conflicts:
#	crates/render/src/fx.rs
2026-10-30 21:57:48 +01:00
Brandon Thomas a1e9bea41b Merge storytold/main into PR #1879 2026-10-29 21:55:46 -04:00
Brandon Thomas a8c92bb960 Merge storytold/main into PR #1879 2026-10-29 21:53:39 -04:00
Brandon Thomas e5b30c4527 Merge storytold/main into PR #1238 2026-10-29 21:53:38 -04:00
Brandon Thomas 2b15bf79a2 Merge pull request #1842 from Silvertree2010/fix/1835-document-not-updated-on-image-re
Repaint the canvas when a placed file is relinked or updated
2026-10-29 21:51:38 -04:00
Brandon Thomas af284b8bd8 Merge remote-tracking branch 'origin/main' into HEAD 2026-10-29 21:40:31 -04:00
moppeeer b6fec896f9 Merge remote-tracking branch 'origin/main' into effect-blend-modes
# Conflicts:
#	crates/doc/src/item.rs
#	crates/idml/src/export.rs
#	crates/idml/src/import.rs
#	crates/ui-egui/src/effects_dialog.rs
2026-10-29 11:42:14 +01:00
Claude 5c6909db46 Merge storytold/main (v0.14.0) into inline-objects-under-text
The PDF change moves to export/walk.rs (draw_leaf_content passes the drawn flag back) and the
render test to render/src/tests.rs, with upstream's splits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
2026-10-28 18:03:03 +00:00
Dylan M. Taylor 072dd02f73 Refactor render for strict Clippy checks 2026-10-28 11:39:26 +00:00
aiongg 27e21ba19a refactor(render): split lib.rs into modules 2026-10-26 23:05:57 +00:00
aiongg 6e078e1167 refactor(render): move the tests module of lib.rs to tests.rs 2026-10-26 18:18:13 +00:00
PiMinusMaxandClaude Opus 5.5 13013b09d0 Effects: inner shadow, glow and bevel follow a transparent image's edge
On a frame holding a graphic, Inner Shadow, Inner Glow (from the edges) and Bevel and Emboss are built from what the object paints instead of the frame's path: the colour everywhere but under the painted pixels moved by the offset, blurred, and kept only where the object paints. A transparent part of an image is outside the object, so the effect lines the image's opaque edge; before, it lined the frame and nothing marked the image's own edge. Frames without a graphic draw as before. Satin and a centred Inner Glow still follow the frame.

Fixes #1622.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:13:10 +01:00
aiongg d90881a8a9 Merge branch 'print-color' into print-color-separations
# Conflicts:
#	Cargo.toml
2026-10-26 01:11:35 +00:00
NetterSilverandClaude Opus 5.5 b390324c1f Repaint the canvas when a placed file is relinked or updated
Fixes #1835

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 23:48:25 +00:00
Dylan M. TaylorandClaude Sonnet 5.5 8e77e8db2d refactor: split complex functions in swatch_refs, xlsx, render group drawing (Sonar S3776) (#1733)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 17:33:59 -04:00
aiongg 9c977f41a6 Merge print-color (#1374 with main: egui 0.37, craft-libs e3b9e239) into print-color-separations
print_pdf, shared by Export PDF, File › Print and Separations Preview, takes main's two
changes to the inline export pipeline: rasterize_layered runs only for PDF/A-2b (other
standards keep hidden placed-PDF layers as optional content), and the report gets
GRAPHIC_LAYER_RENDERING_WARNING when the source document has graphic layer visibility
overrides and the writer did not report it. The Separations Preview command matches
craft_prepress::Conversion with a fallback arm, since the enum is non-exhaustive at
craft-libs e3b9e239.
2026-10-25 19:54:40 +00:00
aiongg 02cb2876d2 Merge upstream main into docking-trial
Main's File Info PDF metadata gets craft-pdf's modified field (None, as before), and the
Notes panel ids use Id::unique (egui 0.37).
2026-10-25 17:52:22 +00:00
Brandon Thomas fffe2fdc3d Merge pull request #1768 from alichaudhry55/fix/table-gradient-fills
Tables: gradient cell fills draw as gradients on screen and in PDF
2026-10-25 12:26:38 -04:00
Brandon Thomas 743eced7ba Merge pull request #1712 from dotCooCoo/feat/file-info
File Info: PDF export writes the document's title, author, description and keywords
2026-10-25 12:26:32 -04:00
aiongg 56f15a600d Merge upstream main into docking-trial; pin craft-libs to main 5bbe9f62 2026-10-25 16:25:57 +00:00
dotCooCoo 0f037cb67e Merge main into feat/file-info 2026-10-24 18:14:03 -07:00
aiongg 6053b099bc Docking: pin craft-libs to 6e7f28518dd1 (main)
Every craft-libs crate and the Krilla/Hayro patches use one revision, which
also vendors hayro-postscript. Clipping text paints nothing in the PDF bounds
device; its clip arrives through push_clip_path.
2026-10-24 22:58:49 +00:00
aiongg 67bfdde682 build: pin only craft-ui to craft-libs 16fb3d46e; other craft-libs crates stay at main's revs 2026-10-24 20:29:28 +00:00
aiongg f6bca1d85b build: craft-libs 16fb3d46e (shared docking and native windows); PDF clip text draws nothing 2026-10-24 19:24:58 +00:00
dotCooCoo 6bc5ac36fb Merge main into feat/file-info 2026-10-24 11:30:55 -07:00
alichaudhry55andClaude Opus 5.5 fe44b1cfdd Tables: gradient cell fills draw as gradients on screen and in PDF
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 18:36:54 +05:00
andeecollard 8d295b101e PDF: distinguish all-on layer choices from file defaults 2026-10-24 13:23:02 +01:00
andeecollard 7074dc8a85 M6: preserve per-placement graphic layer options 2026-10-24 13:22:08 +01:00
moppeeer 0f653bcc73 Merge remote-tracking branch 'origin/main' into effect-blend-modes
# Conflicts:
#	ROADMAP.md
2026-10-24 14:18:42 +02:00
Dylan M. TaylorandClaude Sonnet 5.5 c313c53497 refactor: split complex functions in ruby, warichu, pdf text, render text, epub, pdfx (Sonar S3776) (#1728)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:58 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 cb763c2583 refactor: split complex functions in psd, table, parabox, index, trace, pdf export, render (Sonar S3776) (#1724)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:51:26 -04:00
Dylan M. TaylorandClaude Sonnet 5.5 8299d26400 chore: replace trivial closures with method paths (Sonar S1612) (#1714)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-24 04:30:43 -04:00
Dylan M. TaylorandDylan Taylor f90d286721 chore: resolve SonarCloud maintainability issues (#1698)
* chore: resolve SonarCloud maintainability issues

- Replace lambda closures with method references (S1612)
- Replace wildcard imports with explicit imports (S2208)
- Refactor complex functions with extracted helpers (S3776)
- Replace OR pattern with range pattern in math parser (S9047)

* style: apply rustfmt to warichu helper

* fix(compose): revert slice conversion in tests and remove unused var in warichu

* Group warichu row layout scalars to satisfy S107 parameter limit

* style: satisfy rustfmt in warichu.rs

---------

Co-authored-by: Dylan Taylor <dylan@craftmaker.dev>
2026-10-24 03:54:24 -04:00
dotCooCoo a525894355 File Info: PDF export writes the document's title, author, description and keywords
File › File Info… opens a dialog with Document Title, Author,
Description, Keywords, Copyright Notice and Copyright Info URL, and the
document saves them. The new file.info command reads them with {} and
sets the fields it is given; "" or null clears a field, and keywords
are a list or one line split at semicolons and commas. file.info.get
returns the fields without editing the document, so opening the dialog
does not end a Data Merge preview.

Export PDF, PDF/X-4 and Print Booklet write the title, author,
description and keywords into the PDF's document information and XMP.
EPUB export takes the title and author from File Info, and HTML export
takes the title. A title or author given to the export replaces File
Info's, and an empty Document Title leaves the document's name as the
title. Export PDF's dialog no longer sends the document's name as the
PDF title, so the PDF takes its title from File Info; the file name
still comes from the document's name.
2026-10-24 00:20:21 -07:00
skylar taylor-barrick 00d5fa5cdd M6: reject unreadable PDF trailer history links (#1670)
Reject a non-null Prev entry that cannot be read as an offset instead of silently treating it as the end of the guarded trailer chain. Keep absent/null end markers and readable numeric offsets unchanged.

Reproduced CodeRabbit discussion_r4366245854 with an independent probe and a failing native regression before the fix. The synthetic regression covers seven unreadable value types plus absent/null and integer/real history controls.

Validation: all 9 cargo xtask ci gates passed (3063 tests passed, 6 skipped; 16 WASM-safe crates). One unrelated GPU test was labelled leaky by nextest in that run and passed cleanly in an isolated rerun. Independent checks: 17 original supported PDF variants still pass qpdf, logical preservation and Poppler pixels; 6 original refusal cases remain refused. All 11 additional Prev controls pass (7 refused, 4 accepted).
2026-10-24 00:40:33 -06:00
skylar taylor-barrick 7427a15863 M6: harden placed PDF layer variants (#1670)
Integrate current main (d8d78851) without rewriting the contributor's commits, retaining craft-libs 9f75d3dc.

Accept literal null trailer entries while rejecting actual or ambiguous encryption/hybrid markers. Structurally inspect bounded xref/trailer history instead of adopting trailer-looking comments. Preflight all selected source variants before editing/undo; preserve reset-to-defaults. Suppress stale unrewritable canvas overrides rather than revealing source content. Keep conservative all-content crop fallback without overcropping layerless/null stubs.

Validation: cargo xtask ci, all 9 gates passed; 3062 tests passed, 6 skipped; all 16 WASM-safe crates checked. 17 supported variants passed independent qpdf, logical preservation and Poppler pixel checks; 6 unsupported/repair-only cases refused. Direct-harness Claude Opus 5 reviewed the exact main-relative delta with no blocking findings.

No native-format changes or unrelated layer features. Synthetic regression fixtures are generated in test code.
2026-10-24 00:18:22 -06:00
andeecollard da8d3a2937 PDF: accept forward xref links and reject cycles 2026-10-23 19:19:20 +01:00
andeecollard 62a26d9e35 PDF: preserve catalogs and full references in layer variants 2026-10-23 17:47:18 +01:00
aiongg 3dbbcf2d07 Merge branch 'print-color' into print-color-separations
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	crates/engine/src/cmd/export.rs
#	crates/ui-egui/src/lib.rs
2026-10-23 05:52:56 +00:00
moppeeer 5d2db6f958 Merge remote-tracking branch 'origin/main' into effect-blend-modes
# Conflicts:
#	ROADMAP.md
2026-10-22 08:59:41 +02:00
Claude 899e48ce2e Merge remote-tracking branch 'upstream/main' into inline-objects-under-text 2026-10-21 21:42:48 +00:00
Hamza 0fc845750a An underline runs across a tab, as the rest of the line's text (#1466)
A tab draws nothing, so it was left out of the underline and strikethrough
bars: they stopped at the last letter before each tab and began again after it.
Forms rule their fill-in lines with underlined tabs — `Name ⇥⇥⇥⇥, city ⇥⇥⇥⇥` —
so an imported form lost every writing line, and an IDML `Underline="true"` on
a run of tabs drew nothing at all.

A tab is a character with an advance, and InDesign rules its whole width.
`PlacedGlyph::spans_rules` says which glyphs a rule runs across: the drawn
ones, and a tab or a right-indent tab that advances. The spaces a line break
trimmed off the end, the break characters and the markers' carriers are not
part of the line's text and are still skipped, so an underline stops at the
text and not at the frame edge.

Both places that draw the bars from the glyphs use it: the renderer
(`build_line`) and the PDF export (`text_rules`). The HTML and PPTX exports
mark up runs of text, which already included their tabs.

Measured on the repro in the issue, a 420×120 pt page at 2×:

  before   one underline, 63 px: the word "Name"
  now      three, 63 + 219 + 231 px: the word and both tab stretches

and the exported PDF gains the two fills for them. A tab with a leader is one
continuous bar across the leader dots to the right-aligned text after it.

Tests: the renderer's bars and the PDF export's bars for "Name<tab>City" are
one bar covering the tab's width, not two with a gap where it is. Both fail
without the change (two bars, 36→67.7 and 72→93.2, the tab's 67.7–72 unruled).
2026-10-21 20:04:12 +05:00
moppeeerandClaude Opus 5.5 75d72c69b5 Effects: blend modes for Drop Shadow, Inner Shadow and Outer Glow
As InDesign's Effects dialog › Blending › Mode: the shadows start Multiply
and the outer glow Screen in white; the renderer blends each with what's
behind it, the commands take mode, IDML reads and writes the drop shadow's
BlendMode. Effects saved before read Normal, as they were drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 08:28:10 +02:00
skylar taylor-barrick 1420d8c79b refactor(pdf): share placed-PDF rendering (PDFR) (#876) 2026-10-20 19:52:28 -06:00
aiongg 1284bf400d Merge print-color-preview into print-color-separations
Export PDF, File > Print and Separations Preview share one print
pipeline: print_pdf builds the print PDF of a set of pages (flattener,
rasterized layers and effects, PDF boxes, the writer, the blend space
outside print color), pdf_export adds Export PDF's view options for
file.exportPdf and file.print, and the preview separates print_pdf's
page per spread. Gradient stops on spot swatches resolve through the
same InkSet as fills (inks::spot_output). The hayro patches move to
craft-libs 8fbfea8 with craft-pdf, craft-prepress and krilla.
2026-10-20 13:50:13 +00:00
aiongg dd1f4b02ed Print color: Separations Preview shows the exported PDF's plates
Each visible spread is exported in memory as Export PDF writes it (its
print settings, the document bleed) and separated with
craft_prepress::plates off the UI thread, at a resolution matched to the
zoom. The canvas draws all inks composited, one plate as film or the ink
limit over gray; Window > Output > Separations Preview lists the plates,
spot plates by name, with each ink's percentage under the pointer.
view.separations takes spot ink names and reports the plates, ui.inspect
shows the preview's sheets, and ink.separations gives coverage and the
areas over an ink limit to automation. The renderer's GCR separation view
is gone; its plate passes stay for the CMYK blend space.
2026-10-20 13:30:14 +00:00
Claude afc6d31764 Inline objects paint under their frame's text
Anchored objects were painted after all of their frame's text, so an inline
picture whose frame reaches below its baseline (a negative Y offset, common in
IDML) covered the top of the next line with its white background. InDesign
paints them under the text. Both the renderer and the PDF export now draw a
frame's anchored objects after its paragraph shading and before its text.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
2026-10-17 16:15:32 +00:00
skylar taylor-barrick bc840130a4 Satisfy clippy's nonminimal_bool on rustc 1.96
Four sites already on main that `cargo xtask ci` cannot get past with the
current toolchain; each rewrite is the one clippy suggests and changes no
behaviour. `!x.is_some_and(f)` becomes `x.is_none_or(!f)`, and pdf_bounds
folds `!(a && b) || !c` into `!(a && b && c)` by De Morgan.

Unrelated to the merge they are committed beside; separated so that merge
stays a merge.
2026-10-16 20:20:36 -06:00