* Pin craft-libs at 420d21a
* Pin craft-libs at 16fb3d4
* Use craft-ui's shared docking workspace and ui.dock commands
Replace the local Workspace, its validation, apply, visibility and the
ui.dock parser with craft_ui::docking::Workspace and DockOperation.
CADCraft keeps its panels, the drawing view's rules, the default layout
and the workspace file. Add tests for loading a v1 workspace file and for
dragging a panel group by its bar.
* Pin craft-libs at 6e7f285
* Docking: reveal panels through craft-ui's set_visible, which reopens groups and places new panels itself
* Docking: palette switches regroup a panel whose recorded anchor is hidden instead of opening it alone
* Depend on craft-pdf (krilla writer, reader for tests) at craft-libs 9f75d3dc
The root patches pin the patched krilla and hayro-syntax/hayro-jbig2 to
the same revision, as craft-pdf requires.
* Plot PDFs with craft-pdf's krilla writer
The hand-written object, xref, stream and font writer goes. Each sheet's
display list is built, written as its page and dropped before the next.
Strokes with the same colour, width and transparency stay one path, and
each filled primitive is one path of its triangles. Text in embeddable
TrueType fonts is drawn as glyphs; krilla subsets the fonts and writes
their ToUnicode maps, so the hand-written subsetter goes too and
cadcraft-fonts keeps only the fsType embedding check. Primitives with a
point that is not finite or beyond 1e7 pt are left out. A font krilla
cannot embed after all makes the export retry with text as outlines.
Optional content (PDF layers) is not written until craft-libs' writer
supports it: the layer transitions go through one empty function, layers
that are off are not plotted, and the layer tests are ignored.
The tests read the PDF back with craft-pdf's reader.
* Pin craft-pdf and its krilla and hayro patches to craft-libs cd160e73
cd160e73 adds optional content groups to the patched krilla.
* Write drawing layers as PDF optional content groups
Each drawing layer a page draws on gets one group, named after the layer
and shared by all pages, created before the first page that uses it. A
group starts hidden when its layer is off in the drawing, so `offLayers`
again plots layers that are off on hidden PDF layers. At most 4096
groups per file; objects on further layers print unmarked. A single
sheet with groups opens with the viewer's layer panel (/PageMode /UseOC).
Layer changes end and start the marked content, and the last mark ends
before the page finishes.
The layer and text tests that check the groups run again, and a test
covers the group cap.
* Plot a zero-length line as a round dot in PDFs
krilla leaves out a path without extent, so a lone zero-length line drew
nothing. It is filled as the dot its round-capped stroke would make, as
wide as the stroke, with 0.25 pt for a hairline.
* PDF: retry as outlines when the writer fails inside a font; cap layer names; restore two test checks
* Tests: read plotted PDFs back through the shared reader in plot_layout_scale and plot_styles
* Pin craft-pdf, krilla, hayro-syntax and hayro-jbig2 to craft-libs main (7895f5e)
* PDF tests: read path coordinates in page space; cover the font retry and out-of-range points
- pdf_read maps path operands through the CTM (`page_ops`, used by `drawn` and
`clip_rect`) and checks that the plot area is drawn in page space.
- The 1:1 layout test finds the viewport corner at (72, 72) in page space, so a
mirrored page fails it.
- A font with a short hmtx passes the writer's font checks but fails subsetting;
the plot retries and draws its text as outlines.
- A primitive with a point past 1e7 pt is left out, and the rest still plots.
* PDF: clip a primitive with a far vertex to the plot area instead of leaving it out
A polyline or fill with a point past the writer's f32 range now keeps the
parts inside the plot area (polylines with the area widened by the stroke
width), each piece its own subpath. Primitives in range are written as before.
The test reader requires a decodable content stream.
* Build: line tables only in dev, no debug info for dependencies
* Tests: one integration-test binary per crate
Each crate's tests/*.rs becomes a module of tests/it/main.rs. Files that
install process-wide state (the file io hooks, user aliases, SAVETIME and
SAVEFILEPATH, user linetype and pattern files, registered fonts) stay their
own test binaries.
* xtask ci: nextest, tests without examples, one wasm check call
* Use chrono for UTC/calendar conversion instead of hand-rolled copies
Replaces the three civil_from_days copies (logging timestamp, Drawing
Recovery time, parity checklist date) with chrono as a workspace
dependency. Output formats are unchanged and pinned by the existing tests.
AGENTS.md now says time goes through chrono.
Fixes#1785
* Never panic on a clock outside chrono's range; keep 5-digit years unprefixed
chrono's From<SystemTime> unwraps, so a clock past year 262143 panicked
inside the logger. timestamp and xtask's date now use the fallible
DateTime::from_timestamp and read such a clock as the epoch, as the old
saturating code did. xtask's date also clamps a pre-epoch clock to
1970-01-01 again. Years past 9999 are written with {:04} like before,
because %Y would add a '+'. Tests cover all three cases.
* Don't build an unrepresentable SystemTime in the far-future test
UNIX_EPOCH + Duration::from_secs(u64::MAX / 2) overflows Windows'
SystemTime and panicked before timestamp() ran, failing the Windows
test job. Build it with checked_add and only assert where it exists.
* logging/autosave/parity: keep extended-year dates, no epoch fallback
Applies the stricter no-epoch-fallback rule (from wordcraft#3427 / filmcraft#2662,
superseding the earlier epoch-or-last-valid suggestion) so all sibling PRs agree:
a timestamp the old code converted past chrono's year 262143 range must keep its real
proleptic-Gregorian date, not collapse to 1970-01-01. Each site uses the 400-year
Gregorian cycle (146_097 days) with chrono as the only calendar logic: chrono converts
the day within one cycle, whole cycles carry in the year (i128, saturated into i64).
This also removes the panic FredApps flagged — `DateTime::<Utc>::from(SystemTime)` could
panic past chrono's range; `from_num_days_from_ce_opt` within one cycle never does.
Verified the cycle result equals the old formula across a wide range and at the extremes.
- apps/cadcraft/src/logging.rs `timestamp`: cycle `civil_from_days(u64)`; pre-1970 epoch
clamp and ms/time-of-day format kept. Pins: +10_000_000_000_000 s -> 318857-05-20T17:46:40.000Z
(was 1970-...); checked_add u64::MAX/2 s -> 292277026596-12-04T15:30:07.000Z (was epoch).
- crates/ui-egui/src/autosave.rs `utc`: cycle converter. Pins: utc(10_000_000_000_000)
= "318857-05-20 17:46"; utc(u64::MAX) = "584554051223-11-09 07:00" (was "1970-01-01 00:00").
- xtask/src/parity.rs `date`: cycle converter; pre-1970 epoch clamp kept. Pins:
day(115_740_740) = "318857-05-20"; checked_add u64::MAX/2 s -> "292277026596-12-04" (was epoch).
* Don't build a year-318857 SystemTime unchecked in the logging test
Windows' SystemTime only reaches about year 30828, so
UNIX_EPOCH + Duration::from_secs(10_000_000_000_000) panicked before
timestamp() ran and failed the Windows test job. Build it with
checked_add and assert where the platform can hold it. The year-10000
case fits everywhere and stays unconditional.
* Name the 400-year range extension as the one exception to the time rule
The rule said never to hand-roll calendar math, but the range fix
(shifting by whole 400-year Gregorian cycles so dates past chrono's year
range keep their old output) is cycle arithmetic, so the rule and the code
disagreed. The rule now names that exception: the library still computes
month, day and time, and only whole cycles are carried in the year.
* Say the library computes month and day; time-of-day is plain arithmetic
Narrows the range-extension wording: the date library computes the
calendar fields, and splitting seconds into hours, minutes and seconds
is ordinary arithmetic, which is what the code does.
craft-libs#169 is merged, so the fork pin is no longer needed. Pinned to
storytold/craft-libs 82a24b006eefa036b43c09a67fb9a3fbd17ffe63 (main after the merge) rather than the older 12281d07,
which predates resolve_absolute and the Windows colon refusal.
Xref paths saved in a drawing (on open, on Reload, in the External
References list, XOPEN, nested xrefs) and table data-link paths re-read by
DATALINKUPDATE go through doc_path::resolve (craft-docpath): relative
paths resolve beside the drawing that stores them, and paths to other
computers, devices and URLs are not opened. Such an xref is Unresolved
with the reason, unless a file of its name is beside the host drawing.
Paths given to XATTACH, -XREF Path and DATALINK are used as given.
One load of xrefs reads at most 1 GB from referenced files in total.
The previous release build failed in craft-common-actions, not in this
repo: riscv64 packaging got --formats deb,rpm,tar (fixed in
craft-common-actions#3), Linux jobs lacked the ALSA headers
(craft-common-actions#5), and Windows signing needed the AZURE_* secrets
listed in the caller.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The shared release workflow sets CRAFT_FONTS_DIR with CRAFT_FONTS_REQUIRED=1
but only checks craft-fonts out when craft-fonts-ref is given. Since #321
cadcraft-fonts reads that directory, so every native release job failed
with "fonts/manifest.txt: No such file or directory". Pin craft-fonts
3d9ab3a (current main, with the Arabic faces the web build embeds).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- release.yml: new `linux-riscv64` job (ported from GridCraft): cross-compiles on ubuntu-24.04
against ports.ubuntu.com riscv64 libraries, packages a tar.gz, smoke-tests the CLI under
QEMU. The draft-release job now needs it, so SHA256SUMS covers the tarball.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support.
- README Downloads and docs/releasing.md list the riscv64 tarball.
- Version 0.4.0 -> 0.5.0 (cargo xtask version set), Cargo.lock refreshed.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Annotation (M4):
- TrueType text from system fonts (filled/outlined), shared placement for all text
- MTEXT formatting codes: fonts, heights, colours, under/overline, stacks, wrapping
- Full DIMSTYLE variables, per-dimension overrides, all arrowheads and ticks,
unit formats, tolerances, limits, alternate units, colours by role
- Associative dimensions that follow geometry; DIMREASSOCIATE/DIMDISASSOCIATE
- STYLE/DIMSTYLE management commands, DIMTEDIT, DIMSPACE, TABLE create/edit/merge
Parametric (M9):
- New cadcraft-constraints crate: weighted damped Gauss-Newton solver, conflict
and redundancy detection, expressions, AutoConstrain inference
- All GC*/DC* commands, GEOMCONSTRAINT/DIMCONSTRAINT, PARAMETERS, DELCONSTRAINT,
constraint bar / display settings; re-solve after every edit
Also: MODEL/PAPER status bar toggle, cargo xtask alias, roadmap update
(233/491 menu items, 290 commands).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>