Commit Graph
1933 Commits
Author SHA1 Message Date
Dylan M. Taylor d8cc88a772 Add image document formats to shared registry 2026-11-13 00:39:59 -05:00
Dylan M. Taylor ba24fe2435 Move bounded EPS rectangle parsing to craft-eps 2026-11-13 00:39:37 -05:00
Dylan M. Taylor c1a1b976d0 Resolve raster subformats centrally 2026-11-13 00:34:48 -05:00
Dylan M. Taylor 8d3c753b5e Recognize G-code filename extensions 2026-11-13 00:34:11 -05:00
Dylan M. Taylor 79c2003ac9 Add shared file format detection 2026-11-13 00:30:56 -05:00
Dylan M. Taylor 7c3a099ad8 Read native format JSON from streams 2026-11-13 05:21:58 +00:00
Dylan M. Taylor 3afade5163 Expose renderer-neutral SVG preflight 2026-11-13 00:13:31 -05:00
Dylan M. Taylor e95c99e7bc Support common raster output formats by path 2026-11-13 00:10:01 -05:00
Dylan M. Taylor dc705aa364 Re-export common RGBA pixel types 2026-11-13 00:09:00 -05:00
Dylan M. Taylor 1dbfad04fd Support extension-based raster encoding 2026-11-13 00:08:05 -05:00
Dylan M. Taylor 5407ea8220 Document required kerf field in native format example 2026-11-13 00:04:29 -05:00
Dylan M. Taylor 4ecdcd78da Export common raster codec facade 2026-11-13 00:03:41 -05:00
Dylan M. Taylor 8c41139369 Add shared raster codec facade and versioned JSON headers 2026-11-13 00:01:32 -05:00
Dylan M. Taylor ca7a73bd2c ci: allow longer Windows workspace gate 2026-11-13 04:50:46 +00:00
Dylan M. Taylor 7c10820123 Preserve ZIP directory semantics in bundle reader 2026-11-13 04:26:31 +00:00
Dylan M. Taylor a2e0f58632 Bound shared SoundCraft session IO 2026-11-13 04:20:55 +00:00
Dylan M. Taylor 88aa0bed6a Add shared SoundCraft session format 2026-11-13 04:07:08 +00:00
Dylan M. Taylor 4c25109473 test(openpgp): align signature time with generated key 2026-11-13 03:47:36 +00:00
Dylan M. Taylor f29cb7076f Merge remote-tracking branch 'origin/main' into codex/craft-time-soundcraft
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	README.md
2026-11-13 03:46:49 +00:00
Dylan M. Taylor ae0f0488dc craft-time: preserve SoundCraft time API and serialization 2026-11-13 03:44:51 +00:00
Dylan M. Taylor 7316e4e223 fix: clear workspace baseline gates on Rust 1.100 2026-11-13 03:13:53 +00:00
Dylan M. Taylor 94e65a4606 ci: run workspace checks with shared gate and test inputs 2026-11-13 03:06:38 +00:00
Nicolas Bohn 5056c13ef7 fix(dxf): split binary hex payloads into chunks of at most 127 bytes (#1147) (#1148) 2026-11-12 21:49:37 -05:00
Dylan M. Taylor 1b53814a38 Apply verified workspace format fixes 2026-11-13 02:37:09 +00:00
Dylan M. Taylor 7a639e04a7 Fix workspace clippy loop in LaTeX tests 2026-11-13 02:35:01 +00:00
Dylan M. Taylor d31b04810b Fix current workspace clippy diagnostics 2026-11-13 02:28:06 +00:00
Dylan M. Taylor c7fb7544c2 craft-stencilcraft-format: add native JSON schema 2026-11-13 02:23:04 +00:00
Dylan M. Taylor 6ef2334920 plotter: expect registration offset command 2026-11-13 02:05:17 +00:00
Dylan M. Taylor d316f0fc2d fix(xml): walk deep KRA and ORA trees iteratively 2026-11-13 02:05:09 +00:00
Dylan M. Taylor 2253894e2f fix: satisfy Rust 1.100 workspace clippy 2026-11-13 01:39:26 +00:00
Dylan M. Taylor 92d1bba5de fix(proof): satisfy workspace clippy gate 2026-11-13 01:28:46 +00:00
Dylan M. Taylor 198697cfc8 fix(cms): keep clippy compatible with workspace gate 2026-11-13 01:18:59 +00:00
Dylan M. Taylor 4cca9be2ab video: configure bounded decoder frame limits 2026-11-13 01:10:32 +00:00
Dylan M. Taylor 6fa8323991 video: saturate extreme H.264 picture order values 2026-11-13 00:44:21 +00:00
Dylan M. Taylor 409b0036f8 video: bound H.264 picture number arithmetic 2026-11-13 00:37:31 +00:00
Dylan M. Taylor 61d9de7846 psd: bound resource iterator size hint 2026-11-13 00:21:00 +00:00
Dylan M. Taylor dc20b58f01 Bound document bundle asset reads 2026-11-12 19:19:53 -05:00
Dylan M. Taylor ef01d69f7d Shared document bundle package IO 2026-11-12 19:11:55 -05:00
Dylan M. Taylor cc9c380543 Fix PSD resource iterator size hint 2026-11-13 00:05:37 +00:00
Dylan M. Taylor 341c84d1b1 Add borrowed PSD head resource views 2026-11-13 00:03:19 +00:00
Dylan M. TaylorandDylan Taylor f92a91afa4 plotter: add TB54 registration-mark offset command (#1139)
* plotter: add TB54 registration-mark offset command with py_silhouette citation

The full Silhouette registration sequence (TB99 through TB55, plus
TB123/TB124 for search and TB23 for manual positioning) is documented
in the community driver py_silhouette (zero_on_registration_mark()),
which reverse-engineered the protocol from public behaviour — not from
any proprietary binary.

TB54,0,0 sets the registration-mark offset to zero (mark at expected
position). Without it the machine may use a non-zero default offset.

* workspace: allow unused_workspace_dependencies lint

The root Cargo.toml declares many workspace dependencies that are not
referenced by any crate's Cargo.toml (e.g. craft-aep, craft-ai-core,
craft-cms, etc.). This is intentional — they are available for apps to
use. Suppress the clippy warning so CI passes.

* workspace: allow unused_workspace_dependencies (cargo lint)

This is a cargo-level lint (not clippy) that fires when workspace
dependencies declared in [workspace.dependencies] are not referenced
by any crate's Cargo.toml. Many entries are intentionally available
for apps to use.

* cms, prepress, proof: allow unused_workspace_dependencies lint

These crates are built individually by CI (cargo clippy -p <crate>)
which does not inherit workspace lints. Add per-crate suppression.

* cms, prepress, proof: inherit workspace lints

Add [lints] workspace = true so these crates pick up the
unused_workspace_dependencies suppression from the root Cargo.toml.

* revert: remove duplicate [lints] sections

The cms, prepress, and proof crates already had [lints] workspace = true.
My previous commits accidentally added duplicate sections.

* cargo: suppress unused_workspace_dependencies lint via config

This is a cargo-level lint (not clippy) that fires when workspace
dependencies declared in [workspace.dependencies] are not referenced
by any crate's Cargo.toml. Many entries are intentionally available
for apps to use.

---------

Co-authored-by: Dylan Taylor <dylanmtaylor@gmail.com>
2026-11-12 15:44:47 -05:00
.CooCoo d23f5f36bb craft-drawingml: outline digests print a near-zero coordinate without its sign (#1127)
outlines_match_the_string_dispatch failed on macOS for curvedRightArrow
while Linux and Windows passed. The digest prints each coordinate with
{:.3}, which writes a residue such as -1.4e-14 from the sine or cosine of
a right angle as "-0.000". The sign of that residue depends on the
platform's libm, so the digest did too.

digest_coord now maps every coordinate that prints as zero to 0.0 before
it is printed. The digests of pieWedge, curvedRightArrow and
curvedDownArrow, the only names whose outlines held such residues, are
taken again; no outline changes.
2026-11-12 13:45:57 -06:00
Dylan M. Taylor e98299546f crs: a repeated name keeps its first value, as craft-metadata reads it
craft-metadata #1042 keeps the first text-bearing value of a repeated
property so a blank repeat cannot hide a location, but craft-crs's doc
comment and test still claimed the last repeat wins. The workspace-wide
test job has been red since it landed because of that assertion.
2026-11-12 11:26:10 -05:00
Jeremy e85bd30bb2 Document the proposed Windows installation and persistent-model policy
* docs: add the Windows installation policy; models are persistent asse…

…ts, not caches

A companion policy to settings-storage.md: dual-scope per-user-default MSIs,
the ArtCraft suite folder, what an update must preserve (folder, context, no
duplicates), standalone installability, and the platform-native boundary on
macOS, Linux and FreeBSD. Splits models out of the disposable-caches row:
downloaded models are persistent user assets that cache cleanup and app
uninstallers must never delete.

* docs: describe suite Windows installation policy

* docs: record the wizard scope and folder rules and the real-install c…

…hecks

The scope page leaves ALLUSERS unset for Only for me, and the wizard sets the new-install folder itself after the choice, because Windows Installer resolves Program Files once for the context it started in. Notes the 32-bit Program Files (x86) folder and updates the adoption table to say real per-user and all-users msiexec runs were done. Clean-machine and second-account checks are still pending.

* docs: new installs default to per-machine; only the old default folde…

…r moves

* docs: say plainly that released packages still default to per-user

The policy says new installs are per-machine, but every released package is
dual-scope with a per-user authored default, and the inventory still listed
"Per-user default". The policy now separates the two: what the policy is, what
the packages do today, who picks per-machine (the launcher, or "Everyone" in the
wizard), and the follow-up that closes the gap.

Also: Update all's one-prompt route was reverted after the antivirus incident,
so the policy no longer says it asks once; the Linux model folder names its
ArtCraft/models subfolder; repair is listed where the 26/10 payload runs
covered it; the inventory no longer says nothing was released.

* docs: the launcher and a direct MSI run match only for the same scope…

… and folder

CodeRabbit pointed out that 'produce the same result' contradicted the
documented new-install difference: the launcher sets ALLUSERS=1, while a
direct run keeps the package's per-user default.

* docs: make the legacy-folder migration exception explicit

State that exact former-default paths can migrate even when manually
chosen, subject to maintainer acceptance of the proposed policy. Preserve
other chosen folders and document the effect on custom shortcuts.

---------

Co-authored-by: Jeremy <jeremy8776@googlemail.com>
2026-11-12 10:43:51 -05:00
nonplessesdsnrffffandBen Mathews 65cf3f9b0d craft-web-host: accept PDF page attachments from the host
* craft-web-host: accept PDF page attachments from the host

---------

Co-authored-by: Ben Mathews <ben@themathewsgroup.com>
2026-11-12 10:43:32 -05:00
Ken MantleandKenM76 f3b643d081 prepress: separate a page in bands, past the 4 MP plate cap
* prepress: separate a page in bands, past the 4 MP plate cap

`plates_in_bands` finds a page's inks once, then separates it in row
bands of at most MAX_PLATE_PIXELS each, rendering every band through
craft-pdf raster's size/offset viewport. A page can now be separated at
print resolution with bounded memory: only the renderer's 8192-pixel
side limit and a 256 MP per-plate total (MAX_BANDED_PIXELS) lower the
resolution. `plates` is unchanged in behaviour: it is the one-band case
of the same code.

Tests: bands of 7 rows join byte for byte into the whole-page render of
an anti-aliased disc under an overprinting spot (fails when the band
offset is dropped), and a 40 pt page at 3700 dpi separates at full
resolution in bands under the cap (fails when banding uses the plate
cap's scale).

Refs #838.

* prepress: bands pass the renderer's whole-page limits

The page's pixel size came from `raster::dimensions` on the whole page,
which enforces the renderer's 64 MP and 8192-pixel side limits, so a
Letter page past about 830 dpi failed with OutputLimit instead of
banding. The size is now computed as the renderer floors it, and only
each band's viewport reaches the renderer. Bands are also capped at
MAX_SIDE rows, and ink discovery renders within the renderer's limits.

A Letter page at 900 dpi now separates in 19 bands at full resolution;
across the page the side limit still lowers it, near 960 dpi.

Test: a 10 x 2000 pt strip at 600 dpi (16 666 rows) separates in three
bands with its black square on the right rows. It fails with either the
whole-page dimensions call or the uncapped band height restored.

* prepress: check the page before discovery; say what the banded cap bounds

The page-size check now runs before ink discovery renders anything.
MAX_BANDED_PIXELS bounds pixels, not the number of bands; the doc
comment and the README caps table say so.

* prepress: count a sub-pixel side as one pixel in the banded cap

A side scaled under one pixel still renders one, so a very thin, tall
page could pass MAX_BANDED_PIXELS by far. banded_scale now fits the
other side alone in that case, and separate() refuses any floored size
over the cap before it renders a band.

* prepress: keep the banded area scale under the cap after rounding

The area scale came from the exact cap, so f32 rounding could floor a
page one row past it (17 x 15 058 824 pt at 72 dpi), which then failed
with OutputLimit. The same 0.1% margin as the one-pixel branches now
applies to the area scale too, with a test on that page.

---------

Co-authored-by: KenM76 <KenM76>
2026-11-12 10:41:24 -05:00
skylar taylor-barrickandskylartaylor 86ed498b49 Prepare v0.1.0 with release notes, versioning policy and pinned adoption
* Prepare the first coordinated craft-libs release

---------

Co-authored-by: skylartaylor <skylartaylor@users.noreply.github.com>
2026-11-12 10:38:46 -05:00
aionggandaiongg 270db68c1e craft-cms: run the CMS suite in CI
* craft-cms: run the CMS suite in CI; say when system-profile checks are skipped

* craft-cms: satisfy clippy's chunks_exact_to_as_chunks lint in the total-ink test

---------

Co-authored-by: aiongg <aiongtaigi@gmail.com>
2026-11-12 10:38:37 -05:00
Zach Shallbetter b6cbd59671 craft-atomic: eliminate runtime panic on wasm32-unknown-unknown (closes #81)
* craft-atomic: eliminate runtime panic on wasm32-unknown-unknown (closes #81)

---------

Co-authored-by: Zach Shallbetter <zachshallbetter@icloud.com>
2026-11-12 10:38:30 -05:00
Hamza NaveedandHamza 75af6f589a PDF interpret: a glyph shown in a clipping mode clips even with no outline
* PDF interpret: a glyph shown in a clipping mode clips even with no outline

A glyph shown in a clipping render mode (`4 Tr` to `7 Tr`) adds its outline to
the clipping path, and that clip applies to everything painted after `ET` until
the enclosing `Q`. When the glyphs shown have no outline -- a space, say -- the
clip they contribute is empty, and an empty clip admits nothing.

`interpret_window` applied a clip only once a glyph had contributed an outline,
so such a text object applied *no* clip and what followed painted unmasked.

A text object that shows no glyph at all is a different case and is left alone:
the clipping path is unchanged there, as readers leave it, and a glyph whose
outline is unavailable (Type 3) leaves the real clip unknown, so both stay
unclipped. pdf.js draws the same line in `endText`: it builds the clip from the
glyphs shown, empty outlines and all, and applies none when none were shown.

Measured on a page filled red behind the text object, Preview (CoreGraphics)
and Firefox (pdf.js) agreeing on the case this changes:

    a space shown in 7 Tr    before: the fill paints   after: nothing paints
    no glyph shown in 7 Tr   unchanged: the fill paints

Companion to storytold/pdfcraft#3451.

The first push of this branch also carried 803 build-artifact files from
`crates/pdf/read-only-contract/target/`, which `.gitignore` did not cover: its
`/target` is anchored to the repository root, so a sub-crate's own build
directory is not ignored. Recommitted without them, and `target/` added so the
next one cannot slip in either (#185 review).

* pdf: test visible glyphs in a clipping mode, and what each clip leaves on the page

---------

Co-authored-by: Hamza <mail.hamzanaveed@gmail.com>
2026-11-12 10:38:02 -05:00