pdfium_render/pdf/document/page/annotation/
attachment_points.rs1use crate::bindgen::FPDF_ANNOTATION;
6use crate::error::{PdfiumError, PdfiumInternalError};
7use crate::pdf::quad_points::PdfQuadPoints;
8use crate::pdfium::PdfiumLibraryBindingsAccessor;
9use std::marker::PhantomData;
10use std::ops::{Range, RangeInclusive};
11
12pub type PdfPageAnnotationAttachmentPointIndex = usize;
15
16pub struct PdfPageAnnotationAttachmentPoints<'a> {
19 annotation_handle: FPDF_ANNOTATION,
20 lifetime: PhantomData<&'a FPDF_ANNOTATION>,
21}
22
23impl<'a> PdfPageAnnotationAttachmentPoints<'a> {
24 #[inline]
25 pub(crate) fn from_pdfium(annotation_handle: FPDF_ANNOTATION) -> Self {
26 PdfPageAnnotationAttachmentPoints {
27 annotation_handle,
28 lifetime: PhantomData,
29 }
30 }
31
32 pub fn len(&self) -> PdfPageAnnotationAttachmentPointIndex {
34 if self.bindings().is_true(unsafe {
35 self.bindings()
36 .FPDFAnnot_HasAttachmentPoints(self.annotation_handle)
37 }) {
38 (unsafe {
39 self.bindings()
40 .FPDFAnnot_CountAttachmentPoints(self.annotation_handle)
41 }) as PdfPageAnnotationAttachmentPointIndex
42 } else {
43 0
46 }
47 }
48
49 #[inline]
51 pub fn is_empty(&self) -> bool {
52 self.len() == 0
53 }
54
55 #[inline]
58 pub fn as_range(&self) -> Range<PdfPageAnnotationAttachmentPointIndex> {
59 0..self.len()
60 }
61
62 #[inline]
65 pub fn as_range_inclusive(&self) -> RangeInclusive<PdfPageAnnotationAttachmentPointIndex> {
66 if self.is_empty() {
67 0..=0
68 } else {
69 0..=(self.len() - 1)
70 }
71 }
72
73 pub fn get(
76 &self,
77 index: PdfPageAnnotationAttachmentPointIndex,
78 ) -> Result<PdfQuadPoints, PdfiumError> {
79 if index >= self.len() {
80 return Err(PdfiumError::PageAnnotationAttachmentPointIndexOutOfBounds);
81 }
82
83 let mut result = PdfQuadPoints::ZERO.as_pdfium();
84
85 if self.bindings().is_true(unsafe {
86 self.bindings().FPDFAnnot_GetAttachmentPoints(
87 self.annotation_handle,
88 index,
89 &mut result,
90 )
91 }) {
92 Ok(PdfQuadPoints::from_pdfium(result))
93 } else {
94 Err(PdfiumError::PdfiumLibraryInternalError(
95 PdfiumInternalError::Unknown,
96 ))
97 }
98 }
99
100 #[inline]
103 pub fn first(&self) -> Result<PdfQuadPoints, PdfiumError> {
104 if !self.is_empty() {
105 self.get(0)
106 } else {
107 Err(PdfiumError::NoAttachmentPointsInPageAnnotation)
108 }
109 }
110
111 #[inline]
114 pub fn last(&self) -> Result<PdfQuadPoints, PdfiumError> {
115 if !self.is_empty() {
116 self.get(self.len() - 1)
117 } else {
118 Err(PdfiumError::NoAttachmentPointsInPageAnnotation)
119 }
120 }
121
122 #[inline]
125 pub fn create_attachment_point_at_end(
126 &mut self,
127 attachment_point: PdfQuadPoints,
128 ) -> Result<(), PdfiumError> {
129 if self.bindings().is_true(unsafe {
130 self.bindings().FPDFAnnot_AppendAttachmentPoints(
131 self.annotation_handle,
132 &attachment_point.as_pdfium(),
133 )
134 }) {
135 Ok(())
136 } else {
137 Err(PdfiumError::PdfiumLibraryInternalError(
138 PdfiumInternalError::Unknown,
139 ))
140 }
141 }
142
143 pub fn set_attachment_point_at_index(
146 &mut self,
147 index: PdfPageAnnotationAttachmentPointIndex,
148 attachment_point: PdfQuadPoints,
149 ) -> Result<(), PdfiumError> {
150 if self.bindings().is_true(unsafe {
151 self.bindings().FPDFAnnot_SetAttachmentPoints(
152 self.annotation_handle,
153 index,
154 &attachment_point.as_pdfium(),
155 )
156 }) {
157 Ok(())
158 } else {
159 Err(PdfiumError::PdfiumLibraryInternalError(
160 PdfiumInternalError::Unknown,
161 ))
162 }
163 }
164
165 #[inline]
167 pub fn iter(&self) -> PdfPageAnnotationAttachmentPointsIterator<'_> {
168 PdfPageAnnotationAttachmentPointsIterator::new(self)
169 }
170}
171
172impl<'a> PdfiumLibraryBindingsAccessor<'a> for PdfPageAnnotationAttachmentPoints<'a> {}
173
174#[cfg(feature = "thread_safe")]
175unsafe impl<'a> Send for PdfPageAnnotationAttachmentPoints<'a> {}
176
177#[cfg(feature = "thread_safe")]
178unsafe impl<'a> Sync for PdfPageAnnotationAttachmentPoints<'a> {}
179
180pub struct PdfPageAnnotationAttachmentPointsIterator<'a> {
182 attachment_points: &'a PdfPageAnnotationAttachmentPoints<'a>,
183 next_index: PdfPageAnnotationAttachmentPointIndex,
184}
185
186impl<'a> PdfPageAnnotationAttachmentPointsIterator<'a> {
187 #[inline]
188 pub(crate) fn new(attachment_points: &'a PdfPageAnnotationAttachmentPoints<'a>) -> Self {
189 PdfPageAnnotationAttachmentPointsIterator {
190 attachment_points,
191 next_index: 0,
192 }
193 }
194}
195
196impl<'a> Iterator for PdfPageAnnotationAttachmentPointsIterator<'a> {
197 type Item = PdfQuadPoints;
198
199 fn next(&mut self) -> Option<Self::Item> {
200 let next = self.attachment_points.get(self.next_index);
201
202 self.next_index += 1;
203
204 next.ok()
205 }
206}