Skip to main content

pdfkit/
view.rs

1use std::ptr;
2
3use crate::destination::PdfDestination;
4use crate::document::PdfDocument;
5use crate::error::Result;
6use crate::ffi;
7use crate::handle::ObjectHandle;
8use crate::page::PdfPage;
9use crate::page_overlay_view_provider::PdfPageOverlayViewProviderHandle;
10use crate::selection::PdfSelection;
11use crate::types::{
12    DisplayBox, PdfAreaOfInterest, PdfDisplayDirection, PdfDisplayMode, PdfPoint, PdfSize,
13    PdfViewInfo,
14};
15use crate::util::parse_json;
16use crate::view_delegate::PdfViewDelegateHandle;
17
18/// Wraps `PDFView`.
19#[derive(Debug, Clone)]
20pub struct PdfView {
21    handle: ObjectHandle,
22}
23
24impl PdfView {
25    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
26        Self { handle }
27    }
28
29    /// Wraps `PDFView(frame:)`.
30    pub fn new(size: PdfSize) -> Result<Self> {
31        let mut out_view = ptr::null_mut();
32        let mut out_error = ptr::null_mut();
33        let status =
34            unsafe { ffi::pdf_view_new(size.width, size.height, &mut out_view, &mut out_error) };
35        crate::util::status_result(status, out_error)?;
36        Ok(Self::from_handle(crate::util::required_handle(
37            out_view, "PDFView",
38        )?))
39    }
40
41    /// Wraps the corresponding `PDFView` API.
42    pub fn info(&self) -> Result<PdfViewInfo> {
43        parse_json(
44            unsafe { ffi::pdf_view_info_json(self.handle.as_ptr()) },
45            "PDFView",
46        )
47    }
48
49    /// Wraps the corresponding `PDFView` API.
50    #[must_use]
51    pub fn document(&self) -> Option<PdfDocument> {
52        let ptr = unsafe { ffi::pdf_view_document(self.handle.as_ptr()) };
53        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfDocument::from_handle)
54    }
55
56    /// Wraps the corresponding `PDFView` API.
57    pub fn set_document(&self, document: Option<&PdfDocument>) -> Result<()> {
58        let mut out_error = ptr::null_mut();
59        let status = unsafe {
60            ffi::pdf_view_set_document(
61                self.handle.as_ptr(),
62                document.map_or(ptr::null_mut(), PdfDocument::as_handle_ptr),
63                &mut out_error,
64            )
65        };
66        crate::util::status_result(status, out_error)
67    }
68
69    /// Wraps the corresponding `PDFView` API.
70    pub fn set_delegate(&self, delegate: Option<&PdfViewDelegateHandle>) -> Result<()> {
71        let mut out_error = ptr::null_mut();
72        let status = unsafe {
73            ffi::pdf_view_set_delegate(
74                self.handle.as_ptr(),
75                delegate.map_or(ptr::null_mut(), PdfViewDelegateHandle::as_handle_ptr),
76                &mut out_error,
77            )
78        };
79        crate::util::status_result(status, out_error)
80    }
81
82    /// Wraps the corresponding `PDFView` API.
83    pub fn set_page_overlay_view_provider(
84        &self,
85        provider: Option<&PdfPageOverlayViewProviderHandle>,
86    ) -> Result<()> {
87        let mut out_error = ptr::null_mut();
88        let status = unsafe {
89            ffi::pdf_view_set_page_overlay_view_provider(
90                self.handle.as_ptr(),
91                provider.map_or(
92                    ptr::null_mut(),
93                    PdfPageOverlayViewProviderHandle::as_handle_ptr,
94                ),
95                &mut out_error,
96            )
97        };
98        crate::util::status_result(status, out_error)
99    }
100
101    /// Wraps the corresponding `PDFView` API.
102    #[must_use]
103    pub fn current_page(&self) -> Option<PdfPage> {
104        let ptr = unsafe { ffi::pdf_view_current_page(self.handle.as_ptr()) };
105        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfPage::from_handle)
106    }
107
108    /// Wraps the corresponding `PDFView` API.
109    #[must_use]
110    pub fn current_destination(&self) -> Option<PdfDestination> {
111        let ptr = unsafe { ffi::pdf_view_current_destination(self.handle.as_ptr()) };
112        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfDestination::from_handle)
113    }
114
115    /// Wraps the corresponding `PDFView` API.
116    #[must_use]
117    pub fn current_selection(&self) -> Option<PdfSelection> {
118        let ptr = unsafe { ffi::pdf_view_current_selection(self.handle.as_ptr()) };
119        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfSelection::from_handle)
120    }
121
122    /// Wraps the corresponding `PDFView` API.
123    pub fn set_current_selection(
124        &self,
125        selection: Option<&PdfSelection>,
126        animate: bool,
127    ) -> Result<()> {
128        let mut out_error = ptr::null_mut();
129        let status = unsafe {
130            ffi::pdf_view_set_current_selection(
131                self.handle.as_ptr(),
132                selection.map_or(ptr::null_mut(), PdfSelection::as_handle_ptr),
133                i32::from(animate),
134                &mut out_error,
135            )
136        };
137        crate::util::status_result(status, out_error)
138    }
139
140    /// Wraps the corresponding `PDFView` API.
141    pub fn clear_selection(&self) {
142        unsafe { ffi::pdf_view_clear_selection(self.handle.as_ptr()) };
143    }
144
145    /// Wraps the corresponding `PDFView` API.
146    pub fn go_to_page(&self, page: &PdfPage) -> Result<()> {
147        let mut out_error = ptr::null_mut();
148        let status = unsafe {
149            ffi::pdf_view_go_to_page(self.handle.as_ptr(), page.as_handle_ptr(), &mut out_error)
150        };
151        crate::util::status_result(status, out_error)
152    }
153
154    /// Wraps the corresponding `PDFView` API.
155    pub fn go_to_destination(&self, destination: &PdfDestination) -> Result<()> {
156        let mut out_error = ptr::null_mut();
157        let status = unsafe {
158            ffi::pdf_view_go_to_destination(
159                self.handle.as_ptr(),
160                destination.as_handle_ptr(),
161                &mut out_error,
162            )
163        };
164        crate::util::status_result(status, out_error)
165    }
166
167    /// Wraps the corresponding `PDFView` API.
168    pub fn go_to_selection(&self, selection: &PdfSelection) -> Result<()> {
169        let mut out_error = ptr::null_mut();
170        let status = unsafe {
171            ffi::pdf_view_go_to_selection(
172                self.handle.as_ptr(),
173                selection.as_handle_ptr(),
174                &mut out_error,
175            )
176        };
177        crate::util::status_result(status, out_error)
178    }
179
180    /// Wraps the corresponding `PDFView` API.
181    pub fn set_display_mode(&self, mode: PdfDisplayMode) -> Result<()> {
182        let mut out_error = ptr::null_mut();
183        let status = unsafe {
184            ffi::pdf_view_set_display_mode(self.handle.as_ptr(), mode as i32, &mut out_error)
185        };
186        crate::util::status_result(status, out_error)
187    }
188
189    /// Wraps the corresponding `PDFView` API.
190    pub fn set_display_direction(&self, direction: PdfDisplayDirection) -> Result<()> {
191        let mut out_error = ptr::null_mut();
192        let status = unsafe {
193            ffi::pdf_view_set_display_direction(
194                self.handle.as_ptr(),
195                direction as i32,
196                &mut out_error,
197            )
198        };
199        crate::util::status_result(status, out_error)
200    }
201
202    /// Wraps the corresponding `PDFView` API.
203    pub fn set_display_box(&self, display_box: DisplayBox) -> Result<()> {
204        let mut out_error = ptr::null_mut();
205        let status = unsafe {
206            ffi::pdf_view_set_display_box(
207                self.handle.as_ptr(),
208                display_box.as_raw(),
209                &mut out_error,
210            )
211        };
212        crate::util::status_result(status, out_error)
213    }
214
215    /// Wraps the corresponding `PDFView` API.
216    pub fn set_auto_scales(&self, value: bool) {
217        unsafe { ffi::pdf_view_set_auto_scales(self.handle.as_ptr(), i32::from(value)) };
218    }
219
220    /// Wraps the corresponding `PDFView` API.
221    pub fn set_scale_factor(&self, value: f64) {
222        unsafe { ffi::pdf_view_set_scale_factor(self.handle.as_ptr(), value) };
223    }
224
225    /// Wraps the corresponding `PDFView` API.
226    pub fn set_min_scale_factor(&self, value: f64) {
227        unsafe { ffi::pdf_view_set_min_scale_factor(self.handle.as_ptr(), value) };
228    }
229
230    /// Wraps the corresponding `PDFView` API.
231    pub fn set_max_scale_factor(&self, value: f64) {
232        unsafe { ffi::pdf_view_set_max_scale_factor(self.handle.as_ptr(), value) };
233    }
234
235    /// Wraps the corresponding `PDFView` API.
236    pub fn layout_document_view(&self) {
237        unsafe { ffi::pdf_view_layout_document_view(self.handle.as_ptr()) };
238    }
239
240    /// Wraps the corresponding `PDFView` API.
241    #[must_use]
242    pub fn area_of_interest_for_point(&self, point: PdfPoint) -> PdfAreaOfInterest {
243        PdfAreaOfInterest::from_bits(unsafe {
244            ffi::pdf_view_area_of_interest_for_point(self.handle.as_ptr(), point.x, point.y)
245        })
246    }
247
248    /// Wraps the corresponding `PDFView` API.
249    #[must_use]
250    pub fn visible_page_count(&self) -> usize {
251        unsafe { ffi::pdf_view_visible_page_count(self.handle.as_ptr()) as usize }
252    }
253
254    /// Wraps the corresponding `PDFView` API.
255    #[must_use]
256    pub fn visible_page(&self, index: usize) -> Option<PdfPage> {
257        let ptr = unsafe { ffi::pdf_view_visible_page_at(self.handle.as_ptr(), index as u64) };
258        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfPage::from_handle)
259    }
260
261    /// Wraps the corresponding `PDFView` API.
262    #[must_use]
263    pub fn visible_pages(&self) -> Vec<PdfPage> {
264        (0..self.visible_page_count())
265            .filter_map(|index| self.visible_page(index))
266            .collect()
267    }
268
269    pub(crate) fn as_handle_ptr(&self) -> *mut core::ffi::c_void {
270        self.handle.as_ptr()
271    }
272}