1use std::cmp::Ordering;
2use std::ptr;
3
4use crate::error::Result;
5use crate::ffi;
6use crate::handle::ObjectHandle;
7use crate::page::PdfPage;
8use crate::types::{PdfDestinationInfo, PdfPoint};
9use crate::util::parse_json;
10
11#[derive(Debug, Clone)]
12pub struct PdfDestination {
13 handle: ObjectHandle,
14}
15
16impl PdfDestination {
17 pub const UNSPECIFIED_VALUE: f64 = 3.402_823_466_385_288_6e38;
18
19 pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
20 Self { handle }
21 }
22
23 pub fn new(page: &PdfPage, point: PdfPoint) -> Result<Self> {
24 let mut out_destination = ptr::null_mut();
25 let mut out_error = ptr::null_mut();
26 let status = unsafe {
27 ffi::pdf_destination_new(
28 page.as_handle_ptr(),
29 point.x,
30 point.y,
31 &mut out_destination,
32 &mut out_error,
33 )
34 };
35 crate::util::status_result(status, out_error)?;
36 Ok(Self::from_handle(crate::util::required_handle(
37 out_destination,
38 "PDFDestination",
39 )?))
40 }
41
42 pub fn info(&self) -> Result<PdfDestinationInfo> {
43 parse_json(
44 unsafe { ffi::pdf_destination_info_json(self.handle.as_ptr()) },
45 "PDFDestination",
46 )
47 }
48
49 #[must_use]
50 pub fn page(&self) -> Option<PdfPage> {
51 let ptr = unsafe { ffi::pdf_destination_page(self.handle.as_ptr()) };
52 unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfPage::from_handle)
53 }
54
55 pub fn set_zoom(&self, zoom: f64) {
56 unsafe { ffi::pdf_destination_set_zoom(self.handle.as_ptr(), zoom) };
57 }
58
59 #[must_use]
60 pub fn compare(&self, other: &Self) -> Ordering {
61 match unsafe { ffi::pdf_destination_compare(self.handle.as_ptr(), other.handle.as_ptr()) } {
62 value if value < 0 => Ordering::Less,
63 value if value > 0 => Ordering::Greater,
64 _ => Ordering::Equal,
65 }
66 }
67
68 pub(crate) fn as_handle_ptr(&self) -> *mut core::ffi::c_void {
69 self.handle.as_ptr()
70 }
71}