| name | pdfium-impl-page-objects-edit |
| description | Use when adding, removing, transforming, or relocating page objects on a PDF page with pdfium-render: stamping an image, drawing a path, scaling or rotating an object with a PdfMatrix, or moving an object to another page. Prevents the borrow-checker fight that naive remove-then-insert object moving causes, the double-add bug from calling both a create_ and an add_ method, and reaching for the set_matrix and copy_onto_new_page names that were removed in 0.9.0. Covers PdfPageObjects create_ and add_ and remove_ methods, PdfPageImageObject constructors, PdfMatrix transforms, apply_matrix, PdfPageGroupObject, and copy_to_page / move_to_page across pdfium-render 0.8.x and 0.9.x. Keywords: pdfium-render page objects, PdfPageObjects, add_image_object, create_image_object, create_path_object_bezier, remove_object, PdfPageImageObject, new_from_jpeg_file, apply_matrix, PdfMatrix, transform, PdfPageGroupObject, copy_to_page, move_to_page, set_matrix removed, copy_onto_new_page removed, objects_mut, stamp image on PDF, draw on a PDF page, move object between pages, borrow checker error moving objects.
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires pdfium-render 0.8,0.9. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
pdfium-impl-page-objects-edit
What this skill covers
A PDF page holds a collection of page objects: text, path, image, shading, and
XObject form objects. This skill covers MUTATING that collection: creating
objects, adding and removing them, transforming them with a PdfMatrix, and
relocating them between pages with PdfPageGroupObject and the
copy_to_page / move_to_page methods.
For reading and inspecting existing page objects see
pdfium-syntax-page-objects. For copying whole pages between documents see
pdfium-impl-multi-page. For PdfPoints and coordinate geometry see
pdfium-core-coordinates. Default API surface here is 0.9.x.
Quick reference
| Goal | Call |
|---|
| Get a mutable collection | page.objects_mut() |
| Create and add an image in one step | objects.create_image_object(x, y, &image, w, h) |
| Create and add a bezier path | objects.create_path_object_bezier(...) |
| Build a detached image object | PdfPageImageObject::new(&document, &image) |
| Attach a detached object | objects.add_image_object(obj) / add_path_object(obj) |
| Remove an object | objects.remove_object(obj) / remove_object_at_index(i) |
| Transform an object | object.apply_matrix(matrix) |
| Relocate an object | object.copy_to_page(&mut page) / move_to_page(&mut page) |
ALWAYS call objects_mut() to mutate. objects() returns an immutable
&PdfPageObjects; the create_, add_, and remove_ methods all take
&mut self and will not compile against it.
Two ways to create an object
pdfium-render offers two distinct construction styles. NEVER mix them for the
same object.
Style A : create_* (build and add in one call)
The create_* methods on PdfPageObjects build the object AND add it to the
page, returning the added PdfPageObject:
use pdfium_render::prelude::*;
let object = page.objects_mut().create_image_object(
PdfPoints::new(100.0),
PdfPoints::new(500.0),
&image,
Some(PdfPoints::new(200.0)),
Some(PdfPoints::new(150.0)),
)?;
Path variants: create_path_object_line, create_path_object_bezier,
create_path_object_rect, create_path_object_circle,
create_path_object_circle_at, create_path_object_ellipse,
create_path_object_ellipse_at. Also create_text_object.
Style B : new then add_* (build detached, then attach)
PdfPageImageObject constructors build a detached object bound to a document.
A separate add_image_object call attaches it to a page:
let object = PdfPageImageObject::new_from_jpeg_file(&document, "logo.jpg")?;
let added = page.objects_mut().add_image_object(object)?;
NEVER call both a create_* method and an add_* method for the same object:
create_* already added it. A second add_* adds a duplicate or fails.
PdfPageImageObject constructors
| Constructor | Use |
|---|
new(&document, &image) | image at its natural size |
new_with_width(&document, &image, width) | width fixed, height from aspect ratio |
new_with_height(&document, &image, height) | height fixed, width from aspect ratio |
new_with_size(&document, &image, width, height) | exact size |
new_from_jpeg_file(&document, path) | load straight from a JPEG file (0.8.29) |
new_from_jpeg_reader(&document, reader) | load from any Read + Seek (0.8.29) |
Every constructor returns Result<PdfPageImageObject, PdfiumError> and takes
the PdfDocument the object will belong to. Use set_image() to replace the
image, get_raw_image() / get_processed_image() to read it back.
Transforming an object with PdfMatrix
A PdfPageObject carries a transformation matrix. Apply a PdfMatrix with
apply_matrix:
use pdfium_render::prelude::*;
let matrix = PdfMatrix::IDENTITY
.scale(2.0, 2.0)?
.rotate_clockwise_degrees(45.0)?;
object.apply_matrix(matrix)?;
PdfMatrix factory methods (translate, scale, rotate_clockwise_degrees,
rotate_counter_clockwise_degrees, flip_horizontally, flip_vertically)
each return Result<PdfMatrix, PdfiumError>, so chain them with ?.
| Method on a page object | Effect |
|---|
apply_matrix(matrix) | compose matrix onto the object's current transform |
transform(a, b, c, d, e, f) | apply a raw six-value matrix |
reset_matrix(matrix) | replace the object's transform |
reset_matrix_to_identity() | clear the transform |
matrix() | read the current transform |
Version trap: set_matrix() was deprecated in 0.8.15 and removed in 0.9.0.
ALWAYS use apply_matrix() (or reset_matrix() to replace rather than
compose).
Removing objects
let removed = page.objects_mut().remove_object(object)?;
let removed = page.objects_mut().remove_object_at_index(0)?;
Both return the removed PdfPageObject. Version trap: the 0.6.x names
delete_object / delete_object_at_index were renamed to remove_object /
remove_object_at_index in 0.7.4.
Relocating objects between pages
NEVER hand-roll object moving as remove-from-page-A then add-to-page-B. That
pattern fights the borrow checker, because removing requires a mutable borrow
of one page's objects while inserting requires a mutable borrow of another
(issues #60, #25). ALWAYS use the dedicated relocation methods.
| Method | Source | Effect |
|---|
object.copy_to_page(&mut page) | a single PdfPageObject | duplicate onto page |
object.move_to_page(&mut page) | a single PdfPageObject | move onto page |
group.copy_to_page(&mut page) | a PdfPageGroupObject | duplicate the whole group |
group.move_to_page(&mut page) | a PdfPageGroupObject | move the whole group |
PdfPageGroupObject collects several objects so one transform or one
relocation applies to all of them at once. Build a group with
objects.create_group(...) or create_empty_group(), then call apply_matrix,
copy_to_page, move_to_page, or move_to_annotation on the group.
Version trap: the PdfPageGroupObject::copy_onto_new_page_* methods were
removed in 0.9.0. ALWAYS use copy_to_page().
Common failures (quick triage)
| Symptom | Likely cause | Fix |
|---|
compile error: method takes &mut self | called a mutator on objects() | use objects_mut() |
compile error: set_matrix not found | removed 0.9.0 name | use apply_matrix() |
compile error: copy_onto_new_page not found | removed 0.9.0 name | use copy_to_page() |
compile error: delete_object not found | renamed in 0.7.4 | use remove_object() |
| borrow-checker error moving an object | hand-rolled remove-then-insert | use move_to_page() |
CannotMoveObjectAcrossDocuments | move_to_page targeted another document's page | see pdfium-impl-multi-page |
| duplicate object on the page | both create_* and add_* called | use exactly one construction style |
Reference files
references/methods.md: complete signatures for PdfPageObjects,
PdfPageImageObject, PdfMatrix, PdfPageGroupObject, and the object
transform methods, with version annotations.
references/examples.md: verified editing code, from stamping an image to
moving objects between pages.
references/anti-patterns.md: real editing failures, why each fails, and the
fix.
Companion skills
pdfium-syntax-page-objects: reading and inspecting existing page objects.
pdfium-impl-multi-page: copying whole pages between documents.
pdfium-core-coordinates: PdfPoints, PdfRect vs PdfQuadPoints.
pdfium-impl-saving: persisting the edited document.