1use crate::bindgen::{
5 FPDF_LIBRARY_CONFIG, FPDF_RENDERER_TYPE_FPDF_RENDERERTYPE_AGG,
6 FPDF_RENDERER_TYPE_FPDF_RENDERERTYPE_SKIA,
7};
8use crate::error::PdfiumError;
9use std::ffi::{CString, NulError};
10use std::os::raw::{c_char, c_uint};
11use std::pin::Pin;
12use std::ptr::null_mut;
13use std::str::FromStr;
14
15#[cfg(not(target_arch = "wasm32"))]
16use std::os::raw::c_void;
17
18#[cfg(any(
19 feature = "pdfium_future",
20 feature = "pdfium_7881",
21 feature = "pdfium_7763",
22))]
23use crate::bindgen::{
24 FPDF_FONT_BACKEND_TYPE_FPDF_FONTBACKENDTYPE_FONTATIONS,
25 FPDF_FONT_BACKEND_TYPE_FPDF_FONTBACKENDTYPE_FREETYPE,
26};
27
28#[derive(Clone)]
29pub struct PdfiumLibraryConfig {
30 user_font_paths: Pin<Box<Vec<CString>>>,
31
32 #[cfg(not(target_arch = "wasm32"))]
33 v8_isolate_ptr: *mut c_void,
34 #[cfg(not(target_arch = "wasm32"))]
35 v8_embedder_slot_idx: c_uint,
36 #[cfg(not(target_arch = "wasm32"))]
37 v8_platform_ptr: *mut c_void,
38
39 renderer_type: c_uint,
40
41 #[cfg(any(
42 feature = "pdfium_future",
43 feature = "pdfium_7881",
44 feature = "pdfium_7763",
45 ))]
46 font_library_type: c_uint,
47}
48
49impl PdfiumLibraryConfig {
50 pub fn new() -> Self {
53 PdfiumLibraryConfig {
54 user_font_paths: Box::pin(vec![]),
55
56 #[cfg(not(target_arch = "wasm32"))]
57 v8_isolate_ptr: null_mut(),
58 #[cfg(not(target_arch = "wasm32"))]
59 v8_embedder_slot_idx: 0,
60 #[cfg(not(target_arch = "wasm32"))]
61 v8_platform_ptr: null_mut(),
62
63 renderer_type: FPDF_RENDERER_TYPE_FPDF_RENDERERTYPE_SKIA,
64
65 #[cfg(any(
66 feature = "pdfium_future",
67 feature = "pdfium_7881",
68 feature = "pdfium_7763",
69 ))]
70 font_library_type: FPDF_FONT_BACKEND_TYPE_FPDF_FONTBACKENDTYPE_FREETYPE,
71 }
72 }
73
74 #[inline]
77 pub fn clear_user_font_paths(self) -> Self {
78 self.set_user_font_paths(&[]).unwrap()
79 }
80
81 #[cfg(target_arch = "wasm32")]
82 #[inline]
88 pub fn set_platform_default_user_font_paths(self) -> Self {
89 self.clear_user_font_paths()
90 }
91
92 #[cfg(not(target_arch = "wasm32"))]
93 #[cfg(target_os = "linux")]
94 #[inline]
100 pub fn set_platform_default_user_font_paths(self) -> Self {
101 self.set_user_font_paths(&["/usr/share/fonts/truetype/", "/usr/local/share/fonts/"])
102 .unwrap()
103 }
104
105 #[cfg(not(target_arch = "wasm32"))]
106 #[cfg(target_os = "macos")]
107 #[inline]
113 pub fn set_platform_default_user_font_paths(self) -> Self {
114 self.set_user_font_paths(&["/Library/Fonts/", "/System/Library/Fonts/"])
115 .unwrap()
116 }
117
118 #[cfg(not(target_arch = "wasm32"))]
119 #[cfg(target_os = "windows")]
120 #[inline]
125 pub fn set_platform_default_user_font_paths(self) -> Self {
126 self.set_user_font_paths(&["C:\\Windows\\Fonts\\"]).unwrap()
127 }
128
129 pub fn set_user_font_paths(mut self, paths: &[&str]) -> Result<Self, PdfiumError> {
132 let cstr_paths = paths
133 .iter()
134 .map(|path| CString::from_str(path))
135 .collect::<Result<Vec<CString>, NulError>>();
136
137 match cstr_paths {
138 Ok(paths) => {
139 self.user_font_paths = Box::pin(paths);
140 Ok(self)
141 }
142 Err(e) => Err(PdfiumError::InvalidUserFontPath(e)),
143 }
144 }
145
146 #[cfg(not(target_arch = "wasm32"))]
147 #[inline]
149 pub unsafe fn set_v8_isolate_ptr(mut self, ptr: *mut c_void) -> Self {
150 self.v8_isolate_ptr = ptr;
151 self
152 }
153
154 #[cfg(not(target_arch = "wasm32"))]
155 #[inline]
159 pub unsafe fn set_v8_embedder_slot(mut self, idx: c_uint) -> Self {
160 self.v8_embedder_slot_idx = idx;
161 self
162 }
163
164 #[cfg(not(target_arch = "wasm32"))]
165 #[inline]
167 pub unsafe fn set_v8_platform_ptr(mut self, ptr: &mut c_void) -> Self {
168 self.v8_platform_ptr = ptr;
169 self
170 }
171
172 #[inline]
174 pub fn set_renderer_anti_grain_geometry(mut self) -> Self {
175 self.renderer_type = FPDF_RENDERER_TYPE_FPDF_RENDERERTYPE_AGG;
176 self
177 }
178
179 #[inline]
181 pub fn set_renderer_skia(mut self) -> Self {
182 self.renderer_type = FPDF_RENDERER_TYPE_FPDF_RENDERERTYPE_SKIA;
183 self
184 }
185
186 #[cfg(any(
187 feature = "pdfium_future",
188 feature = "pdfium_7881",
189 feature = "pdfium_7763",
190 ))]
191 #[inline]
193 pub fn set_font_backend_freetype(mut self) -> Self {
194 self.font_library_type = FPDF_FONT_BACKEND_TYPE_FPDF_FONTBACKENDTYPE_FREETYPE;
195 self
196 }
197
198 #[cfg(any(
199 feature = "pdfium_future",
200 feature = "pdfium_7881",
201 feature = "pdfium_7763",
202 ))]
203 #[inline]
205 pub fn set_font_backend_fontations(mut self) -> Self {
206 self.font_library_type = FPDF_FONT_BACKEND_TYPE_FPDF_FONTBACKENDTYPE_FONTATIONS;
207 self
208 }
209
210 pub(crate) fn as_pdfium(&self) -> FPDF_LIBRARY_CONFIG {
213 FPDF_LIBRARY_CONFIG {
214 version: 2,
215 m_pUserFontPaths: if self.user_font_paths.is_empty() {
216 std::ptr::null_mut()
217 } else {
218 self.user_font_paths
219 .iter()
220 .map(|path| path.as_ptr())
221 .collect::<Vec<*const c_char>>()
222 .as_mut_slice()
223 .as_mut_ptr()
224 },
225
226 #[cfg(not(target_arch = "wasm32"))]
227 m_pIsolate: self.v8_isolate_ptr,
228 #[cfg(not(target_arch = "wasm32"))]
229 m_v8EmbedderSlot: self.v8_embedder_slot_idx,
230 #[cfg(not(target_arch = "wasm32"))]
231 m_pPlatform: self.v8_platform_ptr,
232
233 #[cfg(target_arch = "wasm32")]
234 m_pIsolate: null_mut(),
235 #[cfg(target_arch = "wasm32")]
236 m_v8EmbedderSlot: 0,
237 #[cfg(target_arch = "wasm32")]
238 m_pPlatform: null_mut(),
239
240 m_RendererType: self.renderer_type,
241
242 #[cfg(any(
243 feature = "pdfium_future",
244 feature = "pdfium_7881",
245 feature = "pdfium_7763",
246 ))]
247 m_FontLibraryType: self.font_library_type,
248 }
249 }
250}
251
252#[cfg(feature = "thread_safe")]
253unsafe impl Sync for PdfiumLibraryConfig {}
254
255#[cfg(feature = "thread_safe")]
256unsafe impl Send for PdfiumLibraryConfig {}