Commit Graph
871 Commits
Author SHA1 Message Date
aiongg 786367e9ba Merge pull request #2331 from Silvertree2010/perf/export-speed
Speed up PNG export: stroke runs of hairline polylines as one path
2026-10-27 13:41:15 -04:00
NetterSilverandClaude Opus 5.5 850dd94f3c Stroke runs of hairline polylines as one path in the rasteriser
PNG export (and everything else drawn by raster::render) stroked every
polyline primitive with its own tiny-skia stroke_path call: a new path
and a newly built paint pipeline per primitive. Hatch patterns, linetype
dashes and text strokes produce long runs of short polylines in one
colour, so that per-call setup dominated the render.

Consecutive hairline polylines (zero width, or at most one pixel when
anti-aliased; the default for PNG export) with the same colour, alpha
and width are now collected into one path and stroked once. tiny-skia
draws hairlines segment by segment straight onto the pixmap with the
same per-contour round caps, so the pixels and their blending order are
unchanged. Thicker strokes (filled outlines), fills, points, infinite
lines and polylines with non-finite or far-out screen coordinates break
the run and are drawn exactly as before.

Adds crates/io/examples/export_bench.rs, which exports examples/
apartment.dxf repeated on a grid (10x10: 5,800 entities) and reports
median/min wall time per format.

PNG export, 10x10 grid, 11 interleaved runs (Ryzen, 16 threads, Linux):
  before: median 1790.7 ms, min 1703.3 ms
  after:  median 1037.6 ms, min  926.0 ms   (-42.1 %)
