rootvg_core/
math.rs

1use std::ops::{Div, Mul};
2
3use euclid::UnknownUnit;
4
5pub type ZIndex = u16;
6
7/// Units in physical pixels.
8#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct Physical;
10
11/// A point in units of logical points.
12///
13/// Alias for ```euclid::default::Point2D<f32>```.
14pub type Point = euclid::default::Point2D<f32>;
15
16/// A point in units of logical points.
17///
18/// Alias for ```euclid::default::Point2D<i32>```.
19pub type PointI32 = euclid::default::Point2D<i32>;
20
21/// A point in units of logical points.
22///
23/// Alias for ```euclid::default::Point2D<f64>```.
24pub type PointF64 = euclid::default::Point2D<f64>;
25
26/// A vector in units of logical points.
27///
28/// Alias for ```euclid::default::Vector2D<f32>```.
29pub type Vector = euclid::default::Vector2D<f32>;
30
31/// A vector in units of logical points.
32///
33/// Alias for ```euclid::default::Vector2D<f64>```.
34pub type VectorF64 = euclid::default::Vector2D<f64>;
35
36/// A size in units of logical points.
37///
38/// Alias for ```euclid::default::Size2D<f32>```.
39pub type Size = euclid::default::Size2D<f32>;
40
41/// A size in units of logical points.
42///
43/// Alias for ```euclid::default::Size2D<i32>```.
44pub type SizeI32 = euclid::default::Size2D<i32>;
45
46/// A size in units of logical points.
47///
48/// Alias for ```euclid::default::Size2D<f64>```.
49pub type SizeF64 = euclid::default::Size2D<f64>;
50
51/// Alias for ```euclid::default::Box2D<f32>```
52pub type Box2D = euclid::default::Box2D<f32>;
53
54/// Alias for ```euclid::default::Box2D<f64>```
55pub type Box2DF64 = euclid::default::Box2D<f64>;
56
57/// Alias for ```euclid::default::Transform2D<f32>```
58pub type Transform = euclid::default::Transform2D<f32>;
59
60/// Alias for ```euclid::default::Transform2D<f64>```
61pub type TransformF64 = euclid::default::Transform2D<f64>;
62
63/// Alias for ```euclid::default::Rotation2D<f32>```
64pub type Rotation = euclid::default::Rotation2D<f32>;
65
66/// Alias for ```euclid::default::Rotation2D<f64>```
67pub type RotationF64 = euclid::default::Rotation2D<f64>;
68
69/// Alias for ```euclid::default::Translation2D<f32>```
70pub type Translation = euclid::Translation2D<f32, euclid::UnknownUnit, euclid::UnknownUnit>;
71
72/// Alias for ```euclid::default::Translation2D<f64>```
73pub type TranslationF64 = euclid::Translation2D<f64, euclid::UnknownUnit, euclid::UnknownUnit>;
74
75/// Alias for ```euclid::default::Scale<f32>```
76pub type Scale = euclid::default::Scale<f32>;
77
78/// Alias for ```euclid::default::Scale<f64>```
79pub type ScaleF64 = euclid::default::Scale<f64>;
80
81/// A rectangle in units of logical points.
82///
83/// Alias for ```euclid::default::Rect<f32>```
84pub type Rect = euclid::default::Rect<f32>;
85
86/// A rectangle in units of logical points.
87///
88/// Alias for ```euclid::default::Rect<i32>```
89pub type RectI32 = euclid::default::Rect<i32>;
90
91/// A rectangle in units of logical points.
92///
93/// Alias for ```euclid::default::Rect<f64>```
94pub type RectF64 = euclid::default::Rect<f64>;
95
96/// An angle in radians (f32).
97///
98/// Alias for ```euclid::Angle<f32>```
99pub type Angle = euclid::Angle<f32>;
100
101/// An angle in radians (f64).
102///
103/// Alias for ```euclid::Angle<f64>```
104pub type AngleF64 = euclid::Angle<f64>;
105
106/// A group of 2D side offsets, which correspond to top/right/bottom/left for borders,
107/// padding,and margins in CSS, optionally tagged with a unit.
108///
109/// Alias for ```euclid::SideOffsets2D<f32, UnknownUnit>```
110pub type SideOffsets = euclid::SideOffsets2D<f32, UnknownUnit>;
111
112/// A group of 2D side offsets, which correspond to top/right/bottom/left for borders,
113/// padding,and margins in CSS, optionally tagged with a unit.
114///
115/// Alias for ```euclid::SideOffsets2D<f64, UnknownUnit>```
116pub type SideOffsetsF64 = euclid::SideOffsets2D<f64, UnknownUnit>;
117
118/*
119/// A point in units of logical points.
120pub type LogicalPoint = euclid::Point2D<f32, Logical>;
121*/
122/// A point in units of physical pixels.
123pub type PhysicalPoint = euclid::Point2D<f32, Physical>;
124/// A point in units of physical pixels.
125pub type PhysicalPointU32 = euclid::Point2D<u32, Physical>;
126/// A point in units of physical pixels.
127pub type PhysicalPointI32 = euclid::Point2D<i32, Physical>;
128
129/*
130/// A size in units of logical points.
131pub type LogicalSize = euclid::Size2D<f32, Logical>;
132*/
133/// A size in units of physical pixels.
134pub type PhysicalSize = euclid::Size2D<f32, Physical>;
135/// A size in units of physical pixels.
136pub type PhysicalSizeU32 = euclid::Size2D<u32, Physical>;
137/// A size in units of physical pixels.
138pub type PhysicalSizeI32 = euclid::Size2D<i32, Physical>;
139
140/*
141/// A rectangle in units of logical points.
142pub type LogicalRect = euclid::Rect<f32, Logical>;
143*/
144/// A rectagngle in units of physical pixels.
145pub type PhysicalRect = euclid::Rect<f32, Physical>;
146/// A rectagngle in units of physical pixels.
147pub type PhysicalRectU32 = euclid::Rect<u32, Physical>;
148/// A rectagngle in units of physical pixels.
149pub type PhysicalRectI32 = euclid::Rect<i32, Physical>;
150
151/// Convert a point from logical points to physical pixels.
152#[inline]
153pub fn to_physical_point(point: Point, scale_factor: ScaleFactor) -> PhysicalPoint {
154    PhysicalPoint::new(point.x * scale_factor.0, point.y * scale_factor.0)
155}
156/// Convert a point from logical points to physical pixels.
157#[inline]
158pub fn to_logical_point(point: PhysicalPoint, scale_factor: ScaleFactor) -> Point {
159    Point::new(point.x / scale_factor.0, point.y / scale_factor.0)
160}
161/// Convert a point from logical points to physical pixels.
162#[inline]
163pub fn to_logical_point_u32(point: PhysicalPointU32, scale_factor: ScaleFactor) -> Point {
164    Point::new(
165        point.x as f32 / scale_factor.0,
166        point.y as f32 / scale_factor.0,
167    )
168}
169/// Convert a point from logical points to physical pixels.
170#[inline]
171pub fn to_logical_point_i32(point: PhysicalPointI32, scale_factor: ScaleFactor) -> Point {
172    Point::new(
173        point.x as f32 / scale_factor.0,
174        point.y as f32 / scale_factor.0,
175    )
176}
177/// Convert a point from logical points to physical pixels using the reciprocal of the scale factor.
178#[inline]
179pub fn to_logical_point_from_recip(point: PhysicalPoint, scale_factor_recip: f32) -> Point {
180    Point::new(point.x * scale_factor_recip, point.y * scale_factor_recip)
181}
182/// Convert a point from logical points to physical pixels using the reciprocal of the scale factor.
183#[inline]
184pub fn to_logical_point_from_recip_u32(point: PhysicalPointU32, scale_factor_recip: f32) -> Point {
185    Point::new(
186        point.x as f32 * scale_factor_recip,
187        point.y as f32 * scale_factor_recip,
188    )
189}
190/// Convert a point from logical points to physical pixels using the reciprocal of the scale factor.
191#[inline]
192pub fn to_logical_point_from_recip_i32(point: PhysicalPointI32, scale_factor_recip: f32) -> Point {
193    Point::new(
194        point.x as f32 * scale_factor_recip,
195        point.y as f32 * scale_factor_recip,
196    )
197}
198
199/// Convert a size from logical points to physical pixels.
200#[inline]
201pub fn to_physical_size(size: Size, scale_factor: ScaleFactor) -> PhysicalSize {
202    PhysicalSize::new(size.width * scale_factor.0, size.height * scale_factor.0)
203}
204/// Convert a size from logical points to physical pixels.
205#[inline]
206pub fn to_logical_size(size: PhysicalSize, scale_factor: ScaleFactor) -> Size {
207    Size::new(size.width / scale_factor.0, size.height / scale_factor.0)
208}
209/// Convert a size from logical points to physical pixels.
210#[inline]
211pub fn to_logical_size_u32(size: PhysicalSizeU32, scale_factor: ScaleFactor) -> Size {
212    Size::new(
213        size.width as f32 / scale_factor.0,
214        size.height as f32 / scale_factor.0,
215    )
216}
217/// Convert a size from logical points to physical pixels.
218#[inline]
219pub fn to_logical_size_i32(size: PhysicalSizeI32, scale_factor: ScaleFactor) -> Size {
220    Size::new(
221        size.width as f32 / scale_factor.0,
222        size.height as f32 / scale_factor.0,
223    )
224}
225/// Convert a size from logical points to physical pixels using the reciprocal of the scale factor.
226#[inline]
227pub fn to_logical_size_from_recip(size: PhysicalSize, scale_factor_recip: f32) -> Size {
228    Size::new(
229        size.width * scale_factor_recip,
230        size.height * scale_factor_recip,
231    )
232}
233/// Convert a size from logical points to physical pixels using the reciprocal of the scale factor.
234#[inline]
235pub fn to_logical_size_from_recip_u32(size: PhysicalSizeU32, scale_factor_recip: f32) -> Size {
236    Size::new(
237        size.width as f32 * scale_factor_recip,
238        size.height as f32 * scale_factor_recip,
239    )
240}
241/// Convert a size from logical points to physical pixels using the reciprocal of the scale factor.
242#[inline]
243pub fn to_logical_size_from_recip_i32(size: PhysicalSizeI32, scale_factor_recip: f32) -> Size {
244    Size::new(
245        size.width as f32 * scale_factor_recip,
246        size.height as f32 * scale_factor_recip,
247    )
248}
249
250/// Convert a rectangle from logical points to physical pixels.
251#[inline]
252pub fn to_physical_rect(rect: Rect, scale_factor: ScaleFactor) -> PhysicalRect {
253    PhysicalRect::new(
254        to_physical_point(rect.origin, scale_factor),
255        to_physical_size(rect.size, scale_factor),
256    )
257}
258/// Convert a rectangle from logical points to physical pixels.
259#[inline]
260pub fn to_logical_rect(rect: PhysicalRect, scale_factor: ScaleFactor) -> Rect {
261    Rect::new(
262        to_logical_point(rect.origin, scale_factor),
263        to_logical_size(rect.size, scale_factor),
264    )
265}
266/// Convert a rectangle from logical points to physical pixels.
267#[inline]
268pub fn to_logical_rect_u32(rect: PhysicalRectU32, scale_factor: ScaleFactor) -> Rect {
269    Rect::new(
270        to_logical_point_u32(rect.origin, scale_factor),
271        to_logical_size_u32(rect.size, scale_factor),
272    )
273}
274/// Convert a rectangle from logical points to physical pixels.
275#[inline]
276pub fn to_logical_rect_i32(rect: PhysicalRectI32, scale_factor: ScaleFactor) -> Rect {
277    Rect::new(
278        to_logical_point_i32(rect.origin, scale_factor),
279        to_logical_size_i32(rect.size, scale_factor),
280    )
281}
282/// Convert a rectangle from logical points to physical pixels using the reciprocal of the scale factor.
283#[inline]
284pub fn to_logical_rect_from_recip(rect: PhysicalRect, scale_factor_recip: f32) -> Rect {
285    Rect::new(
286        to_logical_point_from_recip(rect.origin, scale_factor_recip),
287        to_logical_size_from_recip(rect.size, scale_factor_recip),
288    )
289}
290/// Convert a rectangle from logical points to physical pixels using the reciprocal of the scale factor.
291#[inline]
292pub fn to_logical_rect_from_recip_u32(rect: PhysicalRectU32, scale_factor_recip: f32) -> Rect {
293    Rect::new(
294        to_logical_point_from_recip_u32(rect.origin, scale_factor_recip),
295        to_logical_size_from_recip_u32(rect.size, scale_factor_recip),
296    )
297}
298/// Convert a rectangle from logical points to physical pixels using the reciprocal of the scale factor.
299#[inline]
300pub fn to_logical_rect_from_recip_i32(rect: PhysicalRectI32, scale_factor_recip: f32) -> Rect {
301    Rect::new(
302        to_logical_point_from_recip_i32(rect.origin, scale_factor_recip),
303        to_logical_size_from_recip_i32(rect.size, scale_factor_recip),
304    )
305}
306
307/// Shorthand for `Vector::new(x, y)`.
308#[inline]
309pub const fn vector(x: f32, y: f32) -> Vector {
310    Vector::new(x, y)
311}
312
313/// Shorthand for `Point::new(x, y)`.
314#[inline]
315pub const fn point(x: f32, y: f32) -> Point {
316    Point::new(x, y)
317}
318
319/// Shorthand for `Size::new(x, y)`.
320#[inline]
321pub const fn size(w: f32, h: f32) -> Size {
322    Size::new(w, h)
323}
324
325/// Shorthand for `Angle { radians: value }`.
326#[inline]
327pub const fn radians(radians: f32) -> Angle {
328    Angle { radians }
329}
330
331/// Shorthand for `Angle { radians: value * PI / 180.0 }`.
332#[inline]
333pub fn degrees(degrees: f32) -> Angle {
334    Angle {
335        radians: degrees * (std::f32::consts::PI / 180.0),
336    }
337}
338
339/// Shorthand for `Rect::new(Point::new(x, y), Size::new(width, height))`.
340#[inline]
341pub const fn rect(x: f32, y: f32, width: f32, height: f32) -> Rect {
342    Rect::new(Point::new(x, y), Size::new(width, height))
343}
344
345/// A scaling factor in points per pixel.
346#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
347pub struct ScaleFactor(pub f32);
348
349impl ScaleFactor {
350    pub fn new(scale_factor: f32) -> Self {
351        Self(scale_factor)
352    }
353
354    pub fn recip(&self) -> f32 {
355        self.0.recip()
356    }
357}
358
359impl Default for ScaleFactor {
360    fn default() -> Self {
361        Self(1.0)
362    }
363}
364
365impl From<f32> for ScaleFactor {
366    fn from(s: f32) -> Self {
367        Self(s)
368    }
369}
370
371impl From<f64> for ScaleFactor {
372    fn from(s: f64) -> Self {
373        Self(s as f32)
374    }
375}
376
377impl From<ScaleFactor> for f32 {
378    fn from(s: ScaleFactor) -> Self {
379        s.0
380    }
381}
382
383impl From<ScaleFactor> for f64 {
384    fn from(s: ScaleFactor) -> Self {
385        s.0 as f64
386    }
387}
388
389impl Mul<ScaleFactor> for f32 {
390    type Output = f32;
391    fn mul(self, rhs: ScaleFactor) -> Self::Output {
392        self * rhs.0
393    }
394}
395
396impl Div<ScaleFactor> for f32 {
397    type Output = f32;
398    fn div(self, rhs: ScaleFactor) -> Self::Output {
399        self / rhs.0
400    }
401}
402
403/// Returns a scaling vector that can be used to convert screen coordinates
404/// to clip coordinates in shaders.
405pub fn screen_to_clip_scale(screen_size: PhysicalSizeI32, scale_factor: ScaleFactor) -> [f32; 2] {
406    [
407        2.0 * scale_factor * (screen_size.width as f32).recip(),
408        2.0 * scale_factor * (screen_size.height as f32).recip(),
409    ]
410}