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