1#![allow(unsafe_code)]
6#![warn(missing_docs)]
7extern crate alloc;
13use crate::Coord;
14use crate::SharedString;
15use crate::api::PlatformError;
16use crate::lengths::LogicalLength;
17use alloc::boxed::Box;
18
19pub use euclid;
20pub type Rect = euclid::default::Rect<Coord>;
22pub type IntRect = euclid::default::Rect<i32>;
24pub type Point = euclid::default::Point2D<Coord>;
26pub type Size = euclid::default::Size2D<Coord>;
28pub type IntSize = euclid::default::Size2D<u32>;
30pub type Transform = euclid::default::Transform2D<Coord>;
32
33pub(crate) mod color;
34pub use color::*;
35
36#[cfg(feature = "shared-fontique")]
37use i_slint_common::sharedfontique::{self, fontique};
38#[cfg(feature = "path")]
39mod path;
40#[cfg(feature = "path")]
41pub use path::*;
42
43mod brush;
44pub use brush::*;
45
46pub(crate) mod image;
47pub use self::image::*;
48
49pub(crate) mod bitmapfont;
50pub use self::bitmapfont::*;
51
52pub mod rendering_metrics_collector;
53
54#[cfg(feature = "box-shadow-cache")]
55pub mod boxshadowcache;
56
57pub mod border_radius;
58pub use border_radius::*;
59
60#[cfg(feature = "wgpu-28")]
61pub mod wgpu_28;
62#[cfg(feature = "wgpu-29")]
63pub mod wgpu_29;
64
65pub struct CachedGraphicsData<T> {
70 pub data: T,
72 pub dependency_tracker: Option<core::pin::Pin<Box<crate::properties::PropertyTracker>>>,
75}
76
77impl<T> CachedGraphicsData<T> {
78 pub fn new(update_fn: impl FnOnce() -> T) -> Self {
81 let dependency_tracker = Box::pin(crate::properties::PropertyTracker::default());
82 let data = dependency_tracker.as_ref().evaluate(update_fn);
83 Self { data, dependency_tracker: Some(dependency_tracker) }
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Default)]
91pub struct FontRequest {
92 pub family: Option<SharedString>,
95 pub weight: Option<i32>,
97 pub pixel_size: Option<LogicalLength>,
99 pub letter_spacing: Option<LogicalLength>,
102 pub italic: bool,
104}
105
106#[cfg(feature = "shared-fontique")]
107impl FontRequest {
108 pub fn query_fontique(
110 &self,
111 collection: &mut fontique::Collection,
112 source_cache: &mut fontique::SourceCache,
113 ) -> Option<fontique::QueryFont> {
114 let mut query = collection.query(source_cache);
115 query.set_families(
116 self.family
117 .as_ref()
118 .map(|family| fontique::QueryFamily::from(family.as_str()))
119 .into_iter()
120 .chain(
121 sharedfontique::FALLBACK_FAMILIES
122 .into_iter()
123 .map(fontique::QueryFamily::Generic),
124 ),
125 );
126
127 query.set_attributes(fontique::Attributes {
128 weight: self
129 .weight
130 .as_ref()
131 .map(|&weight| fontique::FontWeight::new(weight as f32))
132 .unwrap_or_default(),
133 style: if self.italic {
134 fontique::FontStyle::Italic
135 } else {
136 fontique::FontStyle::Normal
137 },
138 ..Default::default()
139 });
140
141 let mut font = None;
142
143 query.matches_with(|queried_font| {
144 font = Some(queried_font.clone());
145 fontique::QueryStatus::Stop
146 });
147
148 font
149 }
150}
151
152#[derive(Debug, Clone, PartialEq)]
155pub enum RequestedOpenGLVersion {
156 OpenGL(Option<(u8, u8)>),
158 OpenGLES(Option<(u8, u8)>),
160}
161
162#[derive(Debug, Clone)]
165#[allow(clippy::large_enum_variant)]
166pub enum RequestedGraphicsAPI {
167 OpenGL(RequestedOpenGLVersion),
169 Metal,
171 Vulkan,
173 Direct3D,
175 #[cfg(feature = "unstable-wgpu-28")]
176 WGPU28(wgpu_28::api::WGPUConfiguration),
178 #[cfg(feature = "unstable-wgpu-29")]
179 WGPU29(wgpu_29::api::WGPUConfiguration),
181}
182
183impl TryFrom<&RequestedGraphicsAPI> for RequestedOpenGLVersion {
184 type Error = PlatformError;
185
186 fn try_from(requested_graphics_api: &RequestedGraphicsAPI) -> Result<Self, Self::Error> {
187 match requested_graphics_api {
188 RequestedGraphicsAPI::OpenGL(requested_open_glversion) => {
189 Ok(requested_open_glversion.clone())
190 }
191 RequestedGraphicsAPI::Metal => {
192 Err("Metal rendering is not supported with an OpenGL renderer".into())
193 }
194 RequestedGraphicsAPI::Vulkan => {
195 Err("Vulkan rendering is not supported with an OpenGL renderer".into())
196 }
197 RequestedGraphicsAPI::Direct3D => {
198 Err("Direct3D 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 #[cfg(feature = "unstable-wgpu-29")]
205 RequestedGraphicsAPI::WGPU29(..) => {
206 Err("WGPU 29.x rendering is not supported with an OpenGL renderer".into())
207 }
208 }
209 }
210}
211
212impl From<RequestedOpenGLVersion> for RequestedGraphicsAPI {
213 fn from(version: RequestedOpenGLVersion) -> Self {
214 Self::OpenGL(version)
215 }
216}
217
218#[cfg(feature = "unstable-wgpu-28")]
221pub fn create_graphics_api_wgpu_28(
222 instance: wgpu_28::wgpu::Instance,
223 device: wgpu_28::wgpu::Device,
224 queue: wgpu_28::wgpu::Queue,
225) -> crate::api::GraphicsAPI<'static> {
226 crate::api::GraphicsAPI::WGPU28 { instance, device, queue }
227}
228
229#[cfg(feature = "unstable-wgpu-29")]
232pub fn create_graphics_api_wgpu_29(
233 instance: wgpu_29::wgpu::Instance,
234 device: wgpu_29::wgpu::Device,
235 queue: wgpu_29::wgpu::Queue,
236) -> crate::api::GraphicsAPI<'static> {
237 crate::api::GraphicsAPI::WGPU29 { instance, device, queue }
238}
239
240#[cfg(feature = "ffi")]
242pub mod ffi {
243 #![allow(unsafe_code)]
244
245 #[cfg(cbindgen)]
247 #[repr(C)]
248 struct Rect {
249 x: f32,
250 y: f32,
251 width: f32,
252 height: f32,
253 }
254
255 #[cfg(cbindgen)]
257 #[repr(C)]
258 struct IntRect {
259 x: i32,
260 y: i32,
261 width: i32,
262 height: i32,
263 }
264
265 #[cfg(cbindgen)]
267 #[repr(C)]
268 struct Point {
269 x: f32,
270 y: f32,
271 }
272
273 #[cfg(cbindgen)]
275 #[repr(C)]
276 struct Box2D<T, U> {
277 min: euclid::Point2D<T>,
278 max: euclid::Point2D<T>,
279 _unit: std::marker::PhantomData<U>,
280 }
281
282 #[cfg(feature = "std")]
283 pub use super::path::ffi::*;
284
285 pub fn physical_size_from_api(
289 size: crate::api::PhysicalSize,
290 ) -> crate::graphics::euclid::default::Size2D<u32> {
291 size.to_euclid()
292 }
293
294 pub fn physical_position_from_api(
298 position: crate::api::PhysicalPosition,
299 ) -> crate::graphics::euclid::default::Point2D<i32> {
300 position.to_euclid()
301 }
302
303 pub fn physical_position_to_api(
306 position: crate::graphics::euclid::default::Point2D<i32>,
307 ) -> crate::api::PhysicalPosition {
308 crate::api::PhysicalPosition::from_euclid(position)
309 }
310}