1#![allow(unsafe_code)]
5#![warn(missing_docs)]
6extern crate alloc;
12use crate::Coord;
13use crate::SharedString;
14use crate::api::PlatformError;
15use crate::lengths::LogicalLength;
16use alloc::boxed::Box;
17
18pub use euclid;
19pub type Rect = euclid::default::Rect<Coord>;
21pub type IntRect = euclid::default::Rect<i32>;
23pub type Point = euclid::default::Point2D<Coord>;
25pub type Size = euclid::default::Size2D<Coord>;
27pub type IntSize = euclid::default::Size2D<u32>;
29pub type Transform = euclid::default::Transform2D<Coord>;
31
32pub(crate) mod color;
33pub use color::*;
34
35#[cfg(feature = "std")]
36mod path;
37#[cfg(feature = "std")]
38pub use path::*;
39
40mod brush;
41pub use brush::*;
42
43pub(crate) mod image;
44pub use self::image::*;
45
46pub(crate) mod bitmapfont;
47pub use self::bitmapfont::*;
48
49pub mod rendering_metrics_collector;
50
51#[cfg(feature = "box-shadow-cache")]
52pub mod boxshadowcache;
53
54pub mod border_radius;
55pub use border_radius::*;
56
57#[cfg(feature = "unstable-wgpu-27")]
58pub mod wgpu_27;
59#[cfg(feature = "unstable-wgpu-28")]
60pub mod wgpu_28;
61
62pub struct CachedGraphicsData<T> {
67 pub data: T,
69 pub dependency_tracker: Option<core::pin::Pin<Box<crate::properties::PropertyTracker>>>,
72}
73
74impl<T> CachedGraphicsData<T> {
75 pub fn new(update_fn: impl FnOnce() -> T) -> Self {
78 let dependency_tracker = Box::pin(crate::properties::PropertyTracker::default());
79 let data = dependency_tracker.as_ref().evaluate(update_fn);
80 Self { data, dependency_tracker: Some(dependency_tracker) }
81 }
82}
83
84#[derive(Debug, Clone, PartialEq, Default)]
88pub struct FontRequest {
89 pub family: Option<SharedString>,
92 pub weight: Option<i32>,
94 pub pixel_size: Option<LogicalLength>,
96 pub letter_spacing: Option<LogicalLength>,
99 pub italic: bool,
101}
102
103#[cfg(feature = "shared-fontique")]
104impl FontRequest {
105 pub fn query_fontique(&self) -> Option<i_slint_common::sharedfontique::fontique::QueryFont> {
107 use i_slint_common::sharedfontique::{self, fontique};
108
109 let mut collection = sharedfontique::get_collection();
110
111 let mut query = collection.query();
112 query.set_families(
113 self.family
114 .as_ref()
115 .map(|family| fontique::QueryFamily::from(family.as_str()))
116 .into_iter()
117 .chain(
118 sharedfontique::FALLBACK_FAMILIES
119 .into_iter()
120 .map(fontique::QueryFamily::Generic),
121 ),
122 );
123
124 query.set_attributes(fontique::Attributes {
125 weight: self
126 .weight
127 .as_ref()
128 .map(|&weight| fontique::FontWeight::new(weight as f32))
129 .unwrap_or_default(),
130 style: if self.italic {
131 fontique::FontStyle::Italic
132 } else {
133 fontique::FontStyle::Normal
134 },
135 ..Default::default()
136 });
137
138 let mut font = None;
139
140 query.matches_with(|queried_font| {
141 font = Some(queried_font.clone());
142 fontique::QueryStatus::Stop
143 });
144
145 font
146 }
147}
148
149#[derive(Debug, Clone, PartialEq)]
152pub enum RequestedOpenGLVersion {
153 OpenGL(Option<(u8, u8)>),
155 OpenGLES(Option<(u8, u8)>),
157}
158
159#[derive(Debug, Clone)]
162pub enum RequestedGraphicsAPI {
163 OpenGL(RequestedOpenGLVersion),
165 Metal,
167 Vulkan,
169 Direct3D,
171 #[cfg(feature = "unstable-wgpu-27")]
172 WGPU27(wgpu_27::api::WGPUConfiguration),
174 #[cfg(feature = "unstable-wgpu-28")]
175 WGPU28(wgpu_28::api::WGPUConfiguration),
177}
178
179impl TryFrom<&RequestedGraphicsAPI> for RequestedOpenGLVersion {
180 type Error = PlatformError;
181
182 fn try_from(requested_graphics_api: &RequestedGraphicsAPI) -> Result<Self, Self::Error> {
183 match requested_graphics_api {
184 RequestedGraphicsAPI::OpenGL(requested_open_glversion) => {
185 Ok(requested_open_glversion.clone())
186 }
187 RequestedGraphicsAPI::Metal => {
188 Err("Metal rendering is not supported with an OpenGL renderer".into())
189 }
190 RequestedGraphicsAPI::Vulkan => {
191 Err("Vulkan rendering is not supported with an OpenGL renderer".into())
192 }
193 RequestedGraphicsAPI::Direct3D => {
194 Err("Direct3D rendering is not supported with an OpenGL renderer".into())
195 }
196 #[cfg(feature = "unstable-wgpu-27")]
197 RequestedGraphicsAPI::WGPU27(..) => {
198 Err("WGPU 27.x rendering is not supported with an OpenGL renderer".into())
199 }
200 #[cfg(feature = "unstable-wgpu-28")]
201 RequestedGraphicsAPI::WGPU28(..) => {
202 Err("WGPU 28.x rendering is not supported with an OpenGL renderer".into())
203 }
204 }
205 }
206}
207
208impl From<RequestedOpenGLVersion> for RequestedGraphicsAPI {
209 fn from(version: RequestedOpenGLVersion) -> Self {
210 Self::OpenGL(version)
211 }
212}
213
214#[cfg(feature = "unstable-wgpu-27")]
217pub fn create_graphics_api_wgpu_27(
218 instance: wgpu_27::wgpu::Instance,
219 device: wgpu_27::wgpu::Device,
220 queue: wgpu_27::wgpu::Queue,
221) -> crate::api::GraphicsAPI<'static> {
222 crate::api::GraphicsAPI::WGPU27 { instance, device, queue }
223}
224
225#[cfg(feature = "unstable-wgpu-28")]
228pub fn create_graphics_api_wgpu_28(
229 instance: wgpu_28::wgpu::Instance,
230 device: wgpu_28::wgpu::Device,
231 queue: wgpu_28::wgpu::Queue,
232) -> crate::api::GraphicsAPI<'static> {
233 crate::api::GraphicsAPI::WGPU28 { instance, device, queue }
234}
235
236#[cfg(feature = "ffi")]
238pub mod ffi {
239 #![allow(unsafe_code)]
240
241 #[cfg(cbindgen)]
243 #[repr(C)]
244 struct Rect {
245 x: f32,
246 y: f32,
247 width: f32,
248 height: f32,
249 }
250
251 #[cfg(cbindgen)]
253 #[repr(C)]
254 struct IntRect {
255 x: i32,
256 y: i32,
257 width: i32,
258 height: i32,
259 }
260
261 #[cfg(cbindgen)]
263 #[repr(C)]
264 struct Point {
265 x: f32,
266 y: f32,
267 }
268
269 #[cfg(cbindgen)]
271 #[repr(C)]
272 struct Box2D<T, U> {
273 min: euclid::Point2D<T>,
274 max: euclid::Point2D<T>,
275 _unit: std::marker::PhantomData<U>,
276 }
277
278 #[cfg(feature = "std")]
279 pub use super::path::ffi::*;
280
281 pub fn physical_size_from_api(
285 size: crate::api::PhysicalSize,
286 ) -> crate::graphics::euclid::default::Size2D<u32> {
287 size.to_euclid()
288 }
289
290 pub fn physical_position_from_api(
294 position: crate::api::PhysicalPosition,
295 ) -> crate::graphics::euclid::default::Point2D<i32> {
296 position.to_euclid()
297 }
298
299 pub fn physical_position_to_api(
302 position: crate::graphics::euclid::default::Point2D<i32>,
303 ) -> crate::api::PhysicalPosition {
304 crate::api::PhysicalPosition::from_euclid(position)
305 }
306}