Commit Graph
635 Commits
Author SHA1 Message Date
Brandon Thomas b8d975b094 Merge PR #866 2026-10-14 12:39:59 -04:00
Brandon Thomas 23aeddb354 Merge PR #864 2026-10-14 12:39:58 -04:00
Brandon Thomas c1a1970168 Merge PR #862 2026-10-14 12:39:58 -04:00
Brandon Thomas a6e7e2a0c7 Merge PR #838 2026-10-14 12:39:58 -04:00
Brandon Thomas e8a3cda237 Merge PR #836 2026-10-14 12:39:58 -04:00
Brandon Thomas d67fb28456 Merge PR #840 2026-10-14 12:39:58 -04:00
Brandon Thomas 6ceb57d4f5 Merge PR #845 2026-10-14 12:39:58 -04:00
Brandon Thomas 24e86db864 Merge PR #855 2026-10-14 12:39:58 -04:00
Brandon ThomasandClaude Opus 5.5 11a51d5b66 Release 0.8.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v0.8.0
2026-10-14 09:06:57 -04:00
sanyamsingh001andCodex 44485e08da Merge tested main 0f4f382b0e into PR #845
Preserve the reviewed PR behavior and tested upstream base.

Co-Authored-By: Codex <codex@openai.com>
2026-10-14 19:33:57 +10:00
moppeeerandClaude Opus 5.5 23e1680e7d feat(ui): Swatches panel header like InDesign's; swatches go to the fill or stroke in front
LYH Studio episode 6 colours the "1969" headline (8:28) and the loop's
stroke (9:15) from the Swatches panel, whose header holds InDesign's
Fill/Stroke proxy, Formatting Affects Container/Text and the Tint field.

- Header: a Fill/Stroke proxy showing the colours of what colour edits
  apply to (panels::color_target; a click brings the other to the front,
  as X does), the container/text buttons (app.formattingAffectsText) and
  the tint of the colour in front.
- The Tint field sends only the tint, so each selected object (or run of
  text) keeps its own swatch: object.fill takes a tint without a swatch,
  and a stroke tint alone doesn't give a stroke-less object a stroke.
- Clicking a swatch applies it to the fill or stroke in front
  (panels::apply_swatch, to the text when colours affect text); that row
  is highlighted.
- Bottom row: New Color Group, New Swatch, Delete Swatch (the swatch last
  clicked). Rows and the proxy are named for accessibility (and tests).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:27:38 +02:00
moppeeer 2a9e29f6ff Merge branch 'codex/page-tool-control-panel' into codex/liquid-object-pins
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:39:24 +02:00
aiongg 7d601b5903 Integration: #864 drops the Controlled by Parent rule from the menus and the Objects Move with Page checkbox (neither has an effect yet)
(cherry picked from commit 47b51d6377)
2026-10-14 09:38:25 +02:00
moppeeer 3f1eb00bb3 Merge branch 'codex/page-tool' into codex/page-tool-control-panel
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:38:16 +02:00
moppeeer 65dbf3c3a2 Merge remote-tracking branch 'origin/main' into codex/page-tool
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:37:32 +02:00
aiongg 87682c3674 Integration: #836 a grey stop beside a CMYK stop exports as the K ink, keeping the PDF shading in DeviceCMYK
(cherry picked from commit f28456d9d3)
2026-10-14 09:18:00 +02:00
moppeeer 25dadce9c8 Merge remote-tracking branch 'origin/main' into codex/fitting-shortcuts 2026-10-14 09:13:08 +02:00
moppeeer ed6bcae877 Merge remote-tracking branch 'origin/main' into codex/gradient-cmyk-blend 2026-10-14 09:12:51 +02:00
Brandon Thomas 43a46c04bf Merge PR #843 2026-10-14 01:54:43 -04:00
Brandon Thomas 80663cccfd Merge PR #846 2026-10-14 01:54:43 -04:00
Brandon Thomas b30b67dae3 Merge PR #834 2026-10-14 01:54:42 -04:00
Brandon Thomas 0421455b22 Merge PR #854 2026-10-14 01:54:41 -04:00
Brandon Thomas 9dc2068580 Merge PR #857 2026-10-14 01:54:41 -04:00
Brandon Thomas 21472519c0 Merge PR #858 2026-10-14 01:54:40 -04:00
Brandon Thomas c1ce6f77bf Merge PR #860 2026-10-14 01:54:39 -04:00
Brandon Thomas af6992dc65 Merge PR #837 2026-10-14 01:54:39 -04:00
Brandon Thomas 986c5487e9 Merge PR #849 2026-10-14 01:54:38 -04:00
Brandon Thomas d34384574c Merge PR #853 2026-10-14 01:54:37 -04:00
Brandon Thomas d83184f8b3 Merge PR #863 2026-10-14 01:54:37 -04:00
LabDennis ff5d866ff3 chore(sync): merge upstream main into PR #854 2026-10-14 06:51:45 +02:00
0f4f382b0e feat(text): improve editing, snapping, and threading
Add multi-click text selection, pending caret formatting and clipboard support, text-aware colour controls, guide/grid snapping, and frame threading with loaded-port interactions.

