agg_rust/
span_interpolator_trans.rs1use crate::basics::iround;
8use crate::span_interpolator_linear::{SpanInterpolator, Transformer};
9
10const SUBPIXEL_SHIFT: u32 = 8;
12const SUBPIXEL_SCALE: i32 = 1 << SUBPIXEL_SHIFT;
13
14pub struct SpanInterpolatorTrans<T: Transformer> {
26 trans: T,
27 x: f64,
28 y: f64,
29 ix: i32,
30 iy: i32,
31}
32
33impl<T: Transformer> SpanInterpolatorTrans<T> {
34 pub fn new(trans: T) -> Self {
35 Self {
36 trans,
37 x: 0.0,
38 y: 0.0,
39 ix: 0,
40 iy: 0,
41 }
42 }
43
44 pub fn new_begin(trans: T, x: f64, y: f64, len: u32) -> Self {
45 let mut s = Self::new(trans);
46 s.begin(x, y, len);
47 s
48 }
49
50 pub fn transformer(&self) -> &T {
51 &self.trans
52 }
53
54 pub fn set_transformer(&mut self, trans: T) {
55 self.trans = trans;
56 }
57
58 pub fn begin(&mut self, x: f64, y: f64, _len: u32) {
60 self.x = x;
61 self.y = y;
62 let mut tx = x;
63 let mut ty = y;
64 self.trans.transform(&mut tx, &mut ty);
65 self.ix = iround(tx * SUBPIXEL_SCALE as f64);
66 self.iy = iround(ty * SUBPIXEL_SCALE as f64);
67 }
68
69 #[inline]
71 pub fn next(&mut self) {
72 self.x += 1.0;
73 let mut tx = self.x;
74 let mut ty = self.y;
75 self.trans.transform(&mut tx, &mut ty);
76 self.ix = iround(tx * SUBPIXEL_SCALE as f64);
77 self.iy = iround(ty * SUBPIXEL_SCALE as f64);
78 }
79
80 #[inline]
82 pub fn coordinates(&self, x: &mut i32, y: &mut i32) {
83 *x = self.ix;
84 *y = self.iy;
85 }
86}
87
88impl<T: Transformer> SpanInterpolator for SpanInterpolatorTrans<T> {
89 fn begin(&mut self, x: f64, y: f64, len: u32) {
90 self.begin(x, y, len);
91 }
92 fn next(&mut self) {
93 self.next();
94 }
95 fn coordinates(&self, x: &mut i32, y: &mut i32) {
96 self.coordinates(x, y);
97 }
98}
99
100#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::trans_affine::TransAffine;
108
109 #[test]
110 fn test_identity_transform() {
111 let trans = TransAffine::new();
112 let mut interp = SpanInterpolatorTrans::new(trans);
113 interp.begin(10.0, 20.0, 5);
114
115 let mut x = 0i32;
116 let mut y = 0i32;
117 interp.coordinates(&mut x, &mut y);
118 assert_eq!(x, 2560);
120 assert_eq!(y, 5120);
121 }
122
123 #[test]
124 fn test_next_increments_x() {
125 let trans = TransAffine::new();
126 let mut interp = SpanInterpolatorTrans::new(trans);
127 interp.begin(5.0, 3.0, 10);
128
129 let mut x = 0i32;
130 let mut y = 0i32;
131 interp.coordinates(&mut x, &mut y);
132 assert_eq!(x, 5 * 256);
133 assert_eq!(y, 3 * 256);
134
135 interp.next();
136 interp.coordinates(&mut x, &mut y);
137 assert_eq!(x, 6 * 256);
138 assert_eq!(y, 3 * 256);
139 }
140
141 #[test]
142 fn test_with_translation() {
143 let trans = TransAffine::new_translation(10.0, 20.0);
144 let mut interp = SpanInterpolatorTrans::new(trans);
145 interp.begin(0.0, 0.0, 1);
146
147 let mut x = 0i32;
148 let mut y = 0i32;
149 interp.coordinates(&mut x, &mut y);
150 assert_eq!(x, 10 * 256);
151 assert_eq!(y, 20 * 256);
152 }
153
154 #[test]
155 fn test_with_scaling() {
156 let trans = TransAffine::new_scaling(2.0, 3.0);
157 let mut interp = SpanInterpolatorTrans::new(trans);
158 interp.begin(5.0, 4.0, 1);
159
160 let mut x = 0i32;
161 let mut y = 0i32;
162 interp.coordinates(&mut x, &mut y);
163 assert_eq!(x, 10 * 256);
164 assert_eq!(y, 12 * 256);
165 }
166
167 #[test]
168 fn test_new_begin() {
169 let trans = TransAffine::new();
170 let interp = SpanInterpolatorTrans::new_begin(trans, 1.0, 2.0, 5);
171 let mut x = 0i32;
172 let mut y = 0i32;
173 interp.coordinates(&mut x, &mut y);
174 assert_eq!(x, 256);
175 assert_eq!(y, 512);
176 }
177}