From b66fb03b8fb538bdaca9fd09d38d480402d53079 Mon Sep 17 00:00:00 2001 From: Jakob Dalsgaard Date: Fri, 29 May 2020 23:26:43 +0200 Subject: [PATCH] Making a better secondary display --- Cargo.lock | 30 ++++++++++++++++++++++++++++++ src/forms.rs | 33 +++++++++++++++++++++++++++++++++ src/main.rs | 38 +++++++++++++++++++++++++------------- 3 files changed, 88 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a612efa..5e1325b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -184,6 +184,7 @@ dependencies = [ "imageproc", "rppal", "rusttype", + "serde_json", "text_io", "xml-rs", ] @@ -250,6 +251,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" + [[package]] name = "jpeg-decoder" version = "0.1.19" @@ -547,6 +554,12 @@ dependencies = [ "stb_truetype", ] +[[package]] +name = "ryu" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3d612bc64430efeb3f7ee6ef26d590dce0c43249217bddc62112540c7941e1" + [[package]] name = "scoped_threadpool" version = "0.1.9" @@ -559,6 +572,23 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "serde" +version = "1.0.110" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c" + +[[package]] +name = "serde_json" +version = "1.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "stb_truetype" version = "0.3.1" diff --git a/src/forms.rs b/src/forms.rs index 410ce22..87377cb 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -109,6 +109,39 @@ impl Screen { Screen { width, height, model_scale, image } } + pub fn text (&mut self, font: &Font, text: &str, scale: f32, x: u16, y: u16) { + let scale = rusttype::Scale { x: scale, y: scale }; + draw_text_mut(&mut self.image, Rgb([255, 255, 255]), x as u32, y as u32, scale, &font, text); + } + + /* + * put two lines of text over each other, centered, with a horisontal line en between... + */ + pub fn fraction (&mut self, font: &Font, nominator: &str, denominator: &str, scale: f32, x: u16, y: u16) { + let scale = rusttype::Scale { x: scale, y: scale }; + let vmetrics = font.v_metrics(scale); + let height = vmetrics.ascent - vmetrics.descent; + let nominator_layout_last_glyph = font.layout(nominator, scale, rusttype::Point:: { x: 0.0, y: 0.0 }).last().unwrap(); + let nominator_width = nominator_layout_last_glyph.pixel_bounding_box().unwrap().max.x; + let denominator_layout_last_glyph = font.layout(denominator, scale, rusttype::Point:: { x: 0.0, y: 0.0}).last().unwrap(); + let denominator_width = denominator_layout_last_glyph.pixel_bounding_box().unwrap().max.x; + let max_width = std::cmp::max(nominator_width, denominator_width); + draw_text_mut(&mut self.image, Rgb([255, 255, 255]), x as u32 + ((max_width - nominator_width)/2) as u32, y as u32, scale, &font, nominator); + draw_text_mut(&mut self.image, Rgb([255, 255, 255]), x as u32 + ((max_width - denominator_width)/2) as u32, y as u32 + (height as u32) + 1, scale, &font, denominator); + draw_line_segment_mut(&mut self.image, (x as f32, y as f32 + height + 1.0), (x as f32 + max_width as f32, y as f32 + height + 1.0), Rgb([225, 225, 225])); + println!("height is: {} width is: {}", height, nominator_width); + } + + /** + * Text, Right Justified at x + */ + pub fn text_rj (&mut self, font: &Font, text: &str, scale: f32, x: u16, y: u16) { + let scale = rusttype::Scale { x: scale, y: scale }; + let last_glyph = font.layout (text, scale, rusttype::Point:: { x: 0.0, y: 0.0 }).last().unwrap(); + let width = last_glyph.pixel_bounding_box().unwrap().max.x; + draw_text_mut(&mut self.image, Rgb([255, 255, 255]), x as u32 - width as u32, y as u32, scale, &font, text); + } + pub fn render (&mut self, form: &Form, angle: f32, x: u16, y: u16) { let transform : Transform2D = Transform2D::create_rotation(Angle::radians(angle)).post_translate(Vector2D::new(500.0, 500.0)); let tx_points = form.points.iter().map(|p| transform.transform_point(*p)).collect::>(); diff --git a/src/main.rs b/src/main.rs index 81d868a..4c043e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,8 +18,11 @@ mod forms; fn main() -> Result<(), Box> { - let mut screen = forms::Screen::new(200, 200); + let mut course_screen = forms::Screen::new(200, 200); + let mut navigation_screen = forms::Screen::new(160,320); + let mut loader = forms::Loader::new("/root/helms-display".to_string()); + let c = loader.load_form("compass-rose.svg").unwrap(); let b = loader.load_form("boat.svg").unwrap(); let cog = loader.load_form("cog.svg").unwrap(); @@ -37,20 +40,29 @@ fn main() -> Result<(), Box> { let mut e = ilidisplay::IliDisplay::init()?; e.init_chip(); e.turn_on(); - for i in 0..10 { - let rad = (i as f32) * 2.0*PI / 100.0; - screen.clear(); - screen.render(&cog, -rad*2.0, 500, 500); - screen.render(&wind, rad*2.0, 500, 500); - screen.render(&c, rad, 500, 500); - screen.render(&b, 0.0, 500, 500); - e.put_image(&(screen.image), ((240-100), (160-100))); - } - screen.save(); + - // draw_filled_rect_mut(&mut img, Rect::at(0,0).of_size(480, 320), Rgb([0, 0, 0])); + course_screen.clear(); + let rad = (6 as f32) * 2.0*PI / 100.0; + course_screen.clear(); + course_screen.render(&cog, -rad*2.0, 500, 500); + course_screen.render(&wind, rad*2.0, 500, 500); + course_screen.render(&c, rad, 500, 500); + course_screen.render(&b, 0.0, 500, 500); + e.put_image(&(course_screen.image), (160, (160-100))); + + navigation_screen.clear(); + navigation_screen.text(&font, "SOG", 32.0, 5, 5); + navigation_screen.text(&font, "speed over ground", 12.0, 5, 38); + let speed_over_ground = 5.0; // in m/s + let speed_over_ground = speed_over_ground * 1.9438612860586; // now in nautic miles per hour + navigation_screen.text_rj(&font, &format!("{:.1}", speed_over_ground).as_str(), 32.0, 138, 5); + navigation_screen.fraction(&font, "nm", "h", 14.0, 140, 6); + e.put_image(&(navigation_screen.image), (0, 0)); + + navigation_screen.save(); - println!("You should see image now, sleeping for 5s"); + println!("Display has been rendered now, sleeping for 5s"); thread::sleep(Duration::from_millis(5000)); e.turn_off(); Ok(())