|
|
|
|
@ -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<Point>; |
|
|
|
|
|
|
|
|
|
@ -28,16 +35,20 @@ fn read_file(file_name: String) -> Vec<u8> { |
|
|
|
|
file_content |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
pub fn generate_glyph_atlas() -> Vec<Glyph> { |
|
|
|
|
pub fn generate_glyph_data() -> (Vec<Glyph>, 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<Glyph> { |
|
|
|
|
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> { |
|
|
|
|
} |
|
|
|
|
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<Glyph>, content: &str, offset: Point) -> Vec<Point> { |
|
|
|
|
pub fn draw_text(glyph_atlas: &Vec<Glyph>, glyph_metrics: &GlyphMetrics, content: &str, offset: Point) -> Vec<Point> { |
|
|
|
|
let mut points: Vec<Point> = 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<Glyph>, 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<Glyph>, 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)) |
|
|
|
|
} |
|
|
|
|
|