1use bytemuck::{Pod, Zeroable};
2use core::fmt::Debug;
3use derive_more::{Add, AddAssign, Div, Mul, Sub, SubAssign};
4use refineable::Refineable;
5use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign};
6
7#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
8#[refineable(debug)]
9#[repr(C)]
10pub struct Point<T: Clone + Debug> {
11 pub x: T,
12 pub y: T,
13}
14
15pub fn point<T: Clone + Debug>(x: T, y: T) -> Point<T> {
16 Point { x, y }
17}
18
19impl<T: Clone + Debug> Point<T> {
20 pub fn new(x: T, y: T) -> Self {
21 Self { x, y }
22 }
23
24 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Point<U> {
25 Point {
26 x: f(self.x.clone()),
27 y: f(self.y.clone()),
28 }
29 }
30}
31
32impl<T, Rhs> Mul<Rhs> for Point<T>
33where
34 T: Mul<Rhs, Output = T> + Clone + Debug,
35 Rhs: Clone + Debug,
36{
37 type Output = Point<T>;
38
39 fn mul(self, rhs: Rhs) -> Self::Output {
40 Point {
41 x: self.x * rhs.clone(),
42 y: self.y * rhs,
43 }
44 }
45}
46
47impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Point<T> {
48 fn mul_assign(&mut self, rhs: S) {
49 self.x = self.x.clone() * rhs.clone();
50 self.y = self.y.clone() * rhs;
51 }
52}
53
54impl<T: Clone + Debug + Sub<Output = T>> SubAssign<Size<T>> for Point<T> {
55 fn sub_assign(&mut self, rhs: Size<T>) {
56 self.x = self.x.clone() - rhs.width;
57 self.y = self.y.clone() - rhs.height;
58 }
59}
60
61impl<T: Clone + Debug + Add<Output = T> + Copy> AddAssign<T> for Point<T> {
62 fn add_assign(&mut self, rhs: T) {
63 self.x = self.x.clone() + rhs;
64 self.y = self.y.clone() + rhs;
65 }
66}
67
68impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Point<T> {
69 type Output = Self;
70
71 fn div(self, rhs: S) -> Self::Output {
72 Self {
73 x: self.x / rhs.clone(),
74 y: self.y / rhs,
75 }
76 }
77}
78
79impl<T: Clone + Debug + std::cmp::PartialOrd> Point<T> {
80 pub fn max(&self, other: &Self) -> Self {
81 Point {
82 x: if self.x >= other.x {
83 self.x.clone()
84 } else {
85 other.x.clone()
86 },
87 y: if self.y >= other.y {
88 self.y.clone()
89 } else {
90 other.y.clone()
91 },
92 }
93 }
94}
95
96impl<T: Clone + Debug> Clone for Point<T> {
97 fn clone(&self) -> Self {
98 Self {
99 x: self.x.clone(),
100 y: self.y.clone(),
101 }
102 }
103}
104
105unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Point<T> {}
106unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Point<T> {}
107
108#[derive(Refineable, Default, Clone, Copy, Debug, PartialEq, Div, Hash)]
109#[refineable(debug)]
110#[repr(C)]
111pub struct Size<T: Clone + Debug> {
112 pub width: T,
113 pub height: T,
114}
115
116unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Size<T> {}
117unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Size<T> {}
118
119pub fn size<T: Clone + Debug>(width: T, height: T) -> Size<T> {
120 Size { width, height }
121}
122
123impl<T: Clone + Debug> Size<T> {
124 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Size<U> {
125 Size {
126 width: f(self.width.clone()),
127 height: f(self.height.clone()),
128 }
129 }
130}
131
132impl<T: Clone + Debug + Ord> Size<T> {
133 pub fn max(&self, other: &Self) -> Self {
134 Size {
135 width: if self.width >= other.width {
136 self.width.clone()
137 } else {
138 other.width.clone()
139 },
140 height: if self.height >= other.height {
141 self.height.clone()
142 } else {
143 other.height.clone()
144 },
145 }
146 }
147}
148
149impl<T, Rhs> Mul<Rhs> for Size<T>
150where
151 T: Mul<Rhs, Output = Rhs> + Debug + Clone,
152 Rhs: Debug + Clone,
153{
154 type Output = Size<Rhs>;
155
156 fn mul(self, rhs: Rhs) -> Self::Output {
157 Size {
158 width: self.width * rhs.clone(),
159 height: self.height * rhs,
160 }
161 }
162}
163
164impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Size<T> {
165 fn mul_assign(&mut self, rhs: S) {
166 self.width = self.width.clone() * rhs.clone();
167 self.height = self.height.clone() * rhs;
168 }
169}
170
171impl<T: Eq + Debug + Clone> Eq for Size<T> {}
172
173impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
174 fn from(val: Size<Option<Pixels>>) -> Self {
175 Size {
176 width: val.width.map(|p| p.0 as f32),
177 height: val.height.map(|p| p.0 as f32),
178 }
179 }
180}
181
182impl Size<Length> {
183 pub fn full() -> Self {
184 Self {
185 width: relative(1.).into(),
186 height: relative(1.).into(),
187 }
188 }
189}
190
191impl Size<DefiniteLength> {
192 pub fn zero() -> Self {
193 Self {
194 width: px(0.).into(),
195 height: px(0.).into(),
196 }
197 }
198}
199
200impl Size<Length> {
201 pub fn auto() -> Self {
202 Self {
203 width: Length::Auto,
204 height: Length::Auto,
205 }
206 }
207}
208
209#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
210#[refineable(debug)]
211#[repr(C)]
212pub struct Bounds<T: Clone + Debug> {
213 pub origin: Point<T>,
214 pub size: Size<T>,
215}
216
217unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Bounds<T> {}
218unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Bounds<T> {}
219
220// Bounds<f32> * Pixels = Bounds<Pixels>
221impl<T, Rhs> Mul<Rhs> for Bounds<T>
222where
223 T: Mul<Rhs, Output = Rhs> + Clone + Debug,
224 Point<T>: Mul<Rhs, Output = Point<Rhs>>,
225 Rhs: Clone + Debug,
226{
227 type Output = Bounds<Rhs>;
228
229 fn mul(self, rhs: Rhs) -> Self::Output {
230 Bounds {
231 origin: self.origin * rhs.clone(),
232 size: self.size * rhs,
233 }
234 }
235}
236
237impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Bounds<T> {
238 fn mul_assign(&mut self, rhs: S) {
239 self.origin *= rhs.clone();
240 self.size *= rhs;
241 }
242}
243
244impl<T: Clone + Debug + Div<S, Output = T>, S: Clone> Div<S> for Bounds<T>
245where
246 Size<T>: Div<S, Output = Size<T>>,
247{
248 type Output = Self;
249
250 fn div(self, rhs: S) -> Self {
251 Self {
252 origin: self.origin / rhs.clone(),
253 size: self.size / rhs,
254 }
255 }
256}
257
258impl<T: Clone + Debug + Add<T, Output = T>> Bounds<T> {
259 pub fn upper_right(&self) -> Point<T> {
260 Point {
261 x: self.origin.x.clone() + self.size.width.clone(),
262 y: self.origin.y.clone(),
263 }
264 }
265
266 pub fn lower_right(&self) -> Point<T> {
267 Point {
268 x: self.origin.x.clone() + self.size.width.clone(),
269 y: self.origin.y.clone() + self.size.height.clone(),
270 }
271 }
272}
273
274impl<T: Clone + Debug + PartialOrd + Add<T, Output = T>> Bounds<T> {
275 pub fn contains_point(&self, point: Point<T>) -> bool {
276 point.x >= self.origin.x
277 && point.x <= self.origin.x.clone() + self.size.width.clone()
278 && point.y >= self.origin.y
279 && point.y <= self.origin.y.clone() + self.size.height.clone()
280 }
281
282 pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Bounds<U> {
283 Bounds {
284 origin: self.origin.map(&f),
285 size: self.size.map(f),
286 }
287 }
288}
289
290impl<T: Clone + Debug + Copy> Copy for Bounds<T> {}
291
292#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
293#[refineable(debug)]
294#[repr(C)]
295pub struct Edges<T: Clone + Debug> {
296 pub top: T,
297 pub right: T,
298 pub bottom: T,
299 pub left: T,
300}
301
302impl<T: Clone + Debug + Mul<Output = T>> Mul for Edges<T> {
303 type Output = Self;
304
305 fn mul(self, rhs: Self) -> Self::Output {
306 Self {
307 top: self.top.clone() * rhs.top,
308 right: self.right.clone() * rhs.right,
309 bottom: self.bottom.clone() * rhs.bottom,
310 left: self.left.clone() * rhs.left,
311 }
312 }
313}
314
315impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Edges<T> {
316 fn mul_assign(&mut self, rhs: S) {
317 self.top = self.top.clone() * rhs.clone();
318 self.right = self.right.clone() * rhs.clone();
319 self.bottom = self.bottom.clone() * rhs.clone();
320 self.left = self.left.clone() * rhs.clone();
321 }
322}
323
324impl<T: Clone + Debug + Copy> Copy for Edges<T> {}
325
326unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Edges<T> {}
327
328unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Edges<T> {}
329
330impl<T: Clone + Debug> Edges<T> {
331 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Edges<U> {
332 Edges {
333 top: f(&self.top),
334 right: f(&self.right),
335 bottom: f(&self.bottom),
336 left: f(&self.left),
337 }
338 }
339
340 pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
341 predicate(&self.top)
342 || predicate(&self.right)
343 || predicate(&self.bottom)
344 || predicate(&self.left)
345 }
346}
347
348impl Edges<Length> {
349 pub fn auto() -> Self {
350 Self {
351 top: Length::Auto,
352 right: Length::Auto,
353 bottom: Length::Auto,
354 left: Length::Auto,
355 }
356 }
357
358 pub fn zero() -> Self {
359 Self {
360 top: px(0.).into(),
361 right: px(0.).into(),
362 bottom: px(0.).into(),
363 left: px(0.).into(),
364 }
365 }
366}
367
368impl Edges<DefiniteLength> {
369 pub fn zero() -> Self {
370 Self {
371 top: px(0.).into(),
372 right: px(0.).into(),
373 bottom: px(0.).into(),
374 left: px(0.).into(),
375 }
376 }
377}
378
379impl Edges<AbsoluteLength> {
380 pub fn zero() -> Self {
381 Self {
382 top: px(0.).into(),
383 right: px(0.).into(),
384 bottom: px(0.).into(),
385 left: px(0.).into(),
386 }
387 }
388
389 pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
390 Edges {
391 top: self.top.to_pixels(rem_size),
392 right: self.right.to_pixels(rem_size),
393 bottom: self.bottom.to_pixels(rem_size),
394 left: self.left.to_pixels(rem_size),
395 }
396 }
397}
398
399#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
400#[refineable(debug)]
401#[repr(C)]
402pub struct Corners<T: Clone + Debug> {
403 pub top_left: T,
404 pub top_right: T,
405 pub bottom_right: T,
406 pub bottom_left: T,
407}
408
409impl<T: Clone + Debug> Corners<T> {
410 pub fn map<U: Clone + Debug, F: Fn(&T) -> U>(&self, f: F) -> Corners<U> {
411 Corners {
412 top_left: f(&self.top_left),
413 top_right: f(&self.top_right),
414 bottom_right: f(&self.bottom_right),
415 bottom_left: f(&self.bottom_left),
416 }
417 }
418}
419
420impl<T: Clone + Debug + Mul<Output = T>> Mul for Corners<T> {
421 type Output = Self;
422
423 fn mul(self, rhs: Self) -> Self::Output {
424 Self {
425 top_left: self.top_left.clone() * rhs.top_left,
426 top_right: self.top_right.clone() * rhs.top_right,
427 bottom_right: self.bottom_right.clone() * rhs.bottom_right,
428 bottom_left: self.bottom_left.clone() * rhs.bottom_left,
429 }
430 }
431}
432
433impl<T: Clone + Debug + Mul<S, Output = T>, S: Clone> MulAssign<S> for Corners<T> {
434 fn mul_assign(&mut self, rhs: S) {
435 self.top_left = self.top_left.clone() * rhs.clone();
436 self.top_right = self.top_right.clone() * rhs.clone();
437 self.bottom_right = self.bottom_right.clone() * rhs.clone();
438 self.bottom_left = self.bottom_left.clone() * rhs;
439 }
440}
441
442impl<T: Clone + Debug + Copy> Copy for Corners<T> {}
443
444unsafe impl<T: Clone + Debug + Zeroable + Pod> Zeroable for Corners<T> {}
445
446unsafe impl<T: Clone + Debug + Zeroable + Pod> Pod for Corners<T> {}
447
448#[derive(
449 Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd, Zeroable, Pod,
450)]
451#[repr(transparent)]
452pub struct Pixels(pub(crate) f32);
453
454impl Mul<f32> for Pixels {
455 type Output = Pixels;
456
457 fn mul(self, other: f32) -> Pixels {
458 Pixels(self.0 * other)
459 }
460}
461
462impl Mul<Pixels> for f32 {
463 type Output = Pixels;
464
465 fn mul(self, rhs: Pixels) -> Self::Output {
466 Pixels(self * rhs.0)
467 }
468}
469
470impl MulAssign<f32> for Pixels {
471 fn mul_assign(&mut self, other: f32) {
472 self.0 *= other;
473 }
474}
475
476impl Pixels {
477 pub fn round(&self) -> Self {
478 Self(self.0.round())
479 }
480
481 pub fn floor(&self) -> Self {
482 Self(self.0.floor())
483 }
484
485 pub fn to_device_pixels(&self, scale: f32) -> DevicePixels {
486 DevicePixels((self.0 * scale).ceil() as u32)
487 }
488}
489
490impl Mul<Pixels> for Pixels {
491 type Output = Pixels;
492
493 fn mul(self, rhs: Pixels) -> Self::Output {
494 Pixels(self.0 * rhs.0)
495 }
496}
497
498impl Eq for Pixels {}
499
500impl Ord for Pixels {
501 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
502 self.0.partial_cmp(&other.0).unwrap()
503 }
504}
505
506impl std::hash::Hash for Pixels {
507 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
508 self.0.to_bits().hash(state);
509 }
510}
511
512impl From<f64> for Pixels {
513 fn from(val: f64) -> Self {
514 Pixels(val as f32)
515 }
516}
517
518impl From<f32> for Pixels {
519 fn from(val: f32) -> Self {
520 Pixels(val)
521 }
522}
523
524impl Debug for Pixels {
525 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
526 write!(f, "{} px", self.0)
527 }
528}
529
530impl From<Pixels> for f32 {
531 fn from(pixels: Pixels) -> Self {
532 pixels.0
533 }
534}
535
536impl From<&Pixels> for f32 {
537 fn from(pixels: &Pixels) -> Self {
538 pixels.0
539 }
540}
541
542impl From<Pixels> for f64 {
543 fn from(pixels: Pixels) -> Self {
544 pixels.0 as f64
545 }
546}
547
548#[derive(
549 Add,
550 AddAssign,
551 Clone,
552 Copy,
553 Debug,
554 Default,
555 Div,
556 Eq,
557 Hash,
558 Ord,
559 PartialEq,
560 PartialOrd,
561 Sub,
562 SubAssign,
563)]
564#[repr(transparent)]
565pub struct DevicePixels(pub(crate) u32);
566
567impl DevicePixels {
568 pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
569 self.0 * bytes_per_pixel as u32
570 }
571}
572
573unsafe impl bytemuck::Pod for DevicePixels {}
574unsafe impl bytemuck::Zeroable for DevicePixels {}
575
576impl From<DevicePixels> for u32 {
577 fn from(device_pixels: DevicePixels) -> Self {
578 device_pixels.0
579 }
580}
581
582impl From<u32> for DevicePixels {
583 fn from(val: u32) -> Self {
584 DevicePixels(val)
585 }
586}
587
588impl From<DevicePixels> for u64 {
589 fn from(device_pixels: DevicePixels) -> Self {
590 device_pixels.0 as u64
591 }
592}
593
594impl From<u64> for DevicePixels {
595 fn from(val: u64) -> Self {
596 DevicePixels(val as u32)
597 }
598}
599
600#[derive(Clone, Copy, Default, Add, Sub, Mul, Div)]
601pub struct Rems(f32);
602
603impl Mul<Pixels> for Rems {
604 type Output = Pixels;
605
606 fn mul(self, other: Pixels) -> Pixels {
607 Pixels(self.0 * other.0)
608 }
609}
610
611impl Debug for Rems {
612 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
613 write!(f, "{} rem", self.0)
614 }
615}
616
617#[derive(Clone, Copy, Debug)]
618pub enum AbsoluteLength {
619 Pixels(Pixels),
620 Rems(Rems),
621}
622
623impl AbsoluteLength {
624 pub fn is_zero(&self) -> bool {
625 match self {
626 AbsoluteLength::Pixels(px) => px.0 == 0.,
627 AbsoluteLength::Rems(rems) => rems.0 == 0.,
628 }
629 }
630}
631
632impl From<Pixels> for AbsoluteLength {
633 fn from(pixels: Pixels) -> Self {
634 AbsoluteLength::Pixels(pixels)
635 }
636}
637
638impl From<Rems> for AbsoluteLength {
639 fn from(rems: Rems) -> Self {
640 AbsoluteLength::Rems(rems)
641 }
642}
643
644impl AbsoluteLength {
645 pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
646 match self {
647 AbsoluteLength::Pixels(pixels) => *pixels,
648 AbsoluteLength::Rems(rems) => *rems * rem_size,
649 }
650 }
651}
652
653impl Default for AbsoluteLength {
654 fn default() -> Self {
655 px(0.).into()
656 }
657}
658
659/// A non-auto length that can be defined in pixels, rems, or percent of parent.
660#[derive(Clone, Copy)]
661pub enum DefiniteLength {
662 Absolute(AbsoluteLength),
663 /// A fraction of the parent's size between 0 and 1.
664 Fraction(f32),
665}
666
667impl DefiniteLength {
668 pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
669 match self {
670 DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
671 DefiniteLength::Fraction(fraction) => match base_size {
672 AbsoluteLength::Pixels(px) => px * *fraction,
673 AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
674 },
675 }
676 }
677}
678
679impl Debug for DefiniteLength {
680 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
681 match self {
682 DefiniteLength::Absolute(length) => Debug::fmt(length, f),
683 DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
684 }
685 }
686}
687
688impl From<Pixels> for DefiniteLength {
689 fn from(pixels: Pixels) -> Self {
690 Self::Absolute(pixels.into())
691 }
692}
693
694impl From<Rems> for DefiniteLength {
695 fn from(rems: Rems) -> Self {
696 Self::Absolute(rems.into())
697 }
698}
699
700impl From<AbsoluteLength> for DefiniteLength {
701 fn from(length: AbsoluteLength) -> Self {
702 Self::Absolute(length)
703 }
704}
705
706impl Default for DefiniteLength {
707 fn default() -> Self {
708 Self::Absolute(AbsoluteLength::default())
709 }
710}
711
712/// A length that can be defined in pixels, rems, percent of parent, or auto.
713#[derive(Clone, Copy)]
714pub enum Length {
715 Definite(DefiniteLength),
716 Auto,
717}
718
719impl Debug for Length {
720 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
721 match self {
722 Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
723 Length::Auto => write!(f, "auto"),
724 }
725 }
726}
727
728pub fn relative(fraction: f32) -> DefiniteLength {
729 DefiniteLength::Fraction(fraction).into()
730}
731
732/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
733pub fn phi() -> DefiniteLength {
734 relative(1.61803398875)
735}
736
737pub fn rems(rems: f32) -> Rems {
738 Rems(rems)
739}
740
741pub fn px(pixels: f32) -> Pixels {
742 Pixels(pixels)
743}
744
745pub fn auto() -> Length {
746 Length::Auto
747}
748
749impl From<Pixels> for Length {
750 fn from(pixels: Pixels) -> Self {
751 Self::Definite(pixels.into())
752 }
753}
754
755impl From<Rems> for Length {
756 fn from(rems: Rems) -> Self {
757 Self::Definite(rems.into())
758 }
759}
760
761impl From<DefiniteLength> for Length {
762 fn from(length: DefiniteLength) -> Self {
763 Self::Definite(length)
764 }
765}
766
767impl From<AbsoluteLength> for Length {
768 fn from(length: AbsoluteLength) -> Self {
769 Self::Definite(length.into())
770 }
771}
772
773impl Default for Length {
774 fn default() -> Self {
775 Self::Definite(DefiniteLength::default())
776 }
777}
778
779impl From<()> for Length {
780 fn from(_: ()) -> Self {
781 Self::Definite(DefiniteLength::default())
782 }
783}