Skip to main content

pdfkit/
annotation.rs

1use std::ptr;
2
3use crate::action_goto::PdfActionGoTo;
4use crate::action_url::PdfActionUrl;
5use crate::border::PdfBorder;
6use crate::error::Result;
7use crate::ffi;
8use crate::handle::ObjectHandle;
9use crate::types::{PdfAnnotationInfo, PdfRect};
10use crate::util::{c_string, option_c_string, parse_json};
11
12#[derive(Debug, Clone)]
13pub struct PdfAnnotation {
14    handle: ObjectHandle,
15}
16
17impl PdfAnnotation {
18    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
19        Self { handle }
20    }
21
22    pub fn new(bounds: PdfRect, annotation_type: &str) -> Result<Self> {
23        let annotation_type = c_string(annotation_type)?;
24        let mut out_annotation = ptr::null_mut();
25        let mut out_error = ptr::null_mut();
26        let status = unsafe {
27            ffi::pdf_annotation_new(
28                bounds.x,
29                bounds.y,
30                bounds.width,
31                bounds.height,
32                annotation_type.as_ptr(),
33                &mut out_annotation,
34                &mut out_error,
35            )
36        };
37        crate::util::status_result(status, out_error)?;
38        Ok(Self::from_handle(crate::util::required_handle(
39            out_annotation,
40            "PDFAnnotation",
41        )?))
42    }
43
44    pub fn info(&self) -> Result<PdfAnnotationInfo> {
45        parse_json(
46            unsafe { ffi::pdf_annotation_info_json(self.handle.as_ptr()) },
47            "PDFAnnotation",
48        )
49    }
50
51    pub fn set_contents(&self, value: Option<&str>) -> Result<()> {
52        let value = option_c_string(value)?;
53        let mut out_error = ptr::null_mut();
54        let status = unsafe {
55            ffi::pdf_annotation_set_contents(
56                self.handle.as_ptr(),
57                value.as_ref().map_or(ptr::null(), |value| value.as_ptr()),
58                &mut out_error,
59            )
60        };
61        crate::util::status_result(status, out_error)
62    }
63
64    pub fn set_highlighted(&self, value: bool) {
65        unsafe { ffi::pdf_annotation_set_highlighted(self.handle.as_ptr(), i32::from(value)) };
66    }
67
68    #[must_use]
69    pub fn border(&self) -> Option<PdfBorder> {
70        let ptr = unsafe { ffi::pdf_annotation_border(self.handle.as_ptr()) };
71        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfBorder::from_handle)
72    }
73
74    pub fn set_border(&self, border: Option<&PdfBorder>) -> Result<()> {
75        let mut out_error = ptr::null_mut();
76        let status = unsafe {
77            ffi::pdf_annotation_set_border(
78                self.handle.as_ptr(),
79                border.map_or(ptr::null_mut(), PdfBorder::as_handle_ptr),
80                &mut out_error,
81            )
82        };
83        crate::util::status_result(status, out_error)
84    }
85
86    #[must_use]
87    pub fn action_url(&self) -> Option<PdfActionUrl> {
88        let ptr = unsafe { ffi::pdf_annotation_action_url(self.handle.as_ptr()) };
89        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfActionUrl::from_handle)
90    }
91
92    pub fn set_action_url(&self, action: Option<&PdfActionUrl>) -> Result<()> {
93        let mut out_error = ptr::null_mut();
94        let status = unsafe {
95            ffi::pdf_annotation_set_action_url(
96                self.handle.as_ptr(),
97                action.map_or(ptr::null_mut(), PdfActionUrl::as_handle_ptr),
98                &mut out_error,
99            )
100        };
101        crate::util::status_result(status, out_error)
102    }
103
104    #[must_use]
105    pub fn action_goto(&self) -> Option<PdfActionGoTo> {
106        let ptr = unsafe { ffi::pdf_annotation_action_goto(self.handle.as_ptr()) };
107        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(PdfActionGoTo::from_handle)
108    }
109
110    pub fn set_action_goto(&self, action: Option<&PdfActionGoTo>) -> Result<()> {
111        let mut out_error = ptr::null_mut();
112        let status = unsafe {
113            ffi::pdf_annotation_set_action_goto(
114                self.handle.as_ptr(),
115                action.map_or(ptr::null_mut(), PdfActionGoTo::as_handle_ptr),
116                &mut out_error,
117            )
118        };
119        crate::util::status_result(status, out_error)
120    }
121
122    pub(crate) fn as_handle_ptr(&self) -> *mut core::ffi::c_void {
123        self.handle.as_ptr()
124    }
125}