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::selection::PdfSelection;
10use crate::types::{DisplayBox, PdfDisplayDirection, PdfDisplayMode, PdfSize, PdfViewInfo};
11use crate::util::parse_json;
12
13#[derive(Debug, Clone)]
14pub struct PdfView {
15    handle: ObjectHandle,
16}
17
18impl PdfView {
19    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
20        Self { handle }
21    }
22
23    pub fn new(size: PdfSize) -> Result<Self> {
24        let mut out_view = ptr::null_mut();
25        let mut out_error = ptr::null_mut();
26        let status = unsafe { ffi::pdf_view_new(size.width, size.height, &mut out_view, &mut out_error) };
27        crate::util::status_result(status, out_error)?;
28        Ok(Self::from_handle(crate::util::required_handle(
29            out_view,
30            "PDFView",
31        )?))
32    }
33
34    pub fn info(&self) -> Result<PdfViewInfo> {
35        parse_json(unsafe { ffi::pdf_view_info_json(self.handle.as_ptr()) }, "PDFView")
36    }
37
38    #[must_use]
39    pub fn document(&self) -> Option<PdfDocument> {
40        let ptr = unsafe { ffi::pdf_view_document(self.handle.as_ptr()) };
41        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfDocument::from_handle)
42    }
43
44    pub fn set_document(&self, document: Option<&PdfDocument>) -> Result<()> {
45        let mut out_error = ptr::null_mut();
46        let status = unsafe {
47            ffi::pdf_view_set_document(
48                self.handle.as_ptr(),
49                document.map_or(ptr::null_mut(), PdfDocument::as_handle_ptr),
50                &mut out_error,
51            )
52        };
53        crate::util::status_result(status, out_error)
54    }
55
56    #[must_use]
57    pub fn current_page(&self) -> Option<PdfPage> {
58        let ptr = unsafe { ffi::pdf_view_current_page(self.handle.as_ptr()) };
59        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfPage::from_handle)
60    }
61
62    #[must_use]
63    pub fn current_destination(&self) -> Option<PdfDestination> {
64        let ptr = unsafe { ffi::pdf_view_current_destination(self.handle.as_ptr()) };
65        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfDestination::from_handle)
66    }
67
68    #[must_use]
69    pub fn current_selection(&self) -> Option<PdfSelection> {
70        let ptr = unsafe { ffi::pdf_view_current_selection(self.handle.as_ptr()) };
71        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfSelection::from_handle)
72    }
73
74    pub fn set_current_selection(&self, selection: Option<&PdfSelection>, animate: bool) -> Result<()> {
75        let mut out_error = ptr::null_mut();
76        let status = unsafe {
77            ffi::pdf_view_set_current_selection(
78                self.handle.as_ptr(),
79                selection.map_or(ptr::null_mut(), PdfSelection::as_handle_ptr),
80                i32::from(animate),
81                &mut out_error,
82            )
83        };
84        crate::util::status_result(status, out_error)
85    }
86
87    pub fn clear_selection(&self) {
88        unsafe { ffi::pdf_view_clear_selection(self.handle.as_ptr()) };
89    }
90
91    pub fn go_to_page(&self, page: &PdfPage) -> Result<()> {
92        let mut out_error = ptr::null_mut();
93        let status = unsafe { ffi::pdf_view_go_to_page(self.handle.as_ptr(), page.as_handle_ptr(), &mut out_error) };
94        crate::util::status_result(status, out_error)
95    }
96
97    pub fn go_to_destination(&self, destination: &PdfDestination) -> Result<()> {
98        let mut out_error = ptr::null_mut();
99        let status = unsafe {
100            ffi::pdf_view_go_to_destination(
101                self.handle.as_ptr(),
102                destination.as_handle_ptr(),
103                &mut out_error,
104            )
105        };
106        crate::util::status_result(status, out_error)
107    }
108
109    pub fn go_to_selection(&self, selection: &PdfSelection) -> Result<()> {
110        let mut out_error = ptr::null_mut();
111        let status = unsafe {
112            ffi::pdf_view_go_to_selection(
113                self.handle.as_ptr(),
114                selection.as_handle_ptr(),
115                &mut out_error,
116            )
117        };
118        crate::util::status_result(status, out_error)
119    }
120
121    pub fn set_display_mode(&self, mode: PdfDisplayMode) -> Result<()> {
122        let mut out_error = ptr::null_mut();
123        let status = unsafe { ffi::pdf_view_set_display_mode(self.handle.as_ptr(), mode as i32, &mut out_error) };
124        crate::util::status_result(status, out_error)
125    }
126
127    pub fn set_display_direction(&self, direction: PdfDisplayDirection) -> Result<()> {
128        let mut out_error = ptr::null_mut();
129        let status = unsafe {
130            ffi::pdf_view_set_display_direction(self.handle.as_ptr(), direction as i32, &mut out_error)
131        };
132        crate::util::status_result(status, out_error)
133    }
134
135    pub fn set_display_box(&self, display_box: DisplayBox) -> Result<()> {
136        let mut out_error = ptr::null_mut();
137        let status = unsafe {
138            ffi::pdf_view_set_display_box(self.handle.as_ptr(), display_box.as_raw(), &mut out_error)
139        };
140        crate::util::status_result(status, out_error)
141    }
142
143    pub fn set_auto_scales(&self, value: bool) {
144        unsafe { ffi::pdf_view_set_auto_scales(self.handle.as_ptr(), i32::from(value)) };
145    }
146
147    pub fn set_scale_factor(&self, value: f64) {
148        unsafe { ffi::pdf_view_set_scale_factor(self.handle.as_ptr(), value) };
149    }
150
151    pub fn set_min_scale_factor(&self, value: f64) {
152        unsafe { ffi::pdf_view_set_min_scale_factor(self.handle.as_ptr(), value) };
153    }
154
155    pub fn set_max_scale_factor(&self, value: f64) {
156        unsafe { ffi::pdf_view_set_max_scale_factor(self.handle.as_ptr(), value) };
157    }
158
159    pub fn layout_document_view(&self) {
160        unsafe { ffi::pdf_view_layout_document_view(self.handle.as_ptr()) };
161    }
162
163    #[must_use]
164    pub fn visible_page_count(&self) -> usize {
165        unsafe { ffi::pdf_view_visible_page_count(self.handle.as_ptr()) as usize }
166    }
167
168    #[must_use]
169    pub fn visible_page(&self, index: usize) -> Option<PdfPage> {
170        let ptr = unsafe { ffi::pdf_view_visible_page_at(self.handle.as_ptr(), index as u64) };
171        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfPage::from_handle)
172    }
173
174    #[must_use]
175    pub fn visible_pages(&self) -> Vec<PdfPage> {
176        (0..self.visible_page_count())
177            .filter_map(|index| self.visible_page(index))
178            .collect()
179    }
180
181    pub(crate) fn as_handle_ptr(&self) -> *mut core::ffi::c_void {
182        self.handle.as_ptr()
183    }
184}