StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.
| 1 | mod gpu_info; |
| 2 | pub mod texture_cache; |
| 3 | pub use gpu_info::{GPUBackend, GPUDeviceInfo, GPUDeviceType, OnGPUDeviceSelected}; |
| 4 | |
| 5 | use serde::{Deserialize, Serialize}; |
| 6 | |
| 7 | use crate::platform::GraphicsBackend; |
| 8 | |
| 9 | /// Circumstances under which glyphs should be rasterized with thin strokes. |
| 10 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] |
| 11 | #[cfg_attr(feature = "schema_gen", derive(schemars::JsonSchema))] |
| 12 | #[cfg_attr( |
| 13 | feature = "schema_gen", |
| 14 | schemars( |
| 15 | description = "When to render text with thinner strokes for a lighter appearance.", |
| 16 | rename_all = "snake_case" |
| 17 | ) |
| 18 | )] |
| 19 | pub enum ThinStrokes { |
| 20 | /// Never render glyphs using thin strokes. |
| 21 | Never, |
| 22 | /// Render glyphs using thin strokes when rendering on a low-DPI display. |
| 23 | OnLowDpiDisplays, |
| 24 | /// Render glyphs using thin strokes when rendering on a high-DPI display. |
| 25 | #[default] |
| 26 | OnHighDpiDisplays, |
| 27 | /// Always render glyphs using thin strokes. |
| 28 | Always, |
| 29 | } |
| 30 | |
| 31 | impl ThinStrokes { |
| 32 | /// The minimum scale factor for which we'll consider a display to be high-DPI. |
| 33 | const HIGH_DPI_SCALE_FACTOR: f32 = 1.5; |
| 34 | |
| 35 | pub fn enabled_for_scale_factor(&self, scale_factor: f32) -> bool { |
| 36 | match self { |
| 37 | Self::Never => false, |
| 38 | Self::OnLowDpiDisplays => scale_factor < Self::HIGH_DPI_SCALE_FACTOR, |
| 39 | Self::OnHighDpiDisplays => scale_factor >= Self::HIGH_DPI_SCALE_FACTOR, |
| 40 | Self::Always => true, |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | /// Options for configuring rendering of glyphs. |
| 46 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] |
| 47 | pub struct GlyphConfig { |
| 48 | /// Whether to render glyphs using thin strokes. |
| 49 | pub use_thin_strokes: ThinStrokes, |
| 50 | } |
| 51 | |
| 52 | /// Power preference for GPU for rendering. |
| 53 | /// |
| 54 | /// Relevant for machines with multiple GPUs (typically a discrete high-performance GPU and an |
| 55 | /// integrated low-power-usage GPU). |
| 56 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Default)] |
| 57 | pub enum GPUPowerPreference { |
| 58 | LowPower, |
| 59 | #[default] |
| 60 | HighPerformance, |
| 61 | } |
| 62 | |
| 63 | /// Options for configuring rendering at the application level. These options |
| 64 | /// will apply for the entirety of a frame, but may change between frames. |
| 65 | #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] |
| 66 | pub struct Config { |
| 67 | /// Configuration options relating to glyph rendering. |
| 68 | pub glyphs: GlyphConfig, |
| 69 | |
| 70 | /// Power preference for GPU used for rendering; this is applicable on dual GPU machines where |
| 71 | /// there's a choice between a discrete high-performance GPU and a more power-efficient |
| 72 | /// integrated GPU. |
| 73 | pub gpu_power_preference: GPUPowerPreference, |
| 74 | |
| 75 | pub backend_preference: Option<GraphicsBackend>, |
| 76 | } |
| 77 | |
| 78 | #[derive(Clone, Debug, Default)] |
| 79 | pub struct CornerRadius { |
| 80 | pub top_left: f32, |
| 81 | pub top_right: f32, |
| 82 | pub bottom_left: f32, |
| 83 | pub bottom_right: f32, |
| 84 | } |
| 85 | |
| 86 | impl CornerRadius { |
| 87 | pub fn from_ui_corner_radius( |
| 88 | corner_radius: crate::scene::CornerRadius, |
| 89 | scale_factor: f32, |
| 90 | min_dimension: f32, |
| 91 | ) -> Self { |
| 92 | let top_left = match corner_radius.get_top_left() { |
| 93 | crate::scene::Radius::Pixels(px) => px * scale_factor, |
| 94 | crate::scene::Radius::Percentage(percent) => percent / 100. * min_dimension, |
| 95 | }; |
| 96 | let top_right = match corner_radius.get_top_right() { |
| 97 | crate::scene::Radius::Pixels(px) => px * scale_factor, |
| 98 | crate::scene::Radius::Percentage(percent) => percent / 100. * min_dimension, |
| 99 | }; |
| 100 | let bottom_left = match corner_radius.get_bottom_left() { |
| 101 | crate::scene::Radius::Pixels(px) => px * scale_factor, |
| 102 | crate::scene::Radius::Percentage(percent) => percent / 100. * min_dimension, |
| 103 | }; |
| 104 | let bottom_right = match corner_radius.get_bottom_right() { |
| 105 | crate::scene::Radius::Pixels(px) => px * scale_factor, |
| 106 | crate::scene::Radius::Percentage(percent) => percent / 100. * min_dimension, |
| 107 | }; |
| 108 | Self { |
| 109 | top_left, |
| 110 | top_right, |
| 111 | bottom_left, |
| 112 | bottom_right, |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 |