pdfium_render/pdf/document/page/
objects.rs1pub mod common;
5pub(crate) mod private;
6
7use crate::bindgen::{FPDF_DOCUMENT, FPDF_PAGE};
8use crate::bindings::PdfiumLibraryBindings;
9use crate::error::{PdfiumError, PdfiumInternalError};
10use crate::pdf::document::PdfDocument;
11use crate::pdf::document::page::PdfPageIndexCache;
12use crate::pdf::document::page::object::PdfPageObject;
13use crate::pdf::document::page::object::group::PdfPageGroupObject;
14use crate::pdf::document::page::object::ownership::PdfPageObjectOwnership;
15use crate::pdf::document::page::object::private::internal::PdfPageObjectPrivate;
16use crate::pdf::document::page::object::x_object_form::PdfPageXObjectFormObject;
17use crate::pdf::document::page::objects::common::{PdfPageObjectIndex, PdfPageObjectsCommon, PdfPageObjectsIterator};
18use crate::pdf::document::page::objects::private::internal::PdfPageObjectsPrivate;
19use std::os::raw::c_int;
20
21#[cfg(doc)]
22use {
23 crate::pdf::document::page::PdfPage, crate::pdf::document::page::PdfPageContentRegenerationStrategy,
24 crate::pdf::document::page::object::PdfPageObjectType,
25};
26
27pub struct PdfPageObjects<'a> {
37 document_handle: FPDF_DOCUMENT,
38 page_handle: FPDF_PAGE,
39 ownership: PdfPageObjectOwnership,
40 bindings: &'a dyn PdfiumLibraryBindings,
41}
42
43impl<'a> PdfPageObjects<'a> {
44 #[inline]
45 pub(crate) fn from_pdfium(
46 document_handle: FPDF_DOCUMENT,
47 page_handle: FPDF_PAGE,
48 bindings: &'a dyn PdfiumLibraryBindings,
49 ) -> Self {
50 Self {
51 document_handle,
52 page_handle,
53 ownership: PdfPageObjectOwnership::owned_by_page(document_handle, page_handle),
54 bindings,
55 }
56 }
57
58 #[inline]
60 pub(crate) fn document_handle(&self) -> FPDF_DOCUMENT {
61 self.document_handle
62 }
63
64 #[inline]
66 pub(crate) fn page_handle(&self) -> FPDF_PAGE {
67 self.page_handle
68 }
69
70 pub fn create_group<F>(&'a self, predicate: F) -> Result<PdfPageGroupObject<'a>, PdfiumError>
73 where
74 F: Fn(&PdfPageObject) -> bool,
75 {
76 let mut result = self.create_empty_group();
77
78 for mut object in self.iter().filter(predicate) {
79 result.push(&mut object)?;
80 }
81
82 Ok(result)
83 }
84
85 #[inline]
89 pub fn create_empty_group(&self) -> PdfPageGroupObject<'a> {
90 PdfPageGroupObject::from_pdfium(self.document_handle(), self.page_handle(), self.bindings())
91 }
92
93 pub fn copy_into_x_object_form_object(
96 &self,
97 destination: &mut PdfDocument<'a>,
98 ) -> Result<PdfPageObject<'a>, PdfiumError> {
99 let page_index = 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
131impl<'a> PdfPageObjectsPrivate<'a> for PdfPageObjects<'a> {
132 #[inline]
133 fn ownership(&self) -> &PdfPageObjectOwnership {
134 &self.ownership
135 }
136
137 #[inline]
138 fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
139 self.bindings
140 }
141
142 #[inline]
143 fn len_impl(&self) -> PdfPageObjectIndex {
144 self.bindings.FPDFPage_CountObjects(self.page_handle) as PdfPageObjectIndex
145 }
146
147 fn get_impl(&self, index: PdfPageObjectIndex) -> Result<PdfPageObject<'a>, PdfiumError> {
148 let object_handle = self.bindings.FPDFPage_GetObject(self.page_handle, index as c_int);
149
150 if object_handle.is_null() {
151 if index >= self.len() {
152 Err(PdfiumError::PageObjectIndexOutOfBounds)
153 } else {
154 Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
155 }
156 } else {
157 Ok(PdfPageObject::from_pdfium(
158 object_handle,
159 *self.ownership(),
160 self.bindings(),
161 ))
162 }
163 }
164
165 #[inline]
166 fn iter_impl(&'a self) -> PdfPageObjectsIterator<'a> {
167 PdfPageObjectsIterator::new(self)
168 }
169
170 #[inline]
171 fn add_object_impl(&mut self, mut object: PdfPageObject<'a>) -> Result<PdfPageObject<'a>, PdfiumError> {
172 object.add_object_to_page(self).map(|_| object)
173 }
174
175 #[inline]
176 fn remove_object_impl(&mut self, mut object: PdfPageObject<'a>) -> Result<PdfPageObject<'a>, PdfiumError> {
177 object.remove_object_from_page().map(|_| object)
178 }
179}