Skip to main content

pdfium_render/pdf/document/page/object/
content_mark.rs

1//! Defines the [PdfPageObjectContentMark] struct, exposing functionality related to a single
2//! content mark associated with a [PdfPageObject].
3
4use crate::bindgen::{FPDF_PAGEOBJECTMARK, FPDF_WCHAR};
5use crate::bindings::PdfiumLibraryBindings;
6use crate::utils::mem::create_byte_buffer;
7use crate::utils::utf16le::get_string_from_pdfium_utf16le_bytes;
8use std::os::raw::{c_int, c_ulong};
9
10/// A single content mark associated with a `PdfPageObject`.
11///
12/// Content marks provide a bridge between page objects (geometric/visual elements)
13/// and the PDF structure tree (semantic document structure). Each mark has a name
14/// (e.g., "P", "Span", "Artifact") and optional key-value parameters.
15pub struct PdfPageObjectContentMark<'a> {
16    mark_handle: FPDF_PAGEOBJECTMARK,
17    bindings: &'a dyn PdfiumLibraryBindings,
18}
19
20impl<'a> PdfPageObjectContentMark<'a> {
21    pub(crate) fn from_pdfium(mark_handle: FPDF_PAGEOBJECTMARK, bindings: &'a dyn PdfiumLibraryBindings) -> Self {
22        Self { mark_handle, bindings }
23    }
24
25    /// Returns the name of this content mark (e.g., "P", "Span", "Artifact").
26    pub fn name(&self) -> Option<String> {
27        let mut name_length: c_ulong = 0;
28
29        if !self.bindings.is_true(self.bindings.FPDFPageObjMark_GetName(
30            self.mark_handle,
31            std::ptr::null_mut(),
32            0,
33            &mut name_length,
34        )) {
35            return None;
36        }
37
38        if name_length == 0 {
39            return None;
40        }
41
42        let mut buffer = create_byte_buffer(name_length as usize);
43
44        let mut actual_length: c_ulong = 0;
45
46        if self.bindings.is_true(self.bindings.FPDFPageObjMark_GetName(
47            self.mark_handle,
48            buffer.as_mut_ptr() as *mut FPDF_WCHAR,
49            name_length,
50            &mut actual_length,
51        )) {
52            get_string_from_pdfium_utf16le_bytes(buffer)
53        } else {
54            None
55        }
56    }
57
58    /// Returns the number of key-value parameters in this content mark.
59    pub fn param_count(&self) -> usize {
60        let count = self.bindings.FPDFPageObjMark_CountParams(self.mark_handle);
61
62        if count < 0 { 0 } else { count as usize }
63    }
64
65    /// Returns the key name of the parameter at the given index.
66    pub fn param_key(&self, index: usize) -> Option<String> {
67        let mut key_length: c_ulong = 0;
68
69        if !self.bindings.is_true(self.bindings.FPDFPageObjMark_GetParamKey(
70            self.mark_handle,
71            index as c_ulong,
72            std::ptr::null_mut(),
73            0,
74            &mut key_length,
75        )) {
76            return None;
77        }
78
79        if key_length == 0 {
80            return None;
81        }
82
83        let mut buffer = create_byte_buffer(key_length as usize);
84
85        let mut actual_length: c_ulong = 0;
86
87        if self.bindings.is_true(self.bindings.FPDFPageObjMark_GetParamKey(
88            self.mark_handle,
89            index as c_ulong,
90            buffer.as_mut_ptr() as *mut FPDF_WCHAR,
91            key_length,
92            &mut actual_length,
93        )) {
94            get_string_from_pdfium_utf16le_bytes(buffer)
95        } else {
96            None
97        }
98    }
99
100    /// Returns the integer value of the parameter with the given key, if the parameter
101    /// exists and is a number type.
102    pub fn param_int_value(&self, key: &str) -> Option<i32> {
103        let mut value: c_int = 0;
104
105        if self.bindings.is_true(
106            self.bindings
107                .FPDFPageObjMark_GetParamIntValue(self.mark_handle, key, &mut value),
108        ) {
109            Some(value as i32)
110        } else {
111            None
112        }
113    }
114
115    /// Returns the float value of the parameter with the given key, if the parameter
116    /// exists and is a number type.
117    pub fn param_float_value(&self, key: &str) -> Option<f32> {
118        let mut value: f32 = 0.0;
119
120        if self.bindings.is_true(
121            self.bindings
122                .FPDFPageObjMark_GetParamFloatValue(self.mark_handle, key, &mut value),
123        ) {
124            Some(value)
125        } else {
126            None
127        }
128    }
129
130    /// Returns the string value of the parameter with the given key, if the parameter
131    /// exists and is a string type.
132    pub fn param_string_value(&self, key: &str) -> Option<String> {
133        let mut value_length: c_ulong = 0;
134
135        if !self.bindings.is_true(self.bindings.FPDFPageObjMark_GetParamStringValue(
136            self.mark_handle,
137            key,
138            std::ptr::null_mut(),
139            0,
140            &mut value_length,
141        )) {
142            return None;
143        }
144
145        if value_length == 0 {
146            return None;
147        }
148
149        let mut buffer = create_byte_buffer(value_length as usize);
150
151        let mut actual_length: c_ulong = 0;
152
153        if self.bindings.is_true(self.bindings.FPDFPageObjMark_GetParamStringValue(
154            self.mark_handle,
155            key,
156            buffer.as_mut_ptr() as *mut FPDF_WCHAR,
157            value_length,
158            &mut actual_length,
159        )) {
160            get_string_from_pdfium_utf16le_bytes(buffer)
161        } else {
162            None
163        }
164    }
165}