split code up and clean up a small bit

This commit is contained in:
Schrottkatze 2024-01-06 21:31:48 +01:00
parent f964d57ca1
commit 970ae0e449
3 changed files with 174 additions and 175 deletions

View file

@ -1,15 +1,18 @@
use cosmic_text::{Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache};
use std::{ use std::{
collections::HashMap, fs::{self},
fs::{self, File},
path::PathBuf, path::PathBuf,
}; };
use clap::Parser; use clap::Parser;
use font_kit::loader::Loader; use log::info;
use log::{debug, info}; use raqote::DrawTarget;
use logos::{Lexer, Logos};
use raqote::{DrawOptions, DrawTarget, Point, SolidSource, Source}; use parse::parse_the_shit_out_of_this_but_manually;
use render::render_text;
mod parse;
mod render;
#[derive(Clone, Debug, Parser)] #[derive(Clone, Debug, Parser)]
struct Args { struct Args {
@ -41,171 +44,3 @@ fn main() {
dt.write_png("out.png").unwrap(); dt.write_png("out.png").unwrap();
} }
fn parse_the_shit_out_of_this_but_manually(text: &str) -> Vec<LanguageStructureThingy> {
let mut lex = Token::lexer(text);
let mut r = Vec::new();
loop {
match lex.next() {
Some(Ok(Token::Text(s))) => r.push(LanguageStructureThingy::Text(s)),
Some(Ok(Token::ParenOpen)) => hehe_sexpression_funy(&mut r, &mut lex),
Some(Ok(Token::ParenClose)) => todo!(),
Some(Ok(Token::String(_))) => todo!(),
Some(Ok(Token::Equals)) => todo!(),
Some(Ok(Token::Asterisk)) => todo!(),
Some(Ok(Token::Underscore)) => todo!(),
Some(Ok(Token::Backslash)) => todo!(),
Some(Ok(Token::WavyThing)) => todo!(),
Some(Ok(Token::Sparkles)) => todo!(),
Some(Ok(Token::HeadingLevelIndicator)) => todo!(),
Some(Err(_)) => panic!("mauuu~ :("),
None => break,
}
}
r
}
fn hehe_sexpression_funy(r: &mut Vec<LanguageStructureThingy>, lex: &mut Lexer<'_, Token>) {
if let Some(Ok(Token::Text(s))) = lex.next() {
let strs = s.trim_start().split_whitespace().collect::<Vec<&str>>();
let name = strs[0].to_owned();
let mut attrs = HashMap::new();
if strs.len() == 1 {
} else if strs.len() == 2 && (lex.next() == Some(Ok(Token::Equals))) {
if let Some(Ok(Token::Text(next))) = lex.next() {
let _ = attrs.insert(strs[1].to_owned(), next.trim_end().to_owned());
}
} else {
todo!()
}
let content = if let Some(Ok(Token::String(s))) = lex.next() {
Box::new(LanguageStructureThingy::Text(s))
} else {
todo!()
};
r.push(LanguageStructureThingy::Sexpression {
name,
attrs,
content,
});
if let Some(Ok(Token::ParenClose)) = lex.next() {
return;
}
// handle other things too
todo!()
}
}
struct HswtRenderer {
dt: DrawTarget,
font_system: FontSystem,
swash_cache: SwashCache,
}
fn render_text(dt: &mut DrawTarget) {
// A FontSystem provides access to detected system fonts, create one per application
let mut font_system = FontSystem::new();
// A SwashCache stores rasterized glyphs, create one per application
let mut swash_cache = SwashCache::new();
// Text metrics indicate the font size and line height of a buffer
let metrics = Metrics::new(48.0, 60.0);
// A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
let mut buffer = Buffer::new(&mut font_system, metrics);
// Borrow buffer together with the font system for more convenient method calls
let mut buffer = buffer.borrow_with(&mut font_system);
// Set a size for the text buffer, in pixels
buffer.set_size(1920.0, 1080.0);
// Attributes indicate what font to choose
let attrs = Attrs::new();
// Add some text!
buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced);
// Perform shaping as desired
buffer.shape_until_scroll();
// Inspect the output runs
for run in buffer.layout_runs() {
for glyph in run.glyphs.iter() {
println!("{:#?}", glyph);
}
}
// Create a default text color
let text_color = Color::rgb(0xFF, 0xFF, 0xFF);
// Draw the buffer (for performance, instead use SwashCache directly)
buffer.draw(&mut swash_cache, text_color, |x, y, w, h, color| {
let (r, g, b, a) = color.as_rgba_tuple();
dt.fill_rect(
x as f32,
y as f32,
w as f32,
h as f32,
&Source::Solid(SolidSource::from_unpremultiplied_argb(a, r, g, b)),
&DrawOptions {
..Default::default()
},
)
});
}
#[derive(Debug)]
enum LanguageStructureThingy {
Text(String),
Newline,
Sexpression {
name: String,
attrs: HashMap<String, String>,
content: Box<LanguageStructureThingy>,
},
}
struct ObjectStyles {
height: Option<Size>,
width: Option<Size>,
}
enum Size {
Absolute(u16),
Relative(f32),
Auto,
}
#[derive(Logos, Debug, PartialEq)]
enum Token {
#[regex("[a-zA-Z\\d\\w]+", |lex| lex.slice().to_owned())]
Text(String),
#[token("(")]
ParenOpen,
#[token(")")]
ParenClose,
#[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#, |lex| lex.slice().to_owned())]
String(String),
#[token("=")]
Equals,
#[token("*")]
Asterisk,
#[token("_")]
Underscore,
#[token("\\")]
Backslash,
#[token("~")]
WavyThing,
#[token("")]
Sparkles,
#[token("|| ")]
HeadingLevelIndicator,
}

