Commit Graph
4827 Commits
Author SHA1 Message Date
moppeeerandClaude Opus 5.5 7a30e5427e fix(render): radial gradients stretch with the object's box, as in InDesign
InDesign draws a radial gradient in the object's bounding box: on a
non-square frame it's an ellipse reaching the frame's sides, and a
Gradient Swatch tool drag keeps those proportions. LYH Studio episode 6
(3:16) gives the left page's background a radial gradient: magenta in
the middle, cyan out to every edge. DesignCraft drew a circle reaching
only the longer side, so a portrait page stayed purple at its sides.

- doc: `Fill::radial_ellipse(bounds)`: centre and radii (default: the
  box's centre and half its width and height; with a tool vector, its
  start, and its length measured with the box made square).
- render: the radial paint is that circle, stretched by the paint
  transform; PDF: the shading's transform does the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:58:05 +02:00
moppeeerandClaude Opus 5.5 19aa1c6f4c feat(swatches): New Swatch names a gradient "New Gradient Swatch"; gradient swatches from colour swatches
InDesign's Swatches panel New Swatch takes what is current: a gradient
built in the Gradient panel becomes "New Gradient Swatch" (applied, and
listed), an unnamed colour a listed swatch, a selected named swatch a
"… copy". DesignCraft's button always added the same orange swatch, and
gradient swatches could not be created at all (LYH Studio episode 6,
2:12: "this is our Swatch … create a new swatch for it").

- engine: `swatch.new {swatch?, target?}` does the above for the
  selection's fill (or stroke) or a named swatch; `swatch.create` also
  takes `gradient: {kind?, stops: [{location, swatch | color, opacity?,
  midpoint?}]}`, its stops taking colour swatches by name, as swatches
  dragged onto the Gradient panel's stops.
- Swatches panel: New Swatch runs `swatch.new`, and with nothing
  selected still adds a colour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:46:31 +02:00
moppeeerandClaude Opus 5.5 1527987a8e perf(render): CMYK ink passes cover only what transparency can change, with the render threads
- The two ink passes run over the area the spread's transparent objects
  (opacity, blend, effects, knockout, nested or anchored) and their
  effects' reach can change, not the whole view; the rest is drawn once,
  through the ordinary renderer, clipped out of that area. Objects the
  area touches join it whole, so no object is drawn partly through each
  colour conversion (no seam). A transparent parent-page item still
  takes the whole view.
- The ink passes get the render threads (effects keep their backdrop:
  with_blended_filters composites the offscreen filters with the blend).
- The view is kept in the 64 MiB cache only when the ink passes ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:26:38 +02:00
PiMinusMax 049ff99590 contributors: add PiMinusMax's display name 2026-10-13 15:23:33 +02:00
moppeeerandClaude Opus 5.5 0ba90118c7 fix(ui): the whole empty app bar moves the window; caption colours are theme tokens
- The window drags from any empty part of the bar: the gap between the
  menus and the tools, and the 7 pt lower band, which is always there,
  so at the 900 px minimum width (menus and tools filling the row) the
  window can still be moved. Menu titles and tools keep their clicks; a
  menu title pressed and dragged doesn't move the window.
- The Close button's hover fill and glyph are Tokens::caption_close and
  caption_close_text instead of fixed RGB values.
- BAR_H and LOWER_BAND replace the literal 36 (drag area, caption
  buttons, title centre).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:21:34 +02:00
