summaryrefslogtreecommitdiff
path: root/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/src')
-rw-r--r--library/src/math/tex.rs151
1 files changed, 0 insertions, 151 deletions
diff --git a/library/src/math/tex.rs b/library/src/math/tex.rs
deleted file mode 100644
index 60f00249..00000000
--- a/library/src/math/tex.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-use rex::error::{Error, LayoutError};
-use rex::font::FontContext;
-use rex::layout::{LayoutSettings, Style};
-use rex::parser::color::RGBA;
-use rex::render::{Backend, Cursor, Renderer};
-use typst::font::Font;
-
-use crate::prelude::*;
-use crate::text::{families, variant, TextNode};
-
-/// Layout a TeX formula into a frame.
-pub fn layout_tex(
- vt: &Vt,
- tex: &str,
- display: bool,
- styles: StyleChain,
-) -> Result<Fragment, &'static str> {
- // Load the font.
- let variant = variant(styles);
- let world = vt.world();
- let mut font = None;
- for family in families(styles) {
- font = world.book().select(family, variant).and_then(|id| world.font(id));
- if font.as_ref().map_or(false, |font| font.math().is_some()) {
- break;
- }
- }
-
- // Prepare the font context.
- let Some(font) = font else { return Err("failed to find suitable math font") };
- let Some(ctx) = font
- .math()
- .map(|math| FontContext::new(font.ttf(), math))
- else {
- return Err("failed to create math font context");
- };
-
- // Layout the formula.
- let em = styles.get(TextNode::SIZE);
- let style = if display { Style::Display } else { Style::Text };
- let settings = LayoutSettings::new(&ctx, em.to_pt(), style);
- let renderer = Renderer::new();
- let Ok(layout) = renderer
- .layout(&tex, settings)
- .map_err(|err| match err {
- Error::Parse(err) => err.to_string(),
- Error::Layout(LayoutError::Font(err)) => err.to_string(),
- })
- else {
- return Err("failed to layout math");
- };
-
- // Determine the metrics.
- let (x0, y0, x1, y1) = renderer.size(&layout);
- let width = Abs::pt(x1 - x0);
- let mut top = Abs::pt(y1);
- let mut bottom = Abs::pt(-y0);
- if style != Style::Display {
- let metrics = font.metrics();
- top = styles.get(TextNode::TOP_EDGE).resolve(styles, metrics);
- bottom = -styles.get(TextNode::BOTTOM_EDGE).resolve(styles, metrics);
- };
-
- // Prepare a frame rendering backend.
- let size = Size::new(width, top + bottom);
- let mut backend = FrameBackend {
- frame: {
- let mut frame = Frame::new(size);
- frame.set_baseline(top);
- frame
- },
- baseline: top,
- font: font.clone(),
- paint: styles.get(TextNode::FILL),
- lang: styles.get(TextNode::LANG),
- colors: vec![],
- };
-
- // Render into the frame.
- renderer.render(&layout, &mut backend);
-
- Ok(Fragment::frame(backend.frame))
-}
-
-/// A ReX rendering backend that renders into a frame.
-struct FrameBackend {
- frame: Frame,
- baseline: Abs,
- font: Font,
- paint: Paint,
- lang: Lang,
- colors: Vec<RGBA>,
-}
-
-impl FrameBackend {
- /// The currently active paint.
- fn paint(&self) -> Paint {
- self.colors
- .last()
- .map(|&RGBA(r, g, b, a)| RgbaColor::new(r, g, b, a).into())
- .unwrap_or(self.paint)
- }
-
- /// Convert a cursor to a point.
- fn transform(&self, cursor: Cursor) -> Point {
- Point::new(Abs::pt(cursor.x), self.baseline + Abs::pt(cursor.y))
- }
-}
-
-impl Backend for FrameBackend {
- fn symbol(&mut self, pos: Cursor, gid: u16, scale: f64) {
- self.frame.push(
- self.transform(pos),
- Element::Text(Text {
- font: self.font.clone(),
- size: Abs::pt(scale),
- fill: self.paint(),
- lang: self.lang,
- glyphs: vec![Glyph {
- id: gid,
- x_advance: Em::new(0.0),
- x_offset: Em::new(0.0),
- c: ' ',
- }],
- }),
- );
- }
-
- fn rule(&mut self, pos: Cursor, width: f64, height: f64) {
- if height == 0.0 {
- return;
- }
-
- self.frame.push(
- self.transform(pos) + Point::with_y(Abs::pt(height) / 2.0),
- Element::Shape(Shape {
- geometry: Geometry::Line(Point::new(Abs::pt(width), Abs::zero())),
- fill: None,
- stroke: Some(Stroke { paint: self.paint(), thickness: Abs::pt(height) }),
- }),
- );
- }
-
- fn begin_color(&mut self, color: RGBA) {
- self.colors.push(color);
- }
-
- fn end_color(&mut self) {
- self.colors.pop();
- }
-}