agg_rust/
span_pattern_rgba.rs1use crate::color::Rgba8;
8use crate::image_accessors::ImageSource;
9use crate::renderer_scanline::SpanGenerator;
10
11pub struct SpanPatternRgba<Src> {
17 src: Src,
18 offset_x: u32,
19 offset_y: u32,
20}
21
22impl<Src: ImageSource> SpanPatternRgba<Src> {
23 pub fn new(src: Src, offset_x: u32, offset_y: u32) -> Self {
24 Self {
25 src,
26 offset_x,
27 offset_y,
28 }
29 }
30
31 pub fn source(&self) -> &Src {
32 &self.src
33 }
34
35 pub fn source_mut(&mut self) -> &mut Src {
36 &mut self.src
37 }
38
39 pub fn offset_x(&self) -> u32 {
40 self.offset_x
41 }
42
43 pub fn set_offset_x(&mut self, v: u32) {
44 self.offset_x = v;
45 }
46
47 pub fn offset_y(&self) -> u32 {
48 self.offset_y
49 }
50
51 pub fn set_offset_y(&mut self, v: u32) {
52 self.offset_y = v;
53 }
54}
55
56impl<Src: ImageSource> SpanGenerator for SpanPatternRgba<Src> {
57 type Color = Rgba8;
58
59 fn prepare(&mut self) {}
60
61 fn generate(&mut self, span: &mut [Rgba8], x: i32, y: i32, len: u32) {
62 let sx = x + self.offset_x as i32;
63 let sy = y + self.offset_y as i32;
64
65 let p = self.src.span(sx, sy, len);
66 span[0] = Rgba8::new(p[0] as u32, p[1] as u32, p[2] as u32, p[3] as u32);
67
68 for i in 1..len as usize {
69 let p = self.src.next_x();
70 span[i] = Rgba8::new(p[0] as u32, p[1] as u32, p[2] as u32, p[3] as u32);
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 struct ConstantSource {
81 pixel: [u8; 4],
82 }
83
84 impl ImageSource for ConstantSource {
85 fn span(&mut self, _x: i32, _y: i32, _len: u32) -> &[u8] {
86 &self.pixel
87 }
88
89 fn next_x(&mut self) -> &[u8] {
90 &self.pixel
91 }
92
93 fn next_y(&mut self) -> &[u8] {
94 &self.pixel
95 }
96 }
97
98 #[test]
99 fn test_constant_pattern() {
100 let src = ConstantSource {
101 pixel: [255, 0, 0, 255],
102 };
103 let mut pattern = SpanPatternRgba::new(src, 0, 0);
104 pattern.prepare();
105
106 let mut span = vec![Rgba8::new(0, 0, 0, 0); 5];
107 pattern.generate(&mut span, 0, 0, 5);
108
109 for c in &span {
110 assert_eq!(c.r, 255);
111 assert_eq!(c.g, 0);
112 assert_eq!(c.b, 0);
113 assert_eq!(c.a, 255);
114 }
115 }
116
117 #[test]
118 fn test_offset() {
119 let src = ConstantSource {
120 pixel: [128, 128, 128, 255],
121 };
122 let mut pattern = SpanPatternRgba::new(src, 10, 20);
123 assert_eq!(pattern.offset_x(), 10);
124 assert_eq!(pattern.offset_y(), 20);
125
126 pattern.set_offset_x(5);
127 pattern.set_offset_y(15);
128 assert_eq!(pattern.offset_x(), 5);
129 assert_eq!(pattern.offset_y(), 15);
130 }
131}