use crate::bindgen::{FPDF_ANNOTATION, FPDF_DOCUMENT, FPDF_PAGE};
use crate::bindings::PdfiumLibraryBindings;
use crate::error::{PdfiumError, PdfiumInternalError};
use crate::page_object::PdfPageObject;
use crate::page_object_private::internal::PdfPageObjectPrivate;
use crate::page_objects_common::{
PdfPageObjectIndex, PdfPageObjectsCommon, PdfPageObjectsIterator,
};
use crate::page_objects_private::internal::PdfPageObjectsPrivate;
use std::os::raw::c_int;
pub struct PdfPageAnnotationObjects<'a> {
document_handle: FPDF_DOCUMENT,
page_handle: FPDF_PAGE,
annotation_handle: FPDF_ANNOTATION,
bindings: &'a dyn PdfiumLibraryBindings,
do_regenerate_page_content_after_each_change: bool,
}
impl<'a> PdfPageAnnotationObjects<'a> {
#[inline]
pub(crate) fn from_pdfium(
document_handle: FPDF_DOCUMENT,
page_handle: FPDF_PAGE,
annotation_handle: FPDF_ANNOTATION,
bindings: &'a dyn PdfiumLibraryBindings,
) -> Self {
Self {
document_handle,
page_handle,
annotation_handle,
bindings,
do_regenerate_page_content_after_each_change: false,
}
}
#[inline]
pub(crate) fn get_annotation_handle(&self) -> &FPDF_ANNOTATION {
&self.annotation_handle
}
#[inline]
pub(crate) fn do_regenerate_page_content_after_each_change(
&mut self,
do_regenerate_page_content_after_each_change: bool,
) {
self.do_regenerate_page_content_after_each_change =
do_regenerate_page_content_after_each_change;
}
}
impl<'a> PdfPageObjectsPrivate<'a> for PdfPageAnnotationObjects<'a> {
#[inline]
fn document_handle(&self) -> FPDF_DOCUMENT {
self.document_handle
}
#[inline]
fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
self.bindings
}
#[inline]
fn len_impl(&self) -> PdfPageObjectIndex {
self.bindings
.FPDFAnnot_GetObjectCount(self.annotation_handle) as PdfPageObjectIndex
}
fn get_impl(&self, index: PdfPageObjectIndex) -> Result<PdfPageObject<'a>, PdfiumError> {
if index >= self.len() {
return Err(PdfiumError::PageObjectIndexOutOfBounds);
}
let object_handle = self
.bindings
.FPDFAnnot_GetObject(self.annotation_handle, index as c_int);
if object_handle.is_null() {
if let Some(error) = self.bindings.get_pdfium_last_error() {
Err(PdfiumError::PdfiumLibraryInternalError(error))
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
} else {
Ok(PdfPageObject::from_pdfium(
object_handle,
None,
Some(self.annotation_handle),
self.bindings,
))
}
}
#[inline]
fn iter_impl(&'a self) -> PdfPageObjectsIterator<'a> {
PdfPageObjectsIterator::new(self)
}
fn add_object_impl(
&mut self,
mut object: PdfPageObject<'a>,
) -> Result<PdfPageObject<'a>, PdfiumError> {
object.add_object_to_annotation(self).and_then(|_| {
if self.do_regenerate_page_content_after_each_change {
if !self
.bindings
.is_true(self.bindings.FPDFPage_GenerateContent(self.page_handle))
{
if let Some(error) = self.bindings.get_pdfium_last_error() {
Err(PdfiumError::PdfiumLibraryInternalError(error))
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
} else {
Ok(object)
}
} else {
Ok(object)
}
})
}
fn remove_object_impl(
&mut self,
mut object: PdfPageObject<'a>,
) -> Result<PdfPageObject<'a>, PdfiumError> {
object.remove_object_from_annotation().and_then(|_| {
if self.do_regenerate_page_content_after_each_change {
self.bindings.FPDFPage_GenerateContent(self.page_handle);
if let Some(error) = self.bindings.get_pdfium_last_error() {
Err(PdfiumError::PdfiumLibraryInternalError(error))
} else {
Ok(object)
}
} else {
Ok(object)
}
})
}
}