Commit Graph
1565 Commits
Author SHA1 Message Date
aiongg 1afbab004e ci: run the PDF jobs when craft-cms changes
craft-plate-test and craft-prepress depend on craft-cms, and the craft-pdf tests read its
CMYK profile.
2026-10-20 04:09:24 +00:00
aiongg 4c3cc64469 pdf: faster plate tests
The plate helper renders all inks of a page with one render cache, as a separating caller
does, so ICC transforms are built once per page instead of once per plate. The mutated
profile test changes the header fields a reader checks instead of every 16th header byte,
and samples the tag data more sparsely: each profile that still loads costs a fifth of a
second in a debug build.
2026-10-20 04:06:29 +00:00
aiongg e6d2a24641 prepress: to_pdf_color writes ink colors as DeviceCMYK, Separation or DeviceN
Process tints become DeviceCMYK, one spot a Separation with its alternate, other mixes a
DeviceN space with process inks first, registration and None the All and None
separations. Lab spot alternates convert through the printing condition, as resolve does.
2026-10-20 03:57:10 +00:00
aiongg 4026931196 Merge craft-prepress into the print color PR 2026-10-20 03:51:59 +00:00
aionggandfilipessmedeiros-collab 07585888d6 docking: floating windows resize from the top edge and corners
A resizable FloatingFrame keeps a 4 pt band above its contents for the
Top, TopLeft and TopRight handles, so they take no title bar moves or
button clicks. They keep the opposite edges in place, respect the size
limits and the screen, take arrow keys when focused, and have hit ids.
Moves carry the whole frame rect, band included.

Ported from #189.

Co-authored-by: filipessmedeiros-collab <343926472+filipessmedeiros-collab@users.noreply.github.com>
2026-10-20 03:51:38 +00:00
aiongg 72a0a4dc78 docking: rustfmt 2026-10-20 03:51:13 +00:00
aiongg 4344dfccf9 plate-test: keep short arrays and objects on one line in the scene files
Mark the krilla patch files as generated, so diffs collapse them.
2026-10-20 03:51:04 +00:00
aiongg 46f2ffd654 docking: a press in a group header focuses the shown panel
Host widgets in the header, such as a menu button or the host's own tabs,
focus the panel the way a press on its tab or body does.
2026-10-20 03:47:12 +00:00
aiongg 91e8cf401e docking: chrome_has_focus recognizes every control a Hit names
It checks the same widget ids as hit_rects and hit_id, which adds icons and
icon grips.
2026-10-20 03:46:31 +00:00
aiongg 815d648016 docking: split divider hits name the layout path while panels are hidden
A split's handle id and its Hit::Divider use the layout path that
ResizeSplit takes, also when hiding panels collapses a split in the drawn
tree.
2026-10-20 03:45:18 +00:00
aiongg ae0c19b49b docking: hidden floating windows do not cover dock targets
Dock targets check the floating windows drawn this frame instead of every
window's last egui area rect. floating_layer says that an undrawn window
keeps its last area rect.
2026-10-20 03:44:25 +00:00
aiongg a55cbe870e docking: a huge wheel delta over a tab strip stops at the last tab
The step count saturates instead of overflowing the index subtraction.
2026-10-20 03:42:52 +00:00
aiongg cef258a356 docking: a column's first tab docks beside its own column
A dock target named by the dragged panel itself anchors on another panel
of the same group or column, or leaves the panel in place when it is alone
there, instead of failing with InvalidPlacement.
2026-10-20 03:42:36 +00:00
aiongg e5b73eb4cf plate-test: mesh gradient paint and scene S17 (spot, process and DeviceN corners) 2026-10-20 03:41:18 +00:00
aiongg 60dc2b54ce krilla: write mesh corner colors in one color space
A mesh gradient took its color space and component count from the first
patch's first corner, so a later corner in another space was truncated or
padded with zeros and written as the wrong color. Mesh corner colors now go
through the same rule as gradient stops (`common_color_space`): process
colors alone are DeviceCMYK, one spot alone is Separation, and mixes are
DeviceN with process colorants first, then spots. Colors that rule can't
unify (RGB with CMYK, registration) fail the document with
`KrillaError::MixedMeshColorSpaces`. The opacity soft mask is unchanged, and
a mesh in one space writes the same bytes as before.

