stet-render 0.7.0

tiny-skia rasterizer for stet display lists — produces RGBA output from both PostScript and PDF input
Documentation

stet-render

crates.io docs.rs

Software rasterizer for stet display lists. Turns a DisplayList — whether it came from the stet PostScript interpreter or from stet-pdf-reader — into RGBA pixels.

Built on stet-tiny-skia, a modified fork of tiny-skia with higher-quality analytical antialiasing for PostScript-grade hairlines. Rendering is multi-threaded and banded (sized to fit L2 cache), with mask caching, clip fast paths, and ICC-aware CMYK handling.

Because DisplayList is the neutral meeting point between stet's PS interpreter and stet-pdf-reader, the same renderer handles both PS and PDF sources — there is no separate PDF rasterizer. The only difference a consumer sees is where the display list came from.

This is a low-level crate. Most users should use the stet facade (for PS / EPS) or stet-pdf-reader (for PDF), both of which drive stet-render for you.

What's inside

API Purpose
render_to_rgba One-shot: DisplayListVec<u8> RGBA. Automatic banded parallelism.
prepare_display_list + render_region_prepared Viewport rendering — pre-compute bounding boxes once, then rasterize any rectangular region at any zoom without re-interpretation. Powers the interactive viewer and the WASM frontend.
render_region_prepared_parallel / _cancellable / _with_progress Parallel viewport variants with progress callbacks and cancellation tokens for interactive UIs.
ImageCache Pre-converted RGBA image cache, amortizing decode + ICC conversion across repeated viewport renders of the same page.
build_icc_cache_for_list Sweep a DisplayList and populate an IccCache with every embedded ICC profile it references.
SkiaDevice OutputDevice implementation — plug it into a Context for streaming per-page PS/PDF rendering. Requires the ps-device feature (on by default).
PngSinkFactory PageSinkFactory that streams banded output straight to a PNG file.

Features

Feature Default Description
parallel yes Multi-threaded banded rendering via rayon. Disable for a single-threaded build.
ps-device yes SkiaDevice and its OutputDevice implementation, for the PostScript interpreter to paint into. Pulls in stet-core.

Turning ps-device off drops stet-core — the PostScript VM — from the dependency graph entirely. Rendering a DisplayList needs none of it, so a consumer that only rasterizes (a PDF viewer, say) can take:

stet-render = { version = "0.7", default-features = false, features = ["parallel"] }

Note that default-features = false also switches off parallel, so re-enable it by name unless you want single-threaded rendering. stet-pdf-reader depends on stet-render exactly this way.

Usage

Render a PDF page to RGBA

use stet_pdf_reader::PdfDocument;
use stet_render::render_to_rgba;

let data = std::fs::read("document.pdf")?;
let doc = PdfDocument::from_bytes(&data)?;
let display_list = doc.render_page(0, 150.0)?;
let (w, h) = {
    let (pw, ph) = doc.page_size(0)?;
    let s = 150.0 / 72.0;
    ((pw * s).round() as u32, (ph * s).round() as u32)
};

let rgba = render_to_rgba(&display_list, w, h, 150.0, Some(doc.icc_cache()), false);
# Ok::<(), Box<dyn std::error::Error>>(())

(For a one-call shortcut, PdfDocument::render_page_to_rgba wraps this and the w/h derivation.)

Render a PostScript-produced display list

use stet::Interpreter;
use stet_render::render_to_rgba;

let mut interp = Interpreter::new();
let pages = interp.render_to_display_list(ps_data, 300.0)?;

let p = &pages[0];
let rgba = render_to_rgba(&p.display_list, p.width, p.height, p.dpi, None, false);
# Ok::<(), Box<dyn std::error::Error>>(())

Viewport rendering (zoom / pan without re-interpreting)

use stet_render::{prepare_display_list, render_region_prepared};

let prepared = prepare_display_list(&display_list);

let rgba = render_region_prepared(
    &display_list,
    &prepared,
    vp_x, vp_y, vp_w, vp_h,   // viewport in device pixels
    pixel_w, pixel_h,           // output dimensions
    dpi,
    None,   // ICC cache
    None,   // ImageCache
    false,  // no_aa
);

License

Apache-2.0 OR MIT