PdfDocument

Struct PdfDocument 

Source
pub struct PdfDocument<R: Read + Seek> { /* private fields */ }
Expand description

High-level PDF document interface for parsing and manipulation.

PdfDocument provides a clean, safe API for working with PDF files. It handles the complexity of PDF structure, object references, and resource management behind a simple interface.

§Type Parameter

  • R - The reader type (must implement Read + Seek)

§Architecture Benefits

  • RefCell Usage: Allows multiple parts of the API to access the document
  • Lazy Loading: Pages and resources are loaded on demand
  • Automatic Caching: Frequently accessed objects are cached
  • Safe API: Borrow checker issues are handled internally

§Example

use oxidize_pdf::parser::{PdfDocument, PdfReader};
use std::fs::File;

// From a file
let reader = PdfReader::open("document.pdf")?;
let document = PdfDocument::new(reader);

// From any Read + Seek source
let file = File::open("document.pdf")?;
let reader = PdfReader::new(file)?;
let document = PdfDocument::new(reader);

// Use the document
let page_count = document.page_count()?;
for i in 0..page_count {
    let page = document.get_page(i)?;
    // Process page...
}

Implementations§

Source§

impl<R: Read + Seek> PdfDocument<R>

Source

pub fn new(reader: PdfReader<R>) -> Self

Create a new PDF document from a reader

Source

pub fn version(&self) -> ParseResult<String>

Get the PDF version of the document.

§Returns

PDF version string (e.g., “1.4”, “1.7”, “2.0”)

§Example
let version = document.version()?;
println!("PDF version: {}", version);
Source

pub fn options(&self) -> ParseOptions

Get the parse options

Source

pub fn page_count(&self) -> ParseResult<u32>

Get the total number of pages in the document.

§Returns

The page count as an unsigned 32-bit integer.

§Errors

Returns an error if the page tree is malformed or missing.

§Example
let count = document.page_count()?;
println!("Document has {} pages", count);

// Iterate through all pages
for i in 0..count {
    let page = document.get_page(i)?;
    // Process page...
}
Source

pub fn metadata(&self) -> ParseResult<DocumentMetadata>

Get document metadata including title, author, creation date, etc.

Metadata is cached after first access for performance.

§Returns

A DocumentMetadata struct containing all available metadata fields.

§Example
let metadata = document.metadata()?;

if let Some(title) = &metadata.title {
    println!("Title: {}", title);
}
if let Some(author) = &metadata.author {
    println!("Author: {}", author);
}
if let Some(creation_date) = &metadata.creation_date {
    println!("Created: {}", creation_date);
}
println!("PDF Version: {}", metadata.version);
Source

pub fn get_page(&self, index: u32) -> ParseResult<ParsedPage>

Get a page by index (0-based).

Pages are cached after first access. This method handles page tree traversal and property inheritance automatically.

§Arguments
  • index - Zero-based page index (0 to page_count-1)
§Returns

A complete ParsedPage with all properties and inherited resources.

§Errors

Returns an error if:

  • Index is out of bounds
  • Page tree is malformed
  • Required page properties are missing
§Example
// Get the first page
let page = document.get_page(0)?;

// Access page properties
println!("Page size: {}x{} points", page.width(), page.height());
println!("Rotation: {}°", page.rotation);

// Get content streams
let streams = page.content_streams_with_document(&document)?;
println!("Page has {} content streams", streams.len());
Source

pub fn get_object(&self, obj_num: u32, gen_num: u16) -> ParseResult<PdfObject>

Get an object by its reference numbers.

This method first checks the cache, then loads from the file if needed. Objects are automatically cached after loading.

§Arguments
  • obj_num - Object number
  • gen_num - Generation number
§Returns

The resolved PDF object.

§Errors

Returns an error if:

  • Object doesn’t exist
  • Object is part of an encrypted object stream
  • File is corrupted
§Example
// Get object 10 0 R
let obj = document.get_object(10, 0)?;

// Check object type
match obj {
    PdfObject::Dictionary(dict) => {
        println!("Object is a dictionary with {} entries", dict.0.len());
    }
    PdfObject::Stream(stream) => {
        println!("Object is a stream");
    }
    _ => {}
}
Source

pub fn resolve(&self, obj: &PdfObject) -> ParseResult<PdfObject>

Resolve a reference to get the actual object.

If the input is a Reference, fetches the referenced object. Otherwise returns a clone of the input object.

§Arguments
  • obj - The object to resolve (may be a Reference or direct object)
§Returns

The resolved object (never a Reference).

§Example
// Contents might be a reference or direct object
if let Some(contents) = page.dict.get("Contents") {
    let resolved = document.resolve(contents)?;
    match resolved {
        PdfObject::Stream(_) => println!("Single content stream"),
        PdfObject::Array(_) => println!("Multiple content streams"),
        _ => println!("Unexpected content type"),
    }
}
Source

