Commit Graph
2291 Commits
Author SHA1 Message Date
Brandon Thomas 50a6b60072 Merge PR #868 2026-10-14 12:39:59 -04:00
Brandon Thomas c8a8a1868d Merge PR #867 2026-10-14 12:39:59 -04:00
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
moppeeerandClaude Opus 5.5 cbba1fe7e1 Tools panel as InDesign's: Gradient Feather a tool of its own; two-column layout; View Options; Apply Color and Apply Gradient
Chris Nielsen's "The Adobe InDesign Toolbox" (InDesign 2020) walks the
Tools panel in one and two columns. Compared with it:

- Gradient Swatch and Gradient Feather are separate tools (one flyout
  here before).
- In two columns InDesign lays out Content Collector and Content Placer,
  Apply Color / Apply Gradient / Apply None and Normal / Preview (with
  Bleed, Slug, Presentation in its flyout) side by side
  (SPLIT_IN_TWO_COLUMNS). One column keeps one well with a flyout, which
  now names what is in front (Apply Color, Apply Gradient or Apply None).
- The utility button is View Options: Frame Edges, Rulers, Guides, Smart
  Guides, Baseline Grid and Hidden Characters, checked when shown, with
  their shortcuts (17:40). It was Text Frame Options (Object › Text Frame
  Options…, ⌘B, still opens it).
