Commit Graph
132 Commits
Author SHA1 Message Date
aiongg 527e5cbc0c Merge main: atomic desktop and CLI exports, staged book updates, recovery checkpoint retention, exit recovery
upstream/main c3859c82 (#614 e198eb5d, #615 9509b2bc, #616 8e151a2f, #617 c3859c82).

Conflict: ROADMAP.md: header keeps next's change list plus orderly native exit recovery; progress log both
Conflict: apps/designcraft-cli/src/main.rs: next's case-insensitive .jpg/.jpeg check with main's write_atomic
Conflict: apps/designcraft/src/main.rs: on_exit keeps next's startup.presented() (not an Option) and adds preserve_documents_on_exit; next's discard_marked_text and main's preserve_documents_on_exit both; Services write uses write_atomic and keeps next's clipboard_text; tests both
Conflict: crates/engine/src/cmd/book.rs: main's ChapterBatch paginate with next's chapter-number resolution and {pages, chapters} result and doc
Conflict: crates/engine/src/cmd/file.rs: revert takes main's discard_document ordering without the revision + 1 (next's DocState::new hands out a fresh revision)
Conflict: crates/engine/src/recovery.rs: main's save_tracked, write_entry and open (st.bump_revision() for next's global revisions); next's reopen-twice test assertions kept
Conflict: docs/gaps.md, docs/target-app-parity.md: headers combined; next's Language, Books and Numbering lines plus main's book update safety line
2026-10-12 19:46:34 +00:00
skylar taylor-barrick c3859c828b fix(recovery): preserve documents on orderly app exit
Checkpoint the latest document state during App::on_exit after honoring current quit approvals. Keep incomplete or stale plans, clear recovery for clean documents and report unavailable or failed storage.

Follow-up to #545; cancelable macOS Dock Quit remains open in #544.

PR #617.
2026-10-12 12:18:32 -06:00
skylar taylor-barrick e198eb5d1d fix(export): replace desktop and CLI outputs atomically
Route desktop writes and CLI raster exports through the engine atomic writer. Add actual-caller regressions for reader visibility, private modes, symlinks and valid long filenames.

Follow-up to #485.

