Commit Graph
4827 Commits
Author SHA1 Message Date
aiongg d36e5fb63f Merge pull request #1927 from Silvertree2010/perf/export-speed
PDF export: ask the composition cache once per story and page
2026-10-27 13:41:05 -04:00
macadminHU 7d48e47057 HU1: record shared-module localization integration
Record the preserved Hungarian catalog and both parents localization, menu, toolbar and docking tests, current keymap-aware flyout sizing and direct Georgian lookup checks. Keep every existing progress entry and readiness percentage.
2026-10-27 18:16:04 +01:00
macadminHU 72a586e0d5 HU1: keep the moved PDF test helpers clippy-clean
Simplify two upstream Option predicates to equivalent is_none_or forms. Preserve the None cases, all test cases and assertions; no coverage is removed.
2026-10-27 18:15:37 +01:00
macadminHU e6e8fc126e HU1: keep the integrated PDF condition clippy-clean
Apply the equivalent De Morgan form of the upstream gradient condition so Rust 1.95 clippy with warnings denied can complete. Short-circuit order and output behavior are unchanged.
2026-10-27 18:15:05 +01:00
macadminHU 4207debc17 HU1: retain Hungarian in the moved language command metadata
Keep hu in the app.language parameter documentation after the UI command table moved to menus/ui_commands.rs.
2026-10-27 18:14:01 +01:00
macadminHU f8b05ee3df HU1: retain toolbar coverage with current keymap captions
Preserve existing toolbar assertions and Hungarian right-click flyout coverage in both column layouts. Check platform-formatted default shortcuts and a user-assigned chord, including painted text, clipping and overlap. All 13 focused toolbar tests passed.
2026-10-27 18:11:25 +01:00
macadminHU 39109cc0df HU1: retain both parents menu tests in the shared layout
Retain the upstream shortcut and navigation tests together with Hungarian selection, persistence, menu-path and document-preservation regressions and the complete Georgian-menu assertion.
2026-10-27 18:10:55 +01:00
macadminHU c9255c30ae HU1: preserve localization regressions in the new test module
Retain localization checks from both merge parents, including Hungarian context and catalog coverage, and directly check the repaired Georgian captions. This file matches the locally tested shared-module integration.
2026-10-27 18:08:51 +01:00
macadminHU 4a85d3b61e Merge branch 'main' into codex/hungarian-localization 2026-10-27 18:07:17 +01:00
macadminHU 450789d627 HU1: align the moved panel test path for the module merge
Upstream d77fdf2d moved these tests to crates/ui-egui/src/panel_docking/tests.rs. The tested local merge preserves every test body from both parents there. Remove the obsolete path to unblock GitHub’s web conflict resolver; the remaining module integration follows immediately.
2026-10-27 18:05:17 +01:00
con3code 206dbe8499 Merge remote-tracking branch 'upstream/main' into fix/effects-panel-units
# Conflicts:
#	crates/ui-egui/src/panels/properties.rs
2026-10-28 02:03:29 +09:00
con3code 7e3c7bd9b3 Merge remote-tracking branch 'upstream/main' into fix/type-fields-read-units
# Conflicts:
#	crates/ui-egui/src/panels/properties.rs
#	crates/ui-egui/src/widgets.rs
2026-10-28 01:37:05 +09:00
NetterSilverandClaude Opus 5.5 1db1635a88 Ask the composition cache once per story and page in PDF export
The PDF exporter called Cache::get twice for every text frame it drew.
Each call rebuilds the cache signature of the whole story, which looks up
every frame of the story with Document::find (a linear walk over all
spreads), and the anchored-frame placements walk them again. For a story
threaded through many frames this is O(frames^2 x items) per export.

The document doesn't change during an export, so the exporter now keeps
the composition it got for each (story, page) and reuses it. The cache
still decides what to compose; the output is byte-identical.

Add examples/pdf_export.rs to designcraft-cli: File > Export PDF through
a headless session on the `designcraft-cli perf` stress document (200
pages, 1M characters in 40 threaded stories, 500 placed images). The
stress document generator moves unchanged from src/perf.rs to a small
library module (src/stress.rs) that the binary and the example share.

