stet 0.2.0 — ⚠ breaking release
[0.2.0] — 2026-05-01
This release lands a substantial expansion of the stet-pdf-reader
structural API, the PDF imaging-extension operators (transparency,
soft masks, optional content), and the pdfmark PostScript-to-PDF
authoring bridge. Several public match-surface enums are now
#[non_exhaustive] to lock in additive evolution — the breaking
changes are deliberate and documented per-crate below.
⚠ Breaking changes
This is a breaking release. Cargo treats the 0.1 → 0.2 bump as
incompatible (per the SemVer rules for 0.x), so existing users
pinned at stet = "0.1" won't be auto-upgraded.
The breaking surface is concentrated in two places:
-
#[non_exhaustive]markers were added to ~40 public
match-surface enums acrossstet-graphics,stet-core, and
stet-pdf-reader. Any downstreammatchoverDisplayElement,
PsError,Destination,AnnotationKind, the various pdfmark
record enums, etc. now requires a_ => { ... }wildcard arm.
See the "Changed — public API breaking changes" subsection below
for the complete list. -
stet-pdfno longer emits PDF/X-3 OutputIntents. PDF output
is now plain PDF 1.7.PdfDevice::set_output_profile()is
#[deprecated]as a no-op; existing call sites compile but stop
producing the (previously broken) PDF/X-3 conformance label.
For a typical downstream renderer that pattern-matches on
DisplayElement, the migration is one wildcard arm per match
site:
match element {
DisplayElement::Fill { .. } => { /* … */ }
DisplayElement::Stroke { .. } => { /* … */ }
DisplayElement::Image { .. } => { /* … */ }
+ _ => { /* fall through; new variants in 0.2.x are additive */ }
}The #[non_exhaustive] ratchet is intentional: it makes future
variant additions non-breaking, so 0.2.x → 0.3.x will be smaller.
Added — stet-pdf-reader structural API
A read-only structural-content API for PDF inspection and tooling.
Every accessor parses lazily on first call and caches its result.
metadata()—/Infodict (title, author, dates, …) and the
catalog's/MetadataXMP stream.viewer_preferences()— page layout, page mode, print preferences,
and reading direction hints.outline()— bookmark tree asOutlineItems with
destination/action resolution.destinations(),resolve_named_destination(name)— named
destination table merged from/Catalog /Dests(legacy) and the
/Names /Destsname tree.page_annotations(page)— typedAnnotationlist with
destination/action resolution.form(),form_fields()— AcroForm field tree (text, choice,
button, signature) with widget cross-references.page_boxes(page)— MediaBox / CropBox / BleedBox / TrimBox /
ArtBox.embedded_files(),embedded_file_bytes(name)—/EmbeddedFiles
name-tree walker.layers(),layer(ocg_id),configurations(),
default_configuration(),layer_tree(),layer_set_for(intent)
— Optional Content Group (OCG) metadata, hierarchy, render-intent
rules, and a runtimeLayerSetfor visibility overrides.parse_warnings()— diagnostic sink for non-fatal parse issues
(broken outlines, bad name trees, malformed/VEexpressions, …).- New
stet inspect <file.pdf>CLI subcommand surfaces the structural
API at the command line.
See docs/PDF-READER-API.md and docs/PDF-LAYERS.md for full
references.
Added — PDF imaging extensions
Display-list-level support for the PDF transparency and optional-content
imaging models, layered on top of the PostScript interpreter.
- Alpha and blend modes:
setblendmode,setfillalpha,
setstrokealpha,setalphaisshape. All 16 PDF blend modes. - Transparency groups:
begintransparencygroup/
endtransparencygroupwithKnockout,Isolated, and group
colour space (DeviceGray/DeviceRGB/DeviceCMYK/ ICC). - Soft masks:
begintransparencymaskgroup/
endtransparencymaskgroupwithAlphaandLuminositysubtypes,
transfer functions, and backdrop-colour handling. - Optional Content (OCG):
setocg/endocgoperators wrap
display-list content inOcgGroupelements with
OcgVisibility::Single/Membership/Expressionpredicates.
LayerSet(instet-graphics) is the consumer's per-render override
map;render_page_to_rgba_with_layershonours it. - Filters:
JBIG2DecodeandJPXDecodefor embedded image
streams.
See docs/PDF-EXTENSIONS.md for the full reference and
docs/PDF-LAYERS.md for the runtime layer-visibility model.
Added — pdfmark PostScript-to-PDF authoring
pdfmark operator dispatch in stet-ops (gated behind
register_pdf_authoring_ops so it's only visible to systemdict on the
PDF output path) plus matching emitters in stet-pdf. Five phases of
authoring support:
/DOCINFO— document info dictionary (title, author, subject,
keywords, creator, producer, dates, trapped)./OUT— outline (bookmark) tree authoring with destination /
action targets./ANN— Link, Text, FreeText annotations./DEST,/PAGE,/PAGES— named destinations and per-page-box
overrides./VIEWERPREFERENCES,/Metadata— viewer preferences and
document-level XMP metadata./Widgetand/FORM— AcroForm widget annotations and field-tree
emission./EMBED, JavaScript / Named actions, page-level/AAtriggers.
See docs/PDFMARK-AUTHORING.md for the full reference.
Added — colour management
- Hand-rolled colorimetric A2B1 CLUT sampler
(stet-graphics::icc::perceptual). moxcms 0.8'screate_transform
pipeline over-saturates CMYK→sRGB output relative to lcms2 / Acrobat
/ Ghostscript on midtone colours; this module bypasses it for v2
lut16TypeCMYK profiles and matches lcms2 RelCol output to ±1 RGB
level on a 17⁴ sweep against ISO Coated v2 300% (ECI). Out-of-gamut
colours clip to the sRGB boundary (matching lcms2 / GS) so pure
process primaries remain saturated. BPC is calibrated against the
sampler's own (1, 1, 1, 1) output so K-heavy CMYK lands at the
correct darkness. Profiles whose tables are mAB / mft1 fall back
to the moxcms-driven bake. - Soft-mask CMYK-domain blend gate widened to accept Group-wrapped
flat CMYK fills (GWG 16.11 "Gradient Feather"). The GWG 16.10
outer-glow protection still rejects on the inner Fill's blend-mode
check.
Changed — public API breaking changes
These match-surface enums are now #[non_exhaustive] so adding
variants is non-breaking for any consumer that includes a _ => arm.
Existing consumers must add wildcard arms (or update their match
expressions) to keep building.
stet-graphics:DisplayElement,ImageColorSpace,
ShadingColorSpace,SpotColorSpace,LineCap,LineJoin,
FillRule.stet-core:PsError,FilterKind,RleState.stet-core::pdfmark:PdfMarkRecord,AnnotationSubtype,
AnnotationTarget,OutlineDestination,OutlineAction,
GoToTarget,ViewSpec,FieldType,FieldValue,DocDate,
TrappedState,TzSign,LinkHighlight,TextAnnotationIcon,
PageOverrideScope.stet-pdf-reader:PdfError,Destination,ViewSpec,Action,
AnnotationDate,AnnotationKind,AnnotationColor,
AnnotationKindData,FieldKind,ButtonType,FieldValue,
TrappedFlag,PageLayout,PageMode,ReadingDirection,
PrintScaling,Duplex,AfRelationship,ParsePhase,
LocationHint,Severity,RenderIntent,LayerIntent,
UsageState,PageElementSubtype,LayerTreeNode,BaseState,
ListMode,AutoStateEvent.
Param structs (FillParams, StrokeParams, ImageParams, the
pdfmark record structs, Annotation, FormField, Layer, etc.) are
not marked #[non_exhaustive] — adding fields lands additively
and consumers should pattern-match with .. for forward
compatibility.
A scripts/check-non-exhaustive.sh audit runs in the local pre-push
hook; new public enums in the listed files must either carry the
marker or be allow-listed with a one-line justification. See the
"Stable extension points" section of CLAUDE.md and the per-doc
"Stability" sections of docs/DISPLAY-LIST.md,
docs/PDF-READER-API.md, and docs/PDFMARK-AUTHORING.md.
Changed — other
stet-pdf: removed the PDF/X-3 OutputIntent emission. The writer
was emitting soft-mask transparency (prohibited by PDF/X-3) while
labelling output asPDF/X-3:2003— a conformance conflict any
preflight tool would flag. PDF output is now plain PDF 1.7 with no
PDF/X conformance claim. A correct PDF/X-4 implementation is
planned.stet-pdf:PdfDevice::set_output_profile()is#[deprecated]
as a no-op. Retained for forward API compatibility with the planned
PDF/X-4 work.stet-cli:--width/--heightflags for PDF input override
the page's MediaBox at render time.
Added — documentation
docs/PDF-READER-API.md— full reference for the structural API.docs/PDF-LAYERS.md— full reference for the OCG / layer API.docs/PDF-EXTENSIONS.md— full reference for the imaging extension
operators and the JBIG2 / JPX filters.docs/PDFMARK-AUTHORING.md— full reference for the pdfmark
authoring bridge.- New Rendering Correctness section in the root README covering
seam-free rendering on adjacent clipped regions and full overprint
simulation.