patches/10-mesh-gradients.patch holds #184's change and this fix, so
patches 01 to 10 reproduce src; the ledger section 10 and SOURCE.json follow.
2026-10-20 03:41:18 +00:00
fastmikey99 ce31f9d710 krilla: mesh gradients as PDF Type 6 shadings
paint::MeshGradient / MeshPatch: Coons patches with a colour and opacity at each corner, written as
one Type 6 (Coons patch mesh) shading through pdf-writer's StreamShading, so viewers and RIPs blend
them smoothly at device resolution instead of an app cutting each patch into flat-colour pieces.
Same path as the other gradients: a shading pattern fill, and corner opacities below 1 as a
luminosity soft mask of the same mesh in gray. 32-bit coordinates over the mesh bounds, 8-bit
components, Flate. Recorded in vendor/krilla/README.craft.md and SOURCE.json.
2026-10-20 03:41:18 +00:00
aiongg 21154585b5 krilla: record the master-rendition patch (#183) in the patch ledger 2026-10-20 03:41:18 +00:00
Hamza 96c45ccde1 krilla: a written document is the master rendition, not a proof
`chunk_container` wrote `xmpMM:RenditionClass` as `proof` on every PDF krilla
produces. That property says which rendition a file is (XMP Part 2, Media
Management): `default` is the master, `proof` a proof copy. So every export
told a prepress system that a print deliverable was only a proof, and PDF/X
output carries the same claim.

Noticed on storytold/designcraft#1207, where PDF/X-4 output was being checked
against Acrobat's preflight; it is not what fails that check, but it is wrong
and it reaches every app that writes PDF through this tree.

Checked with DesignCraft pointed at this tree: `xmpMM:RenditionClass` reads
`default` for a PDF/X-4 export and for an ordinary one, where both read `proof`
before.
2026-10-20 03:41:18 +00:00
aiongg f7ae814d91 plate-test: app-neutral print color scenes, checked by PDF structure and Ghostscript plates
craft-plate-test writes JSON scenes through craft-pdf and checks the written PDF's
structure (CI, under a second) and, locally only, its separated plates through
Ghostscript tiffsep (scripts/plate-check.sh). Apps can run the same scenes through
their own export as a dev-dependency.
2026-10-20 03:41:13 +00:00
aiongg eedd0246df krilla: CMYK print color in the vendored krilla, and a craft-pdf print preset
Print PDFs written through krilla separated wrongly: transparency groups blended in RGB
(K 50% over C100 separated as C84 M34 Y32 K37 instead of C50 K50), and there was no
overprint, knockout, DeviceN, soft-mask backdrop or print output intent.

Patches in vendor/krilla/patches/, recorded in README.craft.md and SOURCE.json:
- 02 blending color space: GroupColorSpace { Rgb (default, unchanged output), Cmyk }
- 03 overprint: Surface::push_overprint (/op /OP /OPM)
- 04 knockout groups: Surface::push_group(GroupOptions { isolated, knockout })
- 05 soft-mask backdrop and transfer function (/BC /TR)
- 06 DeviceN and NChannel colors for fills and strokes
- 07 DeviceN images and shadings
- 08 print output intent (GTS_PDFX), /Trapped, PDF/X version markers

craft_pdf::write::print::settings(PrintColor) turns them on for print export.
2026-10-20 03:41:13 +00:00
aiongg 4585efee97 prepress: rename craft-separations to craft-prepress 2026-10-20 03:39:36 +00:00
aiongg 4674ab7c85 keymap: use US spelling in the shortcuts dialog 2026-10-20 03:28:24 +00:00
aiongg cf9e10a90a Merge branch 'craft-keymap' into keymap-ui
# Conflicts:
#	crates/keymap/README.md
#	crates/keymap/src/lib.rs
2026-10-20 03:26:15 +00:00
aiongg 2c80b65e98 separations: use US spelling 2026-10-20 03:25:47 +00:00
aiongg 890660444c keymap: use US spelling 2026-10-20 03:24:56 +00:00
aiongg ceb75f965e ui: use US spelling 2026-10-20 03:24:45 +00:00
aiongg 602c915272 separations: US spelling in the coverage, composite and ink manager docs 2026-10-20 03:23:15 +00:00
aiongg 9e2c629f25 separations: ink manager on InkSet
Aliases (a spot printed on another ink's plate), spot to process and all
spots to process, with resolve applying both to a colour. The README
describes the coverage, composite and ink manager API and how the apps use
it for a Separations Preview and an Ink Manager.
2026-10-20 03:22:29 +00:00
aionggandGuillem Hermida 3c6089bcfc separations: coverage, TAC regions and a composite preview from plates
Per-ink coverage at a pixel and over a page, TAC per pixel, the pixels and
connected regions over a TAC limit, and an sRGB composite of chosen plates:
process plates through the printing condition, spot plates multiplied over
them by their alternate's appearance. Ported from the data parts of
pdfcraft #2770 separations.rs.

Co-authored-by: Guillem Hermida <66697068+guillehr2@users.noreply.github.com>
2026-10-20 03:22:29 +00:00
aiongg 126440b274 separations: test craft-separations in the PDF workflow on Ubuntu 2026-10-20 03:15:36 +00:00
aionggandGuillem Hermida c025c0dfff separations: add craft-separations with the ink model and plates
The ink model (process and spot inks, InkSet with PDF name lookup,
InkColor, Overprint) and plates(pdf, page, dpi, opts): ink discovery
and one gray film per ink through craft-pdf's raster plate mode, with
process colour converted through craft-cms (output intent, else the
caller's profile or FOGRA39). Plate rendering, ink discovery, caps and
output-intent selection port pdfcraft #2770's separations.rs.

Co-authored-by: Guillem Hermida <66697068+guillehr2@users.noreply.github.com>
2026-10-20 03:15:36 +00:00
aionggandmtlcl410 b01d19c716 vendor: port pdfcraft #2974 knockout groups into hayro
Bring storytold/pdfcraft#2974 (source commit
bae69819594a6385a027fec1f67e6b3c36c259b4) onto the vendored
hayro-interpret and hayro. Knockout transparency groups (/K true) knock
out: while one is innermost, fills, strokes, glyph outlines and shadings
are drawn with Compose::Copy, weighted by coverage. An unmasked image's
rectangle and a nested group's shape are cleared before their layer
composites; the nested group's shape comes from an erase pass over its
content. Masked images and stencils composite as before.

Code comments label the change "Knockout patch (pdfcraft #2974)": the
pull request numbers it hayro-interpret patch 39 and hayro patch 19,
which pdfcraft may renumber. The erase pass resolves resources with
Resources::from_scope, as this tree's form drawing does.

crates/pdf/tests/knockout.rs adapts the pull request's test to the
raster path (without its preview case: craft-pdf has no preview mode).
A plate-mode test checks that a knockout group of two 50% squares
separates with only the top square in the overlap. Options documents
that color_replacement also maps plate films. Ledger, NOTICE and the
source manifests are updated.

Co-authored-by: mtlcl410 <2368091+mtlcl410@users.noreply.github.com>
2026-10-20 03:07:22 +00:00
aionggandGuillem Hermida 7764afb2a7 vendor: convert plate-mode CMYK through a CmykConversion trait
CmykSimulation converts process colour to an output intent's CMYK
through a color::CmykConversion: sRGB colours, and CIE XYZ relative to
the D50 PCS white (color::PCS_WHITE) for Lab and ICCBased colours.
CmykSimulation::new keeps the moxcms conversion from pdfcraft #2770,
which takes XYZ on through its ProPhoto hub; with_conversion takes a
caller's, so a crate can separate with its own colour management.

crates/pdf/tests/plates.rs adapts #2770's plate tests to the raster
path: process, spot, DeviceN, All/None, ICC CMYK, gray and RGB colours,
images, shadings, uncoloured patterns, soft masks, OP/op/OPM, the ink
sink, output-intent simulation with #2770's synthetic ICC profiles, and
a caller's conversion. The ledger and NOTICE name the pull request.

Co-authored-by: Guillem Hermida <66697068+guillehr2@users.noreply.github.com>
2026-10-20 02:53:37 +00:00
aiongg 5e29e70b46 Merge branch 'craft-keymap' into keymap-ui
# Conflicts:
#	crates/keymap/src/egui.rs
2026-10-20 02:42:51 +00:00
aiongg 75a42cb95f keymap: an import change that cannot take a chord from another command leaves both commands as they were 2026-10-20 02:41:01 +00:00
aionggandGuillem Hermida 2c8c3ad261 vendor: port pdfcraft #2770 plate mode into hayro-interpret
Bring the vendored interpreter part of storytold/pdfcraft#2770 (Output
Preview, source commit 6fcf2a4aca29e943e28cb69017ff8f87d00656c6) onto
the ec0a965 snapshot. It applies without conflicts.

InterpreterSettings::plate draws one ink's separation: every paint
draws that ink's tint as a gray film, by the colour space's ink use and
tint. The graphics state reads OP, op and OPM, and an overprinting
paint that doesn't specify the plate's ink leaves the plate as it is
(ISO 32000-2 8.6.7). InterpreterSettings::ink_sink reports the spot
inks paints use, and color::CmykSimulation converts process colour to
an output intent's CMYK profile.

PdfCraft's separations.rs, Output Preview UI and automation are not
part of this port. The ledger in vendor/README.craft-reader.md names the
pull request, author and source commit.

Co-authored-by: Guillem Hermida <66697068+guillehr2@users.noreply.github.com>
2026-10-20 02:40:50 +00:00
aiongg 9b7102e297 keymap: New Set refuses a name that is taken
The set form's New Set replaced a user set of the same name (save_as) or
quietly made the name unique (duplicate). It now refuses a name that
matches a built-in or user set, ignoring case and surrounding spaces, the
way Rename does, and keeps the form open. The check runs before the
prompt to save edits and again after it.
2026-10-20 02:39:59 +00:00
aiongg 1b329b9422 keymap: a web clipboard press takes its clipboard event and the pasted text with it 2026-10-20 02:39:41 +00:00
aiongg b6f60f25b1 vendor: re-sync hayro reader trees from pdfcraft ec0a965
Bring vendor/hayro, hayro-interpret, hayro-syntax and hayro-jbig2 to
storytold/pdfcraft ec0a965074f376a5bf610435948e4e5184bf3299 (main,
2026-10-19), from 7437bde. The local patches (per-document decode
limits, incomplete-content diagnostics, Hayro 0.8 resource scopes,
nesting cap, iterative page tree, TJ fill order, transfer rounding,
safety repairs) are carried by a three-way merge without conflicts.

The re-sync includes transparency group /I and /K reading (pdfcraft
#2027), patches 28, 29 and 31-34, and the reader fixes listed in
vendor/README.craft-reader.md. SOURCE.json manifests, NOTICE and the
craft-pdf README name the new source revision.
2026-10-20 02:30:13 +00:00
aiongg 3600104e76 docking: rustfmt the new tests 2026-10-20 01:00:56 +00:00
aiongg 95c81fa6de docking: say that the drag bar's menu opens on a right click
A left click on the drag bar focuses it and opens nothing, as designed;
the Hit::DragBar docs said otherwise.
2026-10-20 01:00:30 +00:00
aiongg a76d196b80 docking: dividers and resize grips keep focus after a pointer drag
Arrow keys resize the handle right after a drag. Focus that came from
the pointer draws no highlight until a key is pressed, and hovering
still focuses nothing.
2026-10-20 01:00:22 +00:00
aiongg 877f676e19 docking: menu item labels in title case
Float Panel, Close Panel and Move Group To match the other menu items.
Control names that only screen readers announce stay in sentence case.
2026-10-20 00:59:33 +00:00
aiongg 38e2b27a30 docking: window.panel.dock with an edge zone and no anchor docks at that edge
A left, right, top or bottom zone without anchor or side maps to
Placement::Edge, anchored on any docked panel that does not move. A
hidden panel is shown and moved in one step, all or nothing.
2026-10-20 00:59:02 +00:00
aiongg 89849272a0 docking: public widget ids and floating window layers
DockArea::hit_id gives the egui id of the control a Hit names, and
DockArea::floating_layer the layer of a floating window, so apps and
their tests stop rebuilding internal ids. The divider between stacked
groups has one id in docks and floating windows.
2026-10-20 00:58:10 +00:00
aiongg 30cebdc0f2 docking: content that fills its body floats at floating_size or 320
A panel body that reaches the bottom of its rect has no height of its
own, so a floated panel or group falls back to floating_size, else 320
points, instead of the whole frame height. A body in a window fitted to
its recorded height keeps that height. Panels leaving a frame fit their
content like panels leaving a dock.
2026-10-20 00:57:14 +00:00
aiongg b94df6c8b6 docking: wheel selects tabs and middle click closes a tab
Both are on in the Frame profile and off by default in the Dock profile;
DockStyle::wheel_selects_tabs and middle_click_closes_tabs set them. A
middle click closes only a closable panel.
2026-10-20 00:55:43 +00:00
aiongg d3079230da docking: group_header_width gets the tab strip width
A header that draws its own tabs, such as a timeline's open sequences,
sizes them to the room the strip has.
2026-10-20 00:54:23 +00:00
aiongg 488db9e3df Merge branch 'craft-keymap' into keymap-ui 2026-10-20 00:49:07 +00:00
aiongg 3ef24a785b keymap: egui::platform gives the browser's operating system on the web 2026-10-20 00:49:05 +00:00