diff --git a/Cargo.toml b/Cargo.toml index eebe0f0..0819aa0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,8 @@ authors = ["Ryan Kennedy "] edition = "2018" description = "Support for vga specific functions, data structures, and registers." documentation = "https://docs.rs/vga" -keywords = [ - "vga", - "no_std", -] -categories = [ - "no-std", -] +keywords = ["vga", "no_std"] +categories = ["no-std"] license = "MIT/Apache-2.0" readme = "README.md" repository = "https://github.com/rust-osdev/vga" @@ -20,11 +15,20 @@ repository = "https://github.com/rust-osdev/vga" [dependencies] bitflags = "1.2.1" +spin = "0.9" +log = "*" + conquer-once = { version = "0.3.2", default-features = false } -font8x8 = { version = "0.3.1", default-features = false, features = ["unicode"] } +font8x8 = { version = "0.3.1", default-features = false, features = [ + "unicode", +] } spinning_top = { version = "0.2.4", features = ["nightly"] } x86_64 = "0.14.2" - [dependencies.num-traits] version = "0.2.14" default-features = false + +[dependencies.ab_glyph] +version = "0.2.15" +default-features = false +features = ["libm"] diff --git a/assets/fonts/unifont-14.0.01.ttf b/assets/fonts/unifont-14.0.01.ttf new file mode 100644 index 0000000..f955a83 Binary files /dev/null and b/assets/fonts/unifont-14.0.01.ttf differ diff --git a/assets/fonts/unifont_upper-14.0.01.ttf b/assets/fonts/unifont_upper-14.0.01.ttf new file mode 100644 index 0000000..7f6409b Binary files /dev/null and b/assets/fonts/unifont_upper-14.0.01.ttf differ diff --git a/src/lib.rs b/src/lib.rs index 06b9ff5..5c486e8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,8 @@ #![no_std] #![warn(missing_docs)] +extern crate alloc; + pub mod colors; pub mod configurations; pub mod drawing; diff --git a/src/writers/graphics_640x480x16.rs b/src/writers/graphics_640x480x16.rs index 978b2b3..a511fc3 100644 --- a/src/writers/graphics_640x480x16.rs +++ b/src/writers/graphics_640x480x16.rs @@ -5,6 +5,7 @@ use crate::{ registers::{PlaneMask, WriteMode}, vga::{VideoMode, VGA}, }; +use core::convert::From; use font8x8::UnicodeFonts; const WIDTH: usize = 640; @@ -136,3 +137,75 @@ impl Graphics640x480x16 { } } } + +use ab_glyph::{Font, FontRef, Glyph}; +use log::trace; +use spin::Lazy; + +const FONT_BASIC: Lazy = Lazy::new({ + || FontRef::try_from_slice(include_bytes!("../../assets/fonts/unifont-14.0.01.ttf")).unwrap() +}); + +const FONT_SUPPLEMENTARY: Lazy = Lazy::new(|| { + FontRef::try_from_slice(include_bytes!( + "../../assets/fonts/unifont_upper-14.0.01.ttf" + )) + .unwrap() +}); + +const FONT_SCALE: f32 = 14.0; +const GLYPH_HEIGHT: f32 = 10.0; +const GLYPH_WIDTH: f32 = 8.0; + +impl Graphics640x480x16 { + /// Draw a glyph on the screen at the given position + /// + /// # Arguments + /// * `x` - the x position of the glyph + /// * `y` - the y position of the glyph + /// * `glyph` - the glyph to draw + /// * `color` - the color of the glyph + pub fn draw_unicode_char(&self, mut x: usize, mut y: usize, character: char, color: Color16) { + self.set_write_mode_2(); + + // trace!("Char {}", character); + + // if character == '\n' { + // return; + // } + if x == 80 { + x = 0; + y += 1; + } + + if character != '\0' { + let real_x = x as f32 * GLYPH_WIDTH; + let real_y = (y as f32 + 1.0) * GLYPH_HEIGHT; + // trace!("REALX{}\nREALY{}", real_x, real_y); + + let in_supp_plane = character as u32 > 0xffff; + + let plane = match in_supp_plane { + false => FONT_BASIC, + true => FONT_SUPPLEMENTARY, + }; + + let q_glyph: Glyph = plane + .glyph_id(character) + .with_scale_and_position(FONT_SCALE, ab_glyph::point(real_x, real_y)); + + if let Some(q) = plane.outline_glyph(q_glyph) { + q.draw(|gx, gy, c| { + if c > 0.1 { + let corner = q.px_bounds().min; + self._set_pixel( + gx as usize + corner.x as usize, + gy as usize + corner.y as usize, + color, + ); + } + }); + } + } + } +}