PiMinusMax 1c82a5b892 File › Open Recent: recent documents in the menu and on the start screen (#706)
Opening or saving a document moves it to the front of File › Open Recent
(no duplicates; Save a Copy and exports don't count). The submenu lists the
files by name with the full path as tooltip, then Clear Recent Files; the
start screen shows the last eight with their folders. A file that is gone is
dimmed and, when chosen, says so in an alert and stays listed (a disk that
isn't connected comes back). Preferences › File Handling sets how many are
kept (default 20, 0–100).

Engine: Prefs.recent_files / recent_files_max (saved in prefs.json),
file.openRecent {index}, file.recentFiles, file.clearRecent. UI:
app.openRecent; the macOS menu bar rebuilds the submenu when the list
changes.
2026-10-13 15:13:18 +02:00
haranishi 8893344151 chore: mainとmacOS向けテスト修正を同期 (#319) 2026-10-13 22:12:19 +09:00
PiMinusMax d9b13ab702 fix: Cmd/Ctrl + the + key zooms the canvas, not the whole window
On layouts with a dedicated + key (German) or Shift+= (US), Zoom In's
Cmd+= arrives as Key::Plus. No shortcut matched it, so egui's built-in
keyboard zoom scaled the whole UI, and the UI-scale preference reset it
on the next frame. Plus now counts as = for shortcuts, and egui's
keyboard zoom is off since the UI scale is a preference.
2026-10-13 15:09:26 +02:00
moppeeerandClaude Opus 5.5 48f7ebfd50 fix(ui): Effects dialog: an empty field path sets nothing instead of panicking
set() sliced `&path[..path.len() - 1]`, which panics on an empty path;
split_last() returns early instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 15:08:54 +02:00
aiongg 578818466e Merge craft-cms: Colour management on craft-cms 2026-10-13 13:08:18 +00:00
aiongg fc31f7f14d Merge craft-cms-adoption: colour management on craft-cms (next's image path) 2026-10-13 13:07:32 +00:00
aiongg 73af5d7f63 Merge script-dollar: GREP replacements like $1 stay literal in scripts (#749)
# Conflicts:
#	ROADMAP.md
2026-10-13 13:01:31 +00:00
aiongg d227ee84e9 fix(script): only a well-formed $N reference is replaced; $$ is a literal $ (#749) 2026-10-13 13:00:34 +00:00
aiongg 18991a8fc2 Colour: effects goldens with Coated FOGRA39 swatch colours 2026-10-13 13:00:24 +00:00
sanyamsingh001andCodex 3ac4d2e913 Preserve endnote and editorial payloads in text slices
Co-Authored-By: Codex <codex@openai.com>
2026-10-13 22:59:29 +10:00
haranishi 027c986b65 test: Linksパネルのデバッグ用書き出しを除去 (#703) 2026-10-13 21:54:37 +09:00
Losminek 9ea463eb70 Merge remote-tracking branch 'upstream/main' into cs-pr 2026-10-13 14:53:24 +02:00
haranishi 0ca435b170 test: macOSのMCPテスト修正を取り込む (#454) 2026-10-13 21:50:25 +09:00
moppeeerandClaude Opus 5.5 61ea089149 feat(ui): Text Frame Options laid out as InDesign's, with its General options
InDesign's Text Frame Options has a section list (General, Baseline
Options, Column Rules, ...). General holds Columns (Fixed Number / Fixed
Width with Number, Width, Gutter), Balance Columns, Inset Spacing as a
2x2 grid with a link button, Vertical Justification and Ignore Text
Wrap; Baseline Options holds First Baseline Offset and Min. DesignCraft
showed one flat list without the columns type, width, balance, link,
ignore-wrap or baseline settings, although the model keeps them.

- dialogs: a section list (General, Baseline Options, Column Rules);
  General as above (Width shows what Fixed Number columns get, editable
  for Fixed Width; a side typed while linked sets all four insets);
  Baseline Options; Column Rules as before. Enum captions translated.
- OK sends the new fields only when edited, as before.
- engine: `object.textFrameOptions` takes `columnWidth` (Fixed Width)
  and `firstBaselineMin`, which compose already honours.

LYH Studio episode 14 sets two columns (9:45) and a 0.1875 in inset
(10:57) here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:46:54 +02:00
aiongg 44e5a28833 Integration (movable-dialogs x #683): test that the New Document window drags mostly aside and keeps its preview 2026-10-13 12:44:54 +00:00
Philipp Krüger f8474fa1c8 Merge branch 'main' into feat/pptx-export 2026-10-13 14:44:29 +02:00
aiongg cce067f4e1 Merge movable-dialogs: drag a dialog by its title to move it 2026-10-13 12:38:09 +00:00
moppeeerandClaude Opus 5.5 a59919bd24 feat(ui): Text Wrap panel with four offsets, link and Invert
InDesign's Text Wrap panel has the five wrap buttons with Invert, then
Top, Left, Bottom and Right offsets around a link button that makes them
all the same. DesignCraft's panel had a single Offset field that always
showed 0 (the object's offset was never read), and Invert only in
Properties.

- SelInfo carries the wrap offsets; the panel shows each side's value
  in the document's units and sets one side, or all four while linked
  (linked by default when they're equal).
- Invert sits next to the wrap buttons; fields are disabled without a
  wrap.

LYH Studio episode 14 (11:13) opens Window › Text Wrap to give the quote
a Jump Object wrap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:36:40 +02:00
aiongg b6c63d89c2 Colour: craft-cms for ICC transforms; Coated FOGRA39 default CMYK, BPC display, FOGRA39 output intent
- designcraft-color: ICC profiles (built-in RGB working spaces, user .icc files) go through
  craft-cms from storytold/craft-libs. The default CMYK working space is craft-cms's Coated
  FOGRA39; CMYK swatches show relative colorimetric with the settings' black point
  compensation. Generic CMYK and Device CMYK stay selectable. A CMYK profile name resolves
  through Builtin::stand_in_for; a name with no stand-in is an UnknownProfile error.
  ColorSettings::with_known_profiles replaces unavailable saved names with the defaults; the UI
  uses it when it restores saved settings at startup. Lab, gamut error and proofing of ICC CMYK
  spaces use craft-cms transforms. The Generic CMYK output profile is encoded by craft-cms.
- designcraft-pdf: the PDF/X output intent is the working CMYK space's profile: the FOGRA39
  built-in with identifier FOGRA39, user profiles as loaded, Generic CMYK otherwise.
- moxcms is no longer a direct dependency of designcraft-color.
2026-10-13 12:35:17 +00:00
aiongg 98c4022bf5 Integration: format 2026-10-13 12:32:27 +00:00
Fabio LussiandClaude Opus 5.5 3787187199 docs: re-verify against 0.7.1
- Open a file: missing IDML parts now open with an Import Warnings
  alert in the release; drop the "not in a release yet" note.
- Place: an image placed into a frame leaves Auto-Fit off (0.7.0).
- Install, supported systems: add the 32-bit Windows x86 builds and
  the RISC-V .deb and .rpm; example version 0.7.1.
- Set verified: 0.7.1 on every checked page.
- docs/user/CLAUDE.md: a regular file pointing to AGENTS.md instead of
  a symlink.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 14:31:48 +02:00
aiongg afd2f45b69 Merge pr/673: fix(import): preserve XLSX numeric and cached text values (#673) 2026-10-13 12:31:43 +00:00
aiongg 28b6be1a2d Integration (#703): links test assets and graphics carry pdf_crop/pdf_box and clip/wrap 2026-10-13 12:31:24 +00:00
aiongg 3d5fe33f6f Integration (#703): drop the links fixture capture 2026-10-13 12:30:40 +00:00
aiongg bf2a5b81a1 Merge pr/703: fix: show source paths in the Links panel (#703) 2026-10-13 12:30:26 +00:00
aiongg ac6177116b Merge pr/701: docs: fix the README font integration link (#701) 2026-10-13 12:30:04 +00:00
aiongg 354d1248fa Integration (#702): grouped reading-order test assets and graphics carry pdf_crop/pdf_box and clip/wrap 2026-10-13 12:29:59 +00:00
aiongg cd9886116d Merge pr/702: fix: use group transforms for HTML and EPUB reading order (#702) 2026-10-13 12:29:48 +00:00
moppeeer a255dc99b5 feat(tools): resize a selected placed graphic by its own handles (#699)
With a placed graphic selected (Direct Selection, or the content
grabber), the graphic's own brown bounding box has eight handles:
dragging one resizes the image inside its frame (Shift keeps its
proportions, Alt from its centre) and leaves the frame as it is.

- tools: a content-handle hit test on the selected graphic's bounds
  (after the frame's anchors under Direct Selection), a ContentResize
  drag previewing `transform.set {content, bounds}`, the handle cursors,
  and the content ghost while dragging. The frame's handles don't resize
  the frame while its graphic is selected.
- engine: `transform.set` takes `bounds` for content: the graphic's new
  bounding box on the spread (normalized, never empty).
- canvas: the brown content box gets its handles; the frame's handles
  are hidden while the graphic is selected.

(cherry picked from commit 8e0e6c2f2e)
2026-10-13 12:29:32 +00:00
aiongg c9a09989c8 feat(ui): a dragged dialog may go partly off-screen 2026-10-13 12:28:23 +00:00
aiongg 1533665af8 Merge pr/688: Create Outlines makes one compound path per line, so Ungroup separates the lines (#688) 2026-10-13 12:28:22 +00:00
aiongg 3f489a1273 Merge pr/689: Ungroup leaves frames with pasted-in content whole; name them by their shape (#689) 2026-10-13 12:27:49 +00:00
aiongg 0eb1ecfe1b Merge pr/691: Copy a selected placed graphic on its own, so Paste Into puts the whole image in place (#691) 2026-10-13 12:27:29 +00:00
aiongg bcad0182e5 Merge pr/698: Effects apply to frames with pasted-in content (Inner Glow, Basic Feather, shadows…) (#698) 2026-10-13 12:27:17 +00:00
aiongg 23eb86988f Merge pr/704: fix(tables): keep each table anchor in its own paragraph (#704) 2026-10-13 12:26:51 +00:00
aiongg 671c48caed Integration: indd-utils to 7f3060e5 2026-10-13 12:13:36 +00:00
aiongg 5f2110e7e5 Merge pr/687: Bump quick-xml to 0.41 (#687) 2026-10-13 12:13:14 +00:00
aiongg e3ee342a4a feat(ui): drag a dialog by its title to move it 2026-10-13 12:12:16 +00:00
aiongg d234ede3a2 Merge craft-atomic: Save: delegate atomic writes to craft-atomic 2026-10-13 12:12:16 +00:00
aiongg 004e585e34 Merge upstream main e862e0a6 into next 2026-10-13 12:11:25 +00:00
aiongg 2d0c2a5fc3 Colour: craft-cms from storytold/craft-libs main e9546e1 2026-10-13 12:03:50 +00:00
aiongg e81a21e645 refactor(save): delegate atomic writes to craft-atomic
The engine's atomic module keeps its functions and signatures and delegates to craft-libs/craft-atomic (pinned to e9546e19), so every save and export caller is unchanged. write_atomic_with also turns a panicking writer into an error, so its temporary file is removed. Recovery checkpoints and package output keep their own writers, which replace links instead of following them.

On Unix, new files follow the umask and replaced files keep their permissions.
2026-10-13 11:56:42 +00:00
aiongg 9c9f8afc69 ROADMAP: progress-log line for anchored settings and rotated group bounds 2026-10-13 11:54:36 +00:00
dotCooCoo 573e2da84a Swatches: dropping an .ase file on the window loads its swatches
open_dropped sent every dropped file that is not a document to
file.place, so a swatch exchange (.ase) file dropped on the desktop
window failed with a "Can't Place the File" alert: "invalid parameters
for `file.place`: unsupported or corrupt image".

open_dropped now sends .ase files to swatch.load with the dropped path,
as Load Swatches in the Swatches panel menu does with the picked path.
The web app already sent dropped .ase files to swatch.load. The
swatches are added to the active document as Load Swatches adds them,
and if the file can't be loaded, the status line shows the error.
2026-10-13 04:41:03 -07:00
haranishi 27302d8ea3 fix: Linksパネルにリンク元パスを表示 #569 2026-10-13 20:18:40 +09:00