mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Use embedded-graphics crate to draw shapes and text
This commit is contained in:
54
Cargo.lock
generated
54
Cargo.lock
generated
@@ -133,6 +133,12 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "az"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
@@ -270,6 +276,29 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-graphics"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0"
|
||||
dependencies = [
|
||||
"az",
|
||||
"byteorder",
|
||||
"embedded-graphics-core",
|
||||
"float-cmp",
|
||||
"micromath",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-graphics-core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044"
|
||||
dependencies = [
|
||||
"az",
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.8"
|
||||
@@ -344,6 +373,15 @@ dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
@@ -537,6 +575,7 @@ name = "kernel"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bootloader_api",
|
||||
"embedded-graphics",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -588,6 +627,21 @@ version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
|
||||
|
||||
[[package]]
|
||||
name = "micromath"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ovmf-prebuilt"
|
||||
version = "0.1.0-alpha.1"
|
||||
|
||||
@@ -10,3 +10,4 @@ bench = false
|
||||
|
||||
[dependencies]
|
||||
bootloader_api = "0.11.0"
|
||||
embedded-graphics = "0.8.1"
|
||||
|
||||
@@ -1,4 +1,66 @@
|
||||
use bootloader_api::info::{FrameBuffer, PixelFormat};
|
||||
use embedded_graphics::{
|
||||
draw_target::DrawTarget,
|
||||
geometry::{self, Point},
|
||||
pixelcolor::{Rgb888, RgbColor},
|
||||
Pixel,
|
||||
};
|
||||
|
||||
pub struct Display {
|
||||
framebuffer: &'static mut FrameBuffer,
|
||||
}
|
||||
|
||||
impl Display {
|
||||
pub fn new(framebuffer: &'static mut FrameBuffer) -> Display {
|
||||
Self { framebuffer }
|
||||
}
|
||||
|
||||
fn draw_pixel(&mut self, coordinates: Point, color: Rgb888) {
|
||||
// ignore any pixels that are out of bounds.
|
||||
let (width, height) = {
|
||||
let info = self.framebuffer.info();
|
||||
(info.width, info.height)
|
||||
};
|
||||
|
||||
let position = match (coordinates.x.try_into(), coordinates.y.try_into()) {
|
||||
(Ok(x), Ok(y)) if x < width && y < height => Position { x, y },
|
||||
_ => return, // ignore out-of-bounds pixel
|
||||
};
|
||||
let color = Color {
|
||||
red: color.r(),
|
||||
green: color.g(),
|
||||
blue: color.b(),
|
||||
};
|
||||
set_pixel_in(self.framebuffer, position, color);
|
||||
}
|
||||
}
|
||||
|
||||
impl DrawTarget for Display {
|
||||
type Color = Rgb888;
|
||||
|
||||
/// Drawing operations can never fail.
|
||||
type Error = core::convert::Infallible;
|
||||
|
||||
fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
|
||||
where
|
||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||
{
|
||||
for Pixel(coordinates, color) in pixels.into_iter() {
|
||||
self.draw_pixel(coordinates, color);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl geometry::OriginDimensions for Display {
|
||||
fn size(&self) -> geometry::Size {
|
||||
let info = self.framebuffer.info();
|
||||
geometry::Size::new(
|
||||
info.width.try_into().unwrap(),
|
||||
info.height.try_into().unwrap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Position {
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
|
||||
use core::panic::PanicInfo;
|
||||
use core::{convert::Infallible, panic::PanicInfo};
|
||||
|
||||
use bootloader_api::BootInfo;
|
||||
use embedded_graphics::{
|
||||
draw_target::DrawTarget,
|
||||
geometry::Point,
|
||||
mono_font::{self, MonoTextStyle},
|
||||
pixelcolor::{Rgb888, RgbColor, WebColors},
|
||||
primitives::{Circle, PrimitiveStyle, StyledDrawable},
|
||||
text::Text,
|
||||
Drawable,
|
||||
};
|
||||
|
||||
mod framebuffer;
|
||||
|
||||
@@ -11,20 +20,16 @@ bootloader_api::entry_point!(kernel_main);
|
||||
|
||||
fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
|
||||
if let Some(framebuffer) = boot_info.framebuffer.as_mut() {
|
||||
let color = framebuffer::Color {
|
||||
red: 0,
|
||||
green: 0,
|
||||
blue: 255,
|
||||
};
|
||||
for x in 0..100 {
|
||||
for y in 0..100 {
|
||||
let position = framebuffer::Position {
|
||||
x: 20 + x,
|
||||
y: 100 + y,
|
||||
};
|
||||
framebuffer::set_pixel_in(framebuffer, position, color);
|
||||
}
|
||||
}
|
||||
let mut display = framebuffer::Display::new(framebuffer);
|
||||
display.clear(Rgb888::RED).unwrap_or_else(infallible);
|
||||
let style = PrimitiveStyle::with_fill(Rgb888::YELLOW);
|
||||
Circle::new(Point::new(50, 50), 400)
|
||||
.draw_styled(&style, &mut display)
|
||||
.unwrap_or_else(infallible);
|
||||
|
||||
let character_style = MonoTextStyle::new(&mono_font::ascii::FONT_10X20, Rgb888::BLUE);
|
||||
let text = Text::new("Hello, world!", Point::new(190, 250), character_style);
|
||||
text.draw(&mut display).unwrap_or_else(infallible);
|
||||
}
|
||||
loop {}
|
||||
}
|
||||
@@ -34,3 +39,7 @@ fn kernel_main(boot_info: &'static mut BootInfo) -> ! {
|
||||
fn panic(_info: &PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn infallible<T>(v: Infallible) -> T {
|
||||
match v {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user