pub fn get_page_resources<'a>( &self, page: &'a ParsedPage, ) -> ParseResult<Option<&'a PdfDictionary>>

Get content streams for a specific page.

This method handles both single streams and arrays of streams, automatically decompressing them according to their filters.

§Arguments
  • page - The page to get content streams from
§Returns

Vector of decompressed content stream data ready for parsing.

§Example
let page = document.get_page(0)?;
let streams = document.get_page_content_streams(&page)?;

// Parse content streams
for stream_data in streams {
    let operations = ContentParser::parse(&stream_data)?;
    println!("Stream has {} operations", operations.len());
}

Get page resources dictionary.

This method returns the resources dictionary for a page, which may include fonts, images (XObjects), patterns, color spaces, and other resources.

§Arguments
  • page - The page to get resources from
§Returns

Optional resources dictionary if the page has resources.

§Example
let page = document.get_page(0)?;
if let Some(resources) = document.get_page_resources(&page)? {
    // Check for images (XObjects)
    if let Some(PdfObject::Dictionary(xobjects)) = resources.0.get(&PdfName("XObject".to_string())) {
        for (name, _) in xobjects.0.iter() {
            println!("Found XObject: {}", name.0);
        }
    }
}
Source

pub fn get_page_content_streams( &self, page: &ParsedPage, ) -> ParseResult<Vec<Vec<u8>>>

Source

pub fn extract_text(&self) -> ParseResult<Vec<ExtractedText>>

Extract text from all pages in the document.

Uses the default text extraction settings. For custom settings, use extract_text_with_options.

§Returns

A vector of ExtractedText, one for each page in the document.

§Example
let extracted_pages = document.extract_text()?;

for (page_num, page_text) in extracted_pages.iter().enumerate() {
    println!("=== Page {} ===", page_num + 1);
    println!("{}", page_text.text);
    println!();
}
Source

pub fn extract_text_from_page( &self, page_index: u32, ) -> ParseResult<ExtractedText>

Extract text from a specific page.

§Arguments
  • page_index - Zero-based page index
§Returns

Extracted text with optional position information.

§Example
// Extract text from first page only
let page_text = document.extract_text_from_page(0)?;
println!("First page text: {}", page_text.text);

// Access text fragments with positions (if preserved)
for fragment in &page_text.fragments {
    println!("'{}' at ({}, {})", fragment.text, fragment.x, fragment.y);
}
Source

pub fn extract_text_with_options( &self, options: ExtractionOptions, ) -> ParseResult<Vec<ExtractedText>>

Extract text with custom extraction options.

Allows fine control over text extraction behavior including layout preservation, spacing thresholds, and more.

§Arguments
  • options - Text extraction configuration
§Returns

A vector of ExtractedText, one for each page.

§Example
// Configure extraction to preserve layout
let options = ExtractionOptions {
    preserve_layout: true,
    space_threshold: 0.3,
    newline_threshold: 10.0,
    ..Default::default()
};

let extracted_pages = document.extract_text_with_options(options)?;

// Text fragments will include position information
for page_text in extracted_pages {
    for fragment in &page_text.fragments {
        println!("{:?}", fragment);
    }
}
Source

pub fn get_page_annotations( &self, page_index: u32, ) -> ParseResult<Vec<PdfDictionary>>

Get annotations from a specific page.

Returns a vector of annotation dictionaries for the specified page. Each annotation dictionary contains properties like Type, Rect, Contents, etc.

§Arguments
  • page_index - Zero-based page index
§Returns

A vector of PdfDictionary objects representing annotations, or an empty vector if the page has no annotations.

§Example
let annotations = document.get_page_annotations(0)?;
for annot in &annotations {
    if let Some(contents) = annot.get("Contents").and_then(|c| c.as_string()) {
        println!("Annotation: {:?}", contents);
    }
}
Source

pub fn get_all_annotations(&self) -> ParseResult<Vec<(u32, Vec<PdfDictionary>)>>

Get all annotations from all pages in the document.

Returns a vector of tuples containing (page_index, annotations) for each page that has annotations.

§Returns

A vector of tuples where the first element is the page index and the second is a vector of annotation dictionaries for that page.

§Example
let all_annotations = document.get_all_annotations()?;
for (page_idx, annotations) in all_annotations {
    println!("Page {} has {} annotations", page_idx, annotations.len());
}

Auto Trait Implementations§

§

impl<R> !Freeze for PdfDocument<R>

§

impl<R> !RefUnwindSafe for PdfDocument<R>

§

impl<R> !Send for PdfDocument<R>

§

impl<R> !Sync for PdfDocument<R>

§

impl<R> Unpin for PdfDocument<R>
where R: Unpin,

§

impl<R> !UnwindSafe for PdfDocument<R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more