Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-ui-renderer/src/rendering/mod.rs
1pub(crate) mod atlas;
2pub(crate) mod glyph_cache;
3#[cfg(wgpu)]
4pub mod wgpu;
5 
6pub use strato_ui_core::rendering::*;
7use strato_ui_core::scene::Dash;
8 
9pub(crate) use glyph_cache::{GlyphCache, GlyphRasterBoundsFn, RasterizeGlyphFn};
10 
11/// Cache for the result of calling [`is_low_power_gpu_available`], as the
12/// check can be expensive.
13static LOW_POWER_GPU_AVAILABLE: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
14 
15/// Returns `true` if a low power GPU is available for rendering. Typically, this is true for
16/// machines with two GPUs -- a dedicated discrete high-performance GPU and a lower power
17/// integrated GPU.
18pub fn is_low_power_gpu_available() -> bool {
19 *LOW_POWER_GPU_AVAILABLE.get_or_init(|| {
20 cfg_if::cfg_if! {
21 if #[cfg(target_os = "macos")] {
22 crate::platform::mac::is_low_power_gpu_available()
23 } else if #[cfg(wgpu)] {
24 strato_ui_core::r#async::block_on(wgpu::is_low_power_gpu_available())
25 } else {
26 false
27 }
28 }
29 })
30}
31 
32/// Returns the gap length between each dash to ensure that the stroke begins and ends with a full dash,
33/// minimizing deviation from the target gap length.
34// adapted from Blink dashed border rendering code:
35// https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:third_party/blink/renderer/platform/graphics/stroke_data.cc;l=130-147;drc=51e1b713f6da38219910bf8fb93a81262340bf97
36pub(crate) fn get_best_dash_gap(
37 stroke_length: f32,
38 Dash {
39 dash_length,
40 gap_length,
41 force_consistent_gap_length,
42 }: Dash,
43) -> f32 {
44 if force_consistent_gap_length {
45 return gap_length;
46 }
47 
48 // If no space for two dashes and a gap between, return gap length 0 (solid border)
49 if stroke_length < 2. * dash_length + gap_length {
50 return 0.;
51 }
52 
53 let min_num_dashes = (stroke_length / (dash_length + gap_length)).floor();
54 let max_num_dashes = min_num_dashes + 1.;
55 let min_num_gaps = min_num_dashes - 1.;
56 let max_num_gaps = max_num_dashes - 1.;
57 let min_gap = (stroke_length - min_num_dashes * dash_length) / min_num_gaps;
58 let max_gap = (stroke_length - max_num_dashes * dash_length) / max_num_gaps;
59 if max_gap <= 0. || ((min_gap - gap_length).abs() < (max_gap - gap_length).abs()) {
60 min_gap
61 } else {
62 max_gap
63 }
64}
65