pdfium-render

repository·master·Indexed 20 days ago

https://github.com/ajrcarey/pdfium-render

A high-level idiomatic Rust wrapper around Pdfium, the C++ PDF library used by the Google Chromium project. It enables PDF rendering to bitmaps, text and image extraction, and document manipulation. The library supports dynamic linking, static linking, and compilation to WASM for browser use, providing specific APIs for network and memory-based loading when filesystem access is unavailable.

Tokens
6.5K
Snippets
14
Records
42
Agent score
72%

What's inside pdfium-render

  1. Overview of pdfium-render

    master

    pdfium-render provides an idiomatic high-level Rust interface to Pdfium, the C++ PDF library used by Google Chromium. It allows you to:

    • Render PDF pages to bitmaps.
    • Load, edit, and extract text and images from existing PDFs.
    • Create new PDF files from scratch.

    Unlike many bindings, pdfium-render binds to the Pdfium library at run-time. This allows you to choose between system-provided or bundled libraries and enables compiling Rust applications to WASM to run in a browser alongside a WASM-packaged build of Pdfium.

    use pdfium_render::prelude::*;
  2. How thread safety works in pdfium-render

    master

    Pdfium itself is not thread-safe. To prevent crashes in multi-threaded applications, pdfium-render can wrap access to Pdfium behind a mutex.

    When the thread_safe feature is enabled, every call to Pdfium must acquire exclusive access to this mutex. This sequences all calls as if they were single-threaded, ensuring safety at the cost of no performance benefit from parallelizing Pdfium calls. For high-performance document processing, it is recommended to use parallel processing (processing multiple documents simultaneously) rather than multi-threading a single Pdfium instance.

  3. How to bind to a Pdfium library

    master

    pdfium-render does not include Pdfium itself. You must provide a Pdfium library using one of these methods:

    1. Dynamic linking (System): Bind to a library provided by the operating system.
    2. Dynamic linking (Bundled): Bind to a library packaged alongside your Rust executable.
    3. Static linking: Link a statically-built Pdfium library at compile time.

    Note for WASM: When compiling to WASM, you must package an external build of Pdfium as a separate WASM module.

  4. Handle Pdfium string types and conversions

    master

    The Pdfium API uses three string types: C-style null-terminated arrays, UTF-8 byte arrays, and FPDF_WIDESTRING (UTF-16LE).

    • C-style/UTF-8: pdfium-render bindings accept standard Rust &str.
    • FPDF_WIDESTRING: For functions requiring this type, pdfium-render provides two options:
      1. The vanilla FPDF_*() function which requires an FPDF_WIDESTRING.
      2. A helper FPDF_*_str() function that accepts a Rust &str and performs the internal conversion to FPDF_WIDESTRING automatically.

    Utility Functions for Manual Conversion:

    • PdfiumLibraryBindings::get_pdfium_utf16le_bytes_from_str(): Convert &str to FPDF_WIDESTRING bytes.
    • PdfiumLibraryBindings::get_string_from_pdfium_utf16le_bytes(): Convert FPDF_WIDESTRING bytes to String.
  5. Initialize pdfium-render in WASM

    master

    When running in a browser, you must manually bind the Pdfium WASM module and your compiled Rust application module. The sequence is:

    1. Load and instantiate the Pdfium WASM module.
    2. Load and instantiate the WASM module for your compiled Rust application.
    3. Call the exported initialize_pdfium_render() function from your Rust application, passing both instantiated WASM modules as arguments.
  6. Configure Static Linking for Pdfium

    master

    To link Pdfium directly into your executable at compile time, use the static crate feature. This allows you to use Pdfium::bind_to_statically_linked_library() to bind to functions compiled into your binary.

    To specify the location of your static library, set the PDFIUM_STATIC_LIB_PATH environment variable. The path should be the directory containing the library, not the filename itself. The library must be named according to your platform (e.g., libpdfium.a on macOS/Linux).

    For cross-compilation, you can use target-specific environment variables (e.g., PDFIUM_STATIC_LIB_PATH_aarch64_apple_darwin) which take precedence over the generic PDFIUM_STATIC_LIB_PATH.

    use pdfium_render::prelude::*;
    
    let pdfium = Pdfium::new(Pdfium::bind_to_statically_linked_library().unwrap());
  7. Run pdfium-render examples

    master

    You can run any of the provided examples using cargo run. Each example demonstrates a specific capability, such as text extraction, image extraction, or form field iteration.

    Example commands:

    cargo run --example annotations
    cargo run --example text_extract
    cargo run --example image_extract
    cargo run --example <example_name>
  8. Link C++ Standard Libraries and CoreGraphics

    master

    Depending on how your Pdfium library was built, you may need to link against a C++ standard library or macOS frameworks. Use the following crate features to enable these links:

    • GNU C++ (libstdc++): Enable the libstdc++ feature (requires static).
    • LLVM C++ (libc++): Enable the libc++ feature (requires static).
    • macOS CoreGraphics: Enable the core_graphics feature (requires static) to resolve undefined symbols like _CGBitmap or _CGContext.
  9. Bundle pdfium-render for WASM

    master

    To run pdfium-render in a browser, you must bundle it with an external pre-packaged WASM build of pdfium.

    1. Build the Rust WASM module:
      cargo install wasm-pack && wasm-pack build examples/ --target no-modules
       This generates `examples/pkg/pdfium_render_wasm_example.js` and `examples/pkg/pdfium_render_wasm_example_bg.wasm`.
    
    2. **Prepare the release folder**:
       - Copy the generated `.js` and `.wasm` files from `examples/pkg` into your release folder.
       - Download a pre-packaged WASM build from [paulocoutinhox/pdfium-lib](https://github.com/paulocoutinhox/pdfium-lib/releases) and extract `release/node/pdfium.js` and `release/node/pdfium.wasm` into your release folder.
       - Copy `examples/index.html` into your release folder.
       - Copy a sample PDF and rename it to `test.pdf` in the release folder.
    
    3. **Serve the content**:
       Use a webserver or the provided `serve.sh` script to host the folder.
    
  10. Configure logging for WASM using `console_log`

    master

    To see debugging output in the browser console, you must use the console_log crate feature.

    Important: If you are using console_log in your own application, you should disable the console_log feature in pdfium-render and instead initialize console_log manually in your application's initialization code before calling any pdfium-render functions.