pdfium_render/pdf/document/
permissions.rs1use crate::bindgen::FPDF_DOCUMENT;
5use crate::bindings::PdfiumLibraryBindings;
6use crate::error::PdfiumError;
7use bitflags::bitflags;
8use std::os::raw::c_int;
9
10#[cfg(doc)]
11use crate::pdf::document::PdfDocument;
12
13bitflags! {
14 struct FpdfPermissions: u32 {
15 const RESERVED_BIT_1 = 0b00000000000000000000000000000001;
16 const RESERVED_BIT_2 = 0b00000000000000000000000000000010;
17 const CAN_PRINT_BIT_3 = 0b00000000000000000000000000000100;
18 const CAN_MODIFY_BIT_4 = 0b00000000000000000000000000001000;
19 const CAN_EXTRACT_TEXT_AND_GRAPHICS_BIT_5 = 0b00000000000000000000000000010000;
20 const CAN_ANNOTATE_AND_FORM_FILL_BIT_6 = 0b00000000000000000000000000100000;
21 const RESERVED_BIT_7 = 0b00000000000000000000000001000000;
22 const RESERVED_BIT_8 = 0b00000000000000000000000010000000;
23 const V3_CAN_FORM_FILL_BIT_9 = 0b00000000000000000000000100000000;
24 const V3_CAN_EXTRACT_TEXT_AND_GRAPHICS_BIT_10 = 0b00000000000000000000001000000000;
25 const V3_CAN_ASSEMBLE_DOCUMENT_BIT_11 = 0b00000000000000000000010000000000;
26 const V3_CAN_PRINT_HIGH_QUALITY_BIT_12 = 0b00000000000000000000100000000000;
27 }
28}
29
30#[derive(Copy, Clone, Debug, PartialEq)]
32pub enum PdfSecurityHandlerRevision {
33 Unprotected,
34 Revision2,
35 Revision3,
36 Revision4,
37}
38
39impl PdfSecurityHandlerRevision {
40 pub(crate) fn from_pdfium(value: c_int) -> Option<Self> {
41 match value {
42 -1 => Some(PdfSecurityHandlerRevision::Unprotected),
43 2 => Some(PdfSecurityHandlerRevision::Revision2),
44 3 => Some(PdfSecurityHandlerRevision::Revision3),
45 4 => Some(PdfSecurityHandlerRevision::Revision4),
46 _ => None,
47 }
48 }
49}
50
51pub struct PdfPermissions<'a> {
57 document_handle: FPDF_DOCUMENT,
58 bindings: &'a dyn PdfiumLibraryBindings,
59}
60
61impl<'a> PdfPermissions<'a> {
62 #[inline]
63 pub(crate) fn from_pdfium(
64 document_handle: FPDF_DOCUMENT,
65 bindings: &'a dyn PdfiumLibraryBindings,
66 ) -> Self {
67 Self {
68 document_handle,
69 bindings,
70 }
71 }
72
73 #[inline]
75 pub fn bindings(&self) -> &'a dyn PdfiumLibraryBindings {
76 self.bindings
77 }
78
79 #[inline]
81 fn get_permissions_bits(&self) -> FpdfPermissions {
82 FpdfPermissions::from_bits_truncate(
83 self.bindings().FPDF_GetDocPermissions(self.document_handle) as u32,
84 )
85 }
86
87 pub fn security_handler_revision(&self) -> Result<PdfSecurityHandlerRevision, PdfiumError> {
90 PdfSecurityHandlerRevision::from_pdfium(
91 self.bindings()
92 .FPDF_GetSecurityHandlerRevision(self.document_handle),
93 )
94 .ok_or(PdfiumError::UnknownPdfSecurityHandlerRevision)
95 }
96
97 pub fn can_print_high_quality(&self) -> Result<bool, PdfiumError> {
100 let permissions = self.get_permissions_bits();
101
102 let result = match self.security_handler_revision()? {
103 PdfSecurityHandlerRevision::Unprotected => true,
104 PdfSecurityHandlerRevision::Revision2 => {
105 permissions.contains(FpdfPermissions::CAN_PRINT_BIT_3)
106 }
107 PdfSecurityHandlerRevision::Revision3 | PdfSecurityHandlerRevision::Revision4 => {
108 permissions.contains(FpdfPermissions::CAN_PRINT_BIT_3)
109 && permissions.contains(FpdfPermissions::V3_CAN_PRINT_HIGH_QUALITY_BIT_12)
110 }
111 };
112
113 Ok(result)
114 }
115
116 pub fn can_print_only_low_quality(&self) -> Result<bool, PdfiumError> {
120 let permissions = self.get_permissions_bits();
121
122 let result = match self.security_handler_revision()? {
123 PdfSecurityHandlerRevision::Unprotected | PdfSecurityHandlerRevision::Revision2 => {
124 false
125 }
126 PdfSecurityHandlerRevision::Revision3 | PdfSecurityHandlerRevision::Revision4 => {
127 permissions.contains(FpdfPermissions::CAN_PRINT_BIT_3)
128 && !permissions.contains(FpdfPermissions::V3_CAN_PRINT_HIGH_QUALITY_BIT_12)
129 }
130 };
131
132 Ok(result)
133 }
134
135 pub fn can_assemble_document(&self) -> Result<bool, PdfiumError> {
139 let permissions = self.get_permissions_bits();
140
141 let result = match self.security_handler_revision()? {
142 PdfSecurityHandlerRevision::Unprotected => true,
143 PdfSecurityHandlerRevision::Revision2 => {
144 permissions.contains(FpdfPermissions::CAN_MODIFY_BIT_4)
145 }
146 PdfSecurityHandlerRevision::Revision3 | PdfSecurityHandlerRevision::Revision4 => {
147 permissions.contains(FpdfPermissions::V3_CAN_ASSEMBLE_DOCUMENT_BIT_11)
148 }
149 };
150
151 Ok(result)
152 }
153
154 pub fn can_modify_document_content(&self) -> Result<bool, PdfiumError> {
160 let permissions = self.get_permissions_bits();
161
162 let result = match self.security_handler_revision()? {
163 PdfSecurityHandlerRevision::Unprotected => true,
164 _ => permissions.contains(FpdfPermissions::CAN_MODIFY_BIT_4),
165 };
166
167 Ok(result)
168 }
169
170 pub fn can_extract_text_and_graphics(&self) -> Result<bool, PdfiumError> {
172 let permissions = self.get_permissions_bits();
173
174 let result = match self.security_handler_revision()? {
175 PdfSecurityHandlerRevision::Unprotected => true,
176 PdfSecurityHandlerRevision::Revision2 => {
177 permissions.contains(FpdfPermissions::CAN_EXTRACT_TEXT_AND_GRAPHICS_BIT_5)
178 }
179 PdfSecurityHandlerRevision::Revision3 | PdfSecurityHandlerRevision::Revision4 => {
181 permissions.contains(FpdfPermissions::V3_CAN_EXTRACT_TEXT_AND_GRAPHICS_BIT_10)
182 }
183 };
184
185 Ok(result)
186 }
187
188 pub fn can_fill_existing_interactive_form_fields(&self) -> Result<bool, PdfiumError> {
191 let permissions = self.get_permissions_bits();
192
193 let result = match self.security_handler_revision()? {
194 PdfSecurityHandlerRevision::Unprotected => true,
195 PdfSecurityHandlerRevision::Revision2 => {
196 permissions.contains(FpdfPermissions::CAN_ANNOTATE_AND_FORM_FILL_BIT_6)
197 }
198 PdfSecurityHandlerRevision::Revision3 | PdfSecurityHandlerRevision::Revision4 => {
199 permissions.contains(FpdfPermissions::V3_CAN_FORM_FILL_BIT_9)
200 }
201 };
202
203 Ok(result)
204 }
205
206 pub fn can_create_new_interactive_form_fields(&self) -> Result<bool, PdfiumError> {
209 let permissions = self.get_permissions_bits();
210
211 let result = match self.security_handler_revision()? {
212 PdfSecurityHandlerRevision::Unprotected => true,
213 _ => {
214 permissions.contains(FpdfPermissions::CAN_MODIFY_BIT_4)
215 && permissions.contains(FpdfPermissions::CAN_ANNOTATE_AND_FORM_FILL_BIT_6)
216 }
217 };
218
219 Ok(result)
220 }
221
222 pub fn can_add_or_modify_text_annotations(&self) -> Result<bool, PdfiumError> {
225 let permissions = self.get_permissions_bits();
226
227 let result = match self.security_handler_revision()? {
228 PdfSecurityHandlerRevision::Unprotected => true,
229 _ => permissions.contains(FpdfPermissions::CAN_ANNOTATE_AND_FORM_FILL_BIT_6),
230 };
231
232 Ok(result)
233 }
234}