Include the layout, drop-cap and IDML updates carried from #83, with safeguards for generated and linked stories, external text references, local IDs, locked frames and atomic colour edits.

Fixes #23.

Co-authored-by: Sean Hammond <sean.hammond@und.edu>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:41:46 -06:00
moppeeerandClaude Opus 5.5 8f71219533 feat(tools): Page tool pins and locks objects on object-based pages, on the canvas
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (6:32–
9:58) clicks an object with the Page tool on an object-based page and
gets InDesign's on-canvas liquid controls: a pin outside each edge
("Object is pinned relative to the page edge. Click to release.") and a
padlock on the width and height lines ("The object's width is locked.
Click to let the object change width as the page changes width."). The
pins and resize settings existed (liquid.object, the Liquid Layout
panel) but the canvas showed none of it.

- tools: on an object-based page a Page tool click selects the object
  with its page (layout.selectPage takes `ids`); its pins (14 px outside
  each edge's middle) and width/height locks (beside the centre) toggle
  liquid.object on click, show InDesign's tooltips on hover and a hand
  cursor.
- canvas: LiquidPins (orange dashed width/height lines with padlocks,
  open when the object follows the page; hollow pins, or a line to the
  page edge when pinned) and Tip overlays; tooltip translations.

Builds on the Page tool PR (#862).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 01:21:51 +02:00
moppeeerandClaude Opus 5.5 8864307d7c docs: the Page tool's Control panel in the parity notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:52:06 +02:00
moppeeerandClaude Opus 5.5 59b6125af1 feat(ui): Control panel for the Page tool; Controlled by Parent; Show Parent Page Overlay
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (1:02–
2:06, 13:47) sizes pages from the Control panel with the Page tool
selected: X/Y, W/H, the page-size preset ("US Business Card"),
orientation, Liquid Page Rule ("Controlled by Parent"), Objects Move with
Page and Show Parent Page Overlay. DesignCraft's Control panel showed the
(empty) object controls.

- ui: with the Page tool, the Control panel shows the selected page (or
  the page in view): the reference point (W/H, preset and orientation
  keep it in place via layout.pageSize's anchor), X/Y (read-only),
  W/H, the preset dropdown, portrait/landscape, Liquid Page Rule, Objects
  Move with Page (always on: pages don't move within spreads yet) and
  Show Parent Page Overlay.
- doc: LiquidRule::ControlledByParent (the parent page's rule, Off
  without one; resolved by liquid::effective_rule); Page.show_parent_overlay.
- engine: layout.pageOptions {pages, showParentOverlay}; liquid.pageRule
  takes controlledByParent.
- canvas: the parent page's size over a page with the overlay on.
- Liquid Layout panel and Control panel share InDesign's rule list
  (Off, Scale, Re-center, Object-based, Guide-based, Controlled by
  Parent); "US Business Card" preset; translations.

Builds on the Page tool PR (#862) for the selected page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:51:47 +02:00
noah1400 554019cdd5 Tables: table.options limits header and footer rows (#861)
table.options added as many rows as the requested header and footer
counts needed, without a limit. A large number typed into the Table
panel's Header Rows field froze the app and exhausted memory. Both
counts are now capped at 100, the limit table.insert already has.
2026-10-14 00:32:16 +02:00
moppeeerandClaude Opus 5.5 cc13e80c9d feat(tools): Page tool selects pages; handles preview the liquid rule, Alt-drag resizes
Chris Cicchino's "Adobe InDesign – Page Tool and Liquid Layout" (0:42–
2:06) selects a page with the Page tool, gets its bounding box with
handles, drags a handle (the page springs back: a liquid-rule preview),
holds Option to really resize it, Shift for proportions, and reads the
size in a tooltip by the cursor. DesignCraft's Page tool only opened a
generic Page Size dialog on click.

- tools: the Page tool selects the page under a click (none on the
  pasteboard); the selected page shows its outline, eight handles and
  its liquid page rule ("Scale", "Object-Based"…) above it. Dragging a
  handle previews layout.pageSize (the liquid rule re-flows the
  objects) and springs back on release; Alt resizes, Shift keeps the
  proportions; a W/H readout follows the pointer; resize cursors on the
  handles. Double-click a page for the Page Size dialog.
- doc: Selection.page (the Page tool's page); engine: layout.selectPage
  (no undo step).
- layout.pageSize `anchor` (0-8): the page grows away from the
  reference point and its objects and guides keep their place relative
  to it (a handle drag anchors the opposite edge); liquid rules work
  from that.
- canvas: PageHandles and Tag overlays; translations for the tags and
  the Resize Page undo label.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:29:55 +02:00
Seon-Jin YoonandClaude Opus 5.5 0aaaa9600d fix(compose): odd/even page starts keep their parity at the top of a frame
Start options were skipped for a paragraph at the top of a frame. That is
right for Next Page, Next Frame and Next Column (there is nothing to break
away from), but a Next Odd Page paragraph that lands at the top of an even
page stayed there, as did Next Even Page at the top of an odd page, and the
same went for odd and even page break characters. A part or chapter opener
whose previous section ended exactly at the bottom of an odd page therefore
opened on a left-hand page.

Cursor::start_at_top now moves such a paragraph to the next page of the
asked parity, for paragraphs, tables and break characters alike. Other
start options at the top of a frame are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 07:12:08 +09:00
sanyamsingh001andCodex bfa536352d FIX-CHILD-NOTE-PASTE: filter unsupported markers in child stories
Co-Authored-By: Codex <codex@openai.com>
2026-10-14 07:54:46 +10:00
Daniel van LithandClaude Opus 5.5 1e153c5c45 macOS DMG: hdiutil create -srcfolder, so the app inside passes codesign --strict
makehybrid -hfs gave every file in the image a com.apple.FinderInfo, so the app in the
DMG, and a copy installed from it, failed codesign --verify --strict --deep ("resource
fork, Finder information, or similar detritus not allowed"), though Gatekeeper accepts
it. Build the image as VectorCraft (#1085) and PdfCraft (#823) do now: hdiutil create
-srcfolder with a few tries for CI's "Resource busy", and verify the mounted app with
--strict --deep so the regression can't ship again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:36:52 +13:00
harrisonoconnorhover 2d07bc5295 fix: refresh canvas when switching parent editing 2026-10-13 17:28:38 -04:00
LabDennis 0fd627aa44 perf(assets): index duplicate candidates by content (#727) 2026-10-13 23:12:09 +02:00
noah1400 1bddba0e75 Compose: cross-reference index no longer rebuilds itself (#851)
The cross-reference index composed its destination stories through
the cache. One with a running header asked for the running-header
index, which composed the story holding the cross-reference, which
asked for the cross-reference index again: the stack overflowed and
the app aborted. Destination stories with a running header are now
composed without it, like those with cross-references already were.
2026-10-13 23:07:21 +02:00
noah1400 3539a72b2f Canvas: baseline grid draws only the lines on the page (#844)
The grid was walked from its start, one line per step, with no
bound. A start far above the page (from document.preferences, a
saved file or an IDML package) made the next frame draw lines until
the app ran out of memory. The lines are now the ones inside the
page, found without walking those above it, and never more than one
per point of the tallest page.
2026-10-13 22:23:48 +02:00
sanyamsingh001andCodex f4f2f0bb08 FIX-TABLE-SELECTION: resolve selected merged-cell owners
Co-Authored-By: Codex <codex@openai.com>
2026-10-14 06:20:41 +10:00
sanyamsingh001andCodex 4760a000db PARITY-FIND-SCOPE: respect search scope and first-match limits
Co-Authored-By: Codex <codex@openai.com>
2026-10-14 06:16:28 +10:00
dotCooCoo 7a89954937 Placed PDFs: render with pdfcraft's patched hayro crates
Placed PDFs rendered through hayro 0.7 from crates.io, whose
hayro-interpret divides integers in calculator functions without a
check, does not limit how deep functions nest and samples each mesh
triangle over its whole bounding box. A placed PDF whose calculator
function runs `1 0 idiv` or `-2147483648 -1 idiv` panicked the render.
A chain of 100,000 functions, each stitching function naming the next,
overflowed the stack and aborted the process. Mesh shadings with points
far off the page, ten thousand overlapping triangles or forty thousand
patches ran for over a minute or passed 2 GiB of memory.

[patch.crates-io] now takes hayro, hayro-interpret, hayro-syntax and
hayro-jbig2 from pdfcraft's vendor/ directory at b5467d93, with the
patches its vendor/README.md lists. The crate versions do not change.
The patched hayro-syntax sizes a page with a /UserUnit in points, and
pdf_page_box scales the page's boxes by the same unit, so with Crop to
the frame still shows the chosen box. NOTICE names the new source and
the licenses. The function and mesh tests in
crates/render/tests/placed_pdf.rs follow pdfcraft's tests in
crates/render/src/raster.rs.
2026-10-13 12:52:10 -07:00
moppeeerandClaude Opus 5.5 08386d03b1 feat(ui): Object > Fitting with InDesign's shortcuts
LYH Studio episode 6 (7:00) fills its photo frames with the caption
"Fit Content to Frame (Ctrl + Shift + Alt + C)", InDesign's shortcut for
Fill Frame Proportionally. DesignCraft's Fitting items were object.fit
variants without shortcuts (a menu shortcut belongs to a command id, and
the five modes share one).

- Five UI commands, one per mode, with InDesign's keys:
  fit.fillFrameProportionally Cmd+Alt+Shift+C,
  fit.contentProportionally Cmd+Alt+Shift+E, fit.frameToContent
  Cmd+Alt+C, fit.contentToFrame Cmd+Alt+E, fit.centerContent
  Cmd+Shift+E (Ctrl on Windows and Linux); each runs object.fit.
- Object > Fitting lists them (with their shortcuts), enabled as
  object.fit is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 21:15:35 +02:00
moppeeerandClaude Opus 5.5 dc712baeca fix(color): gradients between process colours blend as inks, as InDesign shows them
LYH Studio episode 6 builds every gradient from C=0 M=100 Y=0 K=0 to
C=100 M=0 Y=0 K=0. InDesign blends a gradient's process stops as inks:
halfway is C 50 M 50, a light lilac. DesignCraft converted both ends to
RGB and blended there, so the middle came out a darker violet (117, 88,
189 instead of 135, 119, 181), and every Episode 6 gradient looked
different. A midpoint between CMYK stops also became an RGB colour, so
the PDF shading turned RGB with a conversion warning.

- color: `Color::lerp` blends CMYK with CMYK (or grey), and grey with
  grey, in ink space; anything with RGB still blends in RGB.
- `Gradient::display_stops`: the expanded stops plus samples through
  each span that isn't RGB at both ends, for renderers that interpolate
  in RGB; the screen renderer uses it.
- pdf: a midpoint's expanded stop now keeps the stops' space; the
  colour-space test expects no conversion for CMYK or grey midpoints.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 20:38:38 +02:00
noah1400 ba4519c382 Preferences: Story Editor size stays finite and in range (#821)
Preferences OK stored whatever number the dialog held as the Story
Editor font size. One that is not finite ("nan", "inf", or a number
too large for an f32) was written to ui.json as null; the next launch
could not read the file, started with the default UI settings and
saved them over it on exit. The size is now kept between 8 and 36 pt,
the slider's range, and a value that is not a finite number leaves
the size as it was.
2026-10-13 20:31:54 +02:00
Govinda RoyandClaude Opus 5.5 677cafbf9c Images: EPS shows through its proxy at display time; simple PostScript (QR codes) is drawn
An EPS that came in with a document (InDesign embeds its QR codes as
EPS) drew nothing: only File › Place converted EPS to a proxy. Now
`decode_rgba` draws any EPS through `eps_proxy` and `natural_size` measures
it by its bounding box in points, so screen, PNG and PDF show it while the
document keeps the EPS itself.

`eps_proxy` also draws PostScript that only fills rectangles in solid
colours (setcmykcolor, setrgbcolor, setgray, rectfill and procedures that
stand for them, as InDesign's QR codes are written), at 8 px per point so
modules stay crisp. Anything else keeps the preview or placeholder. Input is
bounded: tokens, rectangles, painted area and procedure definitions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 00:26:02 +06:00