use crate::bindgen::FPDF_ANNOTATION;
use crate::error::{PdfiumError, PdfiumInternalError};
use crate::pdf::quad_points::PdfQuadPoints;
use crate::pdfium::PdfiumLibraryBindingsAccessor;
use std::marker::PhantomData;
use std::ops::{Range, RangeInclusive};
pub type PdfPageAnnotationAttachmentPointIndex = usize;
pub struct PdfPageAnnotationAttachmentPoints<'a> {
annotation_handle: FPDF_ANNOTATION,
lifetime: PhantomData<&'a FPDF_ANNOTATION>,
}
impl<'a> PdfPageAnnotationAttachmentPoints<'a> {
#[inline]
pub(crate) fn from_pdfium(annotation_handle: FPDF_ANNOTATION) -> Self {
PdfPageAnnotationAttachmentPoints {
annotation_handle,
lifetime: PhantomData,
}
}
pub fn len(&self) -> PdfPageAnnotationAttachmentPointIndex {
if self.bindings().is_true(unsafe {
self.bindings()
.FPDFAnnot_HasAttachmentPoints(self.annotation_handle)
}) {
(unsafe {
self.bindings()
.FPDFAnnot_CountAttachmentPoints(self.annotation_handle)
}) as PdfPageAnnotationAttachmentPointIndex
} else {
0
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn as_range(&self) -> Range<PdfPageAnnotationAttachmentPointIndex> {
0..self.len()
}
#[inline]
pub fn as_range_inclusive(&self) -> RangeInclusive<PdfPageAnnotationAttachmentPointIndex> {
if self.is_empty() {
0..=0
} else {
0..=(self.len() - 1)
}
}
pub fn get(
&self,
index: PdfPageAnnotationAttachmentPointIndex,
) -> Result<PdfQuadPoints, PdfiumError> {
if index >= self.len() {
return Err(PdfiumError::PageAnnotationAttachmentPointIndexOutOfBounds);
}
let mut result = PdfQuadPoints::ZERO.as_pdfium();
if self.bindings().is_true(unsafe {
self.bindings().FPDFAnnot_GetAttachmentPoints(
self.annotation_handle,
index,
&mut result,
)
}) {
Ok(PdfQuadPoints::from_pdfium(result))
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
}
#[inline]
pub fn first(&self) -> Result<PdfQuadPoints, PdfiumError> {
if !self.is_empty() {
self.get(0)
} else {
Err(PdfiumError::NoAttachmentPointsInPageAnnotation)
}
}
#[inline]
pub fn last(&self) -> Result<PdfQuadPoints, PdfiumError> {
if !self.is_empty() {
self.get(self.len() - 1)
} else {
Err(PdfiumError::NoAttachmentPointsInPageAnnotation)
}
}
#[inline]
pub fn create_attachment_point_at_end(
&mut self,
attachment_point: PdfQuadPoints,
) -> Result<(), PdfiumError> {
if self.bindings().is_true(unsafe {
self.bindings().FPDFAnnot_AppendAttachmentPoints(
self.annotation_handle,
&attachment_point.as_pdfium(),
)
}) {
Ok(())
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
}
pub fn set_attachment_point_at_index(
&mut self,
index: PdfPageAnnotationAttachmentPointIndex,
attachment_point: PdfQuadPoints,
) -> Result<(), PdfiumError> {
if self.bindings().is_true(unsafe {
self.bindings().FPDFAnnot_SetAttachmentPoints(
self.annotation_handle,
index,
&attachment_point.as_pdfium(),
)
}) {
Ok(())
} else {
Err(PdfiumError::PdfiumLibraryInternalError(
PdfiumInternalError::Unknown,
))
}
}
#[inline]
pub fn iter(&self) -> PdfPageAnnotationAttachmentPointsIterator<'_> {
PdfPageAnnotationAttachmentPointsIterator::new(self)
}
}
impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfPageAnnotationAttachmentPoints<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Send for PdfPageAnnotationAttachmentPoints<'a> {}
#[cfg(feature = "thread_safe")]
unsafe impl<'a> Sync for PdfPageAnnotationAttachmentPoints<'a> {}
pub struct PdfPageAnnotationAttachmentPointsIterator<'a> {
attachment_points: &'a PdfPageAnnotationAttachmentPoints<'a>,
next_index: PdfPageAnnotationAttachmentPointIndex,
}
impl<'a> PdfPageAnnotationAttachmentPointsIterator<'a> {
#[inline]
pub(crate) fn new(attachment_points: &'a PdfPageAnnotationAttachmentPoints<'a>) -> Self {
PdfPageAnnotationAttachmentPointsIterator {
attachment_points,
next_index: 0,
}
}
}
impl<'a> Iterator for PdfPageAnnotationAttachmentPointsIterator<'a> {
type Item = PdfQuadPoints;
fn next(&mut self) -> Option<Self::Item> {
let next = self.attachment_points.get(self.next_index);
self.next_index += 1;
next.ok()
}
}