Ryzen 16 threads, Linux, 12 runs each, interleaved:
  main     median 3485 ms, min 3427 ms
  patched  median 2016 ms, min 1656 ms  (-42 % median, -52 % min)
The exported PDF is byte-identical (12,075,744 bytes).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 16:47:25 +01:00
Jeremy d7e57d2016 fix(installer): resolve the wizard scope and folder correctly
Real msiexec runs (per-user and all-users, silent and wizard) found two defects
that the metadata fixtures cannot see:

- "Only for me" published ALLUSERS=2, so FindRelatedProducts treated the run as
  per-machine and skipped the existing per-user copy. An interactive upgrade
  left two registered products and uninstall left files behind. The page now
  leaves ALLUSERS unset for a per-user choice.
- Windows Installer resolves Program Files once, for the context it started in,
  so choosing "Everyone" in the wizard installed into the user profile with a
  machine-wide registration. The wizard now sets the new-install folder itself
  after the choice (Program Files, Program Files (x86) for 32-bit, or the
  per-user Programs folder). Silent installs are unchanged.

check-install-policy.ps1 now fails if either regresses.
2026-10-27 15:32:18 +00:00
aiongg d77fdf2d4c fix(ui): dropdown menus grow back after a search with no matches (#1917)
* fix(ui): font menus grow back after a search with no matches

Every combo box is craft_ui::ComboBox (craft-libs pinned at 62bb0e1d), whose
menu follows its contents' height while open (egui#5225); clippy.toml bans
egui::ComboBox.

The Font menu splits into a header (search field, filters) and a list
(font_menu_header, font_menu_list). Font fields show it in a
craft_ui::combo::Menu and the style dialogs' Font Family combo boxes in
ComboBox::show_ui_with_header, so only the rows scroll and the search field
stays in place. The blank and Parent's Font rows sit in the header, above
the search.

* chore(deps): craft-libs 60d60d48 (dropdown fixes)

* chore(deps): craft-libs 4d7b82f7 (dropdown fixes)

* chore(deps): craft-libs 92d392cf (#387 merged)

* chore(xtask): pdf-deps expects craft-libs 92d392cf
2026-10-27 10:27:32 -04:00
dotCooCoo 9ef2e64f9f Merge main into the column rule extent fix 2026-10-27 07:16:50 -07:00
NetterSilverandClaude Haiku 5.5 516998d449 Export form field borders from the item stroke
Fixes #1881

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 13:33:17 +00:00
hslrmnp27 79af5ead54 T.DE1: integrate updated PR 1254 history 2026-10-27 13:34:20 +01:00
hslrmnp27 66447c01ae T.DE1: merge upstream main and resolve update conflicts 2026-10-27 13:33:24 +01:00
Jeremy dfe5296522 docs(installer): note that the 32-bit all-users folder is Program Files (x86); tidy wording 2026-10-27 12:25:18 +00:00
Jeremy 01328d169a docs(installer): describe the per-user default install location and scope 2026-10-27 12:09:02 +00:00
Jeremy abe4847a61 fix(installer): harden install-policy checks and packaging-lint workflow 2026-10-27 12:00:59 +00:00
Jeremy 0d51fbd0bb fix(installer): address scope and ARM64 review feedback 2026-10-27 12:00:59 +00:00
Jeremy f4e05f4f2d feat(installer): default to a per-user ArtCraft folder 2026-10-27 12:00:59 +00:00
Hamza bb49e56627 Fonts: a missing Korean sans face falls back to a sans one (#1692)
Rebuilt on the split `fontdb/`: `KOREAN_SANS_FALLBACKS` and `sans_by_name` sit
in `fontdb/fallback.rs` beside `KOREAN_FALLBACKS`, `cjk_chain` takes the style,
`fallback_for_styled` is on both `ScopedFonts` and `FontDb`, and the tests live
in `fontdb/tests/fallback.rs` where that file's other fallback tests are.

`KOREAN_FALLBACKS` is serif-first (AppleMyungjo, Apple SD Gothic Neo, Batang,
Malgun Gothic...), so on Windows the first installed entry is Batang. A document
whose Korean text asks for faces that are not installed -- KoPub Dotum, KHNP
Han Dotum, BM Dohyeon -- came out in a serif face throughout: the report
measured 5,298 characters of one school document turning from sans to serif.

The font is not installed, so its name is all there is to go on. `sans_by_name`
reads the style out of the family name: Dotum (돋움), Gulim (굴림), Gothic
(고딕), Sans, Headline, Graphic and Dohyeon are sans; Batang (바탕),
Myungjo/Myeongjo (명조), Gungsuh (궁서) and Serif are serif. Serif is tested
first, so "Noto Serif KR" is not caught by the `sans` rule.

A run whose requested face is sans draws its fallback from the sans chain, which
leads with the system faces. If the requested name says neither, the
substitute's own name decides, which leaves today's chain in place.

The tests do not depend on which fonts the machine has: they pin the name
classification and the chain order -- the first sans entry comes before Batang,
and the serif chain still leads with a serif face, so a missing Myungjo is not
turned into a sans one.

`fallback_for` keeps its signature and delegates, so the ruby, kenten and image
callers are unchanged.
2026-10-27 16:30:57 +05:00
NetterSilverandClaude Haiku 5.5 e8c0a19180 Fix duplicated xref format text before an unclosed '<' in IDML export
Found while testing crates/idml/src/export/designmap.rs:208-230 (xref_format_el)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 11:26:46 +00:00
NetterSilverandClaude Haiku 5.5 e6a14a516a Keep underline, strikethrough, caps and tracking in EPUB/HTML character styles and overrides
Found while testing crates/epub/src/css.rs:~128-153 (the character-style loop in stylesheet_with)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 11:02:53 +00:00
Hamza 7c25cd97c4 Data merge: an image named by many records is read once (#1595)
`place_image` stat'd and read its file for every record, so a sheet naming one
image in many rows read it once per row -- up to 256 MiB each time. The audit's
case is a 100,000-row CSV naming one large file: about 25 TB of I/O for one
merge.

A merge now carries an `ImageCache`: the bytes by resolved path, read once and
shared. The asset takes the cached `Arc` rather than a copy, so the records
share one buffer as well. The cache stops growing past 256 MB of distinct
files, so a merge over many large images is slow rather than out of memory.

Measured by counting what the engine hands the file system (`io::touched`):

    without the cache   50 reads for 25 records   (a stat and a read each)
    with it             2

A note on the test, because the first one I wrote was useless: asserting on the
bytes the document holds passes either way, since `add_asset` already dedupes
identical content. Memory never showed this; the I/O is the bug, so the test
counts reads.

Audit DC-14. Its second half -- capping the pages a merge produces -- is not
here: how many pages a merge may make is a product decision, and the records
are the user's own data rather than something arriving from outside.
2026-10-27 15:25:27 +05:00
Hamza 93ab34f515 Data merge: the UNC refusal is tested on Windows too (#1601)
`image_path_tests` was `#[cfg(all(test, unix))]`, so the assertion that matters
most ran only where it matters least: a merge image field naming another
computer must resolve to nothing, because on Windows an outbound SMB connection
hands over NTLM credentials. That refusal was unverified on Windows.

The refusals now run everywhere -- nothing in them is unix-specific, since
`image_candidates` delegates to `craft-docpath` -- and the Windows shapes that
file refuses are asserted where they have meaning: `\\?\UNC\...`,
`\\.\pipe\...`, `\\?\C:\...` and the legacy device names.

Resolution beside the data and the document stays unix-only: it asserts what an
absolute path means, which cannot be checked on Windows from here.

No production code changes. On macOS both cross-platform tests pass; Windows CI
is the first real run of the Windows ones, which is the point.

Audit DC-20 (its testable part; the privacy note about absolute local paths
matches InDesign and is a product decision, not a bug).
2026-10-27 14:16:27 +05:00
NetterSilverandClaude Haiku 5.5 7fcebedf98 Drop XML-forbidden control characters in file.exportXml
Found while testing crates/engine/src/cmd/xml.rs:40 (esc, used by para_xml at :68 and the href at :104)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 09:07:12 +00:00
NetterSilverandClaude Haiku 5.5 590ea661a4 Fix RTF import swallowing characters after a short \'hh escape
Found while testing crates/textimport/src/rtf.rs:~118-131 (the \' branch of import: `i += 4` and `u8::from_str_radix(&hex, 16)`)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-27 08:29:34 +00:00
aiongg 50650f74d7 Iconic panel flyouts stay open while the canvas is in use (#1902)
Auto-Collapse Iconic Panels is off by default, so a flyout closes only from its icon or
another icon. The setting is saved under a new key, so preferences saved with the old
default start with it off, and Preferences > Interface > Panels shows it.
2026-10-27 01:54:50 -04:00
dotCooCoo fcea4173be Hide stale Story Editor depth marks while text changes
Draw the depth ruler and overset line after composition reflects the edited
text. Add a paint-output regression for inserting a paragraph break.
2026-10-26 21:42:22 -07:00
dotCooCoo 17247c929e Merge main into feat/story-editor-depth-ruler
Move the depth ruler state, translations, and menu command into the split UI modules.
2026-10-26 21:02:19 -07:00
aiongg 935b817b89 Merge pull request #1892 from aiongg/layout
refactor: shared module layout (craft-contrib#20)
2026-10-26 21:30:37 -04:00
skylar taylor-barrick 446a36d08b Merge pull request #1890 from storytold/fix/nextest-0.9.150
ci: require nextest 0.9.150
2026-10-26 17:34:43 -06:00
aiongg 42993ae680 test(engine): read only test cfgs and any pub(…) mod as test modules in the file guard
Split files share test helpers through pub(super)/pub(crate) test modules. The guard read only `mod` and `pub mod` as a test module, so it scanned their fixtures as production code. `attr.contains("test")` also matched `#[cfg(not(test))]`, so such a module was skipped; it is scanned now.
2026-10-26 23:06:07 +00:00
aiongg bbb495111e refactor(epub): split lib.rs into modules 2026-10-26 23:05:57 +00:00
aiongg 27e21ba19a refactor(render): split lib.rs into modules 2026-10-26 23:05:57 +00:00
aiongg 08f633ae48 refactor(fonts): split fontdb.rs into fontdb/ 2026-10-26 23:05:57 +00:00
NetterSilverandClaude Haiku 5.5 4f03e10594 Reject invalid XML tag names in xml.mapStyle
Found while testing crates/engine/src/cmd/xml.rs:~290 (the xml.mapStyle command; the export is in export_xml)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 21:37:07 +00:00
aiongg f553e17406 refactor(doc): move the CharAttrs and ParaAttrs sets to attrs/char_attrs.rs and attrs/para_attrs.rs 2026-10-26 21:00:23 +00:00
aiongg f15fe7aef0 refactor(ui-egui): split i18n.rs into i18n/table.rs 2026-10-26 21:00:23 +00:00
aiongg 2bca3285bf refactor(ui-egui): split app.rs into app/ 2026-10-26 21:00:23 +00:00
aiongg 02f595fe92 refactor(ui-egui): split lib.rs into app, state, services, clock and key_names 2026-10-26 21:00:23 +00:00
aiongg 2dd87273a2 refactor(doc): split attrs.rs into attrs/ 2026-10-26 21:00:23 +00:00
aiongg bc345384f6 refactor(doc): split table.rs into table/ 2026-10-26 21:00:23 +00:00
aiongg a24e9dffd1 refactor(doc): split item.rs into item/ 2026-10-26 21:00:23 +00:00
aiongg f70c3efa3c refactor(ui-egui): split chrome.rs into chrome/ 2026-10-26 21:00:23 +00:00
aiongg 8f601148b6 refactor(engine): split cmd/layout.rs into cmd/layout/ 2026-10-26 21:00:23 +00:00