Guide

Quickstart

Add rustybara to your Cargo.toml and you have a complete PDF manipulation pipeline. The crate is modular — use only the operations you need.

Cargo.toml
[dependencies]
rustybara = "0.1.8"

The entry point is PdfPipeline — a chaining API that opens a PDF and composes operations in a single pass.

src/main.rs
use rustybara::PdfPipeline;

fn main() -> rustybara::Result<()> {
    // Trim marks, expand to 9pt bleed, save
    PdfPipeline::open("input.pdf")?
        .trim()?
        .resize(9.0)?
        .save_pdf("output.pdf")?;

    Ok(())
}
pdfium required rustybara uses pdfium-render which needs a pdfium binary at link time. See pdfium Setup → before your first build.

Guide

Core Concepts

rustybara is organized around operations, pipelines, and modules.

Operations

An operation is a pure transformation on a PDF. The chaining API sequences operations lazily — each method returns the modified pipeline and only the final save_pdf() or save_page_image() call writes output.

Pipelines

PdfPipeline::open(path)? opens the source document and validates it. Chain .trim()?, .resize(bleed)?, .remap_color(from, to, tolerance)?, then call a save method. Page-level rasterization processes each page in sequence.

Modules

Each capability lives in its own module. Use them directly for lower-level control without going through the pipeline.

rustybara::pipeline — Top-level orchestration. PdfPipeline lives here. The correct entry point for most use cases; it composes all other modules and handles thread safety internally.


Guide

pdfium Setup

rustybara uses pdfium-render, which wraps Google's pdfium library. A pdfium binary must be available at compile and runtime.

Dynamic linking (development)

The fastest way to get started. Download a pdfium release from pdfium-binaries and place it on your library path.

# macOS (Apple Silicon)
curl -L https://github.com/bblanchon/pdfium-binaries/releases/\
  latest/download/pdfium-mac-arm64.tgz | tar xz
export DYLD_LIBRARY_PATH=$PWD/lib:$DYLD_LIBRARY_PATH

# Linux (x64)
export LD_LIBRARY_PATH=$PWD/lib:$LD_LIBRARY_PATH

Static linking (distribution)

For shipping binaries, enable the static feature. This bundles pdfium into your binary — no runtime dependency for end users.

Cargo.toml
rustybara = { version = "0.1.8", features = ["static"] }
Binary size Static linking adds roughly 40 MB to binary size due to the pdfium runtime. This is expected and matches what rbara ships.

Guide

Page Operations

Trim marks and resize page boxes with a single pipeline chain. All operations are non-destructive until you call a save method.

Trim then resize

use rustybara::PdfPipeline;

PdfPipeline::open("artwork.pdf")?
    .trim()?            // strip content outside TrimBox
    .resize(9.0)?      // expand boxes by 9pt bleed
    .save_pdf("press-ready.pdf")?;

Remap CMYK colors

use rustybara::PdfPipeline;

// Replace rich black with C60 M40 Y20 K100
PdfPipeline::open("doc.pdf")?
    .remap_color(
        [1.0, 1.0, 1.0, 1.0],  // from: full CMYK
        [0.6, 0.4, 0.2, 1.0],  // to: print black
        0.05                   // tolerance
    )?
    .save_pdf("remapped.pdf")?;

Guide

Rasterization

Page rendering processes each page via the pdfium-render backend. For large batches, loop over pages using the pipeline API.

use rustybara::PdfPipeline;
use rustybara::encode::OutputFormat;
use rustybara::raster::RenderConfig;

let pipeline = PdfPipeline::open("press-ready.pdf")?;
let config = RenderConfig::prepress(); // 300 DPI

pipeline.save_page_image(0, "page_1.tiff", &OutputFormat::Tiff, &config)?;
pdfium binary rasterization requires a pdfium binary at runtime. See the pdfium Setup section for linking instructions.

Guide

Geometry & Trim

Full PDF box model inspection — MediaBox, TrimBox, BleedBox, CropBox — as first-class values. All dimensions in points (1/72 inch).

use rustybara::pages::PageBoxes;

let boxes = PageBoxes::read(&doc, page_id)?;

// TrimBox if present, else MediaBox
let trim = boxes.trim_or_media();

// Expand trim rect by 9pt bleed
let bleed = boxes.bleed_rect(9.0);

Reference

pipeline

Top-level orchestration module. PdfPipeline is the high-level chaining API.

structPdfPipeline
The main pipeline. Open with PdfPipeline::open(path)? — chain operations, then call a save method. Not Clone.
pub struct PdfPipeline { /* private */ }

PdfPipeline methods

