From e95b7dfd431ad417a6fcc5eea57baa1a1f7f35a1 Mon Sep 17 00:00:00 2001 From: xuanplus <107631981+xuanplus@users.noreply.github.com> Date: Sun, 28 Jan 2024 21:03:45 +0800 Subject: [PATCH] Update edition3/03/index.md enable it to print "Hello Rust!" on qemu --- .../edition-3/posts/03-screen-output/index.md | 79 +++++++++++++++++-- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/blog/content/edition-3/posts/03-screen-output/index.md b/blog/content/edition-3/posts/03-screen-output/index.md index e1a62a1de..172667e4e 100644 --- a/blog/content/edition-3/posts/03-screen-output/index.md +++ b/blog/content/edition-3/posts/03-screen-output/index.md @@ -157,6 +157,15 @@ pub struct Position { pub y: usize, } +impl From for Position { + fn from(value: Point) -> Self { + Self { + x: value.x as usize, + y: value.y as usize, + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Color { pub red: u8, @@ -312,27 +321,48 @@ Fortunately, there is the nice `no_std`-compatible [`embedded-graphics`] crate, ```rust ,hl_lines=3 // in kernel/src/framebuffer.rs +use embedded_graphics::geometry::Point; use embedded_graphics::pixelcolor::Rgb888; +use embedded_graphics::prelude::OriginDimensions; +use embedded_graphics::prelude::Pixel; +use embedded_graphics::prelude::Size; pub struct Display { - framebuffer: FrameBuffer, + framebuffer: &'static mut FrameBuffer, } impl Display { - pub fn new(framebuffer: FrameBuffer) -> Display { + pub fn new(framebuffer: &'static mut FrameBuffer) -> Display { Self { framebuffer } } - fn draw_pixel(&mut self, Pixel(coordinates, color): Pixel) { - // ignore any pixels that are out of bounds. + fn in_range(&mut self, point: Point) -> bool { let (width, height) = { let info = self.framebuffer.info(); (info.width, info.height) + }; + + if point.x < width as i32 && point.x > 0 && point.y < height as i32 && point.y > 0 { + true + } else { + false } + } - if let Ok((x @ 0..width, y @ 0..height)) = coordinates.try_into() { - let color = Color { red: color.r(), green: color.g(), blue: color.b()}; - set_pixel_in(&mut self.framebuffer, Position { x, y }, color); + pub fn clear(&mut self) { + self.framebuffer.buffer_mut().fill(0); + } + + fn draw_pixel(&mut self, Pixel(point, color): Pixel) { + use embedded_graphics::prelude::RgbColor; + + if self.in_range(point) { + let color = Color { + red: color.r(), + green: color.g(), + blue: color.b(), + }; + set_pixel_in(&mut self.framebuffer, Position::from(point), color) } } } @@ -354,6 +384,41 @@ impl embedded_graphics::draw_target::DrawTarget for Display { Ok(()) } } + +impl OriginDimensions for Display { + fn size(&self) -> Size { + let width: usize = self.framebuffer.info().width.try_into().unwrap(); + let height: usize = self.framebuffer.info().height.try_into().unwrap(); + Size::new(width as u32, height as u32) + } +} +``` + +```rust ,hl_lines=3 +// in kernel/src/main.rs +use kernel::framebuffer::Display; + +use embedded_graphics::{ + mono_font::{ascii::FONT_9X18, MonoTextStyle}, + pixelcolor::Rgb888, + prelude::*, + text::Text, +}; + +entry_point!(kernel_main); +fn kernel_main(boot_info: &'static mut BootInfo) -> ! { + let mut display = Display::new(boot_info.framebuffer.as_mut().unwrap()); + + // clear the log + display.clear(); + + let style = MonoTextStyle::new(&FONT_9X18, Rgb888::WHITE); + + // Create a text at position (20, 30) and draw it using the previously defined style + Text::new("Hello Rust!", Point::new(20, 30), style).draw(&mut display).unwrap(); + + loop {} +} ``` ---