diff --git a/Cargo.lock b/Cargo.lock index f4c0650..a612efa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ dependencies = [ "image", "imageproc", "rppal", + "rusttype", "text_io", "xml-rs", ] diff --git a/Cargo.toml b/Cargo.toml index 73b65b5..9195b9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,6 @@ arrayref = "*" euclid = "*" xml-rs = "0.8" text_io = "0.1.8" +rusttype = "0.8.3" +serde_json = "*" diff --git a/media/forms/boat.svg b/media/boat.svg similarity index 100% rename from media/forms/boat.svg rename to media/boat.svg diff --git a/media/forms/compass-rose.svg b/media/compass-rose.svg similarity index 100% rename from media/forms/compass-rose.svg rename to media/compass-rose.svg diff --git a/src/forms.rs b/src/forms.rs index e9e2f06..410ce22 100644 --- a/src/forms.rs +++ b/src/forms.rs @@ -1,7 +1,7 @@ use std::cmp; use euclid::{Angle, Scale, Transform2D, Vector2D}; use image::{Rgb, RgbImage}; -use imageproc::drawing::draw_line_segment_mut; +use imageproc::drawing::{draw_line_segment_mut, draw_text_mut}; use std::str::FromStr; use std::f32; @@ -10,8 +10,11 @@ use std::error::Error; use std::fs::File; use std::io::BufReader; +use std::io::Read; +use std::fs; use xml::reader::{EventReader, XmlEvent}; use euclid::Point2D; +use rusttype::Font; use text_io::scan; @@ -25,6 +28,80 @@ pub struct Screen { pub image : RgbImage, } +pub struct Loader { + base_path: String, +} + +impl Loader { + pub fn new(base_path: String) -> Loader { + Loader { base_path } + } + + fn verify_path (&mut self, path: &str) -> bool { + if path.contains("/") { return false; } + if path.contains("..") { return false; } + return true; + } + + fn make_path (&mut self, path: &str) -> Option { + if self.verify_path(path) { + Some(format!("{}/{}", self.base_path, path)) + } else { + None + } + } + + fn make_file(&mut self, path: &str) -> Option { + let fullpath = match self.make_path(path) { + Some(p) => p, + None => return None, + }; + let metadata = match fs::metadata(&fullpath) { + Ok(m) => m, + Err(_) => return None, + }; + if !metadata.is_file() { return None }; + if metadata.len() > 10*1024*1024 { return None; }; + let file = match File::open(fullpath) { + Ok(file) => file, + Err(_) => return None, + }; + Some(file) + } + + + + pub fn load_font (&mut self, path: &str) -> Option { + let mut file = match self.make_file(path) { + Some(f) => f, + None => return None, + }; + let mut data = Vec::new(); + if file.read_to_end(&mut data).is_err() { + return None; + } + + let font = match Font::from_bytes(data) { + Ok(data) => data, + Err(_) => return None, + }; + Some(font) + } + + pub fn load_form(&mut self, path: &str) -> Option
{ + let mut file = match self.make_file(path) { + Some(f) => f, + None => return None, + }; + match Form::load(file) { + Ok(f) => Some(f), + Err(_) => None, + } + } + +} + + impl Screen { pub fn new (width: u32, height: u32) -> Screen { let image = RgbImage::new(width, height); @@ -48,11 +125,6 @@ impl Screen { } last = pn; } - /* - let p0 = screen_points[indices[0] as usize].to_tuple(); - let p1 = screen_points[indices[1] as usize].to_tuple(); - draw_line_segment_mut(&mut self.image, p0, p1, Rgb([*r, *g, *b])); - */ } } @@ -83,10 +155,9 @@ pub struct Form { impl Form { - pub fn load (filename: &str) -> Result> { - let file = File::open(filename)?; - let file = BufReader::new(file); - let parser = EventReader::new(file); + pub fn load (file: File) -> Result> { + let reader = BufReader::new(file); + let parser = EventReader::new(reader); let mut points = Vec::new(); // rust compiler will figure out types :-) neat let mut lines = Vec::new(); @@ -134,7 +205,7 @@ impl Form { } }, Err(e) => { - println!("Error parsing file '{}': {}", filename, e); + println!("Error parsing file {}", e); break; }, _ => {} @@ -145,23 +216,3 @@ impl Form { } -// load the compass rose -pub fn load_compass_rose () -> Form { - let form = Form::load("/root/forms/compass-rose.svg").unwrap(); - form -} - -pub fn load_boat () -> Form { - let form = Form::load("/root/forms/boat.svg").unwrap(); - form -} - -pub fn load_cog () -> Form { - let form = Form::load("/root/forms/cog.svg").unwrap(); - form -} - -pub fn load_wind () -> Form { - let form = Form::load("/root/forms/wind.svg").unwrap(); - form -} diff --git a/src/main.rs b/src/main.rs index d20d289..81d868a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,10 +19,12 @@ mod forms; fn main() -> Result<(), Box> { let mut screen = forms::Screen::new(200, 200); - let c = forms::load_compass_rose(); - let b = forms::load_boat(); - let cog = forms::load_cog(); - let wind = forms::load_wind(); + 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(); + let wind = loader.load_form("wind.svg").unwrap(); + let font = loader.load_font("font.ttf").unwrap(); /* let mut img = RgbImage::new(480, 320);