fnPdfPipeline::open(path)
Open and validate a PDF file. Returns Err(RustyError) if the file can't be parsed.
pub fn open(path: impl AsRef<Path>) -> Result<PdfPipeline>
fn.trim()
Strip content outside the TrimBox (or MediaBox if no TrimBox is set). Removes print marks and slug content.
pub fn trim(self) -> Result<PdfPipeline>
fn.resize(bleed_pts)
Expand MediaBox and CropBox by the bleed margin in points. Prepares files for print production.
pub fn resize(self, bleed_pts: f32) -> Result<PdfPipeline>
fn.remap_color(from, to, tolerance)
Substitute a specific CMYK value in all content streams. tolerance is per-channel (0.0–1.0).
pub fn remap_color(self, from: [f32; 4], to: [f32; 4], tol: f32) -> Result<PdfPipeline>
fn.save_pdf(path)
Write the result to a PDF file. Consumes the pipeline.
pub fn save_pdf(self, path: impl AsRef<Path>) -> Result<()>
fn.save_page_image(page, path, format, config)
Rasterize a single page to an image file. Page index is 0-based.
pub fn save_page_image(&self, page: usize, path: impl AsRef<Path>, fmt: &OutputFormat, cfg: &RenderConfig) -> Result<()>
fn.embed_metadata(source_hash, timestamp, ops)
Embed a rbara: XMP block into the document's metadata stream. Call after all pipeline operations and before save_pdf(). On re-processing, the prior block's UUID is promoted to parentId, forming a lineage chain. Silently skips if the PDF catalog is malformed.
pub fn embed_metadata(&mut self, source_hash: &str, timestamp: &str, ops: &[(&str, &str)]) -> Result<&mut PdfPipeline>
fn.read_xmp_block()
Read the rbara: XMP block previously embedded by rustybara, if any. Returns None for files not processed by rustybara. Use to display provenance info or check for already-applied operations.
pub fn read_xmp_block(&self) -> Option<xmp::RbaraXmpBlock>
fn.outline_text()
Convert all text on every page to outlined vector paths. Each glyph is replaced with its PDF path operators (m/l/c/h/f). After outlining, fonts are no longer needed to render the PDF. Feature-gated: requires features = ["outline"]. Note: colored text is currently filled with CMYK black regardless of original color.
#[cfg(feature = "outline")]
pub fn outline_text(&mut self) -> Result<&mut PdfPipeline>

Reference

pages

Page box geometry types for prepress workflows. All values are in PDF points (1/72 inch).

structPageBoxes
Reads all four PDF page boxes from a document. Use trim_or_media() to get the effective page boundary and bleed_rect(pts) to compute the bleed expansion.
pub struct PageBoxes {
  pub media: Rect, pub trim: Option<Rect>,
  pub bleed: Option<Rect>, pub crop: Option<Rect>,
}
fn.trim_or_media()
Returns the TrimBox if one is set, otherwise falls back to the MediaBox. Correct choice for most prepress geometry calculations.
pub fn trim_or_media(&self) -> Rect
fn.bleed_rect(pts)
Expand the TrimBox (or MediaBox) outward by pts on all sides. Returns the computed bleed rect without mutating state.
pub fn bleed_rect(&self, pts: f32) -> Rect

Reference

raster

Configuration and output types for the rasterization pipeline.

structRenderConfig
Configuration for rasterization. All fields have defaults via Default. Use RenderConfig::prepress() for press-ready 300 DPI output.
fndpi: u32
Output resolution in dots per inch. Default: 300. Use 450600 for extreme-zoom inspection work.
enumOutputFormat
Jpg, Png, WebP, or Tiff. Default: Png. Use Tiff for print proofing — lossless with maximum color depth.
pub enum OutputFormat { Jpg, Png, WebP, Tiff }
traitPageRenderer
Rendering backend trait. CpuRenderer (pdfium-render) ships today. Designed for a future GPU backend.
pub trait PageRenderer {
  fn render(&self, page: &PdfPage, config: &RenderConfig) -> Result<DynamicImage>;
}

Reference

errors

All fallible public API functions return Result<T, RustyError>. RustyError is #[non_exhaustive] to allow future variants without breaking changes.

enumRustyError
The crate-wide error type. Implements std::error::Error, Display, and From<PdfiumError>.
#[non_exhaustive]
pub enum RustyError {
  Io(std::io::Error), Pdfium(PdfiumError),
  InvalidPageRange(String), UnsupportedFormat(String),
  ColorTransform(String),
}
Error handling pattern
match PdfPipeline::open("input.pdf") {
    Ok(p) => p.trim()?.save_pdf("out.pdf")?,
    Err(RustyError::Io(e)) => eprintln!("I/O: {e}"),
    Err(e) => return Err(e.into()),
}