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>
impl<R: Read + Seek> PdfDocument<R>
Sourcepub fn version(&self) -> ParseResult<String>
pub fn version(&self) -> ParseResult<String>
Sourcepub fn options(&self) -> ParseOptions
pub fn options(&self) -> ParseOptions
Get the parse options
Sourcepub fn page_count(&self) -> ParseResult<u32>
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...
}Sourcepub fn metadata(&self) -> ParseResult<DocumentMetadata>
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);Sourcepub fn get_page(&self, index: u32) -> ParseResult<ParsedPage>
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());Sourcepub fn get_object(&self, obj_num: u32, gen_num: u16) -> ParseResult<PdfObject>
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 numbergen_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");
}
_ => {}
}Sourcepub fn resolve(&self, obj: &PdfObject) -> ParseResult<PdfObject>
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"),
}
}Sourcepub fn get_page_resources<'a>(
&self,
page: &'a ParsedPage,
) -> ParseResult<Option<&'a PdfDictionary>>
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);
}
}
}pub fn get_page_content_streams( &self, page: &ParsedPage, ) -> ParseResult<Vec<Vec<u8>>>
Sourcepub fn extract_text(&self) -> ParseResult<Vec<ExtractedText>>
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!();
}Sourcepub fn extract_text_from_page(
&self,
page_index: u32,
) -> ParseResult<ExtractedText>
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);
}Sourcepub fn extract_text_with_options(
&self,
options: ExtractionOptions,
) -> ParseResult<Vec<ExtractedText>>
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);
}
}Sourcepub fn get_page_annotations(
&self,
page_index: u32,
) -> ParseResult<Vec<PdfDictionary>>
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);
}
}Sourcepub fn get_all_annotations(&self) -> ParseResult<Vec<(u32, Vec<PdfDictionary>)>>
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more