mirror of
https://github.com/Astatin3/RusTeX.git
synced 2026-06-09 00:28:01 -06:00
Make lineargroups center properly
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
pub static LINE_WIDTH: f32 = 0.02; // Global scale
|
||||
pub static MIN_LOCAL_SCALE: f32 = 0.1; // Global scale
|
||||
|
||||
pub static FRACTION_SCALE: f32 = 0.95; // Local scale
|
||||
pub static FRACTION_SCALE: f32 = 0.8; // Local scale
|
||||
pub static FRACTION_PADDING: f32 = 0.2; // global scale
|
||||
|
||||
pub static SUPERSCRIPT_SCALE: f32 = 0.6; // local scale
|
||||
|
||||
@@ -10,6 +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> {
|
||||
assert_args(args.len(), 0, 0, "Symbol cannot take in any args!")?;
|
||||
|
||||
Ok(KElement::Text(symbol_str.to_string()))
|
||||
}
|
||||
|
||||
impl KElement {
|
||||
pub fn from_function(name: &str, args: &Vec<Vec<ParsedObject>>) -> Result<KElement, String> {
|
||||
@@ -22,11 +27,7 @@ impl KElement {
|
||||
lower: Rc::new(Self::parse_object(&args[1])?)
|
||||
})
|
||||
}
|
||||
"pm" => {
|
||||
assert_args(args.len(), 0, 0, "Symbol cannot take in any args!")?;
|
||||
|
||||
Ok(KElement::Text("±".to_string()))
|
||||
}
|
||||
"pm" => derive_symbol("±", args),
|
||||
_ => Err(format!("Invalid function: \\{}", name))
|
||||
}
|
||||
}
|
||||
|
||||
+60
-27
@@ -7,23 +7,38 @@ impl KElement {
|
||||
pub fn rasterize(&self, globals: &mut RusTeX, current_scale: f32) -> Bitmap {
|
||||
match self {
|
||||
KElement::LinearGroup(elems) => {
|
||||
let (mut totalx, mut maxy) = (0,0);
|
||||
let (mut totalx, mut mintop, mut maxbottom): (usize, usize, usize) = (0,0,0);
|
||||
let mut positions = Vec::new();
|
||||
|
||||
for elem in elems {
|
||||
let (x,y) = elem.get_bounds(globals, current_scale);
|
||||
positions.push((totalx,y));
|
||||
totalx += x;
|
||||
maxy = maxy.max(y);
|
||||
let (width, height, centery) = elem.get_bounds(globals, current_scale);
|
||||
let top = centery;
|
||||
let bottom = height - centery;
|
||||
|
||||
positions.push((totalx, centery));
|
||||
|
||||
mintop = mintop.max(top);
|
||||
maxbottom = maxbottom.max(bottom);
|
||||
totalx += width;
|
||||
}
|
||||
|
||||
let mut bitmap = Bitmap::new(totalx, maxy);
|
||||
let height = maxbottom + mintop;
|
||||
|
||||
|
||||
let mut bitmap = Bitmap::new(totalx, height);
|
||||
|
||||
for i in 0..elems.len() {
|
||||
let elem = &elems[i];
|
||||
let pos = positions[i];
|
||||
let new_bitmap = elem.rasterize(globals, current_scale);
|
||||
// println!("{:?} {:?} {:?}", (bitmap.width, bitmap.height), pos, (new_bitmap.width, new_bitmap.height));
|
||||
bitmap.overlay(&new_bitmap, pos.0, (maxy-pos.1)/2);
|
||||
// let center = (center - pos.2) / 2;
|
||||
// let center = 0;
|
||||
// println!("{}, {}, {}", center, 0, maxy);
|
||||
|
||||
let y = mintop - pos.1;
|
||||
|
||||
bitmap.overlay(&new_bitmap, pos.0, y);
|
||||
}
|
||||
|
||||
bitmap
|
||||
@@ -39,8 +54,8 @@ impl KElement {
|
||||
},
|
||||
KElement::Fraction{upper,lower} => {
|
||||
let padding = (FRACTION_PADDING * current_scale) as usize;
|
||||
let (ax,ay) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (bx,by) = lower.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (ax,ay, _) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (bx,by, _) = lower.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
|
||||
let (width, height) = (
|
||||
ax.max(bx) + padding*2,
|
||||
@@ -70,12 +85,12 @@ impl KElement {
|
||||
|
||||
}
|
||||
KElement::SuperSub{inner, upper, lower} => {
|
||||
let (ax, ay) = inner.get_bounds(globals, current_scale);
|
||||
let (ax, ay, _) = inner.get_bounds(globals, current_scale);
|
||||
if upper.is_some() && lower.is_some() {
|
||||
todo!();
|
||||
} else if upper.is_some() {
|
||||
let upper = upper.as_ref().unwrap();
|
||||
let (bx, by) = upper.get_bounds(globals, current_scale * SUPERSCRIPT_SCALE);
|
||||
let (bx, by, _) = upper.get_bounds(globals, current_scale * SUPERSCRIPT_SCALE);
|
||||
let yoffset = (by as f32*SUPERSCRIPT_Y_OFFSET) as usize;
|
||||
|
||||
let (width, height) = (
|
||||
@@ -97,16 +112,10 @@ impl KElement {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn get_bounds(&self, globals: &mut RusTeX, current_scale: f32) -> (usize, usize) {
|
||||
pub fn get_bounds(&self, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
||||
match self {
|
||||
KElement::LinearGroup(elems) => {
|
||||
let (mut totalx, mut maxy) = (0,0);
|
||||
for elem in elems {
|
||||
let (x,y) = elem.get_bounds(globals, current_scale);
|
||||
totalx += x;
|
||||
maxy = maxy.max(y);
|
||||
}
|
||||
(totalx, maxy)
|
||||
bounds_of_linear_group(elems, globals, current_scale)
|
||||
}
|
||||
KElement::Integer(i) => {
|
||||
measure_text_bounds(&mut globals.layout, &i.to_string(), current_scale)
|
||||
@@ -118,22 +127,24 @@ impl KElement {
|
||||
measure_text_bounds(&mut globals.layout, &str, current_scale)
|
||||
},
|
||||
KElement::Fraction{upper,lower} => {
|
||||
let (ax,ay) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (bx,by) = lower.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (ax,ay, _) = upper.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
let (bx,by, _) = lower.get_bounds(globals, current_scale * FRACTION_SCALE);
|
||||
(
|
||||
(ax.max(bx)) + 2*(FRACTION_PADDING * current_scale) as usize,
|
||||
ay+by + (FRACTION_PADDING * current_scale) as usize
|
||||
ay+by + (FRACTION_PADDING * current_scale) as usize,
|
||||
ay + (FRACTION_PADDING * current_scale) as usize,
|
||||
)
|
||||
},
|
||||
KElement::SuperSub{inner, upper, lower} => {
|
||||
let (ax, ay) = inner.get_bounds(globals, current_scale);
|
||||
let (ax, ay, center) = inner.get_bounds(globals, current_scale);
|
||||
if upper.is_some() && lower.is_some() {
|
||||
todo!();
|
||||
} else if upper.is_some() {
|
||||
let (bx, by) = upper.as_ref().unwrap().get_bounds(globals, current_scale * SUPERSCRIPT_SCALE);
|
||||
let (bx, by, _) = upper.as_ref().unwrap().get_bounds(globals, current_scale * SUPERSCRIPT_SCALE);
|
||||
(
|
||||
ax+bx,
|
||||
ay + (by as f32*SUPERSCRIPT_Y_OFFSET) as usize
|
||||
ay + (by as f32*SUPERSCRIPT_Y_OFFSET) as usize,
|
||||
center + (by as f32*SUPERSCRIPT_Y_OFFSET) as usize
|
||||
)
|
||||
} else if lower.is_some() {
|
||||
todo!();
|
||||
@@ -147,6 +158,28 @@ impl KElement {
|
||||
}
|
||||
}
|
||||
|
||||
fn bounds_of_linear_group(elems: &Vec<KElement>, globals: &mut RusTeX, current_scale: f32) -> (usize, usize, usize) {
|
||||
// let common_centery = elems[0].get_bounds(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
|
||||
)
|
||||
}
|
||||
|
||||
// impl KSymbol {
|
||||
// // pub fn get_max_bounds(&self) -> (f32, f32) {
|
||||
// // match self {
|
||||
@@ -165,7 +198,7 @@ impl KElement {
|
||||
// }
|
||||
// }
|
||||
|
||||
fn measure_text_bounds(layout: &mut Layout, text: &str, scale:f32) -> (usize, usize) {
|
||||
fn measure_text_bounds(layout: &mut Layout, text: &str, scale:f32) -> (usize, usize, usize) {
|
||||
layout.clear();
|
||||
layout.append(&FONTS, &TextStyle::new(text, scale, 0));
|
||||
|
||||
@@ -175,7 +208,7 @@ fn measure_text_bounds(layout: &mut Layout, text: &str, scale:f32) -> (usize, us
|
||||
height = height.max(glyph.y as usize + glyph.height);
|
||||
}
|
||||
|
||||
(width, height)
|
||||
(width, height, height/2)
|
||||
|
||||
}
|
||||
|
||||
|
||||
-106
@@ -5,8 +5,6 @@ mod element;
|
||||
mod bitmap;
|
||||
mod consts;
|
||||
|
||||
use std::{rc::Rc, time::Instant};
|
||||
|
||||
use fontdue::{layout::{CoordinateSystem, Layout, LayoutSettings}};
|
||||
|
||||
use crate::{bitmap::Bitmap, element::{KElement}};
|
||||
@@ -16,8 +14,6 @@ fn main() -> Result<(), std::fmt::Error> {
|
||||
}
|
||||
|
||||
fn parse_test() -> Result<(), std::fmt::Error> {
|
||||
// Test the quadratic formula
|
||||
// let tex_input = r"x=\frac{-b\pm\sqrt{b^2 - 4ac}}{2a}";
|
||||
let tex_input = &std::env::args().nth(1).unwrap();
|
||||
|
||||
match KElement::parse(tex_input) {
|
||||
@@ -28,111 +24,9 @@ fn parse_test() -> Result<(), std::fmt::Error> {
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
|
||||
// println!("Parsing: {}", tex_input);
|
||||
|
||||
// match parser::parse(tex_input) {
|
||||
// Ok(result) => {
|
||||
// println!("Parsed result:");
|
||||
// for (i, obj) in result.iter().enumerate() {
|
||||
// println!(" [{}]: {:#?}", i, obj);
|
||||
// }
|
||||
// }
|
||||
// Err(e) => {
|
||||
// println!("Error parsing TeX: {}", e);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Test some other examples
|
||||
// let examples = vec![
|
||||
// "a^2",
|
||||
// r"\frac{12.34a+b}{2}",
|
||||
// r"\sqrt{x}",
|
||||
// "x_{a^2}^{2^a}",
|
||||
// "(a+b)^2",
|
||||
// ];
|
||||
|
||||
// for example in examples {
|
||||
// println!("\n--- Parsing: {} ---", example);
|
||||
// match parser.parse(example) {
|
||||
// Ok(result) => {
|
||||
// for obj in result {
|
||||
// println!("{:#?}", obj);
|
||||
// }
|
||||
// }
|
||||
// Err(e) => println!("Error: {}", e),
|
||||
// }
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// fn raster_test() -> Result<(), std::fmt::Error> {
|
||||
// let start = Instant::now();
|
||||
|
||||
// let mut rustex = RusTeX::new(TeXSettings { scale: 100. });
|
||||
|
||||
// let element =
|
||||
|
||||
// KElement::Superscript(Rc::new(
|
||||
// KElement::LinearGroup(vec![
|
||||
// KElement::Fraction(
|
||||
// Rc::new(KElement::LinearGroup(vec![
|
||||
// KElement::Integer(123),
|
||||
// KElement::Text("*".to_string()),
|
||||
// KElement::Superscript(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(5)),
|
||||
// Rc::new(KElement::Integer(2)))
|
||||
// ),
|
||||
// )
|
||||
// ])),
|
||||
// Rc::new(KElement::Integer(12))
|
||||
// ),
|
||||
// // KElement::Integer(12),
|
||||
// // KElement::Integer(12),
|
||||
// KElement::Decimal(12.34),
|
||||
// KElement::Fraction(
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Integer(12)))
|
||||
// ),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Fraction(
|
||||
// Rc::new(KElement::Integer(123)),
|
||||
// Rc::new(KElement::Decimal(1234.5678))
|
||||
// ))
|
||||
// ))
|
||||
// ))
|
||||
// ))
|
||||
// ))
|
||||
// ))
|
||||
// )),
|
||||
// ),
|
||||
// ])), Rc::new(KElement::Decimal(12.34)));
|
||||
|
||||
// // rustex.add_text(&TextStyle::new("testi12345ng! e^23", 100.0, 0));
|
||||
// let bitmap = rustex.rasterize(element);
|
||||
|
||||
// println!("Rasterizing time: {:?}", start.elapsed());
|
||||
|
||||
// bitmap.print();
|
||||
|
||||
// // print_bitmap(&bitmap, width, height);
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
struct RusTeX {
|
||||
pub settings: TeXSettings,
|
||||
|
||||
Reference in New Issue
Block a user