1use crate::{
4 math::{abs_transform, get_scale, identity, Matrix2d, Scalar, Vec2d},
5 DrawState, Viewport,
6};
7
8#[derive(Copy, Clone)]
10pub struct Context {
11 pub viewport: Option<Viewport>,
13 pub view: Matrix2d,
15 pub transform: Matrix2d,
17 pub draw_state: DrawState,
19}
20
21impl Context {
22 #[inline(always)]
24 pub fn new() -> Context {
25 Context {
26 view: identity(),
27 transform: identity(),
28 draw_state: Default::default(),
29 viewport: None,
30 }
31 }
32
33 #[inline(always)]
44 pub fn new_viewport(viewport: Viewport) -> Context {
45 let mat = viewport.abs_transform();
46 Context {
47 view: mat,
48 transform: mat,
49 draw_state: Default::default(),
50 viewport: Some(viewport),
51 }
52 }
53
54 #[inline(always)]
65 pub fn new_abs(w: Scalar, h: Scalar) -> Context {
66 let mat = abs_transform(w, h);
67 Context {
68 view: mat,
69 transform: mat,
70 draw_state: Default::default(),
71 viewport: None,
72 }
73 }
74
75 #[inline(always)]
81 pub fn view(mut self) -> Self {
82 self.transform = self.view;
83 self
84 }
85
86 #[inline(always)]
92 pub fn reset(mut self) -> Self {
93 self.transform = identity();
94 self
95 }
96
97 #[inline(always)]
99 pub fn store_view(mut self) -> Self {
100 self.view = self.transform;
101 self
102 }
103
104 #[inline(always)]
106 pub fn get_view_size(&self) -> Vec2d {
107 let scale = get_scale(self.view);
108 [2.0 / scale[0], 2.0 / scale[1]]
109 }
110}
111
112impl Default for Context {
113 fn default() -> Context {
114 Context::new()
115 }
116}
117
118#[cfg(test)]
119mod test {
120 use super::Context;
121
122 #[test]
123 fn test_context() {
124 use crate::Transformed;
125
126 let c = Context::new();
127 {
128 let d = c.trans(20.0, 40.0);
129 let d = d.trans(10.0, 10.0);
130 let transform = d.transform;
131 assert_eq!(transform[0][2], 30.0);
132 assert_eq!(transform[1][2], 50.0);
133 }
134
135 let transform = c.transform;
136 assert_eq!(transform[0][2], 0.0);
137 assert_eq!(transform[1][2], 0.0);
138
139 let c = c.rot_deg(90.0);
140 let transform = c.transform;
141 assert!((transform[0][0] - 0.0).abs() < 0.00001);
142 assert!((transform[0][1] + 1.0).abs() < 0.00001);
143 }
144
145 #[test]
146 fn test_scale() {
147 use crate::Transformed;
148
149 let c = Context::new();
150 let c = c.scale(2.0, 3.0);
151 let transform = c.transform;
152 assert!((transform[0][0] - 2.0).abs() < 0.00001);
153 assert!((transform[1][1] - 3.0).abs() < 0.00001);
154 }
155}