A/A noise on the same setup: 1.1 %. Output PNGs are byte-identical
(bench at 10x10 and 20x20, CLI export of apartment.dxf and a 23,200-
entity drawing). New tests compare render() against stroking each
primitive on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 15:47:42 +01:00
aiongg 0ff1b03537 refactor(ui): use craft-ui's ComboBox for every dropdown (#2303)
* ui: use craft_ui::ComboBox so dropdown menus grow back (egui#5225)

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

* chore(deps): craft-libs 6af63481 (dropdown fixes)

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

* chore(deps): craft-libs 92d392cf (#387 merged)
2026-10-27 10:26:40 -04:00
aiongg d864a08b01 Merge pull request #2220 from aiongg/layout
refactor: shared module layout (craft-contrib#20)
2026-10-26 21:30:19 -04:00
skylar taylor-barrick c3b8e7b7fe Merge pull request #2227 from storytold/fix/nextest-0.9.150
ci: require nextest 0.9.150
2026-10-26 17:35:13 -06:00
skylar b06fd039fb ci: require nextest 0.9.150
Use the fixed release for GHSA-vc25-qg58-w57c.
2026-10-26 14:13:04 -06:00
aiongg 7d2ca90783 refactor(engine): move Session methods from session.rs to session/ 2026-10-26 19:44:13 +00:00
aiongg af9798e200 refactor(doc): move entity.rs items to entity/ 2026-10-26 19:44:13 +00:00
aiongg c042e98abb refactor(render): move dim.rs items to dim/arrowheads.rs and dim/text.rs 2026-10-26 19:44:13 +00:00
aiongg 994af5cac9 refactor(render): move lib.rs items to display, pipeline, viewports, props, draw, text_entity, dim_draw, blocks 2026-10-26 19:44:13 +00:00
aiongg 970e6bb9d4 refactor(io): move dxf_read.rs items to dxf_read/ 2026-10-26 19:18:38 +00:00
aiongg 736a83464a refactor(io): move dxf_write.rs items to dxf_write/ 2026-10-26 19:18:38 +00:00
aiongg aa5dfc2099 refactor(engine): move lisp/builtins.rs items to lisp/builtins/ 2026-10-26 19:18:38 +00:00
aiongg f12b7570b7 refactor(engine): move lib.rs types to error, view, doc_state, settings, running, last_used and Session methods to session.rs 2026-10-26 19:18:38 +00:00
aiongg 795eb62762 refactor(engine): move cmd/draw.rs items to cmd/draw/ 2026-10-26 19:18:38 +00:00
aiongg e7b92c5b8e refactor(engine): move cmd/annotate.rs items to cmd/annotate/ 2026-10-26 19:18:38 +00:00
aiongg 6028cdf187 refactor(engine): move cmd/modify2.rs items to cmd/modify2/ 2026-10-26 19:18:38 +00:00
aiongg 172f9ca44c refactor(engine): move cmd/draw2.rs items to cmd/draw2/ 2026-10-26 19:18:38 +00:00
aiongg c5e7db78e4 refactor(engine): move cmd/modify.rs items to cmd/modify/ 2026-10-26 19:18:38 +00:00
aiongg 31a04e3dbe refactor(ui-egui): move canvas.rs items to canvas/ 2026-10-26 19:18:38 +00:00
aiongg 627ffb8d7e refactor(engine): move grips_tests.rs to grips/tests.rs 2026-10-26 18:18:08 +00:00
aiongg 18f47e021f refactor(engine): move cmd/inquiry/usage_tests.rs to cmd/inquiry/usage/tests.rs 2026-10-26 18:18:08 +00:00
aiongg 21d80b3231 refactor(engine): move cmd/txt2mtxt_tests.rs to cmd/txt2mtxt/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 62deed7880 refactor(engine): move cmd/mleader_edit_tests.rs to cmd/mleader_edit/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 45bcfa6f77 refactor(engine): move cmd/constraints_tests.rs to cmd/constraints/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 627b5a3350 refactor(engine): move cmd/annotate_tests.rs to cmd/annotate/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 1006e487da refactor(engine): move cmd/modify2_tests.rs to cmd/modify2/tests.rs 2026-10-26 18:18:07 +00:00
aiongg fcd4a0c9eb refactor(engine): move cmd/draw2_tests.rs to cmd/draw2/tests.rs 2026-10-26 18:18:07 +00:00
aiongg dbd2bf5dad style: cargo fmt after moving test modules out 2026-10-26 18:18:07 +00:00
aiongg d7915c5f3b refactor(ui-egui): move canvas.rs tests to canvas/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 1bbc5ec76b refactor(engine): move layout.rs tests to cmd/layout/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 012732136c refactor(geom): move spline.rs tests to spline/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 273303134e refactor(ui-egui): move hatchdlg.rs tests to hatchdlg/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 48d25a0414 refactor(render): move dim.rs tests to dim/tests.rs 2026-10-26 18:18:07 +00:00
aiongg 6021d96628 refactor(ui-egui): move capture.rs tests to capture/tests.rs 2026-10-26 18:18:07 +00:00
aiongg ad329273f2 refactor(ui-egui): move crates/ui-egui/src/options/mod.rs to crates/ui-egui/src/options.rs 2026-10-26 18:18:07 +00:00
aiongg f3796d1f7a style(ui-egui): cargo fmt after the i18n.rs move 2026-10-26 18:18:07 +00:00
aiongg 3a64a190ea refactor(ui-egui): move crates/ui-egui/src/i18n/mod.rs to crates/ui-egui/src/i18n.rs 2026-10-26 18:18:07 +00:00
aiongg 5074d2a54c refactor(engine): move crates/engine/src/lisp/mod.rs to crates/engine/src/lisp.rs 2026-10-26 18:15:12 +00:00
aiongg bccba7261e refactor(engine): move crates/engine/src/cmd/mod.rs to crates/engine/src/cmd.rs 2026-10-26 18:15:12 +00:00
aiongg c8ee56a44f test: scan source directories recursively
The translation gap report reads each listed UI module and every file under its directory, so code split into submodules stays in the report.
2026-10-26 17:59:21 +00:00
aiongg d3ae8a6af0 Side panels dock in left and right dock columns (#2158)
* Pin craft-libs at craft-libs#312's head (4dc543c) for the dock-column move

* Side panels dock in left and right dock columns

Tool Sets sits in a left dock column and Layers above Properties in a right
one, at the widths of the old side frames. Palettes dock only into those
columns: a window edge without a dock makes one, and neither the drawing nor
the top and bottom edges take a drop. A palette opened with no recorded place
goes into its dock group (External References below Properties). Iconic
columns show CADCraft's own code-drawn icons.

* Workspace file: dock layout version; split-frame layouts reset to the default

The workspace file saves dockingVersion next to the panel layout. A layout
saved without it, or with an older one, is dropped with its hidden panels on
load; the other workspace settings are kept.

* Floating panels open in their own OS windows on the desktop

- craft-ui's native-windows feature is on for the desktop app (not the web build)
  and for the UI crate's tests.
- While the Save changes prompt, Drawing Recovery or another egui modal is up,
  the panels' OS windows take no input.
- Keys, text and clipboard events typed in a panel's OS window go into the main
  window's next input, so shortcuts, the command line and the canvas get them.
- Files dropped on a panel's OS window open like files dropped on the main window.

* Floating windows stay below the macOS title row

A drag in that row moves the whole app window, so a floating panel drawn over it
could not be moved or used. The dock area keeps floating windows, flyouts and
drag ghosts below it.

* Opening a floating panel from a menu or command brings its window to the front

* Workspace saves are spaced at least 500 ms apart, so dragging a floating window doesn't write the file every frame

* Pin craft-libs at #312's head b6d35e28

* Pin craft-libs at #313's head cdc67131 (result-rectangle drop preview)

* The title row is craft-window's title bar

Its empty part moves the window and follows the macOS double-click setting,
and does nothing in full screen. On macOS the window's movable flag follows
the pointer, so AppKit's title-band drag leaves the window still under the
row's controls and under floating panels. Floating panels may therefore go
over the title row again.

craft-window is pinned at craft-libs#316's head, which is not stacked on the
craft-ui pin.

* Pin craft-libs at 189b4ffe (#313 and #316 merged)

* macOS menu choices and their shortcuts run at once

A menu choice is no window event, so the app ran it only at its next frame
for another reason: File ▸ Close (Cmd+W) on an edited drawing showed
"Save changes?" and dimmed the floating palettes a second or two late. The
menu's event handler now wakes the app.

* Pin craft-libs at pin-round3 d24e4bcc

* Cargo.lock and the native-window test helper after the egui 0.37 merge

* Pin craft-libs at #334 (4638095): the title bar's empty area takes no keyboard focus

* Pin craft-libs at main 271594c0

* A modifier the main window changes while panel keys are forwarded is the one put back
2026-10-25 22:23:01 -04:00
aiongg 2a2d4e2582 macOS Edit menu keys edit a focused text field (#2139)
* macOS Edit menu keys edit a focused text field

The menu bar takes ⌘C, ⌘X, ⌘V, ⌘A, ⌘Z and ⇧⌘Z before any window sees them,
so they ran Copy, Paste or Undo on the drawing while the user was typing in a
field. While a text field has the keyboard, in the main window or a floating
panel's own window, the menu now hands the field its key instead.

craft-libs is pinned at #318's head for typing_window and send_keys.

* Edit menu items a text field takes stay enabled while one has the keyboard

Edit ▸ Paste follows the drawing clipboard, so with nothing copied in the
drawing it was greyed out even while a text field could paste.
2026-10-25 21:58:11 -04:00
Dylan M. Taylor d1cf06cbea refactor: split complex fillet, model, dimstyle and rectangle code into helpers (#2188)
Pure extraction, no behaviour change: same order of side effects, same
early returns and error values. Clears cognitive-complexity findings on
tangent_circles, Model::build_budgeted, DimStyle::apply_fields and
run_rectang2 (S3776), and replaces a redundant closure with a method
reference in menus.rs (S1612).
2026-10-25 21:50:25 -04:00
Dylan M. Taylor 7d33d9d4dd refactor: split complex input, explode, sweep, cache and options code into helpers (#2187)
Pure extraction, no behaviour change: same order of side effects, same
early returns and error values. Clears cognitive-complexity findings on
AreaM::input, explode_kind, hatch sweep, the COMPARE overlay paint and
the Files options tab (S3776).
2026-10-25 21:50:19 -04:00
Dylan M. Taylor 53080b1748 refactor: split complex matchers, scanners and solver setup into helpers (#2186)
Pure extraction, no behaviour change: same order of side effects, same
budget charges, same early returns and error values. Clears
cognitive-complexity findings on glob_inner, the PDF test ops scanner,
snap_ends, the loops inquiry run and build_budgeted (S3776).
2026-10-25 21:43:08 -04:00
Dylan M. Taylor 21c48cc05b refactor(io): split complex PDF marks and DXF readers into helpers (#2185)
Pure extraction, no behaviour change: same order of side effects, same
early returns and error values. Clears cognitive-complexity findings on
pdf::marks, dxf_read::read_budgeted, parse_entities,
entity_with_table_budget and Objects::apply (S3776).
2026-10-25 21:43:04 -04:00
aiongg 47237bd4dd chore(deps): safe dependency refresh (#2179)
* chore(deps): safe dependency refresh

* Hold acadrust at 0.6.6: 0.6.7 reads nothing from a damaged DWG
2026-10-25 21:15:06 -04:00
Dylan M. Taylor 2521605713 refactor: explicit imports instead of wildcards (S2208, batch_02) (#2039)
* refactor: replace wildcard imports with explicit ones (S2208, batch_02)

* Fix unused and missing imports the batch's CI gate reported

Remove two unused imports and restore the json macro and resolve_alias
in test modules that the explicit import lists had dropped.

* fix: keep the imports the explicit lists still need after the rebase

* fix(draw2): import machines, distinct_points and ok from cmd
2026-10-25 19:52:19 -04:00
Dylan M. Taylor f56be09993 refactor: explicit imports instead of wildcards (S2208, batch_04) (#2041)
* refactor: replace wildcard imports with explicit ones (S2208, batch_04)

* refactor: replace wildcard imports with explicit ones (S2208, batch_04)

* Format imports so the CI fmt gate passes

* fix: import f64_req in inquiry.rs
2026-10-25 19:37:00 -04:00