diff --git a/Cargo.lock b/Cargo.lock index 2874ff3..cbbc835 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "366ffbaa4442f4684d91e2cd7c5ea7c4ed8add41959a31447066e279e432b618" +dependencies = [ + "libm", +] + [[package]] name = "allocator-api2" version = "0.3.1" @@ -594,7 +603,9 @@ dependencies = [ "esp-bootloader-esp-idf", "esp-hal", "esp-println", + "libm", "log", + "rusttype", ] [[package]] @@ -826,6 +837,12 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + [[package]] name = "linked_list_allocator" version = "0.10.6" @@ -874,6 +891,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "owned_ttf_parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e6affeb1632d6ff6a23d2cd40ffed138e82f1532571a26f527c8a284bb2fbb" +dependencies = [ + "ttf-parser", +] + [[package]] name = "paste" version = "1.0.15" @@ -1018,6 +1044,17 @@ dependencies = [ "svgbobdoc", ] +[[package]] +name = "rusttype" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff8374aa04134254b7995b63ad3dc41c7f7236f69528b28553da7d72efaa967" +dependencies = [ + "ab_glyph_rasterizer", + "libm", + "owned_ttf_parser", +] + [[package]] name = "rustversion" version = "1.0.22" @@ -1223,6 +1260,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "ttf-parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" + [[package]] name = "typenum" version = "1.20.0" diff --git a/Cargo.toml b/Cargo.toml index 727de0a..2555064 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ esp-bootloader-esp-idf = { version = "0.5.0", features = ["esp32", "log-04"] } log = "0.4.27" critical-section = "1.2.0" -esp-alloc = "0.10.0" +esp-alloc = { version = "0.10.0", features = ["esp32"] } esp-backtrace = { version = "0.19.0", features = [ "esp32", "panic-handler", @@ -20,6 +20,11 @@ esp-backtrace = { version = "0.19.0", features = [ ] } esp-println = { version = "0.17.0", features = ["esp32", "log-04"] } +# ttf-parser = {version = "^0.25.0", features = ["no-std-float"], default-features = false } +rusttype = {version = "^0.9.0", features = ["libm-math"], default-features = false } + +libm = "*" + # For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html [profile.dev] diff --git a/src/OpenSans_Condensed-Regular.ttf b/src/OpenSans_Condensed-Regular.ttf new file mode 100644 index 0000000..67a73b8 Binary files /dev/null and b/src/OpenSans_Condensed-Regular.ttf differ diff --git a/src/main.rs b/src/main.rs index c15617c..2635b36 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,8 +7,9 @@ )] #![deny(clippy::large_stack_frames)] -// use embedded_graphics::{pixelcolor::Rgb565, prelude::DrawTarget}; -// use embedded_hal_bus::spi::ExclusiveDevice; +use core::{hint::black_box, mem::MaybeUninit}; + +use alloc::vec::Vec; use esp_hal::{ clock::CpuClock, delay::Delay, @@ -19,16 +20,19 @@ use esp_hal::{ }; use esp_backtrace as _; -// use mipidsi::{Builder, interface::SpiInterface, models::ST7789}; +use rusttype::Font; use crate::display::{Color, Display, Position, Rgb565, SetAddressMode}; +use esp_alloc::HEAP; -// use crate::display::{Color, Display, Position, Rgb565, Rotation}; +use alloc::vec; extern crate alloc; mod display; +static OPEN_SANS: &'static [u8] = include_bytes!("./OpenSans_Condensed-Regular.ttf"); + // This creates a default app-descriptor required by the esp-idf bootloader. // For more information see: esp_bootloader_esp_idf::esp_app_desc!(); @@ -91,7 +95,7 @@ fn main() -> ! { }; display.init(SetAddressMode { - color_order: display::ColorOrder::Bgr, + color_order: display::ColorOrder::Rgb, ..Default::default() }); display.set_tearing(display::TearingMode::Off); @@ -102,24 +106,64 @@ fn main() -> ! { Rgb565::yellow().as_color(), ); - let test_delay = Delay::new(); + let font = Font::try_from_bytes(OPEN_SANS).unwrap(); + let glyph = font.glyph('a'); + const SCALE: u16 = 30; + let scale = rusttype::Scale { + x: SCALE as f32 * 2., + y: SCALE as f32, + }; + let v_metrics = font.v_metrics(scale); + let offset = rusttype::Point { + x: 0.0, + y: v_metrics.ascent, + }; + let glyphs = font + .layout("Hello world", scale, offset) + .collect::>(); - let mut color = 0; + let width = libm::ceil( + glyphs + .iter() + .rev() + .map(|g| g.position().x as f32 + g.unpositioned().h_metrics().advance_width) + .next() + .unwrap_or(0.0) as f64, + ) as usize; + + let mut pixel_data = vec![Rgb565::white(); SCALE as usize * width]; + + for g in glyphs { + if let Some(bb) = g.pixel_bounding_box() { + g.draw(|x, y, cov| { + let x = bb.min.x + x as i32; + let y = bb.min.y + y as i32; + if x >= 0 && y >= 0 && x < width as i32 && y < SCALE as i32 { + let col = 255 - (255. * cov) as u8; + pixel_data[(x + y * width as i32) as usize] = Rgb565(col, col, col); + } + }); + } + } + + display.set_window( + Position { x: 0, y: 0 }, + Position { + x: width as u16 - 1, + y: SCALE as u16 - 1, + }, + ); + display.write(display::Writeable::Data( + &pixel_data + .iter() + .flat_map(|p| p.as_color().bytes) + .collect::>(), + )); loop { let delay_start = Instant::now(); - log::info!("Hello world: {}", color); - - color = (color + 50) % 200; - - display.draw_rect( - Position::new(0, 0), - Position::new(240, 240), - Color { - bytes: [color, color], - }, - ); + log::info!("Hello world"); while delay_start.elapsed() < Duration::from_millis(100) {} // test_delay.delay_millis(1);