ul_next/config.rs
1//! The configuration of the [`Renderer`](crate::renderer::Renderer) struct.
2
3use std::sync::Arc;
4
5use crate::Library;
6
7/// The winding order for front-facing triangles. (Only used when the GPU renderer is used)
8pub enum FaceWinding {
9 /// Clockwise Winding (Direct3D, etc.)
10 Clockwise = ul_sys::ULFaceWinding_kFaceWinding_Clockwise as isize,
11 /// Counter-Clockwise Winding (OpenGL, etc.)
12 CounterClockwise = ul_sys::ULFaceWinding_kFaceWinding_CounterClockwise as isize,
13}
14
15/// The font hinting algorithm.
16pub enum FontHinting {
17 /// Lighter hinting algorithm-- glyphs are slightly fuzzier but better resemble their original
18 /// shape. This is achieved by snapping glyphs to the pixel grid only vertically which better
19 /// preserves inter-glyph spacing.
20 Smooth = ul_sys::ULFontHinting_kFontHinting_Smooth as isize,
21 /// Default hinting algorithm-- offers a good balance between sharpness and shape at smaller font
22 /// sizes.
23 Normal = ul_sys::ULFontHinting_kFontHinting_Normal as isize,
24 /// Strongest hinting algorithm-- outputs only black/white glyphs. The result is usually
25 /// unpleasant if the underlying TTF does not contain hints for this type of rendering.
26 Monochrome = ul_sys::ULFontHinting_kFontHinting_Monochrome as isize,
27}
28
29/// Configuration settings for Ultralight renderer
30///
31/// This is intended to be implemented by users when creating the Renderer in
32/// [`Renderer::create`](crate::renderer::Renderer::create).
33pub struct Config {
34 lib: Arc<Library>,
35 internal: ul_sys::ULConfig,
36}
37
38impl Config {
39 /// Starts the building process for the [`Config`] struct. returns a builder
40 /// which can be used to configure the settings.
41 pub fn start() -> ConfigBuilder {
42 ConfigBuilder::default()
43 }
44
45 /// Returns the underlying [`ul_sys::ULConfig`] struct, to be used locally for
46 /// calling the underlying C API.
47 pub(crate) unsafe fn to_ul(&self) -> ul_sys::ULConfig {
48 self.internal
49 }
50
51 /// Returns the library associated with this config.
52 pub(crate) fn lib(&self) -> &Arc<Library> {
53 &self.lib
54 }
55}
56
57impl Drop for Config {
58 fn drop(&mut self) {
59 unsafe {
60 self.lib.ultralight().ulDestroyConfig(self.internal);
61 }
62 }
63}
64
65/// Builder for the [`Config`] struct.
66#[derive(Default)]
67pub struct ConfigBuilder {
68 cache_path: Option<String>,
69 resource_path_prefix: Option<String>,
70 face_winding: Option<FaceWinding>,
71 font_hinting: Option<FontHinting>,
72 font_gamma: Option<f64>,
73 user_stylesheet: Option<String>,
74 force_repaint: Option<bool>,
75 animation_timer_delay: Option<f64>,
76 scroll_timer_delay: Option<f64>,
77 recycle_delay: Option<f64>,
78 memory_cache_size: Option<u32>,
79 page_cache_size: Option<u32>,
80 override_ram_size: Option<u32>,
81 min_large_heap_size: Option<u32>,
82 min_small_heap_size: Option<u32>,
83 num_renderer_threads: Option<u32>,
84 max_update_time: Option<f64>,
85 bitmap_alignment: Option<u32>,
86}
87
88impl ConfigBuilder {
89 /// A writable OS file path to store persistent Session data in.
90 ///
91 /// This data may include cookies, cached network resources, indexed DB, etc.
92 ///
93 /// Files are only written to disk when using a persistent Session (see
94 /// [`Renderer::create_session`](crate::renderer::Renderer::create_session)).
95 pub fn cache_path(mut self, path: &str) -> Self {
96 self.cache_path = Some(path.to_string());
97 self
98 }
99
100 /// The relative path to the resources folder (loaded via the FileSystem API).
101 /// The library loads certain resources (SSL certs, ICU data, etc.)
102 /// from the FileSystem API during runtime (eg, `file:///resources/cacert.pem`).
103 ///
104 /// You can customize the relative file path to the resources folder by modifying this setting.
105 ///
106 /// (Default = “resources/”)
107 pub fn resource_path_prefix(mut self, path: &str) -> Self {
108 self.resource_path_prefix = Some(path.to_string());
109 self
110 }
111
112 /// The winding order for front-facing triangles. (See [`FaceWinding`])
113 ///
114 /// Note: This is only used when the GPU renderer is enabled.
115 pub fn face_winding(mut self, winding: FaceWinding) -> Self {
116 self.face_winding = Some(winding);
117 self
118 }
119
120 /// The hinting algorithm to use when rendering fonts. (See [`FontHinting`])
121 pub fn font_hinting(mut self, hinting: FontHinting) -> Self {
122 self.font_hinting = Some(hinting);
123 self
124 }
125
126 /// The gamma to use when compositing font glyphs, change this value to
127 /// adjust contrast (Adobe and Apple prefer 1.8, others may prefer 2.2).
128 pub fn font_gamma(mut self, gamma: f64) -> Self {
129 self.font_gamma = Some(gamma);
130 self
131 }
132
133 /// Default user stylesheet. You should set this to your own custom CSS
134 /// string to define default styles for various DOM elements, scrollbars,
135 /// and platform input widgets.
136 pub fn user_stylesheet(mut self, path: &str) -> Self {
137 self.user_stylesheet = Some(path.to_string());
138 self
139 }
140
141 /// Whether or not we should continuously repaint any Views or compositor
142 /// layers, regardless if they are dirty or not. This is mainly used to
143 /// diagnose painting/shader issues.
144 ///
145 /// (Default = false)
146 pub fn force_repaint(mut self, force: bool) -> Self {
147 self.force_repaint = Some(force);
148 self
149 }
150
151 /// When a CSS animation is active, the amount of time (in seconds) to wait
152 /// before triggering another repaint.
153 ///
154 /// (Default = 1.0 / 60.0)
155 pub fn animation_timer_delay(mut self, delay: f64) -> Self {
156 self.animation_timer_delay = Some(delay);
157 self
158 }
159
160 /// When a smooth scroll animation is active, the amount of time (in seconds)
161 /// to wait before triggering another repaint.
162 ///
163 /// (Default = 1.0 / 60.0)
164 pub fn scroll_timer_delay(mut self, delay: f64) -> Self {
165 self.scroll_timer_delay = Some(delay);
166 self
167 }
168
169 /// The amount of time (in seconds) to wait before running the recycler
170 /// (will attempt to return excess memory back to the system).
171 pub fn recycle_delay(mut self, delay: f64) -> Self {
172 self.recycle_delay = Some(delay);
173 self
174 }
175
176 /// The size of WebCore's memory cache in bytes.
177 ///
178 /// You should increase this if you anticipate handling pages with large
179 /// resources, Safari typically uses 128+ MiB for its cache.
180 ///
181 /// `size` is in bytes.
182 ///
183 /// (Default = 64 * 1024 * 1024)
184 pub fn memory_cache_size(mut self, size: u32) -> Self {
185 self.memory_cache_size = Some(size);
186 self
187 }
188
189 /// Number of pages to keep in the cache. Defaults to 0 (none).
190 ///
191 /// Safari typically caches about 5 pages and maintains an on-disk cache
192 /// to support typical web-browsing activities. If you increase this,
193 /// you should probably increase the memory cache size as well.
194 pub fn page_cache_size(mut self, size: u32) -> Self {
195 self.page_cache_size = Some(size);
196 self
197 }
198
199 /// The system's physical RAM size in bytes.
200 ///
201 /// JavaScriptCore tries to detect the system's physical RAM size to set
202 /// reasonable allocation limits. Set this to anything other than 0 to
203 /// override the detected value. `size` is in bytes.
204 ///
205 /// This can be used to force JavaScriptCore to be more conservative
206 /// with its allocation strategy (at the cost of some performance).
207 pub fn override_ram_size(mut self, size: u32) -> Self {
208 self.override_ram_size = Some(size);
209 self
210 }
211
212 /// The minimum size of large VM heaps in JavaScriptCore. Set this to a lower value to make these
213 /// heaps start with a smaller initial value.
214 ///
215 /// `size` is in bytes.
216 ///
217 /// (Default = 32 * 1024 * 1024)
218 pub fn min_large_heap_size(mut self, size: u32) -> Self {
219 self.min_large_heap_size = Some(size);
220 self
221 }
222
223 /// The minimum size of small VM heaps in JavaScriptCore. Set this to a lower value to make these
224 /// heaps start with a smaller initial value.
225 ///
226 /// `size` is in bytes.
227 ///
228 /// (Default = 1 * 1024 * 1024)
229 pub fn min_small_heap_size(mut self, size: u32) -> Self {
230 self.min_small_heap_size = Some(size);
231 self
232 }
233
234 /// The number of threads to use in the Renderer (for parallel painting on the CPU, etc.).
235 ///
236 /// You can set this to a certain number to limit the number of threads to spawn.
237 ///
238 /// If this value is 0 (the default), the number of threads will be determined at runtime
239 /// using the following formula:
240 ///
241 /// `max(PhysicalProcessorCount() - 1, 1)`
242 pub fn num_renderer_threads(mut self, threads: u32) -> Self {
243 self.num_renderer_threads = Some(threads);
244 self
245 }
246
247 /// The max amount of time (in seconds) to allow repeating timers to run during each call to
248 /// [`Renderer::update`](crate::renderer::Renderer::update).
249 /// The library will attempt to throttle timers and/or reschedule work if this
250 /// time budget is exceeded.
251 ///
252 /// (Default = 1.0 / 200.0)
253 pub fn max_update_time(mut self, time: f64) -> Self {
254 self.max_update_time = Some(time);
255 self
256 }
257
258 /// **Note that this is currently is useless in this library**
259 /// **as we can't get the bitmap from [`Surface`](crate::surface::Surface)**
260 /// **when using CPU rendering**.
261 ///
262 /// The alignment (in bytes) of the BitmapSurface when using the CPU renderer.
263 ///
264 /// The underlying bitmap associated with each BitmapSurface will have
265 /// `row_bytes` padded to reach this `alignment`.
266 ///
267 /// Aligning the bitmap helps improve performance when using the CPU renderer/
268 /// Determining the proper value to use depends on the CPU architecture and
269 /// max SIMD instruction set used.
270 ///
271 /// We generally target the 128-bit SSE2 instruction set across most
272 /// PC platforms so '16' is a default and safe value to use.
273 ///
274 /// You can set this to '0' to perform no padding
275 /// (row_bytes will always be `width * 4`) at a slight cost to performance.
276 pub fn bitmap_alignment(mut self, alignment: u32) -> Self {
277 self.bitmap_alignment = Some(alignment);
278 self
279 }
280
281 /// Builds the [`Config`] struct using the settings configured in this builder.
282 ///
283 /// Returns [`None`] if failed to create [`Config`].
284 pub fn build(self, lib: Arc<Library>) -> Option<Config> {
285 let internal = unsafe { lib.ultralight().ulCreateConfig() };
286
287 if internal.is_null() {
288 return None;
289 }
290
291 set_config_str!(
292 internal,
293 self.cache_path,
294 lib.ultralight().ulConfigSetCachePath
295 );
296 set_config_str!(
297 internal,
298 self.resource_path_prefix,
299 lib.ultralight().ulConfigSetResourcePathPrefix
300 );
301 set_config!(
302 internal,
303 self.face_winding.map(|x| x as u32),
304 lib.ultralight().ulConfigSetFaceWinding
305 );
306 set_config!(
307 internal,
308 self.font_hinting.map(|x| x as u32),
309 lib.ultralight().ulConfigSetFontHinting
310 );
311 set_config!(
312 internal,
313 self.font_gamma,
314 lib.ultralight().ulConfigSetFontGamma
315 );
316 set_config_str!(
317 internal,
318 self.user_stylesheet,
319 lib.ultralight().ulConfigSetUserStylesheet
320 );
321 set_config!(
322 internal,
323 self.force_repaint,
324 lib.ultralight().ulConfigSetForceRepaint
325 );
326 set_config!(
327 internal,
328 self.animation_timer_delay,
329 lib.ultralight().ulConfigSetAnimationTimerDelay
330 );
331 set_config!(
332 internal,
333 self.scroll_timer_delay,
334 lib.ultralight().ulConfigSetScrollTimerDelay
335 );
336 set_config!(
337 internal,
338 self.recycle_delay,
339 lib.ultralight().ulConfigSetRecycleDelay
340 );
341 set_config!(
342 internal,
343 self.memory_cache_size,
344 lib.ultralight().ulConfigSetMemoryCacheSize
345 );
346 set_config!(
347 internal,
348 self.page_cache_size,
349 lib.ultralight().ulConfigSetPageCacheSize
350 );
351 set_config!(
352 internal,
353 self.override_ram_size,
354 lib.ultralight().ulConfigSetOverrideRAMSize
355 );
356 set_config!(
357 internal,
358 self.min_large_heap_size,
359 lib.ultralight().ulConfigSetMinLargeHeapSize
360 );
361 set_config!(
362 internal,
363 self.min_small_heap_size,
364 lib.ultralight().ulConfigSetMinSmallHeapSize
365 );
366 set_config!(
367 internal,
368 self.num_renderer_threads,
369 lib.ultralight().ulConfigSetNumRendererThreads
370 );
371 set_config!(
372 internal,
373 self.max_update_time,
374 lib.ultralight().ulConfigSetMaxUpdateTime
375 );
376 set_config!(
377 internal,
378 self.bitmap_alignment,
379 lib.ultralight().ulConfigSetBitmapAlignment
380 );
381
382 Some(Config { lib, internal })
383 }
384}