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