Commit Graph
314 Commits
Author SHA1 Message Date
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
5cdcac4ace fix(save): replace files atomically
Replace native engine saves and engine/MCP exports atomically, preserving private permissions during staging and cleaning up failed writes. Add regressions for long filenames and caught writer unwinding.

Fixes #436.

Co-authored-by: aiongg <aiongtaigi@gmail.com>
Co-authored-by: skylar taylor-barrick <hi@skylar.cc>
2026-10-12 09:19:36 -06:00
aiongg a5fbf5d8d4 Merge table-border-drag: Tables: drag row and column borders with the Type tool
Conflict: crates/compose/src/lib.rs: one re-export line with next's hit_cell_with and the branch's BorderHit/hit_border
Conflict: crates/tools/src/text.rs: next's IME/preedit, guides and unit_selected kept alongside the border drag; border press checked after the Down resets; drag keeps next's `cell_drag || unit_selected` guard after the border branch; Esc cancels a border drag before next's preedit guard; BorderHit via next's `compose` alias
Conflict: crates/tools/src/tests.rs: both sides' appended tests kept
Conflict: docs/target-app-parity.md: next's IDML line, branch's Tables line
Conflict: ROADMAP.md: branch entry on top of next's entries
2026-10-12 14:56:19 +00:00
aiongg 44fde50463 Tables: drag row and column borders with the Type tool
Hovering a table's inner column or row border, or its end or bottom
edge, shows a double-arrow cursor; dragging resizes instead of selecting
text. A column drag changes the column before the border and moves later
columns; Shift keeps the table width (the next column compensates), and
Shift on the end edge scales every column. Rows work the same way, and a
dragged row becomes At Least. Sizes clamp at 3 pt. One undo step per
drag, Esc cancels, locked frames refuse, and the pointer is mapped
through the frame's transform so rotated frames and turned spreads work.

New command table.resizeBorder {story?, table?, frame?, axis, index,
delta | size, keepTableSize?}; the Type tool emits it through
Begin/Preview/Commit. compose::hit_border finds the border under a point
in frame inner space.

Closes #595
2026-10-12 14:52:31 +00:00
aiongg 1ebefe4db4 Merge fill-stroke-keys: Engine: swap and default fill and stroke in one undo step
Conflict: ROADMAP.md: both progress lines kept
Conflict: docs/target-app-parity.md: next's UI and tools lines kept, with the Fill/Stroke proxy keys added to the UI line
Conflict: crates/ui-egui/src/lib.rs: UiState keeps next's tabs_panel and the branch's stroke_front
Conflict: crates/ui-egui/src/menus.rs: UI_COMMANDS keep next's togglePresentation and formattingAffectsText entries and add the color.* entries
Conflict: crates/ui-egui/src/toolbar.rs: next's text-aware proxy buttons (color_target, colors_affect_text, apply_swatch) kept; the proxy reads stroke_front from UiState instead of egui temp data
2026-10-12 14:48:16 +00:00
aiongg b21111f232 Toolbox: Shift+X, D, X and / shortcuts for the Fill/Stroke proxy
The proxy's tooltips named keys that did nothing. color.defaultFillStroke
(D), color.swapFillStroke (Shift+X), color.toggleFillStroke (X) and
color.applyNone (/) are UI commands; the proxy's buttons run the same
commands. Swap keeps the fill and stroke tints.

Which of fill and stroke is in front lives in UiState, shared by the
Tools panel proxy, the Color panel and the commands. The single-key
shortcuts stay out of text being typed, like the tool shortcuts.
2026-10-12 14:21:36 +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
aiongg 22d428f747 Merge #466: feat(ui): Lay out the font menu like InDesign's
The PR's first three commits are patch-identical to #536/#537, already on next.

