pdfium_render/pdf/document/page/
objects.rs1pub mod common;
5pub(crate) mod private; use crate::bindgen::{FPDF_DOCUMENT, FPDF_PAGE};
8use crate::bindings::PdfiumLibraryBindings;
9use crate::error::{PdfiumError, PdfiumInternalError};
10use crate::pdf::document::page::object::group::PdfPageGroupObject;
11use crate::pdf::document::page::object::ownership::PdfPageObjectOwnership;
12use crate::pdf::document::page::object::private::internal::PdfPageObjectPrivate;
13use crate::pdf::document::page::object::x_object_form::PdfPageXObjectFormObject;
14use crate::pdf::document::page::object::PdfPageObject;
15use crate::pdf::document::page::objects::common::{
16 PdfPageObjectIndex, PdfPageObjectsCommon, PdfPageObjectsIterator,
17};
18use crate::pdf::document::page::objects::private::internal::PdfPageObjectsPrivate;
19use crate::pdf::document::page::PdfPageIndexCache;
20use crate::pdf::document::PdfDocument;
21use std::os::raw::c_int;
22
23#[cfg(doc)]
24use {crate::pdf::document::page::object::PdfPageObjectType, crate::pdf::document::page::PdfPage};
25
26pub struct PdfPageObjects<'a> {
36 document_handle: FPDF_DOCUMENT,
37 page_handle: FPDF_PAGE,
38 ownership: PdfPageObjectOwnership,
39 bindings: &'a dyn PdfiumLibraryBindings,
40}
41
42impl<'a> PdfPageObjects<'a> {
43 #[inline]
44 pub(crate) fn from_pdfium(
45 document_handle: FPDF_DOCUMENT,
46 page_handle: FPDF_PAGE,
47 bindings: &'a dyn PdfiumLibraryBindings,
48 ) -> Self {
49 Self {
50 document_handle,
51 page_handle,
52 ownership: PdfPageObjectOwnership::owned_by_page(document_handle, page_handle),
53 bindings,
54 }
55 }
56
57 #[inline]
59 pub(crate) fn document_handle(&self) -> FPDF_DOCUMENT {
60 self.document_handle
61 }
62
63 #[inline]
65 pub(crate) fn page_handle(&self) -> FPDF_PAGE {
66 self.page_handle
67 }
68
69 pub fn create_group<F>(&'a self, predicate: F) -> Result<PdfPageGroupObject<'a>, PdfiumError>
72 where
73 F: Fn(&PdfPageObject) -> bool,
74 {
75 let mut result = self.create_empty_group();
76
77 for mut object in self.iter().filter(predicate) {
78 result.push(&mut object)?;
79 }
80
81 Ok(result)
82 }
83
84 #[inline]
88 pub fn create_empty_group(&self) -> PdfPageGroupObject<'a> {
89 PdfPageGroupObject::from_pdfium(self.document_handle(), self.page_handle(), self.bindings())
90 }
91
92 pub fn copy_into_x_object_form_object(
95 &self,
96 destination: &mut PdfDocument<'a>,
97 ) -> Result<PdfPageObject<'a>, PdfiumError> {
98 let page_index =
99 PdfPageIndexCache::get_index_for_page(self.document_handle(), self.page_handle());
100
101 match page_index {
102 Some(page_index) => {
103 let x_object = self.bindings().FPDF_NewXObjectFromPage(
104 destination.handle(),
105 self.document_handle(),
106 page_index as c_int,
107 );
108
109 let object_handle = self.bindings().FPDF_NewFormObjectFromXObject(x_object);
110 if object_handle.is_null() {
111 return Err(PdfiumError::PdfiumLibraryInternalError(
112 crate::error::PdfiumInternalError::Unknown,
113 ));
114 }
115
116 let object = PdfPageXObjectFormObject::from_pdfium(
117 object_handle,
118 PdfPageObjectOwnership::owned_by_document(destination.handle()),
119 self.bindings(),
120 );
121
122 self.bindings().FPDF_CloseXObject(x_object);
123
124 Ok(PdfPageObject::XObjectForm(object))
125 }
126 None => Err(PdfiumError::SourcePageIndexNotInCache),
127 }
128 }
129
130 #[cfg(any(feature = "pdfium_future", feature = "pdfium_7350"))]
131 #[inline]
140 pub fn insert_object_at_index(
141 &mut self,
142 index: PdfPageObjectIndex,
143 mut object: PdfPageObject<'a>,
144 ) -> Result<PdfPageObject<'a>, PdfiumError> {
145 object.insert_object_on_page(self, index).map(|_| object)
146 }
147}
148
149impl<'a> PdfPageObjectsPrivate<'a> for PdfPageObjects<'a> {
150 #[inline]
151 fn ownership(&self) -> &PdfPageObjectOwnership {
152 &self.ownership
153 }
154
155 #[inline]
156 fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
157 self.bindings
158 }
159
160 #[inline]
161 fn len_impl(&self) -> PdfPageObjectIndex {
162 self.bindings.FPDFPage_CountObjects(self.page_handle) as PdfPageObjectIndex
163 }
164
165 fn get_impl(&self, index: PdfPageObjectIndex) -> Result<PdfPageObject<'a>, PdfiumError> {
166 let object_handle = self
167 .bindings
168 .FPDFPage_GetObject(self.page_handle, index as c_int);
169
170 if object_handle.is_null() {
171 if index >= self.len() {
172 Err(PdfiumError::PageObjectIndexOutOfBounds)
173 } else {
174 Err(PdfiumError::PdfiumLibraryInternalError(
175 PdfiumInternalError::Unknown,
176 ))
177 }
178 } else {
179 Ok(PdfPageObject::from_pdfium(
180 object_handle,
181 *self.ownership(),
182 self.bindings(),
183 ))
184 }
185 }
186
187 #[inline]
188 fn iter_impl(&'a self) -> PdfPageObjectsIterator<'a> {
189 PdfPageObjectsIterator::new(self)
190 }
191
192 #[inline]
193 fn add_object_impl(
194 &mut self,
195 mut object: PdfPageObject<'a>,
196 ) -> Result<PdfPageObject<'a>, PdfiumError> {
197 object.add_object_to_page(self).map(|_| object)
198 }
199
200 #[inline]
201 fn remove_object_impl(
202 &mut self,
203 mut object: PdfPageObject<'a>,
204 ) -> Result<PdfPageObject<'a>, PdfiumError> {
205 object.remove_object_from_page().map(|_| object)
206 }
207}