1use imgref::ImgVec;
2
3pub const DOT_SRC_WIDTH: usize = 557;
5pub const DOT_HPIXELSPAN: usize = 25;
6pub const DOT_NUM_STRIPS: usize = DOT_HPIXELSPAN;
7pub const DOT_HCENTER: usize = (DOT_HPIXELSPAN - 1) / 2; pub const DOT_STRIP_HEIGHT: usize = 11;
9pub const DOT_VCENTER: usize = (DOT_STRIP_HEIGHT - 1) / 2; pub const DOT_SRC_HEIGHT: usize = DOT_NUM_STRIPS * DOT_STRIP_HEIGHT; pub const DOT_DST_WIDTH: usize = DOT_SRC_WIDTH - 2; pub const DOT_DST_HEIGHT: usize = DOT_SRC_HEIGHT; pub const LINE_SRC_WIDTH: usize = 15;
17pub const LINE_SRC_HEIGHT: usize = 15;
18pub const LINE_DST_WIDTH: usize = 555;
19pub const LINE_DST_HEIGHT: usize = LINE_SRC_HEIGHT; pub const DARK: u8 = 50;
22pub const BRIGHT: u8 = 250;
23
24pub fn generate_dot_pattern() -> ImgVec<u8> {
27 let mut pixels = vec![DARK; DOT_SRC_WIDTH * DOT_SRC_HEIGHT];
28
29 for j in 0..DOT_SRC_HEIGHT {
30 let strip = j / DOT_STRIP_HEIGHT;
31 let strip_row = j % DOT_STRIP_HEIGHT;
32
33 if strip_row != DOT_VCENTER {
34 continue;
35 }
36
37 for i in DOT_HCENTER..(DOT_SRC_WIDTH - DOT_HCENTER) {
38 if i >= strip && (i - strip) % DOT_HPIXELSPAN == DOT_HCENTER {
43 pixels[j * DOT_SRC_WIDTH + i] = BRIGHT;
44 }
45 }
46 }
47
48 ImgVec::new(pixels, DOT_SRC_WIDTH, DOT_SRC_HEIGHT)
49}
50
51pub fn generate_line_pattern() -> ImgVec<u8> {
54 let middle = LINE_SRC_WIDTH / 2; let mut pixels = vec![DARK; LINE_SRC_WIDTH * LINE_SRC_HEIGHT];
56
57 for y in 0..LINE_SRC_HEIGHT {
58 pixels[y * LINE_SRC_WIDTH + middle] = BRIGHT;
59 }
60
61 ImgVec::new(pixels, LINE_SRC_WIDTH, LINE_SRC_HEIGHT)
62}
63
64pub fn generate_edge_pattern() -> ImgVec<u8> {
67 let mut pixels = vec![DARK; LINE_SRC_WIDTH * LINE_SRC_HEIGHT];
68
69 for y in 0..LINE_SRC_HEIGHT {
70 pixels[y * LINE_SRC_WIDTH + 1] = BRIGHT;
71 }
72
73 ImgVec::new(pixels, LINE_SRC_WIDTH, LINE_SRC_HEIGHT)
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn dot_pattern_dimensions() {
82 let img = generate_dot_pattern();
83 assert_eq!(img.width(), DOT_SRC_WIDTH);
84 assert_eq!(img.height(), DOT_SRC_HEIGHT);
85 }
86
87 #[test]
88 fn dot_pattern_has_bright_pixels() {
89 let img = generate_dot_pattern();
90 let bright_count = img.buf().iter().filter(|&&v| v == BRIGHT).count();
91 assert!(bright_count > 500, "only {bright_count} bright pixels");
94 assert!(
95 bright_count < 600,
96 "{bright_count} bright pixels (too many)"
97 );
98 }
99
100 #[test]
101 fn dot_pattern_center_row_of_strip0() {
102 let img = generate_dot_pattern();
103 let row = &img.buf()[DOT_VCENTER * DOT_SRC_WIDTH..][..DOT_SRC_WIDTH];
105 assert_eq!(row[DOT_HCENTER], BRIGHT);
107 assert_eq!(row[DOT_HCENTER - 1], DARK);
108 assert_eq!(row[DOT_HCENTER + 1], DARK);
109 assert_eq!(row[DOT_HCENTER + DOT_HPIXELSPAN], BRIGHT);
111 }
112
113 #[test]
114 fn line_pattern_dimensions() {
115 let img = generate_line_pattern();
116 assert_eq!(img.width(), LINE_SRC_WIDTH);
117 assert_eq!(img.height(), LINE_SRC_HEIGHT);
118 }
119
120 #[test]
121 fn line_pattern_center_column() {
122 let img = generate_line_pattern();
123 for y in 0..LINE_SRC_HEIGHT {
124 for x in 0..LINE_SRC_WIDTH {
125 let expected = if x == 7 { BRIGHT } else { DARK };
126 assert_eq!(
127 img.buf()[y * LINE_SRC_WIDTH + x],
128 expected,
129 "mismatch at ({x}, {y})"
130 );
131 }
132 }
133 }
134
135 #[test]
136 fn edge_pattern_column_at_x1() {
137 let img = generate_edge_pattern();
138 for y in 0..LINE_SRC_HEIGHT {
139 assert_eq!(img.buf()[y * LINE_SRC_WIDTH], DARK);
140 assert_eq!(img.buf()[y * LINE_SRC_WIDTH + 1], BRIGHT);
141 assert_eq!(img.buf()[y * LINE_SRC_WIDTH + 2], DARK);
142 }
143 }
144}