Compare commits
No commits in common. '749eb316160ecc41aa5101376a074592d1c1a870' and '7a47787747e83a66d1ac85e8ffccdd8202342afd' have entirely different histories.
749eb31616
...
7a47787747
12 changed files with 241 additions and 335 deletions
@ -1 +0,0 @@ |
|||||||
/target |
|
||||||
@ -1,11 +0,0 @@ |
|||||||
[package] |
|
||||||
name = "rude" |
|
||||||
version = "0.1.0" |
|
||||||
edition = "2021" |
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
|
||||||
[profile.release] |
|
||||||
opt-level = 3 |
|
||||||
|
|
||||||
[dependencies] |
|
||||||
sdl2 = { version = "0.35.2" } |
|
||||||
@ -1,49 +0,0 @@ |
|||||||
#+title: Todo List |
|
||||||
|
|
||||||
* Movement [0/3] |
|
||||||
- [-] Arrow keys [1/4] |
|
||||||
* [X] L/R (char/char) |
|
||||||
* [ ] L/R (word/word) |
|
||||||
* [ ] L/R (sentence/sentence) |
|
||||||
* [ ] Up and down (line by line) |
|
||||||
- [-] HOME and END keys [1/2] |
|
||||||
* [X] Start to end of document |
|
||||||
* [ ] Confine to line unless CTRL is pressed |
|
||||||
- [ ] Mouse input |
|
||||||
|
|
||||||
* Editing [0/5] |
|
||||||
- [ ] Type text |
|
||||||
- [-] Remove text [3/6] |
|
||||||
* [X] Character backspace |
|
||||||
* [X] Character delete |
|
||||||
* [X] Word backspace |
|
||||||
* [ ] Word delete |
|
||||||
* [ ] Sentence backspace |
|
||||||
* [ ] Sentence delete |
|
||||||
- [ ] Select text |
|
||||||
- [ ] Cut, Copy, & Paste |
|
||||||
- [ ] Undo / Redo |
|
||||||
|
|
||||||
* Rendering [1/6] |
|
||||||
- [-] Text [1/3] |
|
||||||
* [X] Redneck bitmap |
|
||||||
* [ ] Refined bitmap (.otb format) |
|
||||||
* [ ] Vector (.ttf, .otf, etc) |
|
||||||
- [X] Cursor |
|
||||||
- [ ] Selection |
|
||||||
- [ ] Scaling/Zoom |
|
||||||
- [ ] Scrolling |
|
||||||
- [ ] Syntax Highlighting [/] |
|
||||||
- [ ] Built-in basic Rust highlighting |
|
||||||
|
|
||||||
* Misc [0/3] |
|
||||||
- [ ] Search [0/1] |
|
||||||
- [ ] Regex support |
|
||||||
- [ ] Replace [0/2] |
|
||||||
- [ ] Regex support |
|
||||||
- [ ] Sed style |
|
||||||
- [ ] File handling [0/3] |
|
||||||
- [ ] Open files |
|
||||||
- [ ] Save files |
|
||||||
- [ ] Save files as |
|
||||||
- [ ] Folder handling (for projects) |
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,120 +0,0 @@ |
|||||||
//! A redneck bitmap font renderer
|
|
||||||
//!
|
|
||||||
//! This takes a janky ass raw image file with width info inserted
|
|
||||||
//! and turns it into a bunch of points for SDL2 to read.
|
|
||||||
|
|
||||||
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; |
|
||||||
type Glyph = Vec<Point>; |
|
||||||
|
|
||||||
/// Reads the file and turns it into a Vec of u8s
|
|
||||||
fn read_file(file_name: String) -> Vec<u8> { |
|
||||||
let path = Path::new(&file_name); |
|
||||||
|
|
||||||
if !path.exists() { |
|
||||||
return String::from("Not Found!").into(); |
|
||||||
} |
|
||||||
|
|
||||||
let mut file_content = Vec::new(); |
|
||||||
let mut file = File::open(&file_name).expect("Unable to open file"); |
|
||||||
file.read_to_end(&mut file_content).expect("Unable to read"); |
|
||||||
|
|
||||||
file_content |
|
||||||
} |
|
||||||
|
|
||||||
pub fn generate_glyph_atlas() -> Vec<Glyph> { |
|
||||||
// Retrieve font data from file
|
|
||||||
let file_path = String::from("./fonts/Terminus14x8.data"); |
|
||||||
let contents = read_file(file_path); |
|
||||||
|
|
||||||
// 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); |
|
||||||
println!("Left Byte: {width_left_byte}, Right Byte: {width_right_byte}, Byte Pair: {width}"); |
|
||||||
|
|
||||||
let gtable_prune = &contents[width as usize + 2 ..]; |
|
||||||
|
|
||||||
// Generate the glyph atlas
|
|
||||||
let mut glyph_atlas: Vec<Glyph> = 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 multiplier = y * width; |
|
||||||
let offset = glyph * GLYPH_WIDTH as u16; |
|
||||||
let position = (x as u16 + multiplier + offset) as usize; |
|
||||||
|
|
||||||
if gtable_prune[position] == 1 { |
|
||||||
new_glyph.push(Point::new(x as i32, y as i32)); |
|
||||||
} |
|
||||||
} |
|
||||||
glyph_atlas.push(new_glyph); |
|
||||||
} |
|
||||||
glyph_atlas |
|
||||||
} |
|
||||||
|
|
||||||
/// Method for generating points to render, using given string
|
|
||||||
pub fn draw_text(content: &str, glyph_atlas: Vec<Glyph>) -> Vec<Point> { |
|
||||||
let mut points: Vec<Point> = vec![]; |
|
||||||
|
|
||||||
let lines = content.split('\n'); |
|
||||||
for (y, chars) in lines.enumerate() { |
|
||||||
for (x, chara) in chars.chars().enumerate() { |
|
||||||
let index; |
|
||||||
if chara.is_lowercase() { |
|
||||||
index = chara.to_ascii_lowercase() as usize; |
|
||||||
} else { |
|
||||||
index = chara.to_ascii_uppercase() as usize; |
|
||||||
} |
|
||||||
|
|
||||||
for pixel in &glyph_atlas[index - 32] { |
|
||||||
let x_offset = x * GLYPH_WIDTH; |
|
||||||
let y_offset = y * GLYPH_HEIGHT; |
|
||||||
|
|
||||||
let positioned_pixel = Point::new( |
|
||||||
pixel.x + x_offset as i32, |
|
||||||
pixel.y + y_offset as i32, |
|
||||||
); |
|
||||||
points.push(positioned_pixel); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
points |
|
||||||
} |
|
||||||
|
|
||||||
pub fn draw_cursor(content: &str, mut cursor_position: usize) -> (Point, Point) { |
|
||||||
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() { |
|
||||||
x += 1; |
|
||||||
|
|
||||||
if chara == '\n' { |
|
||||||
x = 0; |
|
||||||
y += 1; |
|
||||||
} |
|
||||||
if idx == cursor_position { |
|
||||||
let point_a = Point::new((x * GLYPH_WIDTH) as i32, |
|
||||||
(y * GLYPH_HEIGHT) as i32 |
|
||||||
); |
|
||||||
let point_b = Point::new(point_a.x, |
|
||||||
point_a.y + GLYPH_HEIGHT as i32 |
|
||||||
); |
|
||||||
return (point_a, point_b) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
(Point::new(0, 0), Point::new(0, GLYPH_HEIGHT as i32)) |
|
||||||
} |
|
||||||
@ -0,0 +1,69 @@ |
|||||||
|
use std::{fs::File, path::Path, io::Read}; |
||||||
|
|
||||||
|
const GLYPH_WIDTH: usize = 8; |
||||||
|
const GLYPH_HEIGHT: usize = 14; |
||||||
|
const GLYPH_AREA: usize = GLYPH_WIDTH * GLYPH_HEIGHT; |
||||||
|
#[allow(dead_code)] |
||||||
|
type Glyph = [[bool; GLYPH_WIDTH]; GLYPH_HEIGHT]; |
||||||
|
|
||||||
|
/// Reads the file and turns it into a Vec of u8s
|
||||||
|
fn read_file(file_name: String) -> Vec<u8> { |
||||||
|
let path = Path::new(&file_name); |
||||||
|
|
||||||
|
if !path.exists() { |
||||||
|
return String::from("Not Found!").into(); |
||||||
|
} |
||||||
|
|
||||||
|
let mut file_content = Vec::new(); |
||||||
|
let mut file = File::open(&file_name).expect("Unable to open file"); |
||||||
|
file.read_to_end(&mut file_content).expect("Unable to read"); |
||||||
|
|
||||||
|
file_content |
||||||
|
} |
||||||
|
|
||||||
|
pub fn get_font() { |
||||||
|
// Retrieve font data from file
|
||||||
|
let file_path = String::from("./fonts/Terminus14x8.data"); |
||||||
|
println!("In file {file_path}"); |
||||||
|
|
||||||
|
let contents = read_file(file_path); |
||||||
|
|
||||||
|
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); |
||||||
|
|
||||||
|
println!("Left Byte: {width_left_byte}, Right Byte: {width_right_byte}, Byte Pair {width}"); |
||||||
|
|
||||||
|
/* |
||||||
|
let gtable_prune = contents[2..].iter() |
||||||
|
.filter(|x| **x % 3 == 0) |
||||||
|
.collect::<Vec<_>>(); |
||||||
|
*/ |
||||||
|
// Remove useless Green and Blue data
|
||||||
|
let gtable_prune: Vec<u8> = contents[2..].iter() |
||||||
|
.enumerate() |
||||||
|
.filter(|x| x.0 % 3 == 0) |
||||||
|
.map(|(_, x)| *x) |
||||||
|
.collect(); |
||||||
|
|
||||||
|
println!("Pruned Glyph Table is {} long; it should be {}.", |
||||||
|
gtable_prune.len(), |
||||||
|
(contents.len() - 2) / 3 |
||||||
|
); |
||||||
|
|
||||||
|
let glyph_atlas: Vec<Glyph>; |
||||||
|
for glyph in 0..95 { |
||||||
|
let new_glyph: Glyph = [[false; GLYPH_WIDTH]; GLYPH_HEIGHT]; |
||||||
|
for p in 0..GLYPH_AREA as u16 { |
||||||
|
let multiplier = p / GLYPH_WIDTH as u16 * width; |
||||||
|
let offset = glyph * GLYPH_WIDTH as u16; |
||||||
|
let position = (p % GLYPH_WIDTH as u16 + multiplier + offset) as usize; |
||||||
|
|
||||||
|
println!("Glyph num: {glyph:2.} | Addr: {p:3.} | Line: {multiplier:5.} | Pos: {position:5.}"); |
||||||
|
|
||||||
|
if gtable_prune[position] == 255 { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue