agg_rust/
span_interpolator_adaptor.rs1use crate::span_interpolator_linear::SpanInterpolator;
8
9pub trait Distortion {
13 fn calculate(&self, x: &mut i32, y: &mut i32);
14}
15
16pub struct SpanInterpolatorAdaptor<Interp, Dist> {
22 interp: Interp,
23 distortion: Dist,
24}
25
26impl<Interp: SpanInterpolator, Dist: Distortion> SpanInterpolatorAdaptor<Interp, Dist> {
27 pub fn new(interp: Interp, distortion: Dist) -> Self {
28 Self { interp, distortion }
29 }
30
31 pub fn interpolator(&self) -> &Interp {
32 &self.interp
33 }
34
35 pub fn interpolator_mut(&mut self) -> &mut Interp {
36 &mut self.interp
37 }
38
39 pub fn distortion(&self) -> &Dist {
40 &self.distortion
41 }
42
43 pub fn distortion_mut(&mut self) -> &mut Dist {
44 &mut self.distortion
45 }
46}
47
48impl<Interp: SpanInterpolator, Dist: Distortion> SpanInterpolator
49 for SpanInterpolatorAdaptor<Interp, Dist>
50{
51 fn begin(&mut self, x: f64, y: f64, len: u32) {
52 self.interp.begin(x, y, len);
53 }
54
55 fn next(&mut self) {
56 self.interp.next();
57 }
58
59 fn coordinates(&self, x: &mut i32, y: &mut i32) {
60 self.interp.coordinates(x, y);
61 self.distortion.calculate(x, y);
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use super::*;
68 use crate::span_interpolator_linear::{SpanInterpolatorLinear, SUBPIXEL_SCALE};
69 use crate::trans_affine::TransAffine;
70
71 struct OffsetDistortion {
73 dx: i32,
74 dy: i32,
75 }
76
77 impl Distortion for OffsetDistortion {
78 fn calculate(&self, x: &mut i32, y: &mut i32) {
79 *x += self.dx;
80 *y += self.dy;
81 }
82 }
83
84 #[test]
85 fn test_identity_with_offset_distortion() {
86 let trans = TransAffine::new();
87 let interp = SpanInterpolatorLinear::new(trans);
88 let dist = OffsetDistortion {
89 dx: 10 * SUBPIXEL_SCALE,
90 dy: 20 * SUBPIXEL_SCALE,
91 };
92 let mut adaptor = SpanInterpolatorAdaptor::new(interp, dist);
93
94 adaptor.begin(5.0, 5.0, 1);
95 let (mut x, mut y) = (0, 0);
96 adaptor.coordinates(&mut x, &mut y);
97
98 assert_eq!(x, 5 * SUBPIXEL_SCALE + 10 * SUBPIXEL_SCALE);
100 assert_eq!(y, 5 * SUBPIXEL_SCALE + 20 * SUBPIXEL_SCALE);
101 }
102
103 #[test]
104 fn test_zero_distortion_passthrough() {
105 let trans = TransAffine::new();
106 let interp = SpanInterpolatorLinear::new(trans);
107 let dist = OffsetDistortion { dx: 0, dy: 0 };
108 let mut adaptor = SpanInterpolatorAdaptor::new(interp, dist);
109
110 adaptor.begin(10.0, 20.0, 1);
111 let (mut x, mut y) = (0, 0);
112 adaptor.coordinates(&mut x, &mut y);
113
114 let trans2 = TransAffine::new();
116 let mut interp2 = SpanInterpolatorLinear::new(trans2);
117 interp2.begin(10.0, 20.0, 1);
118 let (mut x2, mut y2) = (0, 0);
119 interp2.coordinates(&mut x2, &mut y2);
120
121 assert_eq!(x, x2);
122 assert_eq!(y, y2);
123 }
124
125 struct WaveDistortion {
127 amplitude: i32,
128 }
129
130 impl Distortion for WaveDistortion {
131 fn calculate(&self, _x: &mut i32, y: &mut i32) {
132 *y += self.amplitude;
133 }
134 }
135
136 #[test]
137 fn test_wave_distortion() {
138 let trans = TransAffine::new();
139 let interp = SpanInterpolatorLinear::new(trans);
140 let dist = WaveDistortion { amplitude: 100 };
141 let mut adaptor = SpanInterpolatorAdaptor::new(interp, dist);
142
143 adaptor.begin(0.0, 0.0, 5);
144 let (mut x, mut y) = (0, 0);
145 adaptor.coordinates(&mut x, &mut y);
146 assert_eq!(y, 100); }
148}