From 32e9ccc97a137f607efccf21e2890cb9a5a22012 Mon Sep 17 00:00:00 2001 From: korin Date: Sat, 8 Apr 2023 17:30:15 -0400 Subject: [PATCH] glyph metrics --- src/editor_render.rs | 57 ++++++++++++++++++++++++++++---------------- src/main.rs | 5 +++- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/editor_render.rs b/src/editor_render.rs index 816c496..3724da2 100644 --- a/src/editor_render.rs +++ b/src/editor_render.rs @@ -7,9 +7,16 @@ use std::{fs::File, path::Path, io::Read}; use sdl2::rect::Point; -const GLYPH_WIDTH: usize = 8; -const GLYPH_HEIGHT: usize = 14; -const GLYPH_AREA: usize = GLYPH_WIDTH * GLYPH_HEIGHT; +pub struct GlyphMetrics { + width: usize, + height: usize, +} + +impl GlyphMetrics { + fn area(&self) -> usize { + self.width * self.height + } +} type Glyph = Vec; @@ -28,16 +35,20 @@ fn read_file(file_name: String) -> Vec { file_content } -pub fn generate_glyph_atlas() -> Vec { +pub fn generate_glyph_data() -> (Vec, GlyphMetrics) { // Retrieve font data from file let file_path = String::from("./fonts/Terminus14x8.data"); let contents = read_file(file_path); + // Get glyph metrics + let glyph_metrics = GlyphMetrics { width: 8, height: 16 }; + let glyph_width = glyph_metrics.width; + // Get width of image for proper positioning of pixels let width_left_byte = contents[0]; let width_right_byte = contents[1]; - let number = [width_left_byte, width_right_byte]; - let width = u16::from_be_bytes(number); + let width_bytes = [width_left_byte, width_right_byte]; + let width = u16::from_be_bytes(width_bytes); println!("Left Byte: {width_left_byte}, Right Byte: {width_right_byte}, Byte Pair: {width}"); let gtable_prune = &contents[width as usize + 2 ..]; @@ -47,12 +58,13 @@ pub fn generate_glyph_atlas() -> Vec { for glyph in 0..96 { let mut new_glyph: Glyph = vec![]; - for p in 0..GLYPH_AREA as u16 { - let x = p % GLYPH_WIDTH as u16; - let y = p / GLYPH_WIDTH as u16; + let glyph_area = glyph_metrics.area(); + for p in 0..glyph_area as u16 { + let x = p % glyph_width as u16; + let y = p / glyph_width as u16; let multiplier = y * width; - let offset = glyph * GLYPH_WIDTH as u16; + let offset = glyph * glyph_width as u16; let position = (x + multiplier + offset) as usize; if gtable_prune[position] == 1 { @@ -61,13 +73,16 @@ pub fn generate_glyph_atlas() -> Vec { } glyph_atlas.push(new_glyph); } - glyph_atlas + (glyph_atlas, glyph_metrics) } /// Method for generating points to render, using given string -pub fn draw_text(glyph_atlas: &Vec, content: &str, offset: Point) -> Vec { +pub fn draw_text(glyph_atlas: &Vec, glyph_metrics: &GlyphMetrics, content: &str, offset: Point) -> Vec { let mut points: Vec = vec![]; + let glyph_width = glyph_metrics.width; + let glyph_height = glyph_metrics.height; + let lines = content.split('\n'); for (y, chars) in lines.enumerate() { for (x, chara) in chars.chars().enumerate() { @@ -79,8 +94,8 @@ pub fn draw_text(glyph_atlas: &Vec, content: &str, offset: Point) -> Vec< } for pixel in &glyph_atlas[index - 32] { - let x_glyph = x * GLYPH_WIDTH; - let y_glyph = y * GLYPH_HEIGHT; + let x_glyph = x * glyph_width; + let y_glyph = y * glyph_height; let positioned_pixel = Point::new( pixel.x + x_glyph as i32 + offset.x, @@ -93,10 +108,12 @@ pub fn draw_text(glyph_atlas: &Vec, content: &str, offset: Point) -> Vec< points } -pub fn draw_cursor(mut cursor_position: usize, content: &str, offset: Point) -> (Point, Point) { +pub fn draw_cursor(glyph_metrics: &GlyphMetrics, mut cursor_position: usize, content: &str, offset: Point) -> (Point, Point) { + let glyph_width = glyph_metrics.width; + let glyph_height = glyph_metrics.height; + let mut x = 0; let mut y = 0; - if cursor_position > 0 { cursor_position = cursor_position.checked_sub(1).unwrap_or(0); for (idx, chara) in content.chars().enumerate() { @@ -107,15 +124,15 @@ pub fn draw_cursor(mut cursor_position: usize, content: &str, offset: Point) -> y += 1; } if idx == cursor_position { - let point_a = Point::new((x * GLYPH_WIDTH) as i32 + offset.x, - (y * GLYPH_HEIGHT) as i32 + offset.y + let point_a = Point::new((x * glyph_width) as i32 + offset.x, + (y * glyph_height) as i32 + offset.y ); let point_b = Point::new(point_a.x, - point_a.y + GLYPH_HEIGHT as i32 + point_a.y + glyph_height as i32 ); return (point_a, point_b) } } } - (Point::new(offset.x, offset.y), Point::new(offset.x, offset.y + GLYPH_HEIGHT as i32)) + (Point::new(offset.x, offset.y), Point::new(offset.x, offset.y + glyph_height as i32)) } diff --git a/src/main.rs b/src/main.rs index 7c282d0..3511a32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,7 @@ struct ModifierKeys { pub fn main() -> Result<(), String> { let mut clipboard_context: ClipboardContext = ClipboardProvider::new().unwrap(); - let glyph_atlas = editor_render::generate_glyph_atlas(); + let (glyph_atlas, glyph_metrics) = editor_render::generate_glyph_data(); let sdl_context = sdl2::init()?; let video_subsys = sdl_context.video()?; @@ -48,6 +48,7 @@ pub fn main() -> Result<(), String> { canvas.set_draw_color(Color::RGB(240, 240, 240)); let fb_text = editor_render::draw_text( &glyph_atlas, + &glyph_metrics, text, pad_offset ); @@ -56,6 +57,7 @@ pub fn main() -> Result<(), String> { // Draw cursor canvas.set_draw_color(Color::RGB(64, 240, 240)); let fb_cursor = editor_render::draw_cursor( + &glyph_metrics, pos, text, pad_offset @@ -233,6 +235,7 @@ pub fn main() -> Result<(), String> { } } } + format!("{selection_anchor:?}"); println!("{buffer}"); Ok(()) }