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.
[dependencies] rustybara = "0.1.8"
The entry point is PdfPipeline — a chaining API that opens
a PDF and composes operations in a single pass.
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-render which needs a pdfium binary
at link time. See pdfium Setup → before your first
build.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.
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.
rustybara = { version = "0.1.8", features = ["static"] }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")?;
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)?;
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);
pipeline
Top-level orchestration module. PdfPipeline is the high-level
chaining API.
PdfPipeline::open(path)? — chain operations, then call a save method. Not Clone.PdfPipeline methods
Err(RustyError) if the file can't be parsed.tolerance is per-channel (0.0–1.0).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.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.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.pub fn outline_text(&mut self) -> Result<&mut PdfPipeline>
pages
Page box geometry types for prepress workflows. All values are in PDF points (1/72 inch).
trim_or_media() to get the effective page boundary and bleed_rect(pts) to compute the bleed expansion.pub media: Rect, pub trim: Option<Rect>,
pub bleed: Option<Rect>, pub crop: Option<Rect>,
}
pts on all
sides. Returns the computed bleed rect without mutating state.raster
Configuration and output types for the rasterization pipeline.
Default. Use RenderConfig::prepress() for press-ready 300 DPI
output.300. Use 450–600 for extreme-zoom inspection work.Jpg, Png, WebP, or Tiff. Default: Png. Use Tiff for print proofing — lossless with maximum color
depth.CpuRenderer (pdfium-render) ships
today. Designed for a future GPU backend.fn render(&self, page: &PdfPage, config: &RenderConfig) -> Result<DynamicImage>;
}
errors
All fallible public API functions return Result<T, RustyError>. RustyError is #[non_exhaustive] to allow future
variants without breaking changes.
std::error::Error, Display, and From<PdfiumError>.pub enum RustyError {
Io(std::io::Error), Pdfium(PdfiumError),
InvalidPageRange(String), UnsupportedFormat(String),
ColorTransform(String),
}
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()), }