Conflict: crates/engine/src/cmd/text.rs: next's side (its `type.selectionAttrs` already carries the PR's selected text, plus next's later `mixed` and typing-format work)
Conflict: crates/fonts/src/fontdb.rs, crates/fonts/src/lib.rs: next's side (the PR's font-kind code is already there through #536; next adds aliases, PostScript names, mac_fonts)
Conflict: crates/ui-egui/src/lib.rs: kept both field sets (`recent_new_documents`, `font_sample`/`font_preview_size`)
Conflict: crates/ui-egui/src/panels/mod.rs: took the PR's move of `font_menu_body` into font_menu.rs; next's #447 test edit and `swatch_list_tests` stay
Conflict: crates/ui-egui/src/i18n.rs, crates/ui-egui/src/i18n/it.rs, ROADMAP.md: kept both sides' rows
2026-10-12 12:27:18 +00:00
aiongg 19bf6dd868 Merge #573: Step and Repeat: InDesign's dialog with Create as a grid and Preview
Conflict: crates/ui-egui/src/dialogs.rs: kept next's Cell Options functions and the PR's Step and Repeat code; both sides added `cancel()`, joined into one that ends a dialog preview (PR) and puts back the Preferences language (next); tests keep next's `document_setup_app` and the PR's Step and Repeat test (the PR's copy of `dialog_context` already exists further down)
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:25:32 +00:00
aiongg 8cd0e74a33 Merge #571: Styles: Load Styles from another document or IDML file
Conflict: crates/ui-egui/src/lib.rs: import_file takes the PR's `styles` early return first, then next's content-sniffing `layout` line
Conflict: ROADMAP.md: kept both progress-log lines
2026-10-12 12:24:34 +00:00
aiongg fbf0fabd1a Merge #565: fix(compose): enable Norwegian hyphenation patterns
Conflict: docs/typography-parity.md: kept next's Justification row (#531 note), took the PR's Hyphenation row (Portuguese and Norwegian)
2026-10-12 12:23:42 +00: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
moppeeerandClaude Opus 5.5 cff0e8b2f8 feat(ui): Step and Repeat dialog with Create as a grid and Preview
Edit > Step and Repeat opened the generic command form (Count 1..1000, Dx, Dy, Rows, Columns, Ids). It now has InDesign's dialog: Repeat (Count, or Rows and Columns when Create as a grid is on), Offset (Vertical, Horizontal, in the document's ruler units or any unit typed) and Preview, which shows the copies on the page while the dialog is open. Cancel, Esc and ui.dialog.cancel take the preview away; OK makes the copies once, as one undo step. A value that isn't a number keeps the dialog open and says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 10:58:17 +02:00
noah1400 d298555e43 Styles: Load Styles from another document or IDML file (#405)
Styles could not be taken from one document into another; a client's
styles had to be rebuilt in every new file. The Paragraph Styles and
Character Styles panels now have Load Paragraph Styles, Load Character
Styles and Load All Text Styles: pick a .designcraft or .idml file,
tick the styles to load and choose what happens to one the document
defines differently (redefine, keep, or load under a new name). The
styles, swatches and lists a loaded style names come along.
`style.load` does it in one undo step.
2026-10-12 10:41:37 +02:00
moppeeerandClaude Opus 5.5 8b0bc54bdb feat(ui): Lay out the font menu like InDesign's
The font menu (Control bar, Character panel, Properties, task bar, style
dialogs, Find Font, Glyphs) now has InDesign's layout:

- a search field with a clear button, and a Filters row: classification
  (All Classes, serif, slab serif, sans serif, script, monospaced,
  decorative, symbol), Show Favorites Only, Show Recently Added (fonts
  added in the last 30 days);
- the sample text (Selected Text, Sample, Aa Bb Cc, a pangram, digits)
  in three sizes, remembered with the UI state;
- Recently Used fonts at the top, then every family;
- a family of several styles shows how many and opens to list them, each
  previewed in its own face; picking a style applies it as it is;
- each family's format after its sample, and Show Similar Fonts (≈) to
  list the families of the same class nearest by PANOSE.

Find More and the activated-fonts filter are Adobe Fonts services and
are left out. The font combo is a field and a plain popup now: egui's
combo box kept its menu at the size it last had, so a family opening or
a filter clearing didn't show. The ≈ button stays while the pointer is
on it (the row under it no longer counts as hovered there). New strings
are translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 09:55:02 +02:00
Akash Bhat c310cf72ed fix(compose): enable Norwegian hyphenation patterns
Enable hypher/norwegian in designcraft-compose so no/nb/nn map to the bundled hyph-no.tex patterns. Add unit + composition regression tests, NOTICE attribution, and update parity docs.

Fixes #535.
2026-10-12 12:09:40 +05:30
aiongg 9a95cee172 Merge anchored-wrap: Text wrap: anchored objects wrap text (#557)
Conflict: ROADMAP.md: both progress lines
Conflict: docs/target-app-parity.md: next's header, anchored objects wrapping text added to its change list
Conflict: docs/typography-parity.md: next's header (dated 2026-10-12) with #557's change added; Text wrap row: next's text and caveat, plus "on page items and anchored objects"
Conflict: crates/compose/src/lib.rs: next's Exclusion (side, contour) with #557's after field (Exclusion::wraps_line; next's constructors and the tests' helper set None); next's contour_path and wrap_obstacles in frame_specs; next's line loop (carry, grid, wrap_slot) with the line's start byte passed to wrap_slot; wrap_slot, free_slots and estimate_slots take line_start and skip exclusions that don't wrap the line (Jump Object test and in-band edges included); #557's re-break trigger stays in the line loop
Conflict: crates/compose/src/cache.rs: next's ComposeOptions (section_marker) with #557's neighbour compositions
Conflict: crates/compose/src/tests.rs: both test blocks
Conflict: crates/render/src/damage.rs: #557's test before next's patched_diff helper
2026-10-12 05:54:58 +00:00
aiongg 6e9517b053 Text wrap: anchored objects wrap text (#557)
An anchored object with text wrap pushes aside the text of other stories
whose frames it overlaps on its spread, and the lines of its own story
after the line holding its anchor (custom and above-line objects). Its own
story is composed again with the objects where the previous pass placed
them until they settle, at most four more times. The composition cache
keys a story wrapped by other stories' anchored objects on their
signatures, and canvas damage repaints the stories they wrap.
2026-10-12 05:51:56 +00: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 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 b1804440d1 Merge #366 (update): Text: input method (IME) composition in the Type tool
#366 with #84's review fixes merged in: keyboard_pane is app.pane == app.focus_pane (the second window too), and the IME line in the parity doc.

Conflict: crates/ui-egui/src/canvas.rs: next's guard (menu_open, text_edit_focused, keyboard_pane)
2026-10-12 04:27:24 +00:00
aiongg 89abf6b6c9 Merge #84 (update): Text editing, snapping and text threading (#23)
Review fixes for text editing, paste and threading (fix84-text,
fix84-thread), the Italian/Japanese/Portuguese/Ukrainian Swatches hint
and #83's update merged into the PR branch.

Conflict: ROADMAP.md: header combines #84's threading change with next's 2026-10-11 changes; progress lines and change-log rows both (#84's 2026-10-12 first); stage line #84's (alpha ~5–7 h away)
Conflict: docs/gaps.md: #84's header text plus next's kerning/fonts/print changes
Conflict: docs/roadmap.md: next's M1 row (#186 done), #84's M2 row
Conflict: crates/engine/src/cmd/style.rs: next's side; add_to_swatches calls next's Document::rename_swatch_refs, #84's rename_in_story/rename_in dropped (next's covers text, tables, cells, notes and items); #84's test kept
Conflict: crates/idml/src/tests.rs: next's side (#84 carries #83's tests.rs, already merged in 9196a164)
Conflict: crates/tools/src/select.rs: overlays keeps next's content-move ghosts and live corners, plus #84's snapped loaded-cursor drag frame; a Place click without a drag shows nothing
Conflict: crates/ui-egui/src/i18n/it.rs: next's side (the Swatches hint entry is already further down)
2026-10-12 04:20:34 +00:00
aiongg 9196a1643f Merge #83 (update): Layout: first baselines, Jump Object wrap, drop caps, IDML defaults
Conflict: crates/format/src/lib.rs: next's side (upgrade, merge_duplicate_assets, then mark_differing_margins_local) in both loaders
Conflict: docs/target-app-parity.md: next's RTL and Interface Language lines, plus #83's "IDML Kashidas"
2026-10-12 04:17:58 +00:00
aiongg 8f1c60e4fc Merge upstream main 835edae6
Brings #514 (MCP request replay), #523 final (already in next), #403
(character fill must name a swatch), #520 and #521 finals (already in
next as their PR heads).

Conflict: crates/engine/src/cmd/object.rs: next's side throughout (transform.move doc with content?, object.fill with tint alone from #525, move_content, reorder/content_move/group/tint_alone test modules); upstream's copy_ids_tests already in next
Conflict: crates/engine/src/cmd/text.rs: both; #403's validate_char_fill after next's ruby_cmd
Conflict: crates/pdf/src/export.rs: next's side (item/item_guarded cycle guard, frame_objects; upstream's anchored loop dropped as in d11ccad3)
Conflict: crates/render/src/lib.rs: next's side (drawing_items, draw_item/draw_item_inner)
2026-10-12 04:15:40 +00:00
aiongg 7eed1dffe1 Merge #84 into feat/ime 2026-10-12 04:12:45 +00:00
aiongg 9d3581929a Threading: progress docs for threading by hand
The alpha gate's threading row and gap 0 shrink to the Primary Text
Frame page fixes (#165). New gaps: autoflow onto the existing following
pages, and threading into a grouped frame with the loaded text cursor.
2026-10-12 04:02:35 +00:00
aiongg 9580ba975c Merge #84 into feat/ime
#84 brings #83 and upstream main.

Conflict: ROADMAP.md: took #84's (main's restructured roadmap); the Input methods inventory line goes into docs/target-app-parity.md
Conflict: apps/designcraft/src/main.rs: kept this branch's discard_marked_text; config_dir lives in main's profile module
Conflict: crates/ui-egui/src/canvas.rs: keys go through keyboard_pane, which takes main's rule (only the focused pane, split or second window)
2026-10-12 03:42:03 +00:00
aiongg 0fae2e4b5a Merge #83 into feat/text-editing-and-frames
Conflict: ROADMAP.md: took #83's (main's restructured roadmap); the Threading inventory line goes into docs/target-app-parity.md
Conflict: crates/compose/src/lib.rs: kept this branch's undrawn trailing spaces after warichu; comment covers both the spaces and the drop cap
Conflict: crates/idml/src/tests.rs: took #83's (drop cap style as a Dropcap nested style, table style fills through the cascade); this branch has no changes of its own there
2026-10-12 03:31:39 +00:00
aiongg 0032d57525 Merge upstream main into feat/layout-parity
Conflict: ROADMAP.md: took main's restructured roadmap; this branch's inventory changes (Keep Lines Together default, IDML defaults, drop caps, IDML Kashidas) go into docs/target-app-parity.md, where the inventory lives now
Conflict: crates/format/src/lib.rs: load runs the format upgrade, then merges duplicate assets; kept both sets of tests
2026-10-12 03:24:27 +00:00
KnottyDyes 80c2904681 fix(mcp): prevent request replay after lost replies
Do not resend a request after a transport failure. Report the uncertain outcome and reconnect on the next explicit request.

Validation: all six cargo xtask ci gates passed on the merge candidate; 1,177 native tests passed and all 15 WASM packages checked. Lost-reply, invalid UTF-8 and timeout probes reproduced duplicate edits before the fix and one edit afterward.

Task: #514
2026-10-11 21:10:01 -06: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 978a9b9b98 Merge #452: M6: Adopt craft-print and support Windows PDF printing
Conflict: crates/engine/src/cmd/print.rs: the PR's print_with/craft_print::submit; print_with and the test's expected bytes export through next's interchange::with_pdf_boxes
Conflict: Cargo.lock: next's lock plus only craft-print (the auto-merge had moved windows-sys back to 0.59/0.60 for several crates)
Conflict: Cargo.toml: craft-print entry moved beside craft-ui with a comment
Conflict: ROADMAP.md: status Change texts combined; both progress-log lines (the PR's 2026-10-11 line under the 2026-10-12 ones)
Conflict: docs/gaps.md: status Change texts combined
Conflict: docs/hardware-parity.md: status Change texts combined
2026-10-12 00:21:22 +00:00
skylar taylor-barrick 65ef027f9f Merge pull request #452 from storytold/codex/craft-print
M6: Adopt craft-print and support Windows PDF printing
2026-10-11 18:12:43 -06:00
japbcoelhoandClaude Opus 5.5 2b46ca664c Hyphenation: Portuguese text is hyphenated with hyph-utf8's Portuguese patterns (#512)
Text set in Portuguese ("Portuguese: Brazilian", "Portuguese", pt_BR) got
no hyphenation, so justified Portuguese columns could only stretch their
word spaces (up to 335 % of the normal space in a 56 mm column of 10 pt
Times).

Turn on hypher's "portuguese" feature, beside Spanish: hyph-pt.tex 1.4
(2024-07-13) from hyph-utf8, BSD-3-Clause, credited in NOTICE.
Lang::for_language already maps the Portuguese names and locale codes.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:39:53 -06:00
aiongg f5ee268962 Merge justification-dialog: a Justification dialog for the selected paragraphs (#531)
Conflict: ROADMAP.md: both progress-log entries, #531's above next's 2026-10-11 lines.
Conflict: docs/typography-parity.md: status line lists next's changes and the Justification dialog.
Conflict: crates/engine/src/cmd/text.rs: selection_attrs keeps next's typing-format chars and adds paraMixed for {mixed: true}; mixed_para_attrs sits beside next's apply_typing_format and link_style.
Conflict: crates/ui-egui/src/dialogs.rs: titles, draw and confirm arms for both paragraphLocal and justification; the style dialog's justify arm calls the shared justification(), which uses next's composer_choice (Japanese composers) and selects neither composer when mixed; the style dialog's justification check moved into next's confirm_paragraph_style_options (section set to justify, reason in next's status line); tests from both sides.
Conflict: crates/ui-egui/src/i18n/ja.rs: union of rows.
Conflict: crates/ui-egui/src/i18n/uk.rs: union of rows.
Conflict: crates/ui-egui/src/menus.rs: UI_COMMANDS, run_ui arms and Type menu keep next's Paragraph Borders and Shading, Span Columns and Bullets and Numbering plus Justification… (Cmd+Alt+Shift+J, free on next) right after Paragraph Rules…; menu_enabled keeps next's IME check before the type.para check.
Auto-merged crates/ui-egui/src/panels/properties.rs: Justification… joins the Paragraph panel menu list after Paragraph Rules….
2026-10-11 20:49:57 +00:00
aiongg 1a9499b465 Merge document-grid: View draws the document grid (#530)
ROADMAP.md: both progress-log lines
docs/target-app-parity.md: next's lines plus the document grid
2026-10-11 20:47:12 +00:00
aiongg 3f752312d6 Type: Justification dialog for the selected paragraphs (#531)
Type > Justification... and the Paragraph panel menu (Cmd+Alt+Shift+J) open
the Justification controls of Paragraph Style Options for the selected
paragraphs: word and letter spacing, glyph scaling, composer, kashidas and
Korean line breaks. Values that differ across the selection show empty, and
OK applies only the edited fields through type.para as one undo step.
Spacing values outside their range or out of minimum/desired/maximum order
keep the dialog open with the reason, in both dialogs.

type.selectionAttrs takes {mixed: true} and lists the paragraph attributes
that differ across the selected paragraphs as paraMixed.
2026-10-11 20:46:38 +00:00
aiongg 61504dae48 View: draw the document grid (#530)
Show/Hide Document Grid (View > Grids & Guides, Cmd+') draws the grid
on the positions Snap to Document Grid uses: subdivision and major
lines from each page's top-left corner, across the spread's band of the
pasteboard, behind or in front of page items as the grid settings say.
Dense lines are left out at low zoom. The Properties toggle runs the
command.
2026-10-11 20:46:38 +00:00
skylar taylor-barrick 3ec5cef6a2 M6: Adopt merged craft-print with scaling and queue duplex defaults 2026-10-11 22:14:24 +02:00
aiongg d240ecb0b9 Merge idml-spread-rotation: IDML keeps a spread's view rotation
ROADMAP.md: both progress-log lines
crates/idml/src/tests.rs: next's test modules plus spread_rotation
docs/target-app-parity.md: next's lines; Rotate Spread names IDML's spread transform
2026-10-11 20:11:34 +00:00
aiongg a8fc6a5219 IDML: read and write a spread's view rotation (#484)
Rotate Spread is the rotation part of the Spread element's ItemTransform.
Import maps the three quarter-turn matrices to view_rotation on the spread's
first page and treats anything else as no rotation; pages and items keep
their unrotated spread coordinates. Export writes the rotation part for
document spreads; parent spreads stay identity.
2026-10-11 20:11:05 +00:00
aiongg 76450c630a Merge #469: feat(ui): Lay out Document Setup like InDesign's
Conflict: ROADMAP.md: progress log keeps both
Conflict: docs/target-app-parity.md: next's New Document line, the PR's Document Setup line
Conflict: crates/engine/src/cmd/layout.rs: setup_tests keep both tests
Conflict: crates/ui-egui/src/dialogs.rs: dispatch takes the PR's documentSetup block and keeps next's numberingSection; tests drop the PR's copies of dialog_context, dialog_frame, visible_label, click_dialog and scroll_dialog (next has them)
Conflict: crates/ui-egui/src/i18n.rs: TABLE keeps both; the PR's Top:/Bottom:/Left:/Right: rows dropped (next has them)
Conflict: crates/ui-egui/src/i18n/it.rs: keeps both; the PR's Top:/Bottom:/Left:/Right: rows dropped (next has them)
2026-10-11 18:03:16 +00:00
aiongg 43019733a8 Merge #512: Hyphenation: Portuguese text is hyphenated with hyph-utf8's Portuguese patterns 2026-10-11 18:01:34 +00:00
moppeeerandClaude Opus 5.5 2d1cad4c45 feat(ui): Lay out Document Setup like InDesign's
File > Document Setup now follows InDesign's layout: Intent, Number of
Pages and Start Page # with Facing Pages and Primary Text Frame (shown,
set when the document is made) beside them, Binding; a Page Size group
(preset menu keeping the orientation, width and height with arrows,
orientation icons); a Margins group (top, bottom, inside, outside, or
left and right without facing pages, with a link that keeps them equal);
Bleed and Slug (collapsible, a column per edge, a link per row); and an
Adjust Layout box whose button applies the changes with objects
following the new page size and margins.

Measures are read in the document's units (a plain 12 is 12 mm in a
metric document, not 12 picas). OK sends one layout.documentSetup (one
undo step); a value that can't be read keeps the dialog open with the
reason in the status bar. New strings are translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 18:53:40 +02:00
japbcoelhoandClaude Opus 5.5 db55cb7e49 Hyphenation: Portuguese text is hyphenated with hyph-utf8's Portuguese patterns
Text set in Portuguese ("Portuguese: Brazilian", "Portuguese", pt_BR) got
no hyphenation, so justified Portuguese columns could only stretch their
word spaces (up to 335 % of the normal space in a 56 mm column of 10 pt
Times).

Turn on hypher's "portuguese" feature, beside Spanish: hyph-pt.tex 1.4
(2024-07-13) from hyph-utf8, BSD-3-Clause, credited in NOTICE.
Lang::for_language already maps the Portuguese names and locale codes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:52:46 -03:00
aiongg 52c28c625e Merge #490: i18n: Czech interface language
# Conflicts:
#	crates/ui-egui/src/i18n.rs
#	crates/ui-egui/src/menus.rs
2026-10-11 16:37:15 +00:00
aiongg ee2f4dffd6 Merge #506: Recovery: each running app keeps its own recovery data 2026-10-11 16:36:07 +00:00