- Apply Color (,) applies the colour applied last ([Black] at first) and
  Apply Gradient (.) the gradient applied last, else the document's first,
  else white to black (InDesign's default), to the fill or stroke in front.
  The flyout had Apply Color as [Black] and no Apply Gradient.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:15:14 +02:00
aiongg 78340e6588 Canvas: tools show their own cursors (Direct Selection, Pen states)
Tool cursors are glyphs drawn in code (black ink, white halo): the filled
arrow for Selection, the hollow arrow for Direct Selection, the pen nib
with an add, delete, close or convert badge, and a curved double arrow
for rotating. Linux and Windows show them as OS cursor bitmaps,
rasterized per pixels-per-point and cached; macOS paints them at the
pointer, since it sizes cursor bitmaps in points; the web build keeps
the system cursors. Text, hand, zoom and resize cursors stay system
cursors.

The Pen tool reports what a click does: over the first anchor of the
path being drawn it closes the path, and between paths a click on a
selected path's anchor deletes it and a click on its outline adds one.
The Add, Delete and Convert Direction Point tools show the matching pen
badges.

The glyph geometry and the rasterizer are adapted from VectorCraft's
code-drawn tool cursors (same organisation, original work).

Fixes #438
2026-10-14 18:11:06 +02:00
aiongg 179a6c5f4e Tools panel: Selection is the filled arrow, Direct Selection the hollow one
Fixes #437
2026-10-14 17:59:20 +02:00
Claude 23105a6df9 Merge upstream main (0.8.0) into small-frame-wrap
Conflict: crates/compose/src/tests.rs, both sides added tests at the same place (upstream's #83 Jump Object tests, our tombstone tests); kept both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
2026-10-14 15:50:20 +00:00
Sean HammondandClaude Opus 5.5 54305b11eb Drop caps: scale with the cap's point size, as InDesign does
A drop cap came out the same size whatever its point size: the fit
(drop + body cap height) / (the cap's own cap height) cancels the cap's
size, since its own cap height grows with it. InDesign fits the cap as if
it were set at the body text's size and scales that by the cap's size over
the body's, keeping its baseline: a larger cap rises above the first line,
a smaller one falls short of it. Measured against an InDesign capture
(Palatino, 14 pt body, 18 pt italic T, 2 lines): cap height 2.04x the line
gap there, 2.03x predicted.

The cap's box (selection highlight, caret) now reaches the top of a cap
that rises above its line; selected glyphs are drawn inverted, so the part
outside the box would vanish. A one-line cap still keeps its own size
when that is smaller.

Test: drop_cap_scales_with_its_point_size (a 15 pt cap over 10 pt text is
1.5x the fitted height on the same baseline, 7.5 pt is 0.75x, the body
lines don't move, the box covers the cap). Before the fix the 15 pt cap
was 30.7 pt, the same as at 10 pt; with it, 46.05 pt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CgGsJkVe5GYG9qK6VFdECa
2026-10-14 15:37:43 +00:00
Marco Arnulfo 8ce1292d0e Footnotes: Span Footnotes Across Columns sets notes across the frame (fixes #915) 2026-10-14 17:04:51 +02:00
midasmatterhorn e9bda1f2d9 idml: cap IDML package part size on import instead of reading unbounded 2026-10-14 18:01:41 +03:00
Marco Arnulfo 52eac14f2c PDF: a placed PDF 1.7 with /Version /1.7 in its catalog goes into PDF/X-4 exports (fixes #907) 2026-10-14 16:48:52 +02:00
KnottyDyes 0d77f39443 Docs: explain hyphenation defaults and image fitting modes to agents
Command descriptions left the new-text hyphenation default and image fitting outcomes implicit. State the default and each fitting mode's semantics, and add an MCP example that disables hyphenation. No behavior changes.
2026-10-14 08:39:00 -06:00
Marco Arnulfo b12e94c11d Package: a missing link stays missing, with no empty file in Links/ (fixes #908) 2026-10-14 16:37:55 +02:00
Marco Arnulfo 455442615b Color parsing: bare CMYK is always 0..100, so C 1 is a 1 % tint (fixes #910) 2026-10-14 16:29:10 +02:00
noah1400 44b24d32ba Render: wide effect blurs are drawn at a lower resolution (#904)
A drop shadow, inner shadow or outer glow with a large size needed
gigabytes for one render: the multithreaded pipeline's offscreen image
grew by three times the blur on every side, and vello pads its own
filter layer by as much again, on single-threaded contexts too. A blur
wider than 1,024 device pixels is now drawn offscreen at a lower
resolution, where it is that wide, and scaled back up. It looks the
same, and both buffers stay close to the window's size.
2026-10-14 16:18:13 +02:00
Govinda RoyandClaude Opus 5.5 c7b3ee4f45 Layers panel: a new selection opens its layer and scrolls its row into view
Selecting an object on the canvas left the Layers panel as it was: its
layer could be closed and its row out of view. A new selection now opens
the layer it is on and scrolls its row into view once (closing or scrolling
afterwards is left alone); selected rows are highlighted, and an object
selected inside a group shows as its group. Unnamed image frames are listed
by their file name, as InDesign lists placed images.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:11:35 +06:00
Govinda RoyandClaude Opus 5.5 edb268af12 Text: kerning takes a typed value, and the Character panel has it
The kerning control in Properties was a menu of Metrics, Optical and 0:
manual kerning, which the engine already supports in 1/1000 em, couldn't
be entered, and the Character panel had no kerning at all (#896).

- One kerning control: its label shows Metrics, Optical, 0 or the manual
  value; its menu keeps the three choices and adds a number field with a
  spinner for a manual value (-1000 to 10000).
- Properties and the Character panel (next to Tracking) both use it.

Fixes #896.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 18:22:44 +06:00
moppeeerandClaude Opus 5.5 69240ab8c2 ui_shot: render every script line, so long scripts don't time out on the GPU
Replaying Chris Nielsen's "Numbering Page Sections" on a 50-page facing
document, a script that set seven sections without screenshots in
between ended in "render failed: PollError: The requested Wait timed out
before the submission was completed". Harness::step doesn't render, so
the texture changes of every frame (each edit redraws the Pages panel's
50 thumbnails) waited for the screenshot's render, which then uploaded
them all at once.

ui_shot now renders after each script line (the image is dropped), so
texture changes are applied as they come. The same script renders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:42:45 +02:00
moppeeerandClaude Opus 5.5 f4aa93f17d Type menu in InDesign's order; Character ⌘T, Paragraph ⌥⌘T and Current Page Number ⌥⇧⌘N
Chris Nielsen's "Numbering Page Sections" (2:09) reaches Insert Special
Character › Markers › Current Page Number through InDesign's Type menu:
Font, Size, Character, Paragraph, Tabs, Glyphs, Story, the style panels,
Create Outlines, Find Font, Change Case, Type on a Path, Notes, Track
Changes, the footnote and endnote items, Hyperlinks & Cross-References,
Text Variables, Bulleted & Numbered Lists, the insert submenus, Fill with
Placeholder Text and Show Hidden Characters. DesignCraft's began with Find/
Replace Font and Create Outlines and held alignment, Bold/Italic and point
size steps InDesign keeps out of its menus.

- Size ▸ (6–72 pt), Character, Paragraph, Glyphs, Character Styles,
  Paragraph Styles (InDesign's shortcuts: ⌘T, ⌥⌘T, ⌥⇧F11, ⇧⌘F11, ⌘F11),
  then InDesign's order. Notes ▸ holds New Note and the Notes panel.
- Current Page Number carries ⌥⇧⌘N (app.insertCurrentPageNumber).
- Alignment, Bold/Italic/Underline/All Caps, point size steps and
  Paragraph Rules leave the menu; their shortcuts and panel buttons stay.
- DesignCraft's math and CJK items follow after Show Hidden Characters.
- Labels "Bulleted & Numbered Lists" and "Show Hidden Characters", with
  translations.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:38:39 +02:00
moppeeerandClaude Opus 5.5 188c4f7007 Facing pages take their side from their section's page numbers
Chris Nielsen's "Numbering Page Sections" (7:03): starting a section at
page 1 on a left page (the spread 8–9 selected) turns it into a lone
right-hand page 1 in InDesign, and the pages after it shuffle. DesignCraft
kept the page on the left, so odd page numbers sat on left pages.

- Document::repaginate gives each facing page the side of its number in
  its section (odd: right, or left bound right to left). Document Setup's
  Start Page # is one case of it.
- layout.section repaginates when a section starts, changes or is removed;
  objects go with their pages, in one undo step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 12:03:58 +02:00
Ikki Nishihara adc03eedf0 Merge upstream main into fix/links-source-path-569
Resolve conflicts with the progress docs and the MCP reconnect test:
- ROADMAP.md: keep the upstream text-threads entry and add the Links source
  path entry (newest first, latest update date).
- crates/mcp/src/backend.rs: take upstream, which already carries the same
  nonblocking-socket fix, so this branch no longer changes the file.
2026-10-14 18:41:35 +09: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
Andres TorresiandClaude Opus 5.5 53374aab24 Type tool: dead keys and input-method composition on the canvas
Typing into a text frame never turned on the OS input method, so macOS
dead keys didn't compose: ⌥E then I typed "ei" instead of "í" (same for
⌥N, ⌥U and Japanese/Chinese input). The canvas now asks for the input
method while the Type tool has a caret and handles its events.

The text being composed shows in the story as an interaction preview
(new `text.compose` command), so it takes the format the next typed
character gets, drawn on a yellow box. On commit it's dropped and the
result typed with `text.insert` (one undo step); any other edit, tool
change or drag drops it first and tells the input method to forget it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:31:32 +01:00
moppeeerandClaude Opus 5.5 38b770230a docs: object.fit leaves locked objects and objects on locked layers as they are
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 11:31:30 +02:00
Gert Pellin 592e6026f4 EPUB fonts: skip bitmap-only fonts, and write the face's numeric weight
A font whose fsType allows embedding bitmaps only (bit 9, 0x0200) was
packaged with its outlines; it is now refused like a restricted one.
char_css wrote font-weight: bold for any style containing "bold", so
Semibold showed as Bold and Light as Regular; it now writes the numeric
weight (100-900) and style from the face's style name. Same approach as
aiongg's integration branch (#259, 8f54d1cc), with his test.
2026-10-14 11:19:31 +02:00
Gert Pellin 6e60bbccbe EPUB: read the cover image through a capped reader (256 MiB)
coverImage was read with an uncapped std::fs::read, so a huge file or a
device like /dev/zero could exhaust memory. Read it through the data
merge's capped reader, which now also stops the read itself at the cap
(a device reports no length), as in aiongg's integration branch (#259,
6eae3620), with /dev/zero as a test.
2026-10-14 11:09:11 +02:00
sanyamsingh001andCodex 17e280335a Merge tested main 0f4f382b0e into PR #458
Preserve the reviewed PR behavior and tested upstream base.

Co-Authored-By: Codex <codex@openai.com>
2026-10-14 19:08:24 +10:00
Gert Pellin 1ad6dd8e39 EPUB chapters: point in-document links at the chapter file of their target
After the split an href="#id" whose target ended up in another chapter
file is dead; endnotes (#798) end the book, so their #en-N / #enref-N
links cross files. Rewrite such links to file#id from the id-to-file
map, as in aiongg's integration branch (#259, 0b353c6f). The test calls
the rewrite directly, since note export comes with #798.
2026-10-14 11:02:52 +02:00
Gert Pellin 8f0a88f628 Merge branch 'fix/769-epub-nav-headings' into fix/768-epub-chapters
# Conflicts:
#	crates/epub/src/lib.rs
2026-10-14 10:56:59 +02:00
Gert Pellin b6a62dbd99 EPUB nav: keep a heading under its parent when it is shallower than the one before it
Headings h1, h3, h2 put the h2 at the top level: the loop closed every
level deeper than the new entry. Close a level only while its parent is
as deep as the new entry or deeper, as in aiongg's integration branch
(#259, bc9b89fc), with both nesting cases as tests.
2026-10-14 10:56:27 +02:00
moppeeerandClaude Opus 5.5 64c99b18d5 Merge origin/main into codex/handle-double-click-fit
Main moved double-click handling to the second press (click_count 2, from the mouse or the control channel); the handle double-click that fits the frame now sits there too, before main's text-frame edit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:43:58 +02:00
moppeeer f4dffb061d Merge remote-tracking branch 'origin/main' into codex/new-document-dialog
# Conflicts:
#	crates/ui-egui/src/dialogs.rs
2026-10-14 10:40:14 +02:00
a2c0cb79ce A radial gradient on a box with no width or height is a circle across it
Review fix from aiongg (6db40bdb, the radial_ellipse part), ported to this
branch: a straight line's box has no ellipse, so its stroke's radial
gradient showed only the last stop once #823's gradient strokes land.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:39:03 +02:00
f69601b0ff A linear gradient across a straight line runs along its length, on screen and in PDF alike
Review fix from aiongg (72d7ea2e, with the line tests of 6db40bdb), ported
to this branch: Fill::linear_axis gives screen and PDF one gradient axis,
and a box with no extent along the gradient's angle takes its longer side.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 10:36:45 +02:00
moppeeer 5f00aa7bb3 Merge remote-tracking branch 'origin/main' into codex/gradient-strokes
# Conflicts:
#	crates/engine/src/cmd/style.rs
#	crates/idml/src/tests.rs
2026-10-14 10:33:30 +02:00
moppeeer 52e0aaa2d6 Merge remote-tracking branch 'origin/main' into codex/radial-gradient-ellipse
# Conflicts:
#	crates/engine/src/cmd/style.rs
2026-10-14 10:32:47 +02: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
Andres TorresiandClaude Haiku 5.5 fbfc1dca76 feat(ui): the Typography panel has its own OT icon in the dock
The icon column's Typography entry reused the Character icon. It now uses an
"OT" glyph (panel-typography), and a test checks it is neither the placeholder
nor the Character icon.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-14 08:46:28 +01:00
Andres TorresiandClaude Haiku 5.5 be98657a22 feat(text): Typography panel lists and sets the OpenType features of the selection
A Typography panel (Window ▸ Show Panel, and the icon column) lists the
features of the selected text's fonts, merged over those fonts, grouped as
Ligatures, Alternates, Stylistic Sets (named by the font), Figure Style,
Figure Width, Figure Position and Capitals. A section or choice appears only
when a font offers it.

Each feature is a checkbox: checked when all of the selection has it, a dash
when only some of it does, empty when none does. A feature only some of the
selection's fonts offer is italic. Mutually exclusive choices are checkboxes
too, and choosing one turns the others off.

type.openTypeFeatures reports each feature's applied and available state over
the selection. type.feature turns features on or off across the selection,
keeping each run's other features. The fonts crate reads GSUB and GPOS
feature lists and stylistic set names.

The Character panel's OpenType menu is now a button that opens or focuses the
Typography panel.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-14 08:46:28 +01:00
aiongg 1758642a96 Integration: #870 the page menu always offers Delete Page for the clicked page, Delete Spread separately for multi-page spreads
(cherry picked from commit 9912a386a8)
2026-10-14 09:43:18 +02:00
moppeeer 02ddeb86da Merge branch 'codex/pages-panel-duplicate' into codex/pages-panel-menu 2026-10-14 09:43:10 +02:00
aiongg f4efb7cc5c Integration: #869 Alt-drag copies a page in one command and one undo step (layout.pages.duplicateSpread takes to)
(cherry picked from commit 7889b25a37)
2026-10-14 09:43:06 +02:00
moppeeer 15fccae6b8 Merge remote-tracking branch 'origin/main' into codex/pages-panel-duplicate
# Conflicts:
#	crates/engine/src/tests.rs
2026-10-14 09:39:45 +02:00