102
src/parse.rs Normal file
View file

@ -0,0 +1,102 @@
use std::collections::HashMap;
use logos::{Lexer, Logos};
#[derive(Logos, Debug, PartialEq)]
pub enum Token {
#[regex("[a-zA-Z\\d\\w]+", |lex| lex.slice().to_owned())]
Text(String),
#[token("(")]
ParenOpen,
#[token(")")]
ParenClose,
#[regex(r#""([^"\\]|\\["\\bnfrt]|u[a-fA-F0-9]{4})*""#, |lex| lex.slice().to_owned())]
String(String),
#[token("=")]
Equals,
#[token("*")]
Asterisk,
#[token("_")]
Underscore,
#[token("\\")]
Backslash,
#[token("~")]
WavyThing,
#[token("")]
Sparkles,
#[token("|| ")]
HeadingLevelIndicator,
#[token("\n")]
Newline,
}
#[derive(Debug)]
pub enum LanguageStructureThingy {
Text(String),
Sexpression {
name: String,
attrs: HashMap<String, String>,
content: Box<LanguageStructureThingy>,
},
}
pub fn parse_the_shit_out_of_this_but_manually(text: &str) -> Vec<LanguageStructureThingy> {
let mut lex = Token::lexer(text);
let mut r = Vec::new();
loop {
match lex.next() {
Some(Ok(Token::Text(s))) => r.push(LanguageStructureThingy::Text(s)),
Some(Ok(Token::Newline)) => r.push(LanguageStructureThingy::Text("\n".to_owned())),
Some(Ok(Token::ParenOpen)) => hehe_sexpression_funy(&mut r, &mut lex),
Some(Ok(Token::ParenClose)) => todo!(),
Some(Ok(Token::String(_))) => todo!(),
Some(Ok(Token::Equals)) => todo!(),
Some(Ok(Token::Asterisk)) => todo!(),
Some(Ok(Token::Underscore)) => todo!(),
Some(Ok(Token::Backslash)) => todo!(),
Some(Ok(Token::WavyThing)) => todo!(),
Some(Ok(Token::Sparkles)) => todo!(),
Some(Ok(Token::HeadingLevelIndicator)) => todo!(),
Some(Err(e)) => panic!("mauuu~ :(, e: {e:?}"),
None => break,
}
}
r
}
fn hehe_sexpression_funy(r: &mut Vec<LanguageStructureThingy>, lex: &mut Lexer<'_, Token>) {
if let Some(Ok(Token::Text(s))) = lex.next() {
let strs = s.trim_start().split_whitespace().collect::<Vec<&str>>();
let name = strs[0].to_owned();
let mut attrs = HashMap::new();
if strs.len() == 1 {
} else if strs.len() == 2 && (lex.next() == Some(Ok(Token::Equals))) {
if let Some(Ok(Token::Text(next))) = lex.next() {
let _ = attrs.insert(strs[1].to_owned(), next.trim_end().to_owned());
}
} else {
todo!()
}
let content = if let Some(Ok(Token::String(s))) = lex.next() {
Box::new(LanguageStructureThingy::Text(s))
} else {
todo!()
};
r.push(LanguageStructureThingy::Sexpression {
name,
attrs,
content,
});
if let Some(Ok(Token::ParenClose)) = lex.next() {
return;
}
// handle other things too
todo!()
}
}

62
src/render.rs Normal file
View file

@ -0,0 +1,62 @@
use cosmic_text::{Attrs, Buffer, Color, FontSystem, Metrics, Shaping, SwashCache};
use raqote::{DrawOptions, DrawTarget, SolidSource, Source};
struct HswtRenderer {
dt: DrawTarget,
font_system: FontSystem,
swash_cache: SwashCache,
}
pub fn render_text(dt: &mut DrawTarget) {
// A FontSystem provides access to detected system fonts, create one per application
let mut font_system = FontSystem::new();
// A SwashCache stores rasterized glyphs, create one per application
let mut swash_cache = SwashCache::new();
// Text metrics indicate the font size and line height of a buffer
let metrics = Metrics::new(48.0, 60.0);
// A Buffer provides shaping and layout for a UTF-8 string, create one per text widget
let mut buffer = Buffer::new(&mut font_system, metrics);
// Borrow buffer together with the font system for more convenient method calls
let mut buffer = buffer.borrow_with(&mut font_system);
// Set a size for the text buffer, in pixels
buffer.set_size(1920.0, 1080.0);
// Attributes indicate what font to choose
let attrs = Attrs::new();
// Add some text!
buffer.set_text("Hello, Rust! 🦀\n", attrs, Shaping::Advanced);
// Perform shaping as desired
buffer.shape_until_scroll();
// Inspect the output runs
for run in buffer.layout_runs() {
for glyph in run.glyphs.iter() {
println!("{:#?}", glyph);
}
}
// Create a default text color
let text_color = Color::rgb(0xFF, 0xFF, 0xFF);
// Draw the buffer (for performance, instead use SwashCache directly)
buffer.draw(&mut swash_cache, text_color, |x, y, w, h, color| {
let (r, g, b, a) = color.as_rgba_tuple();
dt.fill_rect(
x as f32,
y as f32,
w as f32,
h as f32,
&Source::Solid(SolidSource::from_unpremultiplied_argb(a, r, g, b)),
&DrawOptions {
..Default::default()
},
)
});
}