# Idiomatic Rust bindings for Pdfium
`pdfium-render` provides an idiomatic high-level Rust interface around the low-level bindings to
Pdfium exposed by the excellent `pdfium-sys` crate.
```
// Exports each page in the given test PDF file as a separate JPEG image.
use pdfium_render::{pdfium::Pdfium, bitmap::PdfBitmapRotation, bitmap_config::PdfBitmapConfig};
use image::ImageFormat;
let password = None;
let document = Pdfium::new(Pdfium::bind_to_system_library().unwrap())
.load_pdf_from_file("test.pdf", password).unwrap();
let bitmap_render_config = PdfBitmapConfig::new()
.set_target_width(2000)
.set_maximum_height(2000)
.rotate_if_landscape(PdfBitmapRotation::Degrees90, true);
document.pages().iter().for_each(|page| {
page.get_bitmap_with_config(&bitmap_render_config).unwrap()
.as_image() // Renders this page to an Image::DynamicImage
.as_bgra8().unwrap()
.save_with_format(format!("test-page-{}.jpg", page.index()), ImageFormat::Jpeg).unwrap();
});
```
In addition to providing a more natural interface to Pdfium, `pdfium-render` differs from
`pdfium-sys` in several other important ways:
* `pdfium-render` uses `libloading` to late bind to a Pdfium library at run-time, whereas
`pdfium-sys` binds to a library at compile-time. By binding to Pdfium at run-time instead
of compile-time, `pdfium-render` can dynamically switch between bundled libraries and
system libraries and provide idiomatic Rust error handling in situations where a Pdfium
library is not available.
* Late binding to Pdfium means that `pdfium-render` can be compiled to WASM for running in a
browser; this is not possible with `pdfium-sys`.
* Pdfium is composed as a set of separate modules, each covering a separate aspects of PDF creation,
rendering, and editing. `pdfium-sys` only provides bindings for the subset of functions exposed
by Pdfium's view module; `pdfium-render` aims to ultimately provide bindings to all non-interactive
functions exposed by all Pdfium modules, including document creation and editing functions.
This is a work in progress.
* Pages rendered by Pdfium can be exported as instances of `Image::DynamicImage` for easy,
idiomatic post-processing.
## What's new
Version 0.5.2 adds bindings to Pdfium's `FPDF_GetPageBoundingBox()`, `FPDFDoc_GetPageMode()`, `FPDFPage_Get*Box()`, and `FPDFPage_Set*Box()` functions and exposes the `PdfPageBoundaries` collection, accessed from the `PdfPage::boundaries()` function.
## Porting existing Pdfium code from other languages
The high-level idiomatic Rust interface provided by the `Pdfium` struct is entirely optional;
the `Pdfium` struct wraps around raw FFI bindings defined in the `PdfiumLibraryBindings`
trait, and it is completely feasible to simply use those raw FFI bindings directly
rather than the high level interface. This makes porting existing code that calls FPDF_* functions
very straight-forward, while still gaining the benefits of late binding and
WASM compatibility. For instance, the following code snippet (taken from a C++ sample):
```
string test_doc = "test.pdf";
FPDF_InitLibrary();
FPDF_DOCUMENT doc = FPDF_LoadDocument(test_doc, NULL);
// ... do something with doc
FPDF_CloseDocument(doc);
FPDF_DestroyLibrary();
```
would translate to the following Rust code:
```
let bindings = Pdfium::bind_to_system_library().unwrap();
let test_doc = "test.pdf";
bindings.FPDF_InitLibrary();
let doc = bindings.FPDF_LoadDocument(test_doc, None);
// ... do something with doc
bindings.FPDF_CloseDocument(doc);
bindings.FPDF_DestroyLibrary();
```
## External Pdfium builds
`pdfium-render` does not bundle Pdfium at all. You can either bind to a system-provided library
or package an external build of Pdfium alongside your Rust application. When compiling to WASM,
packaging an external build of Pdfium as a separate WASM module is essential.
* Native builds of Pdfium for all major platforms: <https://github.com/bblanchon/pdfium-binaries/releases>
* WASM builds of Pdfium, suitable for deploying alongside `pdfium-render`: <https://github.com/paulo-coutinho/pdfium-lib/releases>
## Compiling to WASM
See <https://github.com/ajrcarey/pdfium-render/tree/master/examples> for a full example that shows
how to bundle a Rust application using `pdfium-render` alongside a pre-built Pdfium WASM module for
inspection and rendering of PDF files in a web browser.
## Development status
The initial focus of this crate has been on rendering pages in a PDF file; consequently, FPDF_*
functions related to bitmaps and rendering have been prioritised. By 1.0, the functionality of all
FPDF_* functions exported by all Pdfium modules will be available, with the exception of certain
functions specific to interactive scripting, user interaction, and printing.
If you need a function that is not currently exposed, just raise an issue.
## Version history
* 0.5.2: adds bindings for `FPDF_GetPageBoundingBox()`, `FPDFDoc_GetPageMode()`, `FPDFPage_Get*Box()`, and `FPDFPage_Set*Box()` functions, exposes `PdfPageBoundaries` collection
* 0.5.1: adds bindings for `FPDFPage_GetRotation()` and `FPDFPage_SetRotation()` functions, exposes `PdfMetadata` collection
* 0.5.0: adds rendering of annotations and form field elements, thanks to an excellent contribution from <https://github.com/inzanez>
* 0.4.2: bug fixes in `PdfBitmapConfig` implementation
* 0.4.1: improvements to documentation and READMEs
* 0.4.0: initial release