mirror of
https://github.com/Astatin3/RusTeX.git
synced 2026-06-09 00:28:01 -06:00
Work on character centering
This commit is contained in:
Binary file not shown.
+5
-3
@@ -1,9 +1,11 @@
|
|||||||
|
|
||||||
pub static LINE_WIDTH: f32 = 0.02; // Global scale
|
pub static LINE_WIDTH: f32 = 0.02; // Global scale
|
||||||
pub static MIN_LOCAL_SCALE: f32 = 0.1; // Global scale
|
// pub static MIN_LOCAL_SCALE: f32 = 0.1; // Global scale
|
||||||
|
pub static TEXT_OFFSET: f32 = 0.; // Local scale
|
||||||
|
pub static TEXT_X_PADDING: f32 = 0.0; // Local scale
|
||||||
|
pub static OPERATOR_X_PADDING: f32 = 0.1; // Local scale
|
||||||
|
|
||||||
pub static FRACTION_SCALE: f32 = 0.8; // Local scale
|
pub static FRACTION_SCALE: f32 = 0.8; // Local scale
|
||||||
pub static FRACTION_PADDING: f32 = 0.2; // global scale
|
pub static FRACTION_PADDING: f32 = 0.2; // global scale
|
||||||
|
|
||||||
pub static SUPERSCRIPT_SCALE: f32 = 0.6; // local scale
|
pub static SUPERSCRIPT_SCALE: f32 = 0.8; // local scale
|
||||||
pub static SUPERSCRIPT_Y_OFFSET: f32 = 0.4; // local scale
|
pub static SUPERSCRIPT_Y_OFFSET: f32 = 0.4; // local scale
|
||||||
@@ -39,36 +39,37 @@ impl KElement {
|
|||||||
} => {
|
} => {
|
||||||
if !super_script.is_empty() && !sub_script.is_empty() {
|
if !super_script.is_empty() && !sub_script.is_empty() {
|
||||||
root.push(KElement::SuperSub {
|
root.push(KElement::SuperSub {
|
||||||
inner: Rc::new(KElement::Text(text.clone())),
|
inner: Rc::new(Self::parse_text(text)),
|
||||||
upper: Some(Rc::new(Self::parse_object(super_script)?)),
|
upper: Some(Rc::new(Self::parse_object(super_script)?)),
|
||||||
lower: Some(Rc::new(Self::parse_object(sub_script)?)),
|
lower: Some(Rc::new(Self::parse_object(sub_script)?)),
|
||||||
});
|
});
|
||||||
} else if !super_script.is_empty() {
|
} else if !super_script.is_empty() {
|
||||||
root.push(KElement::SuperSub {
|
root.push(KElement::SuperSub {
|
||||||
inner: Rc::new(KElement::Text(text.clone())),
|
inner: Rc::new(Self::parse_text(text)),
|
||||||
upper: Some(Rc::new(Self::parse_object(super_script)?)),
|
upper: Some(Rc::new(Self::parse_object(super_script)?)),
|
||||||
lower: None
|
lower: None
|
||||||
});
|
});
|
||||||
} else if !sub_script.is_empty() {
|
} else if !sub_script.is_empty() {
|
||||||
root.push(KElement::SuperSub {
|
root.push(KElement::SuperSub {
|
||||||
inner: Rc::new(KElement::Text(text.clone())),
|
inner: Rc::new(Self::parse_text(text)),
|
||||||
upper: None,
|
upper: None,
|
||||||
lower: Some(Rc::new(Self::parse_object(super_script)?))
|
lower: Some(Rc::new(Self::parse_object(super_script)?))
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
root.push(KElement::Text(text.clone()));
|
root.push(Self::parse_text(text));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
text_parser::ParsedObject::Operator {
|
text_parser::ParsedObject::Operator {
|
||||||
text
|
text
|
||||||
} => {
|
} => {
|
||||||
root.push(KElement::Text(text.clone()));
|
root.push(KElement::from_symbol(text)?);
|
||||||
},
|
},
|
||||||
text_parser::ParsedObject::Parenthesis {
|
text_parser::ParsedObject::Parenthesis {
|
||||||
inner,
|
// inner,
|
||||||
parenthesis_type,
|
// parenthesis_type,
|
||||||
super_script,
|
// super_script,
|
||||||
sub_script
|
// sub_script
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -78,4 +79,14 @@ impl KElement {
|
|||||||
return Ok(KElement::LinearGroup(root));
|
return Ok(KElement::LinearGroup(root));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parse_text(str: &str) -> KElement {
|
||||||
|
if let Ok(num) = str.parse::<f64>() {
|
||||||
|
KElement::Decimal(num)
|
||||||
|
} else if let Ok(num) = str.parse::<i64>() {
|
||||||
|
KElement::Integer(num)
|
||||||
|
} else {
|
||||||
|
KElement::Text(str.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -10,11 +10,11 @@ fn assert_args(n: usize, start: usize, end: usize, err: &str) -> Result<(), Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_symbol(symbol_str: &str, args: &Vec<Vec<ParsedObject>>) -> Result<KElement, String> {
|
// fn derive_symbol(symbol_str: &str, args: &Vec<Vec<ParsedObject>>) -> Result<KElement, String> {
|
||||||
assert_args(args.len(), 0, 0, "Symbol cannot take in any args!")?;
|
// assert_args(args.len(), 0, 0, "Symbol cannot take in any args!")?;
|
||||||
|
|
||||||
Ok(KElement::Text(symbol_str.to_string()))
|
// Ok(KElement::Text(symbol_str.to_string()))
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl KElement {
|
impl KElement {
|
||||||
pub fn from_function(name: &str, args: &Vec<Vec<ParsedObject>>) -> Result<KElement, String> {
|
pub fn from_function(name: &str, args: &Vec<Vec<ParsedObject>>) -> Result<KElement, String> {
|
||||||
@@ -27,7 +27,7 @@ impl KElement {
|
|||||||
lower: Rc::new(Self::parse_object(&args[1])?)
|
lower: Rc::new(Self::parse_object(&args[1])?)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
"pm" => derive_symbol("±", args),
|
"pm" => Ok(KElement::PlusMinus),
|
||||||
_ => Err(format!("Invalid function: \\{}", name))
|
_ => Err(format!("Invalid function: \\{}", name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ mod rasterizer;
|
|||||||
mod text_parser;
|
mod text_parser;
|
||||||
mod element_parser;
|
mod element_parser;
|
||||||
mod functions;
|
mod functions;
|
||||||
|
mod symbols;
|
||||||
|
|
||||||
pub enum KElement {
|
pub enum KElement {
|
||||||
LinearGroup(Vec<KElement>),
|
LinearGroup(Vec<KElement>),
|
||||||
@@ -19,4 +20,9 @@ pub enum KElement {
|
|||||||
upper: Option<Rc<KElement>>,
|
upper: Option<Rc<KElement>>,
|
||||||
lower: Option<Rc<KElement>>
|
lower: Option<Rc<KElement>>
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
Equals,
|
||||||
|
PlusMinus,
|
||||||
}
|
}
|
||||||
+50
-59
@@ -44,13 +44,13 @@ impl KElement {
|
|||||||
bitmap
|
bitmap
|
||||||
}
|
}
|
||||||
KElement::Integer(i) => {
|
KElement::Integer(i) => {
|
||||||
render_text_block(&mut globals.layout, &i.to_string(), current_scale)
|
Self::render_text_block(&mut globals.layout, &i.to_string(), 0, current_scale, TEXT_X_PADDING)
|
||||||
},
|
},
|
||||||
KElement::Decimal(i) => {
|
KElement::Decimal(i) => {
|
||||||
render_text_block(&mut globals.layout, &i.to_string(), current_scale)
|
Self::render_text_block(&mut globals.layout, &i.to_string(), 0, current_scale, TEXT_X_PADDING)
|
||||||
},
|
},
|
||||||
KElement::Text(str) => {
|
KElement::Text(str) => {
|
||||||
render_text_block(&mut globals.layout, &str, current_scale)
|
Self::render_text_block(&mut globals.layout, &str, 1, current_scale, TEXT_X_PADDING)
|
||||||
},
|
},
|
||||||
KElement::Fraction{upper,lower} => {
|
KElement::Fraction{upper,lower} => {
|
||||||
let padding = (FRACTION_PADDING * current_scale) as usize;
|
let padding = (FRACTION_PADDING * current_scale) as usize;
|
||||||
@@ -110,21 +110,38 @@ impl KElement {
|
|||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => self.rasterize_symbol(globals, current_scale),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn get_bounds(&self, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
pub fn get_bounds(&self, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
||||||
match self {
|
match self {
|
||||||
KElement::LinearGroup(elems) => {
|
KElement::LinearGroup(elems) => {
|
||||||
bounds_of_linear_group(elems, globals, current_scale)
|
let (mut totalx, mut mintop, mut maxbottom): (usize, usize, usize) = (0,0,0);
|
||||||
|
for elem in elems {
|
||||||
|
let (width, height, centery) = elem.get_bounds(globals, current_scale);
|
||||||
|
totalx += width;
|
||||||
|
let top = centery;
|
||||||
|
let bottom = height - centery;
|
||||||
|
|
||||||
|
|
||||||
|
mintop = mintop.max(top);
|
||||||
|
maxbottom = maxbottom.max(bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
(
|
||||||
|
totalx,
|
||||||
|
maxbottom + mintop,
|
||||||
|
mintop
|
||||||
|
)
|
||||||
}
|
}
|
||||||
KElement::Integer(i) => {
|
KElement::Integer(i) => {
|
||||||
measure_text_bounds(&mut globals.layout, &i.to_string(), current_scale)
|
Self::measure_text_bounds(&mut globals.layout, &i.to_string(), 0, current_scale, TEXT_X_PADDING, TEXT_OFFSET)
|
||||||
},
|
},
|
||||||
KElement::Decimal(i) => {
|
KElement::Decimal(i) => {
|
||||||
measure_text_bounds(&mut globals.layout, &i.to_string(), current_scale)
|
Self::measure_text_bounds(&mut globals.layout, &i.to_string(), 0, current_scale, TEXT_X_PADDING, TEXT_OFFSET)
|
||||||
},
|
},
|
||||||
KElement::Text(str) => {
|
KElement::Text(str) => {
|
||||||
measure_text_bounds(&mut globals.layout, &str, current_scale)
|
Self::measure_text_bounds(&mut globals.layout, &str, 1, current_scale, TEXT_X_PADDING, TEXT_OFFSET)
|
||||||
},
|
},
|
||||||
KElement::Fraction{upper,lower} => {
|
KElement::Fraction{upper,lower} => {
|
||||||
let (ax,ay, _) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
let (ax,ay, _) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||||
@@ -153,54 +170,35 @@ impl KElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
_ => Self::get_symbol_bounds(&self, globals, current_scale),
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounds_of_linear_group(elems: &Vec<KElement>, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
impl KElement {
|
||||||
// let common_centery = elems[0].get_bounds(globals, current_scale);
|
pub fn measure_text_bounds(layout: &mut Layout, text: &str, font_index: usize, scale:f32, x_padding: f32, center_offset:f32) -> (usize, usize, usize) {
|
||||||
|
layout.clear();
|
||||||
|
layout.append(&FONTS, &TextStyle::new(text, scale, font_index));
|
||||||
|
|
||||||
let (mut totalx, mut mintop, mut maxbottom): (usize, usize, usize) = (0,0,0);
|
let (mut width, mut height): (usize, usize) = (0,0);
|
||||||
for elem in elems {
|
for glyph in layout.glyphs() {
|
||||||
let (width, height, centery) = elem.get_bounds(globals, current_scale);
|
width = width.max(glyph.x as usize + glyph.width);
|
||||||
totalx += width;
|
height = height.max(glyph.y as usize + glyph.height);
|
||||||
let top = centery;
|
|
||||||
let bottom = height - centery;
|
|
||||||
|
|
||||||
|
|
||||||
mintop = mintop.max(top);
|
|
||||||
maxbottom = maxbottom.max(bottom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
totalx,
|
width + 2*(scale*x_padding) as usize,
|
||||||
maxbottom + mintop,
|
height,
|
||||||
mintop
|
height/2 + ((center_offset)*scale) as usize
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
// impl KSymbol {
|
}
|
||||||
// // pub fn get_max_bounds(&self) -> (f32, f32) {
|
|
||||||
// // match self {
|
|
||||||
// // KSymbol::Text { x, y, ..} => (*x,*y),
|
|
||||||
// // _ => (0.,0.)
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// pub fn rasterize(&self, globals.layout: &mut Layout, bitmap: &mut Bitmap) {
|
|
||||||
// match self {
|
|
||||||
// KSymbol::Text { data, x, y, scale } => {
|
|
||||||
// let new_bitmap = render_text_block(globals.layout, data, *scale);
|
|
||||||
// bitmap.overlay(&new_bitmap, *x as usize, *y as usize);
|
|
||||||
// },
|
|
||||||
// KSymbol::None => {},
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn measure_text_bounds(layout: &mut Layout, text: &str, scale:f32) -> (usize, usize, usize) {
|
pub fn render_text_block(layout: &mut Layout, text: &str, font_index: usize, scale:f32, x_padding: f32) -> Bitmap {
|
||||||
layout.clear();
|
layout.clear();
|
||||||
layout.append(&FONTS, &TextStyle::new(text, scale, 0));
|
|
||||||
|
layout.append(&FONTS, &TextStyle::new(text, scale, font_index));
|
||||||
|
|
||||||
let (mut width, mut height): (usize, usize) = (0,0);
|
let (mut width, mut height): (usize, usize) = (0,0);
|
||||||
for glyph in layout.glyphs() {
|
for glyph in layout.glyphs() {
|
||||||
@@ -208,30 +206,23 @@ fn measure_text_bounds(layout: &mut Layout, text: &str, scale:f32) -> (usize, us
|
|||||||
height = height.max(glyph.y as usize + glyph.height);
|
height = height.max(glyph.y as usize + glyph.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
(width, height, height/2)
|
let mut new_bitmap = Bitmap::new(width + 2*(scale*x_padding) as usize, height);
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_text_block(layout: &mut Layout, text: &str, scale:f32) -> Bitmap {
|
|
||||||
layout.clear();
|
|
||||||
|
|
||||||
layout.append(&FONTS, &TextStyle::new(text, scale, 0));
|
|
||||||
|
|
||||||
let (mut width, mut height): (usize, usize) = (0,0);
|
|
||||||
for glyph in layout.glyphs() {
|
|
||||||
width = width.max(glyph.x as usize + glyph.width);
|
|
||||||
height = height.max(glyph.y as usize + glyph.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut new_bitmap = Bitmap::new(width, height);
|
|
||||||
|
|
||||||
for glyph in layout.glyphs() {
|
for glyph in layout.glyphs() {
|
||||||
|
|
||||||
let font = &FONTS[glyph.font_index];
|
let font = &FONTS[glyph.font_index];
|
||||||
let (_, char_bitmap) = font.rasterize_config(glyph.key);
|
let (_, char_bitmap) = font.rasterize_config(glyph.key);
|
||||||
|
|
||||||
new_bitmap.overlay(&Bitmap::from_data(char_bitmap, glyph.width, glyph.height), glyph.x as usize, glyph.y as usize);
|
new_bitmap.overlay(
|
||||||
|
&Bitmap::from_data(
|
||||||
|
char_bitmap,
|
||||||
|
glyph.width,
|
||||||
|
glyph.height
|
||||||
|
),
|
||||||
|
glyph.x as usize + (scale*x_padding) as usize,
|
||||||
|
glyph.y as usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
new_bitmap
|
new_bitmap
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
use crate::{bitmap::Bitmap, consts::OPERATOR_X_PADDING, element::KElement, RusTeX};
|
||||||
|
|
||||||
|
pub const PLUS: &'static str = "+";
|
||||||
|
pub const MINUS: &'static str = "-";
|
||||||
|
pub const EQUALS: &'static str = "=";
|
||||||
|
pub const PLUS_MINUS: &'static str = "±";
|
||||||
|
|
||||||
|
pub const PLUS_YOFFSET: f32 = 0.15;
|
||||||
|
pub const MINUS_YOFFSET: f32 = 0.15;
|
||||||
|
pub const EQUALS_YOFFSET: f32 = 0.27;
|
||||||
|
pub const PLUSMMINUS_YOFFSET: f32 = 0.15;
|
||||||
|
|
||||||
|
impl KElement {
|
||||||
|
pub fn from_symbol(symbol: &str) -> Result<KElement, String> {
|
||||||
|
match symbol {
|
||||||
|
"+" => Ok(KElement::Plus),
|
||||||
|
"-" => Ok(KElement::Minus),
|
||||||
|
"=" => Ok(KElement::Equals),
|
||||||
|
"±" => Ok(KElement::PlusMinus),
|
||||||
|
_ => unreachable!("Unimplemented symbol: {}", symbol),
|
||||||
|
// _ => Ok(KElement::Text(symbol.to_string()))
|
||||||
|
|
||||||
|
// MINUS => KElement::Minus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn rasterize_symbol(&self, globals: &mut RusTeX, current_scale: f32) -> Bitmap {
|
||||||
|
match self {
|
||||||
|
KElement::Plus => Self::render_text_block(&mut globals.layout, PLUS, 0, current_scale, OPERATOR_X_PADDING),
|
||||||
|
KElement::Minus => Self::render_text_block(&mut globals.layout, MINUS, 0, current_scale, OPERATOR_X_PADDING),
|
||||||
|
KElement::Equals => Self::render_text_block(&mut globals.layout, EQUALS, 0, current_scale, OPERATOR_X_PADDING),
|
||||||
|
KElement::PlusMinus => Self::render_text_block(&mut globals.layout, PLUS_MINUS, 0, current_scale, OPERATOR_X_PADDING),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_symbol_bounds(&self, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
||||||
|
match self {
|
||||||
|
KElement::Plus => Self::measure_text_bounds(&mut globals.layout, PLUS, 0, current_scale, OPERATOR_X_PADDING, PLUS_YOFFSET),
|
||||||
|
KElement::Minus => Self::measure_text_bounds(&mut globals.layout, MINUS, 0, current_scale, OPERATOR_X_PADDING, MINUS_YOFFSET),
|
||||||
|
KElement::Equals => Self::measure_text_bounds(&mut globals.layout, EQUALS, 0, current_scale, OPERATOR_X_PADDING, EQUALS_YOFFSET),
|
||||||
|
KElement::PlusMinus => Self::measure_text_bounds(&mut globals.layout, PLUS_MINUS, 0, current_scale, OPERATOR_X_PADDING, PLUSMMINUS_YOFFSET),
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,162 @@
|
|||||||
|
// use regex::{Captures, Regex};
|
||||||
|
// use lazy_static::lazy_static;
|
||||||
|
// use std::collections::VecDeque;
|
||||||
|
|
||||||
|
// lazy_static! {
|
||||||
|
// static ref FUNCTION_REGEX: Regex = Regex::new(r"\\([a-zA-Z]+)(\s*(?:\{[^}]*\}|[^_^{}\s\\])*)\s*(?:_(\{[^}]*\}|[^_^{}\s\\]))?\s*(?:\^(\{[^}]*\}|[^_^{}\s\\]))?").unwrap();
|
||||||
|
// static ref TEXT_REGEX: Regex = Regex::new(r"^\{\}<>()\[\]]+").unwrap();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[derive(Debug, Clone, PartialEq)]
|
||||||
|
// pub enum PerenthesisType {
|
||||||
|
// Round, // ()
|
||||||
|
// Square, // []
|
||||||
|
// // Curly, // {}
|
||||||
|
// // Angle, // <>
|
||||||
|
// }
|
||||||
|
|
||||||
|
// #[derive(Debug, Clone, PartialEq)]
|
||||||
|
// pub enum ParsedObject {
|
||||||
|
// Func {
|
||||||
|
// name: String,
|
||||||
|
// content: Vec<Vec<ParsedObject>>,
|
||||||
|
// super_script: Vec<ParsedObject>,
|
||||||
|
// sub_script: Vec<ParsedObject>,
|
||||||
|
// },
|
||||||
|
// Var {
|
||||||
|
// text: String,
|
||||||
|
// super_script: Vec<ParsedObject>,
|
||||||
|
// sub_script: Vec<ParsedObject>,
|
||||||
|
// },
|
||||||
|
// Operator {
|
||||||
|
// text: String,
|
||||||
|
// },
|
||||||
|
// Parenthesis {
|
||||||
|
// inner: Vec<ParsedObject>,
|
||||||
|
// parenthesis_type: PerenthesisType,
|
||||||
|
// super_script: Vec<ParsedObject>,
|
||||||
|
// sub_script: Vec<ParsedObject>,
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub fn parse(input: &str) -> Result<Vec<ParsedObject>, String> {
|
||||||
|
// if input.is_empty() {
|
||||||
|
// return Ok(Vec::new())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let mut i = 0;
|
||||||
|
|
||||||
|
// let mut objects = Vec::new();
|
||||||
|
|
||||||
|
// for i in 0..input.len() {
|
||||||
|
// // let mut functions = FUNCTION_REGEX.is_match_at();
|
||||||
|
// // FUNCTION_REGEX.(&mut functions, input);
|
||||||
|
// // for i in 0..functions.len() {
|
||||||
|
// // println!("{:?}", functions.get(i));
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// if TEXT_REGEX.is_match_at(input, i) {
|
||||||
|
// println!("TEXT!")
|
||||||
|
// } else if FUNCTION_REGEX.is_match_at(input, i) {
|
||||||
|
// println!("FUNCTION!")
|
||||||
|
// } else {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// // loop {
|
||||||
|
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // for captures in FUNCTION_REGEX.captures_iter(input) {
|
||||||
|
// // objects.push(parse_function(&captures)?);
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // println!("{:?}", objects);
|
||||||
|
|
||||||
|
// // let capture_locations = FUNCTION_REGEX.captures_read(locs, haystack);
|
||||||
|
|
||||||
|
// // loop {
|
||||||
|
|
||||||
|
// // }
|
||||||
|
|
||||||
|
|
||||||
|
// Ok(objects)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn parse_function(captures: &Captures) -> Result<(usize, ParsedObject), String> {
|
||||||
|
// let name = captures.get(1).unwrap().as_str();
|
||||||
|
// let args_str = captures.get(2).map_or("", |m| m.as_str());
|
||||||
|
// let sub = captures.get(3).map(|m| m.as_str());
|
||||||
|
// let super_script = captures.get(4).map(|m| m.as_str());
|
||||||
|
|
||||||
|
// let len = captures.iter().map(|c| c.iter().len()).sum::<usize>();
|
||||||
|
|
||||||
|
// // Parse arguments
|
||||||
|
// let mut args = Vec::new();
|
||||||
|
// let args_clean = args_str.trim();
|
||||||
|
// if !args_clean.is_empty() {
|
||||||
|
// let mut i = 0;
|
||||||
|
// let chars: Vec<char> = args_clean.chars().collect();
|
||||||
|
// while i < chars.len() {
|
||||||
|
// if chars[i] == '{' {
|
||||||
|
// let mut brace_content = String::new();
|
||||||
|
// i += 1;
|
||||||
|
// while i < chars.len() && chars[i] != '}' {
|
||||||
|
// brace_content.push(chars[i]);
|
||||||
|
// i += 1;
|
||||||
|
// }
|
||||||
|
// args.push(brace_content);
|
||||||
|
// i += 1;
|
||||||
|
// } else if chars[i] != ' ' {
|
||||||
|
// args.push(chars[i].to_string());
|
||||||
|
// i += 1;
|
||||||
|
// } else {
|
||||||
|
// i += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Clean up sub/super (remove braces if present)
|
||||||
|
// let sub_clean = sub.map(|s| if s.starts_with('{') && s.ends_with('}') {
|
||||||
|
// &s[1..s.len()-1]
|
||||||
|
// } else { s });
|
||||||
|
// let super_clean = super_script.map(|s| if s.starts_with('{') && s.ends_with('}') {
|
||||||
|
// &s[1..s.len()-1]
|
||||||
|
// } else { s });
|
||||||
|
|
||||||
|
// Ok(
|
||||||
|
// (
|
||||||
|
// len,
|
||||||
|
// ParsedObject::Func {
|
||||||
|
// name: name.to_string(),
|
||||||
|
// content: parse_string_arr(&args)?,
|
||||||
|
// super_script: if let Some(super_clean) = super_clean {
|
||||||
|
// parse(super_clean)?
|
||||||
|
// } else {
|
||||||
|
// Vec::new()
|
||||||
|
// },
|
||||||
|
// sub_script: if let Some(sub_clean) = sub_clean {
|
||||||
|
// parse(sub_clean)?
|
||||||
|
// } else {
|
||||||
|
// Vec::new()
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// ))
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fn parse_string_arr(args: &Vec<String>) -> Result<Vec<Vec<ParsedObject>>, String> {
|
||||||
|
// let mut result_vec = Vec::new();
|
||||||
|
// for arg in args {
|
||||||
|
// result_vec.push(parse(arg)?);
|
||||||
|
// }
|
||||||
|
// Ok(result_vec)
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ use fontdue::Font;
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
pub static KaTeX_Main_Regular: &'static [u8] = include_bytes!("../fonts/KaTeX_Main-Regular.ttf");
|
pub static KaTeX_Main_Regular: &'static [u8] = include_bytes!("../fonts/KaTeX_Main-Regular.ttf");
|
||||||
|
pub static KaTeX_Main_Italic: &'static [u8] = include_bytes!("../fonts/KaTeX_Main-Italic.ttf");
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref FONTS: Vec<Font> = vec![
|
pub static ref FONTS: Vec<Font> = vec![
|
||||||
Font::from_bytes(KaTeX_Main_Regular, fontdue::FontSettings::default()).unwrap(),
|
Font::from_bytes(KaTeX_Main_Regular, fontdue::FontSettings::default()).unwrap(),
|
||||||
|
Font::from_bytes(KaTeX_Main_Italic, fontdue::FontSettings::default()).unwrap(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
+18
-1
@@ -5,6 +5,8 @@ mod element;
|
|||||||
mod bitmap;
|
mod bitmap;
|
||||||
mod consts;
|
mod consts;
|
||||||
|
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
use fontdue::{layout::{CoordinateSystem, Layout, LayoutSettings}};
|
use fontdue::{layout::{CoordinateSystem, Layout, LayoutSettings}};
|
||||||
|
|
||||||
use crate::{bitmap::Bitmap, element::{KElement}};
|
use crate::{bitmap::Bitmap, element::{KElement}};
|
||||||
@@ -16,15 +18,30 @@ fn main() -> Result<(), std::fmt::Error> {
|
|||||||
fn parse_test() -> Result<(), std::fmt::Error> {
|
fn parse_test() -> Result<(), std::fmt::Error> {
|
||||||
let tex_input = &std::env::args().nth(1).unwrap();
|
let tex_input = &std::env::args().nth(1).unwrap();
|
||||||
|
|
||||||
|
let mut start = Instant::now();
|
||||||
|
|
||||||
match KElement::parse(tex_input) {
|
match KElement::parse(tex_input) {
|
||||||
Ok(result) => {
|
Ok(result) => {
|
||||||
|
println!("Parse time: {:?}", start.elapsed());
|
||||||
|
|
||||||
|
start = Instant::now();
|
||||||
let mut rustex = RusTeX::new(TeXSettings { scale: 100. });
|
let mut rustex = RusTeX::new(TeXSettings { scale: 100. });
|
||||||
rustex.rasterize(result).print();
|
|
||||||
|
let bitmap = rustex.rasterize(result);
|
||||||
|
|
||||||
|
println!("Raster time: {:?}", start.elapsed());
|
||||||
|
start = Instant::now();
|
||||||
|
|
||||||
|
bitmap.print();
|
||||||
|
|
||||||
|
println!("Display time: {:?}", start.elapsed());
|
||||||
}
|
}
|
||||||
Err(e) => println!("Error: {}", e),
|
Err(e) => println!("Error: {}", e),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user