| name | pdfium-syntax-pages |
| description | Use when accessing, counting, indexing, or iterating the pages of a PDF with pdfium-render, or reading a page's size or paper format. Prevents the page-access mistakes: storing a page index as u16 after the 0.9.0 c_int change, loading every page just to read its dimensions, calling pages() when a mutable collection is required, and assuming get() cannot fail. Covers PdfDocument::pages and pages_mut, the PdfPages collection (len, is_empty, first, last, get, iter), page_size and page_sizes for load-free dimensions, PdfPage::width, height and paper_size, the PdfPageIndex type, and iterating with enumerate. Keywords: pdfium-render, pages, PdfPages, PdfPage, page count, page index, PdfPageIndex, iter, enumerate, first, last, get, page_size, page_sizes, paper_size, PdfPagePaperSize, pages_mut, "how many pages", "loop over pages", "get page by number", "page out of bounds", "PageIndexOutOfBounds", "expected u16 found c_int", "how big is each page", "iterate PDF pages".
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires pdfium-render 0.8,0.9. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
pdfium-render Pages
This skill covers the page layer of pdfium-render: reaching the page
collection from a PdfDocument, counting and indexing pages, iterating them,
and reading a page's size and paper format. Rendering a page is the scope of
pdfium-syntax-rendering; adding, deleting, and reordering pages is
pdfium-impl-page-manipulation and pdfium-impl-multi-page.
Quick Reference: Page Access Flow
PdfDocument
.pages() -> &PdfPages immutable collection (read, iterate)
.pages_mut() -> &mut PdfPages mutable collection (added 0.8.0)
PdfPages
.len() -> PdfPageIndex page count
.is_empty() -> bool
.get(index) -> Result<PdfPage, PdfiumError>
.first() -> Result<PdfPage, PdfiumError>
.last() -> Result<PdfPage, PdfiumError>
.iter() -> PdfPagesIterator yields PdfPage in order
.page_size(i) -> Result<PdfRect, PdfiumError> no page load
.page_sizes() -> Result<Vec<PdfRect>, PdfiumError> no page load
PdfPage
.width() -> PdfPoints
.height() -> PdfPoints
.paper_size() -> PdfPagePaperSize
ALWAYS reach a page through pages() or pages_mut() on the owning
PdfDocument. NEVER assume a page can be constructed standalone; a PdfPage
borrows from its PdfDocument (see pdfium-core-architecture).
1. Reaching the Page Collection
PdfDocument exposes two collection accessors:
pages() returns &PdfPages<'a> for reading and iterating.
pages_mut() returns &mut PdfPages<'a> for mutation (creating, importing,
deleting, reordering pages). It was added in 0.8.0.
ALWAYS use pages_mut() when the operation changes the page set. NEVER try to
mutate the page set through pages(); the immutable collection has no
creation or import functions, and the borrow checker rejects the attempt.
2. The PdfPages Collection
PdfPages is the collection of all pages in a document. It is generic over
the document lifetime 'a.
Counting
pub fn len(&self) -> PdfPageIndex
pub fn is_empty(&self) -> bool
len() returns a PdfPageIndex, not a plain usize. ALWAYS check
is_empty() (or len()) before calling first() or last() on a document
that could be empty.
Single-page access
pub fn get(&self, index: PdfPageIndex) -> Result<PdfPage<'a>, PdfiumError>
pub fn first(&self) -> Result<PdfPage<'a>, PdfiumError>
pub fn last(&self) -> Result<PdfPage<'a>, PdfiumError>
All three return a Result. Pages are 0-indexed: the first page is index
0, the last is len() - 1. An out-of-range index returns
Err(PdfiumError::PageIndexOutOfBounds). first() and last() on an empty
document return an error.
ALWAYS treat get(), first(), and last() as fallible and handle the
Result. NEVER unwrap a page lookup on a document whose page count is
unknown.
Iterating
pub fn iter(&self) -> PdfPagesIterator<'_>
iter() yields every PdfPage in document order. Pair it with enumerate()
to get a 0-based page number alongside each page:
for (index, page) in document.pages().iter().enumerate() {
println!("page {}: {} pt wide", index, page.width().value);
}
ALWAYS use iter().enumerate() when a page number is needed during a loop.
3. Page Sizes Without Loading the Page
Loading a PdfPage parses its content. When only the dimensions are needed,
PdfPages provides load-free size queries that are considerably faster:
pub fn page_size(&self, index: PdfPageIndex) -> Result<PdfRect, PdfiumError>
pub fn page_sizes(&self) -> Result<Vec<PdfRect>, PdfiumError>
page_size() returns the size of one page as a PdfRect (measured in
PdfPoints) without loading it. page_sizes() returns the sizes of every
page in one call.
ALWAYS use page_size() or page_sizes() when the task only needs
dimensions. NEVER call get() and then width()/height() purely to read a
size; that loads the whole page and is slower.
Version note: the docs.rs 0.9.x API names these page_size and page_sizes.
The 0.9.0 cleanup release removed get_-prefixed accessors across the crate;
do not use a get_page_size form on the 0.9.x line.
4. PdfPage Basics: Size and Paper Format
pub fn width(&self) -> PdfPoints
pub fn height(&self) -> PdfPoints
pub fn paper_size(&self) -> PdfPagePaperSize
width() and height() return PdfPoints, the device-independent 1/72 inch
unit, not pixels. A US Letter page is 612.0 x 792.0 points. Converting
to pixels or physical units is the scope of pdfium-core-coordinates.
paper_size() returns a PdfPagePaperSize, an enum with three variants:
Portrait : a known standard size in portrait orientation.
Landscape : a known standard size in landscape orientation.
Custom : a non-standard size, carried as a (width, height) pair in
PdfPoints.
NEVER expect PdfPagePaperSize to be a flat list of A4 / Letter
variants. It is orientation plus a known-or-custom size. Standard sizes are
reached through constructors and shortcuts such as a4() and a3(); see
references/methods.md.
5. Page Indexing and PdfPageIndex
PdfPageIndex is the index and count type for pages:
pub type PdfPageIndex = c_int;
Version trap: in 0.9.0 PdfPageIndex changed from u16 to c_int. Code
written against 0.8.x that stores a page index or count as u16 fails to
compile against 0.9.x with a type-mismatch error.
ALWAYS store a page index or page count as PdfPageIndex (or let type
inference carry the value), so the code survives the 0.8.x to 0.9.x upgrade.
NEVER hardcode the underlying integer type (u16 or c_int) for a page
index; use the PdfPageIndex alias.
6. Iterating for Page Numbers
The canonical render-every-page loop pairs iter() with enumerate():
let document = pdfium.load_pdf_from_file("input.pdf", None)?;
for (index, page) in document.pages().iter().enumerate() {
println!("page {index}: {:.0} x {:.0} pt",
page.width().value, page.height().value);
}
enumerate() yields a usize index. Use it directly for display or
filenames. When the index must feed back into get() or page_size(),
convert it to PdfPageIndex.
Decision Tree: Which Page Accessor
What do I need from the pages?
Just the count
-> pages().len() / is_empty()
One specific page, index known
-> pages().get(index) (handle the Result)
The first or last page
-> pages().first() / pages().last() (handle the Result)
Walk every page in order
-> pages().iter() (add .enumerate() for page numbers)
Only the size of a page, content not needed
-> pages().page_size(index) / pages().page_sizes()
Change the set of pages (add / delete / import / reorder)
-> pages_mut() then see pdfium-impl-page-manipulation
ALWAYS / NEVER
- ALWAYS reach pages via
pages() or pages_mut() on the PdfDocument.
- ALWAYS use
pages_mut() for any operation that changes the page set.
- ALWAYS treat
get(), first(), and last() as fallible; pages are
0-indexed and an out-of-range index returns PageIndexOutOfBounds.
- ALWAYS use
page_size() / page_sizes() when only dimensions are needed.
- ALWAYS store a page index or count as
PdfPageIndex.
- ALWAYS use
iter().enumerate() to pair pages with page numbers.
- NEVER store a page index as
u16; PdfPageIndex is c_int since 0.9.0.
- NEVER load a page with
get() just to read its size.
- NEVER call
first() / last() without an is_empty() guard on a document
that could have zero pages.
- NEVER treat
width() / height() as pixel counts; they are PdfPoints.
Cross-References
- pdfium-core-coordinates :
PdfPoints, converting page sizes to pixels
or physical units.
- pdfium-syntax-rendering : turning a
PdfPage into a PdfBitmap.
- pdfium-impl-page-manipulation : creating, deleting, rotating, and
cropping pages through
pages_mut().
- pdfium-impl-multi-page : importing and merging pages across documents.
- pdfium-core-architecture : where
PdfPages and PdfPage sit in the
ownership tree.
Reference Files
references/methods.md : signatures of PdfDocument page accessors, the
PdfPages collection, PdfPage basics, PdfPageIndex, and
PdfPagePaperSize, with version annotations.
references/examples.md : verified Rust code for counting, indexing,
iterating, and reading sizes.
references/anti-patterns.md : real page-access failures with the cause
and the fix.
Sources
API names and signatures verified on 2026-05-20 via WebFetch against the
package SOURCES.md:
https://docs.rs/pdfium-render/latest/pdfium_render/prelude/struct.PdfPages.html
https://docs.rs/pdfium-render/latest/pdfium_render/prelude/struct.PdfPage.html
https://docs.rs/pdfium-render/latest/pdfium_render/prelude/struct.PdfDocument.html
https://docs.rs/pdfium-render/latest/pdfium_render/prelude/type.PdfPageIndex.html
https://docs.rs/pdfium-render/latest/pdfium_render/prelude/enum.PdfPagePaperSize.html
https://github.com/ajrcarey/pdfium-render (README, version history).