symcode/acute32/
alphabet.rs1use visioncortex::{BinaryImage, BoundingRect, PointI32};
2use crate::acute32::{Acute32SymcodeConfig, valid_pointi32_on_image};
3use super::Acute32Library;
4
5pub struct AlphabetReader;
6
7pub struct AlphabetReaderParams {
8 pub(crate) top_left: PointI32,
10 pub(crate) symbol_width: usize,
11 pub(crate) symbol_height: usize,
12 pub(crate) offset_x: f64,
13 pub(crate) offset_y: f64,
14 pub(crate) num_columns: usize,
15 pub(crate) num_rows: usize,
16}
17
18impl Default for AlphabetReaderParams {
19 fn default() -> Self {
20 Self {
21 top_left: PointI32::new(100, 100),
22 symbol_width: 155,
23 symbol_height: 155,
24 offset_x: 155.0*1.5,
25 offset_y: 155.0*1.5,
26 num_columns: 4,
27 num_rows: 8,
28 }
29 }
30}
31
32impl AlphabetReaderParams {
33 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn top_left(mut self, x: i32, y: i32) -> Self {
38 self.top_left = PointI32::new(x, y);
39 self
40 }
41
42 pub fn symbol_size(mut self, width: usize, height: usize) -> Self {
43 self.symbol_width = width;
44 self.symbol_height = height;
45 self
46 }
47
48 pub fn offset(mut self, x: f64, y: f64) -> Self {
49 self.offset_x = x;
50 self.offset_y = y;
51 self
52 }
53
54 pub fn matrix_size(mut self, num_columns: usize, num_rows: usize) -> Self {
55 self.num_columns = num_columns;
56 self.num_rows = num_rows;
57 self
58 }
59}
60
61impl AlphabetReader {
62 pub fn read_alphabet_to_library(image: BinaryImage, params: AlphabetReaderParams, symcode_config: &Acute32SymcodeConfig) -> Result<Acute32Library, &'static str> {
63 let mut library = Acute32Library::default();
64 symcode_config.debugger.render_binary_image_to_canvas(&image)?;
65 for i in 0..params.num_rows {
66 for j in 0..params.num_columns {
67 let offset = PointI32::new((j as f64 * params.offset_x) as i32, (i as f64 * params.offset_y) as i32);
68 let top_left = params.top_left + offset;
69 let rect = BoundingRect::new_x_y_w_h(top_left.x, top_left.y, params.symbol_width as i32, params.symbol_height as i32);
70 symcode_config.debugger.render_bounding_rect_to_canvas(&rect);
71 if !valid_pointi32_on_image(top_left, image.width, image.height) || !valid_pointi32_on_image(PointI32::new(rect.right, rect.bottom), image.width, image.height) {
72 return Err("AlphabetReader error: trying to crop out of image bound.");
73 }
74
75 let glyph_image = image.crop_with_rect(rect);
76 library.add_template(glyph_image, symcode_config);
77 }
78 }
79 Ok(library)
81 }
82}