1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Geometric type definitions, such as `Point`, `Rect` and `Size`

use std::f32;

use euclid;
use rusttype;
use webrender::api::*;

/// This is the unit used for all geometric types that represent a position on screen,
/// independent of the device's hidpi factor, or "Device Pixel Ratio".
/// Sometimes known as 'points', logical pixels or device independent pixels,
///
/// `DensityIndependentPixel` is an alias to a webrender `LayerPixel` to simplify
/// integration, but doesn't imply that the reference frame is a layer. Positions
/// should generally be relative to the window, where the origin is the top left,
/// and x and y values increase moving down and to the right.
pub type DensityIndependentPixel = LayerPixel;

pub type Size = euclid::TypedSize2D<f32, DensityIndependentPixel>;
pub type Point = euclid::TypedPoint2D<f32, DensityIndependentPixel>;
pub type Vector = euclid::TypedVector2D<f32, DensityIndependentPixel>;
pub type Rect = euclid::TypedRect<f32, DensityIndependentPixel>;

/// This is the unit of actual pixels in the framebuffer.
/// Multiply by the windows hidpi factor to get `DensityIndependentPixel`s
pub use webrender::api::DevicePixel;

/// Extension trait for rectangles.
/// Helper methods for rectangle sides depend on the assumption that `Rect`
/// size never contains negative values.
pub trait RectExt<T> {
    fn from_rusttype<S: Into<T>>(rect: rusttype::Rect<S>) -> Self;
    fn to_slice(&self) -> [T; 4];
    fn left(&self) -> T;
    fn top(&self) -> T;
    fn right(&self) -> T;
    fn bottom(&self) -> T;
    fn width(&self) -> T;
    fn height(&self) -> T;
    fn center(&self) -> Point;
    fn shrink_bounds(&self, size: T) -> Self;
}
impl RectExt<f32> for Rect {
    fn from_rusttype<S: Into<f32>>(rect: rusttype::Rect<S>) -> Self {
        let origin = Point::new(rect.min.x.into(), rect.min.y.into());
        let size = Size::new(rect.max.x.into() - origin.x, rect.max.y.into() - origin.y);
        Rect::new(origin, size)
    }
    fn to_slice(&self) -> [f32; 4] {
        [self.left(), self.top(), self.width(), self.height()]
    }
    fn left(&self) -> f32 {
        self.origin.x
    }
    fn top(&self) -> f32 {
        self.origin.y
    }
    fn right(&self) -> f32 {
        self.origin.x + self.size.width
    }
    fn bottom(&self) -> f32 {
        self.origin.y + self.size.height
    }
    fn width(&self) -> f32 {
        self.size.width
    }
    fn height(&self) -> f32 {
        self.size.height
    }
    fn center(&self) -> Point {
        Point::new(self.left() + self.width() / 2.0, self.top() + self.height() / 2.0)
    }
    fn shrink_bounds(&self, size: f32) -> Self {
        Rect::new(
            Point::new(self.origin.x + size / 2.0, self.origin.y + size / 2.0),
            Size::new(self.size.width - size, self.size.height - size))
    }
}

/// Extension trait for sizes.
pub trait SizeExt<T> {
    fn from_array(size: [u32; 2]) -> Self;
    fn from_tuple(size: (u32, u32)) -> Self;
}

impl SizeExt<f32> for Size {
    fn from_array(size: [u32; 2]) -> Self {
        Size::new(size[0] as f32, size[1] as f32)
    }
    fn from_tuple(size: (u32, u32)) -> Self {
        Size::new(size.0 as f32, size.1 as f32)
    }
}