PR #614.
2026-10-12 12:04:39 -06:00
aiongg 3719470140 Integration: format 2026-10-12 17:26:21 +00:00
aiongg 3ac3bc90de Merge main (0.7.1): atomic saves, recovery per instance, quit keeps documents when cancelled
Conflict: crates/engine/src/atomic.rs: main's side (the reviewed #485 code supersedes the PR head on next)
Conflict: crates/engine/src/recovery.rs: main's #506 code, with next's write_entry helper kept
Conflict: apps/designcraft/src/profile.rs: main's own_run returning Option (and_then), with next's portable root_with argument
Conflict: crates/ui-egui/src/lib.rs: main's QuitState quit flow (d020b4e8) over the #545 head; next's Find Font alert guard; one import_warning_tests module (next's, with the Find Font test)
Conflict: apps/designcraft/src/native_menu.rs: next's MAC_APP_MENU layout, which already has the dc-quit item running app.quit
Conflict: ROADMAP.md: next's header with the quit change added; next's log entries then main's three
Conflict: docs/target-app-parity.md: main's atomic save, recovery and quit lines
2026-10-12 17:14:07 +00:00
d020b4e85d fix(ui): preserve documents when quitting is cancelled
Prompt for unsaved documents on window close and application/menu quit. Defer discarding documents until all approvals are current, retaining every tab when a later decision cancels quitting.

Refs #544. Cancelable macOS Dock Quit remains separate.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:31:24 -06:00
Noah Scholzandskylar taylor-barrick 328b4d5a52 fix(recovery): isolate recovery data between app instances
Keep each app's recovery data in an owned run folder. Validate current folder and lock ownership and disable recovery when isolation fails instead of using the shared root.

Fixes #496.

Co-authored-by: noah1400 <48360809+noah1400@users.noreply.github.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:26:34 -06:00
aiongg 6d2163d497 Merge #580 (update): portable mode needs a writable DesignCraftData
Conflict: apps/designcraft/src/main.rs: next's catch_unwind/run_native app creator kept; the portable note is set after load_prefs inside it
2026-10-12 14:41:07 +00:00
Marco Arnulfo 1207ab14d3 feat(desktop): portable mode needs a writable DesignCraftData (#574)
A portable copy unzipped into a read-only folder such as Program Files
kept pointing settings and recovery at a DesignCraftData it could not
write, so both were lost without a word. The data folder is now probed
(created, then a file written and removed) and, when that fails, the
platform folders are used as if there were no portable.txt; the log and
the status bar say which folder could not be written.
DESIGNCRAFT_CONFIG_DIR still wins. Adds
a_portable_install_that_cannot_write_its_data_uses_the_platform_paths.
2026-10-12 16:30:58 +02:00
aiongg 1f90703104 Integration: format
rustfmt on the merged recovery_dir (#580 root_with with next's own_run).
2026-10-12 14:17:48 +00:00
aiongg 814153ba62 Merge #580: feat(desktop): portable mode, portable.txt next to the executable (#574)
Conflict: apps/designcraft/src/profile.rs: recovery_dir takes the PR's root_with (config override, else portable folder) and keeps next's .map(own_run) and own_run
Conflict: README.md: the PR's Portable mode section, then next's Graphics backend and processor section
2026-10-12 14:17:27 +00:00
Marco Arnulfo b4eedc42eb feat(desktop): portable mode looks next to DesignCraft.app on macOS (#574)
Inside a macOS bundle the executable sits in DesignCraft.app/Contents/MacOS,
a signed folder nobody edits, so the marker and DesignCraftData are looked
for next to the .app, as craft-settings does. Adds
inside_a_macos_bundle_the_marker_sits_next_to_the_app.
2026-10-12 15:09:02 +02:00
Marco Arnulfo 4acd5ba43c feat(desktop): portable mode, portable.txt next to the executable (#574)
A file named portable.txt beside the executable keeps settings, logs,
the GPU start-up record and crash recovery in a DesignCraftData folder
next to it instead of the per-user folders, as PhotoCraft and FilmCraft
do. A folder of that name is not a marker. DESIGNCRAFT_CONFIG_DIR still
wins, empty or not. The Windows portable zip now ships portable.txt;
the MSI and the macOS app bundle don't, so nothing changes there.
2026-10-12 13:45:05 +02:00
aiongg af389f9a0b Merge clipping-paths: Images: clipping paths from IDML clip the image on screen and in PDF
Conflict: ROADMAP.md: both progress lines
Conflict: docs/gaps.md: next's header, clipping paths added to its change list
Conflict: docs/target-app-parity.md: next's header, clipping paths added to its change list
Conflict: crates/doc/src/item.rs: both Graphic methods (next's shown_bounds, the branch's clip_region)
Conflict: crates/idml/src/names.rs: both imports (ClippingKind, ContourType)
Conflict: crates/idml/src/export.rs: both pushes, TextWrapPreference first, then the clipping settings
Conflict: crates/idml/src/import.rs: both lets (next's wrap, the branch's clip)
Conflict: crates/engine/src/cmd/file.rs: next's size and transform, plus clip: None
Conflict: crates/engine/src/cmd/datamerge/fill.rs: next's Graphic with wrap, plus clip: None
Conflict: crates/engine/src/cmd/mathexpr.rs: next's Graphic with wrap, plus clip: None
Conflict: crates/pdf/src/tests.rs: both tests
2026-10-12 05:37:19 +00:00
aiongg e111bb74f7 Images: declare a graphic's clipping path beside its transform 2026-10-12 05:32:11 +00:00
aiongg 8125f2490b Images: clipping paths from IDML clip the image on screen and in PDF
A placed graphic keeps its clipping path (Detect Edges, Alpha Channel,
Photoshop Path or User-Modified Path) in graphic space, with the
options IDML carries. IDML import reads ClippingPathSettings and its
saved ClippingPathGeometry (anchors capped, non-finite subpaths
dropped); export writes them back. The canvas and PDF export clip the
image to the path inside the frame clip; an inverted path shows the
image outside it. Without saved geometry nothing changes.

object.clippingPathOptions reports a graphic's clipping path, inverts
it or removes it (Object > Clipping Path > None).

Fixes #450.
2026-10-12 05:31:03 +00:00
aiongg c0b28a4478 Merge quit-unsaved: quitting asks to save documents with unsaved changes (#544)
Conflict: apps/designcraft/src/native_menu.rs: next's MAC_APP_MENU loop without the Quit arm; menus.rs MAC_APP_MENU ends with a dc-quit Cmd row running app.quit (AppMenuItem::Quit removed)
Conflict: crates/ui-egui/src/lib.rs: DesignApp fields, initialisers and tests keep both sides
2026-10-12 00:38:50 +00:00
aiongg 6aada5b74a UI: quitting asks to save documents with unsaved changes (#544)
Closing the window or Quit (Cmd+Q, now a menu command instead of the predefined
terminate item) asks about each unsaved document: Save, Don't Save or Cancel.
The control channel's app.quit still quits without asking.
2026-10-12 00:37:32 +00:00
aiongg ee2f4dffd6 Merge #506: Recovery: each running app keeps its own recovery data 2026-10-11 16:36:07 +00:00
noah1400 257fb08dbd Recovery: each running app keeps its own recovery data (#496)
Document uids start at 1 in every process, and every running app wrote
its recovery entries into the one recovery folder. Two apps wrote over
each other's `1.designcraft`, and an app that started reopened and
removed the entries of one still running.

A run now has a folder of its own in the recovery folder and holds a
lock in it for as long as it runs. An app that starts moves the entries
of runs that have ended, and those an earlier version wrote, into its
folder and reopens them. A locked folder is left alone.
2026-10-11 16:55:39 +02:00
aiongg 10d32f0b01 Integration: Interface Language lives in Preferences on next's Russian and macOS menu bar
prefs-language removes the Edit › Interface Language submenu; next added Russian and rebuilds
the macOS menu bar when the language changes (#397).
- de.rs and ru.rs drop their "Edit/Interface Language" path entries, as ja.rs does.
- The Russian language test checks the Preferences list instead of the removed submenu.
- app.language's params doc lists ru and says the macOS menu bar follows at once.
- native_menu.rs: the rebuild comment names Preferences and Cancel, which change
  `app.ui.language` and so reach the same rebuild in `NativeMenu::poll`.
2026-10-11 14:13:23 +00:00
aiongg bbf7ea975f Merge mac-titlebar update: macOS: dragging a title-bar control no longer moves the window
Conflict: apps/designcraft/Cargo.toml: one objc2/objc2-app-kit entry with next's NSTextInputContext and the branch's NSApplication/NSResponder/NSWindow features; next's fmv-macos-events kept
Conflict: apps/designcraft/src/main.rs: next's App fields, GPU startup, IME discard and Apple events kept; the branch's `movable` field and `mac_window::sync_movable` call added before `startup.leave()`
2026-10-11 14:10:18 +00:00
aiongg 44f3f304a5 macOS: dragging a title-bar control no longer moves the window
AppKit moves the window when a drag starts anywhere in the title-bar band
of a full-size content view, on the application bar's controls too. The
title bar now reports whether the pointer is on one of its controls
(title_bar::window_movable), and the macOS app sets the window's movable
flag from it each frame it changes, through objc2-app-kit's safe methods
(the versions muda already uses). Home, the menus, search, the workspace
menu, Share and Discord keep their drags; empty bar space still moves the
window, and so does the band while a modal covers the bar.
2026-10-11 13:40:28 +00:00
aiongg fc40ffed2c Merge #475: CLI: --export writes the file type its extension names 2026-10-11 12:23:53 +00:00
noah1400andClaude Opus 5.5 40e8dbc6fb CLI: --pdf-options that is no JSON object is an error
`run --pdf-options '[1]' --export a.pdf` panicked when the PDF's path
was added to the options (exit status 101). The value is now checked
where it is read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:55:20 +02:00
noah1400andClaude Opus 5.5 8547a9fca4 CLI: --export writes the file type its extension names (#432)
--export knew .pdf, .epub, .idml and .designcraft and saved a PNG of
the page under every other name: out.html, out.txt, OUT.PDF, and
out.designcraft from `script`. The exit status was 0.

.html and .htm now run file.exportHtml, .rtf and .txt run
file.exportText (the story being edited or of the selected frame), and
extensions match in any case. A name with another extension is an
error before anything runs; one with no extension is still a PNG.
`run` and `script` share one list, and `script` saves a copy for
.designcraft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:55:05 +02:00
aiongg 2fae23fcc6 Merge atomic-save: MCP: exported files replace the target atomically (#436)
Conflict: ROADMAP.md: both progress-log entries, next's newer ones first
Conflict: apps/designcraft/src/gpu.rs: next's side; the branch's test fix targets the startup record tests next replaced
Conflict: apps/designcraft/src/main.rs: next's gpu startup and macOS IME helper; config_dir() dropped for the branch's profile::config_dir(), recovery_dir from profile::recovery_dir()
Conflict: crates/ui-egui/src/canvas.rs: next's guard (menu_open, keyboard_pane already limits keys to the focused pane)
Conflict: crates/ui-egui/src/lib.rs: modules from both sides
2026-10-11 05:16:10 +00:00
aiongg 7935c60617 Merge mac-app-menu: macOS: Settings… is in the app menu
No conflicts. native_menu.rs merged automatically: install() builds the
app menu from MAC_APP_MENU and the bar from native_menu_tree(), and
next's poll() rebuilds through install() when the language or Show CJK
Features changes, so a rebuilt menu has the same app menu and keeps
dc-settings in its items map.
2026-10-11 02:53:33 +00:00
aiongg 60f2c597a5 macOS: Settings… is in the app menu
The macOS menu bar shows Settings… (app.preferences, Cmd+K) in the application menu after About and leaves it out of Edit. The app menu labels go through the interface language. Windows, Linux and the web keep Edit › Preferences….
2026-10-11 02:34:49 +00:00
skylar taylor-barrick 2bdb0ea01d UI.9: recover saved docking metadata and declare frontend MSRV 2026-10-10 18:52:20 -06:00
aiongg 0c1d021dfd Integration: macOS menu bar rebuilds when Show CJK Features changes (#397, #336)
NativeMenu keys its rebuild on (language, cjk_features(app)), so the
CJK commands that menus::shown filters appear or disappear at once.
2026-10-10 23:24:57 +00:00
aiongg 3667fcc3a3 Merge #397: macOS menu bar follows the interface language at once
No conflicts.
2026-10-10 23:24:36 +00:00
aiongg 62df5e764a Merge file-open-os: Save adds .designcraft, and the OS opens DesignCraft and IDML files
- apps/designcraft/Cargo.toml: the macOS target keeps objc2 0.6 / objc2-app-kit 0.3 (IME) and
  adds fmv-macos-events =0.1.0, which uses the same objc2 and objc2-app-kit versions.
- apps/designcraft/src/main.rs: the shared Arc<gpu::Startup>, catch_unwind and restart flow
  stay; the Apple-event handlers are installed before run_native (outside catch_unwind, held
  until the window ends), the app drains the inbox each frame, and documents that arrived are
  noted on the Startup. The open dialog keeps the INDD/INDT filter and ends with All files.
  The open-filter test checks both; the save-dialog test is added.
- apps/designcraft/src/gpu.rs: Startup::opening records the documents the OS handed this run;
  a start again after a graphics failure (both finish and the first-frame watch) passes them
  as file arguments, since Finder doesn't send them twice.
- apps/designcraft/src/apple_events.rs: poll returns the documents it handed the app, and
  queued() returns those still in the inbox when the window ends.
- crates/engine/src/cmd/file.rs: file.open decides by content first (IDML by its mimetype
  entry, then a DesignCraft package or JSON), then an InDesign file by its signature or
  .indd/.indt extension, then a .idml or .designcraft extension for the reader's own error;
  anything else is "not a DesignCraft or IDML file". INDD stays in file.openBytes. Save
  commands add .designcraft as on file-open-os; the params docs describe all of it.
- crates/engine/src/cmd/mod.rs: re-exports from both sides (is_document,
  with_document_extension and layout::chapter_numbering).
2026-10-10 23:21:12 +00:00
con3codeandClaude Opus 5.5 cc12ea576f macOS: the menu bar follows the interface language at once
The system menu bar was built once at launch, so Edit › Interface
Language changed the panels but left the menus in the old language
until the next launch. It is rebuilt when the language changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013phQ3ekq6uGBEWD6FjFYG2
2026-10-11 07:49:21 +09:00
aiongg 11532d961e Documents: Save adds .designcraft, and the OS opens DesignCraft and IDML files
- file.save / file.saveAs / file.saveACopy add the .designcraft extension to a
  given path that lacks it and report the path written; saving back to the
  document's own file keeps its name.
- file.open tells DesignCraft and IDML packages apart by content, so files
  without an extension open; anything else is "not a DesignCraft or IDML file".
- Dropped or web-picked files without an extension open as documents when their
  content is one.
- Desktop save dialogs filter on the suggested extension and add it to a name
  typed without it, asking before replacing an existing file; the open dialog
  gains "All files".
- macOS: open-documents Apple events (Finder, Dock, Open With) through
  fmv-macos-events, queued until the window is ready; Info.plist declares the
  .designcraft type and an imported .idml type with CFBundleDocumentTypes.
- Windows MSI: .designcraft ProgId with an Open verb, IDML under Open with.
- Linux: shared-mime-info for both types and MimeType in the .desktop file.

Fixes #158, #211, #375
2026-10-10 22:40:06 +00:00
aiongg fbfd0b2fe9 Merge gpu-startup: recovered documents survive restarts, the watchdog only restarts a hung adapter, software adapters last, the skip list as an argument
Conflicts: designcraft main.rs ui() (#366's macOS marked-text discard, then the startup watch's leave);
engine recovery.rs (the branch's rewrite-then-discard with next's bump_revision).
2026-10-10 21:28:17 +00:00
aiongg 158f366af8 Startup: restarts keep recovered documents, a busy UI never counts as a GPU hang, software renderers last
- Recovery: file.recovery.open moves each entry to the reopened document's uid
  (written before the old one is removed), so recovered documents stay on disk
  until saved or closed, also when the app restarts on another adapter or
  stops before its first recovery save.
- First-frame watch: a late first frame is logged and noted in the status bar.
  The adapter counts as hanging only when the UI thread has been stuck outside
  the app's code (logic/ui mark entry and exit) with no progress for 60 s while
  the window isn't known to be minimized, occluded or unfocused. The watch asks
  for a repaint on each look, so an idle UI ends it. VectorCraft restarts on
  the late frame alone, which a held-back compositor or a long compose can set
  off.
- Software renderers (WARP, llvmpipe) are passed over while another backend is
  left; once no hardware adapter of any backend could show the window, the app
  starts again with them allowed, once.
- A restart clears gpu.json's backend entry just before exec or spawn and puts
  it back when starting again fails. Backends a restart left out are no longer
  recorded as failed.
- The watch ends a hung process with TerminateProcess on Windows.
- The skip list travels as the restarted app's --gpu-skip= argument instead of
  an environment variable, so processes the app starts don't inherit it.
2026-10-10 21:26:51 +00:00
aiongg 9d8bdaef2c Merge wrap-placed-graphic: the CLI's performance document 2026-10-10 21:26:25 +00:00
aiongg 70a04944a5 Layout: the CLI's performance document builds its graphics with a wrap 2026-10-10 21:26:25 +00:00
skylar taylor-barrick c62866443c UI.9: integrate shared panel docking and preserve workspace behavior 2026-10-10 14:42:40 -06:00
aiongg 16bb39e531 Merge gpu-startup: pick the GPU that drives the display, fall back across adapters and backends, and log startup errors (#273, #334) 2026-10-10 20:30:59 +00:00
aiongg 279336c445 Startup: pick the GPU that drives the display, restart on the next adapter or backend, and log startup errors
Ported from VectorCraft's start-up fixes (#502, #545, #651, the display-GPU
choice, #806, #964) and reconciled with the backend fallback of #297:

- The app picks the window's adapter itself (eframe's native_adapter_selector,
  apps/designcraft/src/gpu.rs): adapters that can't present never, then
  WGPU_ADAPTER_NAME, hardware before software, native backends before OpenGL,
  the GPU that drives the primary display (Windows EnumDisplayDevices through
  winsafe, Linux /sys/class/drm), the power preference (WGPU_POWER_PREF;
  otherwise power saving on Windows and macOS, the system's order elsewhere),
  then DX12 before Vulkan. Every adapter and the choice are logged.
- wgpu's indirect-call validation is off (WGPU_VALIDATION_INDIRECT_CALL=1 turns
  it back on): its compute shader failed to compile on an Intel Mac and lost
  the Metal device (#334, first error).
- run_native runs under catch_unwind. A wgpu error or a panic in wgpu,
  egui-wgpu or naga during the first frames, or a first frame that doesn't
  reach the screen in 20 s, starts the app again without that adapter
  (DESIGNCRAFT_GPU_SKIP; exec on Unix, a new process on Windows). When no
  adapter of the start's backends is left, it starts again with the next
  backend. Each restart leaves out one more adapter or backend, so they end.
  Adapters without PCI ids (Metal) are keyed by name.
- The backend fallback (gpu/backend.rs, gpu.json) stays for driver faults that
  take the process down. Windows tries DirectX 12, then OpenGL, then Vulkan,
  each in its own instance: Vulkan last because creating its instance loads
  every installed Vulkan driver, and OpenGL kept out of the DX12 instance
  because creating it crashed in AMD's atio6axx.dll (#167).
- main returns an ExitCode and logs why the app stopped to standard error and
  the log file, which is all a Windows start without a console leaves (#273).

README, architecture, gaps, hardware and target-app parity docs and ROADMAP
describe the choice, the restarts and the variables.
2026-10-10 20:26:06 +00:00
aiongg 23b6ce4cc1 Merge feat/ime: IME composition (#322)
Conflict: crates/ui-egui/src/lib.rs: next's missing-fonts test; the branch's side repeated control_bar_shows_its_second_row (next's newer copy stays) and key_names_sent_as_text_are_dropped, whose IME version replaces next's copy in place
2026-10-10 16:30:09 +00:00
aiongg c3c24a0be8 Merge fix/idml-interchange: $ID/ font names, placed PDF page and crop, packaged IDML links (#338, #339, #340)
Conflict: ROADMAP.md: next's IDML interchange line with the branch's sentence on placed PDFs, $ID/ font names and packaged links appended; next's INDD line kept
Conflict: crates/engine/src/tests_idml.rs: next's drop cap test and the branch's two placed PDF tests
Conflict: crates/fonts/src/fontdb.rs: next's plausible/measured_top/typo_ascent and the branch's plain_family; next's canonical_family lookups, with plain_family in place of without_format_suffix in style_traits, face (two) and has_family; the branch's has_exact_family dropped (has_family uses canonical_family)
Conflict: crates/idml/src/import.rs: next's char_attrs (tab-split family and composite font names), falling back to names::font_family_in
2026-10-10 16:20:17 +00:00
aiongg 1276181cde Text: IME composition in place, commit as one step (#322)
The Type tool shows an input method's marked text in the story as a
preview of text.insert, underlined (the converting clause twice), with
the candidate window at the caret. The commit is one text.insert and one
undo step; a cancelled composition leaves the document as it was. Keys,
shortcuts, the clipboard and Undo wait while the IME composes; a click,
a tool or document switch, or any journaled command keeps the marked
text as typed. On macOS the app tells the input context to drop marked
text the tool kept.

With a split window, only the pane last clicked takes keyboard events
(both panes saw them, so typing went in twice).

The web build drops only real key names from text events, and nothing
while its text input has the keyboard, so autocompleted words survive.

The control channel's ui.ime, the headless MCP backend's ui.ime and the
MCP ime tool send IME events.
2026-10-10 16:05:36 +00:00
aiongg 289c4a6aa4 IDML: a placed PDF keeps its crop choice
The placed PDF's asset stores its Crop to choice (crop, art, trim, bleed,
media, or the content bounds with visible or all layers) and where that
box sits on the page. The graphic spans the box: the screen, PDF export,
rasterised exports and clipping-path tracing draw only that part of the
page, so a larger frame doesn't reveal the bleed.

IDML export writes the choice as PDFCrop, with GraphicBounds spanning the
box. Import reads PDFCrop back; the engine finds the box on the PDF page
after import (and after relink or update) and maps it onto GraphicBounds,
or gives a graphic without bounds the box's size. Documents saved without
a choice load with the crop box. The Place PDF dialog offers the content
bounds too, and links.list reports the choice.
2026-10-10 15:52:40 +00:00
aiongg 5551cf9a25 Merge upstream main into feat/text-editing-and-frames
The layout-parity files (ROADMAP, compose lib/tests, engine text, fonts fontdb, idml import/tests, canvas) resolve as in the merge of main into feat/layout-parity.
Conflict: ROADMAP.md: as feat/layout-parity's merge
Conflict: crates/compose/src/lib.rs: as feat/layout-parity's merge; this branch's trimmed trailing spaces follow main's warichu::place and come before the drop cap splice
Conflict: crates/compose/src/tests.rs: both sides' tests
Conflict: crates/engine/src/cmd/text.rs: as feat/layout-parity's merge; this branch's TypingFormat/typing_format and main's warichu_cmd
Conflict: crates/fonts/src/fontdb.rs: this branch's styles/traits_of/linked_style over style_traits; style_traits falls back to the family without main's format suffix (exact_style_traits)
Conflict: crates/idml/src/import.rs, crates/idml/src/tests.rs, crates/ui-egui/src/canvas.rs: as feat/layout-parity's merge
Conflict: crates/ui-egui/src/control.rs: main's page_index and automation_contract_tests, then this branch's tests module
Conflict: crates/ui-egui/src/lib.rs: this branch's ClipboardFn and main's Inbox of ImportedFile
Conflict: crates/ui-egui/src/menus.rs: main's Quick Apply tests, then this branch's copy and paste keys test
2026-10-10 15:36:43 +00:00
aiongg 6286f7c0a5 Merge #336: UI: CJK features behind a preference that follows the interface language
Conflict: ROADMAP.md: next's Right-to-left and Interface language lines (IDML Kashidas, German and Japanese cover every catalog, Ukrainian covers every key) plus the PR's Show CJK Features line
Conflict: crates/ui-egui/src/lib.rs: the PR's cjk_features() before next's opens_as_document (with .indd/.indt and its doc comment)
2026-10-10 13:50:51 +00:00
aiongg 4fd3c0fcae UI: CJK features behind a preference that follows the interface language
Preferences > Type > Show CJK Features (cjkFeatures; unset follows the
interface language: on for Japanese, Chinese and Korean) hides the
CJK-only Type menu items (Tate-Chu-Yoko, Ruby, Kenten, Warichu) and the
Ruby Quick Apply entry. The commands, layout and IDML work either way.
2026-10-10 13:48:07 +00:00
aiongg aadd54a926 Merge upstream main 736acff into next
Upstream main moved 9e4f694 -> 736acff by 10 squashes: #258, #285, #153, #280, #288, #281,
#176, #299, #298, #297. New to next: #258 (datamerge test), #153 (temporary files and release
inputs), #280 (warichu), #176 (PDF image conversion cache), #297 (graphics backend before the
window). Already on next: #285, #288, #281, #299, #298.

Conflict: ROADMAP.md: next's lines; CJK1 takes main's wording (ruby unfinished, warichu set after the line is broken)
Conflict: crates/compose/src/lib.rs: list labels (#298): next's list_label structure; paragraph start / break moves: next's `go` (with #295's sub-columns) under the maintainer's #285 comment; Cursor: next's start/next_page/next_baseline with tops; line placement: #280's warichu::place right after layout_line, before next's trimmed trailing spaces and the drop cap splice (so neither is stacked and the spaces follow the closed-up end_x); caret(): next's drop-cap branch first, then #280's stacked-row metrics
Conflict: crates/compose/src/tests.rs: next's tests kept; #280's tests auto-merged
Conflict: crates/engine/src/cmd/text.rs: both (next's TypingFormat/typing_format, #280's warichu_cmd)
Conflict: crates/idml/src/tests.rs: next's side; #280's warichu round-trip test auto-merged
Conflict: crates/pdf/src/export.rs: #176's content cache and test counter with next's RasterMode (no Exporter `interpolate` field on next, so the maintainer's `mode.interpolate &= self.interpolate` is not carried); test exporter gets next's drawing_items field
Conflict: crates/ui-egui/src/canvas.rs: #280's compose::highlight_quads (its RTL branch equals next's mixed-direction spans) followed by next's drop-cap highlight
Conflict: crates/ui-egui/src/menus.rs: next's formatting_affects_text test kept

Auto-merge duplicates removed: #288's table-style tests and #298's list test in idml tests.rs,
#288's tests in doc styles.rs and #285's docx test (both files equal next's), #281's dialog
tests in dialogs.rs (equals next's) and its menu_button/menu_max_height/clipped_submenu in
menus.rs. contributors/people.toml takes main's (next had a duplicated
[people.emanuelebonaventura] table from the 9e4f694 merge, which broke the ui-egui build
script's TOML parse).

Maintainer edits carried over: #285 break characters and Next Column through one closure
(next's `go`, comment added); #281 viewport-aware menu_button in the app bar and the Paragraph
menu, per-dialog widths clamped to the window (all already on next); #280 warichu after the
last-line rules (layout_line with ends_para/forced_mid) and rules at each warichu row's
baseline (rule_baseline in render and pdf text_rules); #176 CMYK fallback through
lossless(.., mode) and its updated contract tests; #258 test fixes; #153 and #297 as landed.
2026-10-10 08:20:36 +00:00