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
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
149 .bindings
150 .FPDFPage_GetObject(self.page_handle, index as c_int);
151
152 if object_handle.is_null() {
153 if index >= self.len() {
154 return Err(PdfiumError::PageObjectIndexOutOfBounds);
155 }
156 Err(PdfiumError::PdfiumLibraryInternalError(
157 PdfiumInternalError::Unknown,
158 ))
159 } else {
160 Ok(PdfPageObject::from_pdfium(
161 object_handle,
162 self.ownership().clone(),
163 self.bindings(),
164 ))
165 }
166 }
167
168 #[inline]
169 fn iter_impl(&'a self) -> PdfPageObjectsIterator<'a> {
170 PdfPageObjectsIterator::new(self)
171 }
172
173 #[inline]
174 fn add_object_impl(
175 &mut self,
176 mut object: PdfPageObject<'a>,
177 ) -> Result<PdfPageObject<'a>, PdfiumError> {
178 object.add_object_to_page(self).map(|_| object)
179 }
180
181 #[inline]
182 fn remove_object_impl(
183 &mut self,
184 mut object: PdfPageObject<'a>,
185 ) -> Result<PdfPageObject<'a>, PdfiumError> {
186 object.remove_object_from_page().map(|_| object)
187 }
188}