use crate::bindgen::FPDF_PAGEOBJECT;
use crate::error::{PdfiumError, PdfiumInternalError};
use crate::pdf::document::page::object::private::internal::PdfPageObjectPrivate;
use crate::pdf::document::page::object::{PdfPageObject, PdfPageObjectOwnership};
use crate::pdf::document::page::objects::common::{PdfPageObjectIndex, PdfPageObjectsIterator};
use crate::pdf::document::page::objects::private::internal::PdfPageObjectsPrivate;
use crate::pdf::matrix::{PdfMatrix, PdfMatrixValue};
use crate::pdf::points::PdfPoints;
use crate::pdfium::PdfiumLibraryBindingsAccessor;
use crate::{create_transform_getters, create_transform_setters};
use std::marker::PhantomData;
use std::ops::{Range, RangeInclusive};
use std::os::raw::c_ulong;
#[cfg(doc)]
use {
crate::pdf::document::page::object::group::PdfPageGroupObject,
crate::pdf::document::page::object::PdfPageObjectType,
crate::pdf::document::page::objects::PdfPageObjects,
};
pub struct PdfPageXObjectFormObject<'a> {
object_handle: FPDF_PAGEOBJECT,
ownership: PdfPageObjectOwnership,
lifetime: PhantomData<&'a FPDF_PAGEOBJECT>,
}
impl<'a> PdfPageXObjectFormObject<'a> {
pub(crate) fn from_pdfium(
object_handle: FPDF_PAGEOBJECT,
ownership: PdfPageObjectOwnership,
) -> Self {
PdfPageXObjectFormObject {
object_handle,
ownership,
lifetime: PhantomData,
}
}
#[inline]
pub fn len(&self) -> PdfPageObjectIndex {
self.len_impl()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_range(&self) -> Range<PdfPageObjectIndex> {
0..self.len()
}
#[inline]
pub fn as_range_inclusive(&self) -> RangeInclusive<PdfPageObjectIndex> {
if self.is_empty() {
0..=0
} else {
0..=(self.len() - 1)
}
}
#[inline]
pub fn get(&self, index: PdfPageObjectIndex) -> Result<PdfPageObject<'a>, PdfiumError> {
self.get_impl(index)
}
#[inline]
pub fn first(&self) -> Result<PdfPageObject<'a>, PdfiumError> {
if !self.is_empty() {
self.get(0)
} else {
Err(PdfiumError::NoPageObjectsInCollection)
}
}
#[inline]
pub fn last(&self) -> Result<PdfPageObject<'a>, PdfiumError> {
if !self.is_empty() {
self.get(self.len() - 1)
} else {
Err(PdfiumError::NoPageObjectsInCollection)
}
}
#[inline]
pub fn iter(&'a self) -> PdfPageObjectsIterator<'a> {
self.iter_impl()
}
create_transform_setters!(
&mut Self,
Result<(), PdfiumError>,
"this [PdfPageXObjectFormObject]",
"this [PdfPageXObjectFormObject].",
"this [PdfPageXObjectFormObject],"
);
create_transform_getters!(
"this [PdfPageXObjectFormObject]",
"this [PdfPageXObjectFormObject].",
"this [PdfPageXObjectFormObject],"
);
}
impl<'a> PdfPageObjectPrivate<'a> for PdfPageXObjectFormObject<'a> {
#[inline]
fn object_handle(&self) -> FPDF_PAGEOBJECT {
self.object_handle
}
#[inline]
fn ownership(&self) -> &PdfPageObjectOwnership {
&self.ownership
}
#[inline]
fn set_ownership(&mut self, ownership: PdfPageObjectOwnership) {
self.ownership = ownership;
}
}
impl<'a> PdfPageObjectsPrivate<'a> for PdfPageXObjectFormObject<'a> {
#[inline]
fn ownership(&self) -> &PdfPageObjectOwnership {
&self.ownership
}
#[inline]
fn len_impl(&self) -> PdfPageObjectIndex {
(unsafe { self.bindings().FPDFFormObj_CountObjects(self.object_handle) })
as PdfPageObjectIndex
}
fn get_impl(&self, index: PdfPageObjectIndex) -> Result<PdfPageObject<'a>, PdfiumError> {
let object_handle = unsafe {
self.bindings()
.FPDFFormObj_GetObject(self.object_handle, index as c_ulong)
};
if object_handle.is_null() {
if index >= self.len() {
Err(PdfiumError::PageObjectIndexOutOfBounds)
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
} else {
Ok(PdfPageObject::from_pdfium(
object_handle,
*PdfPageObjectPrivate::ownership(self),
PdfiumLibraryBindingsAccessor::bindings(self),
))
}
}
#[inline]
fn iter_impl(&'a self) -> PdfPageObjectsIterator<'a> {
PdfPageObjectsIterator::new(self)
}
fn add_object_impl(
&mut self,
_object: PdfPageObject<'a>,
) -> Result<PdfPageObject<'a>, PdfiumError> {
Err(PdfiumError::PageObjectsCollectionIsImmutable)
}
#[cfg(any(
feature = "pdfium_future",
feature = "pdfium_7543",
feature = "pdfium_7350"
))]
fn remove_object_impl(
&mut self,
mut object: PdfPageObject<'a>,
) -> Result<PdfPageObject<'a>, PdfiumError> {
if self.bindings().is_true(unsafe {
self.bindings()
.FPDFFormObj_RemoveObject(self.object_handle, object.object_handle())
}) {
object.set_ownership(PdfPageObjectOwnership::Unowned);
Ok(object)
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
}
#[cfg(not(any(
feature = "pdfium_future",
feature = "pdfium_7543",
feature = "pdfium_7350"
)))]
fn remove_object_impl(
&mut self,
_object: PdfPageObject<'a>,
) -> Result<PdfPageObject<'a>, PdfiumError> {
Err(PdfiumError::PageObjectsCollectionIsImmutable)
}
}
impl<'a> Drop for PdfPageXObjectFormObject<'a> {
fn drop(&mut self) {
self.drop_impl();
}
}
impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfPageXObjectFormObject<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Send for PdfPageXObjectFormObject<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Sync for PdfPageXObjectFormObject<'a> {}