pdfium_render/pdf/path/
clip_path.rs1use crate::bindgen::FPDF_CLIPPATH;
4use crate::bindings::PdfiumLibraryBindings;
5use crate::error::{PdfiumError, PdfiumInternalError};
6use crate::pdf::document::page::object::ownership::PdfPageObjectOwnership;
7use crate::pdf::path::segment::PdfPathSegment;
8use crate::pdf::path::segments::{PdfPathSegmentIndex, PdfPathSegments, PdfPathSegmentsIterator};
9use std::convert::TryInto;
10use std::ops::{Range, RangeInclusive};
11use std::os::raw::c_int;
12
13pub type PdfClipPathSegmentIndex = u16;
16
17pub struct PdfClipPath<'a> {
19 handle: FPDF_CLIPPATH,
20 ownership: PdfPageObjectOwnership,
21 bindings: &'a dyn PdfiumLibraryBindings,
22}
23
24impl<'a> PdfClipPath<'a> {
25 #[inline]
26 pub(crate) fn from_pdfium(
27 handle: FPDF_CLIPPATH,
28 ownership: PdfPageObjectOwnership,
29 bindings: &'a dyn PdfiumLibraryBindings,
30 ) -> Self {
31 Self {
32 handle,
33 ownership,
34 bindings,
35 }
36 }
37
38 #[inline]
40 pub(crate) fn handle(&self) -> FPDF_CLIPPATH {
41 self.handle
42 }
43
44 #[inline]
46 pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
47 self.bindings
48 }
49
50 #[inline]
52 pub fn len(&self) -> PdfClipPathSegmentIndex {
53 self.bindings().FPDFClipPath_CountPaths(self.handle()) as PdfClipPathSegmentIndex
54 }
55
56 #[inline]
58 pub fn is_empty(&self) -> bool {
59 self.len() == 0
60 }
61
62 #[inline]
64 pub fn as_range(&self) -> Range<PdfClipPathSegmentIndex> {
65 0..self.len()
66 }
67
68 #[inline]
70 pub fn as_range_inclusive(&self) -> RangeInclusive<PdfClipPathSegmentIndex> {
71 if self.is_empty() { 0..=0 } else { 0..=(self.len() - 1) }
72 }
73
74 pub fn get(&self, index: PdfClipPathSegmentIndex) -> Result<PdfClipPathSegments<'a>, PdfiumError> {
76 if index >= self.len() {
77 return Err(PdfiumError::PdfClipPathSegmentIndexOutOfBounds);
78 }
79
80 Ok(PdfClipPathSegments::from_pdfium(self.handle(), index, self.bindings()))
81 }
82
83 #[inline]
85 pub fn iter(&self) -> PdfClipPathIterator<'_> {
86 PdfClipPathIterator::new(self)
87 }
88}
89
90impl<'a> Drop for PdfClipPath<'a> {
91 #[inline]
93 fn drop(&mut self) {
94 if !self.ownership.is_owned() {
95 self.bindings.FPDF_DestroyClipPath(self.handle)
96 }
97 }
98}
99
100pub struct PdfClipPathIterator<'a> {
102 clip_path: &'a PdfClipPath<'a>,
103 next_index: PdfClipPathSegmentIndex,
104}
105
106impl<'a> PdfClipPathIterator<'a> {
107 #[inline]
108 pub(crate) fn new(clip_path: &'a PdfClipPath<'a>) -> Self {
109 PdfClipPathIterator {
110 clip_path,
111 next_index: 0,
112 }
113 }
114}
115
116impl<'a> Iterator for PdfClipPathIterator<'a> {
117 type Item = PdfClipPathSegments<'a>;
118
119 fn next(&mut self) -> Option<Self::Item> {
120 let next = self.clip_path.get(self.next_index);
121
122 self.next_index += 1;
123
124 next.ok()
125 }
126}
127
128pub struct PdfClipPathSegments<'a> {
130 handle: FPDF_CLIPPATH,
131 index: PdfClipPathSegmentIndex,
132 bindings: &'a dyn PdfiumLibraryBindings,
133}
134
135impl<'a> PdfClipPathSegments<'a> {
136 #[inline]
137 pub(crate) fn from_pdfium(
138 handle: FPDF_CLIPPATH,
139 path_index: PdfClipPathSegmentIndex,
140 bindings: &'a dyn PdfiumLibraryBindings,
141 ) -> Self {
142 Self {
143 handle,
144 index: path_index,
145 bindings,
146 }
147 }
148}
149
150impl<'a> PdfPathSegments<'a> for PdfClipPathSegments<'a> {
151 #[inline]
152 fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
153 self.bindings
154 }
155
156 #[inline]
157 fn len(&self) -> PdfPathSegmentIndex {
158 self.bindings()
159 .FPDFClipPath_CountPathSegments(self.handle, self.index as i32)
160 .try_into()
161 .unwrap_or(0)
162 }
163
164 fn get(&self, index: PdfPathSegmentIndex) -> Result<PdfPathSegment<'a>, PdfiumError> {
165 let handle = self
166 .bindings()
167 .FPDFClipPath_GetPathSegment(self.handle, self.index as i32, index as c_int);
168
169 if handle.is_null() {
170 Err(PdfiumError::PdfiumLibraryInternalError(PdfiumInternalError::Unknown))
171 } else {
172 Ok(PdfPathSegment::from_pdfium(handle, None, self.bindings()))
173 }
174 }
175
176 #[inline]
177 fn iter(&'a self) -> PdfPathSegmentsIterator<'a> {
178 PdfPathSegmentsIterator::new(self)
179 }
180}