summaryrefslogtreecommitdiff
path: root/crates/typst-library/src/math
diff options
context:
space:
mode:
authorSébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com>2023-11-06 21:37:50 +0100
committerGitHub <noreply@github.com>2023-11-06 21:37:50 +0100
commitc0f6d2004afebfa9412ba0c2d598ef8287197c42 (patch)
tree4bb034ca671e7d1982a306f5aecfc4f78a01841d /crates/typst-library/src/math
parent8fd546760c7c425398f0114997c8085a481d8d2a (diff)
Content rework 2 - Electric Boogaloo (#2504)
Diffstat (limited to 'crates/typst-library/src/math')
-rw-r--r--crates/typst-library/src/math/accent.rs7
-rw-r--r--crates/typst-library/src/math/attach.rs8
-rw-r--r--crates/typst-library/src/math/cancel.rs3
-rw-r--r--crates/typst-library/src/math/class.rs6
-rw-r--r--crates/typst-library/src/math/ctx.rs3
-rw-r--r--crates/typst-library/src/math/frac.rs4
-rw-r--r--crates/typst-library/src/math/fragment.rs2
-rw-r--r--crates/typst-library/src/math/lr.rs2
-rw-r--r--crates/typst-library/src/math/matrix.rs36
-rw-r--r--crates/typst-library/src/math/mod.rs14
-rw-r--r--crates/typst-library/src/math/op.rs2
-rw-r--r--crates/typst-library/src/math/root.rs2
-rw-r--r--crates/typst-library/src/math/style.rs4
-rw-r--r--crates/typst-library/src/math/underover.rs12
14 files changed, 59 insertions, 46 deletions
diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs
index a542111b..bedc5635 100644
--- a/crates/typst-library/src/math/accent.rs
+++ b/crates/typst-library/src/math/accent.rs
@@ -52,7 +52,7 @@ impl LayoutMath for AccentElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
ctx.style(ctx.style.with_cramped(true));
- let base = ctx.layout_fragment(&self.base())?;
+ let base = ctx.layout_fragment(self.base())?;
ctx.unstyle();
// Preserve class to preserve automatic spacing.
@@ -67,7 +67,7 @@ impl LayoutMath for AccentElem {
// Forcing the accent to be at least as large as the base makes it too
// wide in many case.
let Accent(c) = self.accent();
- let glyph = GlyphFragment::new(ctx, c, self.span());
+ let glyph = GlyphFragment::new(ctx, *c, self.span());
let short_fall = ACCENT_SHORT_FALL.scaled(ctx);
let variant = glyph.stretch_horizontal(ctx, base.width(), short_fall);
let accent = variant.frame;
@@ -116,6 +116,7 @@ fn attachment(ctx: &MathContext, id: GlyphId, italics_correction: Abs) -> Abs {
}
/// An accent character.
+#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Accent(char);
impl Accent {
@@ -130,7 +131,7 @@ cast! {
self => self.0.into_value(),
v: char => Self::new(v),
v: Content => match v.to::<TextElem>() {
- Some(elem) => Value::Str(elem.text().into()).cast()?,
+ Some(elem) => Value::Str(elem.text().clone().into()).cast()?,
None => bail!("expected text"),
},
}
diff --git a/crates/typst-library/src/math/attach.rs b/crates/typst-library/src/math/attach.rs
index 5d1e477e..3e6b69f2 100644
--- a/crates/typst-library/src/math/attach.rs
+++ b/crates/typst-library/src/math/attach.rs
@@ -50,7 +50,7 @@ impl LayoutMath for AttachElem {
.transpose()
};
- let base = ctx.layout_fragment(&self.base())?;
+ let base = ctx.layout_fragment(self.base())?;
ctx.style(ctx.style.for_superscript());
let tl = layout_attachment(ctx, Self::tl)?;
@@ -91,7 +91,7 @@ pub struct PrimesElem {
impl LayoutMath for PrimesElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- match self.count() {
+ match *self.count() {
count @ 1..=4 => {
let f = ctx.layout_fragment(&TextElem::packed(match count {
1 => '′',
@@ -137,7 +137,7 @@ pub struct ScriptsElem {
impl LayoutMath for ScriptsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- let mut fragment = ctx.layout_fragment(&self.body())?;
+ let mut fragment = ctx.layout_fragment(self.body())?;
fragment.set_limits(Limits::Never);
ctx.push(fragment);
Ok(())
@@ -166,7 +166,7 @@ pub struct LimitsElem {
impl LayoutMath for LimitsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- let mut fragment = ctx.layout_fragment(&self.body())?;
+ let mut fragment = ctx.layout_fragment(self.body())?;
fragment.set_limits(if self.inline(ctx.styles()) {
Limits::Always
} else {
diff --git a/crates/typst-library/src/math/cancel.rs b/crates/typst-library/src/math/cancel.rs
index d521149e..16e4067a 100644
--- a/crates/typst-library/src/math/cancel.rs
+++ b/crates/typst-library/src/math/cancel.rs
@@ -97,7 +97,7 @@ pub struct CancelElem {
impl LayoutMath for CancelElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- let body = ctx.layout_fragment(&self.body())?;
+ let body = ctx.layout_fragment(self.body())?;
// Use the same math class as the body, in order to preserve automatic spacing around it.
let body_class = body.class().unwrap_or(MathClass::Special);
let mut body = body.into_frame();
@@ -146,6 +146,7 @@ impl LayoutMath for CancelElem {
}
/// Defines the cancel line.
+#[derive(Debug, Clone, PartialEq, Hash)]
pub enum CancelAngle {
Angle(Angle),
Func(Func),
diff --git a/crates/typst-library/src/math/class.rs b/crates/typst-library/src/math/class.rs
index fc8a6c79..d2c5192d 100644
--- a/crates/typst-library/src/math/class.rs
+++ b/crates/typst-library/src/math/class.rs
@@ -27,11 +27,11 @@ pub struct ClassElem {
impl LayoutMath for ClassElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- ctx.style(ctx.style.with_class(self.class()));
- let mut fragment = ctx.layout_fragment(&self.body())?;
+ ctx.style(ctx.style.with_class(*self.class()));
+ let mut fragment = ctx.layout_fragment(self.body())?;
ctx.unstyle();
- fragment.set_class(self.class());
+ fragment.set_class(*self.class());
ctx.push(fragment);
Ok(())
}
diff --git a/crates/typst-library/src/math/ctx.rs b/crates/typst-library/src/math/ctx.rs
index 59ba057f..2637921c 100644
--- a/crates/typst-library/src/math/ctx.rs
+++ b/crates/typst-library/src/math/ctx.rs
@@ -1,3 +1,4 @@
+use comemo::Prehashed;
use ttf_parser::gsub::SubstitutionSubtable;
use ttf_parser::math::MathValue;
use typst::font::{FontStyle, FontWeight};
@@ -251,7 +252,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
// because it will be placed somewhere probably not at the left margin
// it will overflow. So emulate an `hbox` instead and allow the paragraph
// to extend as far as needed.
- let frame = ParElem::new(vec![elem])
+ let frame = ParElem::new(vec![Prehashed::new(elem)])
.layout(
self.vt,
self.outer.chain(&self.local),
diff --git a/crates/typst-library/src/math/frac.rs b/crates/typst-library/src/math/frac.rs
index ee582775..bd8d86bf 100644
--- a/crates/typst-library/src/math/frac.rs
+++ b/crates/typst-library/src/math/frac.rs
@@ -29,7 +29,7 @@ pub struct FracElem {
impl LayoutMath for FracElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout(ctx, &self.num(), &[self.denom()], false, self.span())
+ layout(ctx, self.num(), std::slice::from_ref(self.denom()), false, self.span())
}
}
@@ -62,7 +62,7 @@ pub struct BinomElem {
impl LayoutMath for BinomElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout(ctx, &self.upper(), &self.lower(), true, self.span())
+ layout(ctx, self.upper(), self.lower(), true, self.span())
}
}
diff --git a/crates/typst-library/src/math/fragment.rs b/crates/typst-library/src/math/fragment.rs
index 71d8d237..a40ed2bf 100644
--- a/crates/typst-library/src/math/fragment.rs
+++ b/crates/typst-library/src/math/fragment.rs
@@ -196,7 +196,7 @@ pub struct GlyphFragment {
pub font_size: Abs,
pub class: Option<MathClass>,
pub span: Span,
- pub meta: Vec<Meta>,
+ pub meta: SmallVec<[Meta; 1]>,
pub limits: Limits,
}
diff --git a/crates/typst-library/src/math/lr.rs b/crates/typst-library/src/math/lr.rs
index 16696f2e..39143620 100644
--- a/crates/typst-library/src/math/lr.rs
+++ b/crates/typst-library/src/math/lr.rs
@@ -37,7 +37,7 @@ impl LayoutMath for LrElem {
}
}
- let mut fragments = ctx.layout_fragments(&body)?;
+ let mut fragments = ctx.layout_fragments(body)?;
let axis = scaled!(ctx, axis_height);
let max_extent = fragments
.iter()
diff --git a/crates/typst-library/src/math/matrix.rs b/crates/typst-library/src/math/matrix.rs
index 333a5706..b54da5d6 100644
--- a/crates/typst-library/src/math/matrix.rs
+++ b/crates/typst-library/src/math/matrix.rs
@@ -49,7 +49,7 @@ impl LayoutMath for VecElem {
let delim = self.delim(ctx.styles());
let frame = layout_vec_body(
ctx,
- &self.children(),
+ self.children(),
FixedAlign::Center,
self.gap(ctx.styles()),
)?;
@@ -233,7 +233,7 @@ impl LayoutMath for MatElem {
let delim = self.delim(ctx.styles());
let frame = layout_mat_body(
ctx,
- &rows,
+ rows,
augment,
Axes::new(self.column_gap(ctx.styles()), self.row_gap(ctx.styles())),
self.span(),
@@ -303,7 +303,7 @@ impl LayoutMath for CasesElem {
let delim = self.delim(ctx.styles());
let frame = layout_vec_body(
ctx,
- &self.children(),
+ self.children(),
FixedAlign::Start,
self.gap(ctx.styles()),
)?;
@@ -562,7 +562,7 @@ fn layout_delimiters(
/// Parameters specifying how augmentation lines
/// should be drawn on a matrix.
-#[derive(Default, Clone, Hash)]
+#[derive(Debug, Default, Clone, PartialEq, Hash)]
pub struct Augment<T: Numeric = Length> {
pub hline: Offsets,
pub vline: Offsets,
@@ -573,7 +573,7 @@ impl Augment<Abs> {
fn stroke_or(&self, fallback: FixedStroke) -> FixedStroke {
match &self.stroke {
Smart::Custom(v) => v.clone().unwrap_or(fallback),
- _ => fallback,
+ Smart::Auto => fallback,
}
}
}
@@ -594,7 +594,13 @@ impl Fold for Augment<Abs> {
type Output = Augment<Abs>;
fn fold(mut self, outer: Self::Output) -> Self::Output {
- self.stroke = self.stroke.fold(outer.stroke);
+ // Special case for handling `auto` strokes in subsequent `Augment`.
+ if self.stroke.is_auto() && outer.stroke.is_custom() {
+ self.stroke = outer.stroke;
+ } else {
+ self.stroke = self.stroke.fold(outer.stroke);
+ }
+
self
}
}
@@ -602,19 +608,22 @@ impl Fold for Augment<Abs> {
cast! {
Augment,
self => {
- let stroke = self.stroke.unwrap_or_default();
+ // if the stroke is auto and there is only one vertical line,
+ if self.stroke.is_auto() && self.hline.0.is_empty() && self.vline.0.len() == 1 {
+ return self.vline.0[0].into_value();
+ }
let d = dict! {
"hline" => self.hline.into_value(),
"vline" => self.vline.into_value(),
- "stroke" => stroke.into_value()
+ "stroke" => self.stroke.into_value()
};
d.into_value()
},
v: isize => Augment {
hline: Offsets::default(),
- vline: Offsets(vec![v]),
+ vline: Offsets(smallvec![v]),
stroke: Smart::Auto,
},
mut dict: Dict => {
@@ -636,14 +645,13 @@ cast! {
self => self.into_value(),
}
-/// The offsets at which augmentation lines
-/// should be drawn on a matrix.
-#[derive(Debug, Default, Clone, Hash)]
-pub struct Offsets(Vec<isize>);
+/// The offsets at which augmentation lines should be drawn on a matrix.
+#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
+pub struct Offsets(SmallVec<[isize; 1]>);
cast! {
Offsets,
self => self.0.into_value(),
- v: isize => Self(vec![v]),
+ v: isize => Self(smallvec![v]),
v: Array => Self(v.into_iter().map(Value::cast).collect::<StrResult<_>>()?),
}
diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs
index 26ab10c6..a4d44d00 100644
--- a/crates/typst-library/src/math/mod.rs
+++ b/crates/typst-library/src/math/mod.rs
@@ -32,6 +32,8 @@ pub use self::root::*;
pub use self::style::*;
pub use self::underover::*;
+use std::borrow::Cow;
+
use ttf_parser::{GlyphId, Rect};
use typst::eval::{Module, Scope};
use typst::font::{Font, FontWeight};
@@ -46,7 +48,7 @@ use self::spacing::*;
use crate::layout::{AlignElem, BoxElem, HElem, ParElem, Spacing};
use crate::meta::Supplement;
use crate::meta::{
- Count, Counter, CounterUpdate, LocalName, Numbering, Outlinable, Refable,
+ Count, Counter, CounterUpdate, LocalNameIn, Numbering, Outlinable, Refable,
};
use crate::prelude::*;
use crate::shared::BehavedBuilder;
@@ -182,7 +184,7 @@ impl Synthesize for EquationElem {
fn synthesize(&mut self, vt: &mut Vt, styles: StyleChain) -> SourceResult<()> {
// Resolve the supplement.
let supplement = match self.supplement(styles) {
- Smart::Auto => TextElem::packed(self.local_name_in(styles)),
+ Smart::Auto => TextElem::packed(Self::local_name_in(styles)),
Smart::Custom(None) => Content::empty(),
Smart::Custom(Some(supplement)) => supplement.resolve(vt, [self.clone()])?,
};
@@ -236,7 +238,7 @@ impl Layout for EquationElem {
let variant = variant(styles);
let world = vt.world;
let Some(font) = families(styles).find_map(|family| {
- let id = world.book().select(family.as_str(), variant)?;
+ let id = world.book().select(family, variant)?;
let font = world.font(id)?;
let _ = font.ttf().tables().math?.constants?;
Some(font)
@@ -312,7 +314,7 @@ impl Count for EquationElem {
}
impl LocalName for EquationElem {
- fn local_name(&self, lang: Lang, region: Option<Region>) -> &'static str {
+ fn local_name(lang: Lang, region: Option<Region>) -> &'static str {
match lang {
Lang::ALBANIAN => "Ekuacion",
Lang::ARABIC => "معادلة",
@@ -381,7 +383,7 @@ impl Outlinable for EquationElem {
let numbers = self
.counter()
- .at(vt, self.0.location().unwrap())?
+ .at(vt, self.location().unwrap())?
.display(vt, &numbering)?;
Ok(Some(supplement + numbers))
@@ -419,7 +421,7 @@ impl LayoutMath for Content {
if self.is_sequence() {
let mut bb = BehavedBuilder::new();
self.sequence_recursive_for_each(&mut |child: &Content| {
- bb.push(child.clone(), StyleChain::default())
+ bb.push(Cow::Owned(child.clone()), StyleChain::default())
});
for (child, _) in bb.finish().0.iter() {
diff --git a/crates/typst-library/src/math/op.rs b/crates/typst-library/src/math/op.rs
index 152efdf5..b4c36002 100644
--- a/crates/typst-library/src/math/op.rs
+++ b/crates/typst-library/src/math/op.rs
@@ -32,7 +32,7 @@ impl LayoutMath for OpElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
let fragment =
- ctx.layout_text(&TextElem::new(self.text()).spanned(self.span()))?;
+ ctx.layout_text(&TextElem::new(self.text().clone()).spanned(self.span()))?;
ctx.push(
FrameFragment::new(ctx, fragment.into_frame())
.with_class(MathClass::Large)
diff --git a/crates/typst-library/src/math/root.rs b/crates/typst-library/src/math/root.rs
index 49ceb75f..13c5c147 100644
--- a/crates/typst-library/src/math/root.rs
+++ b/crates/typst-library/src/math/root.rs
@@ -32,7 +32,7 @@ pub struct RootElem {
impl LayoutMath for RootElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout(ctx, self.index(ctx.styles()).as_ref(), &self.radicand(), self.span())
+ layout(ctx, self.index(ctx.styles()).as_ref(), self.radicand(), self.span())
}
}
diff --git a/crates/typst-library/src/math/style.rs b/crates/typst-library/src/math/style.rs
index 4d80a235..774fadac 100644
--- a/crates/typst-library/src/math/style.rs
+++ b/crates/typst-library/src/math/style.rs
@@ -344,7 +344,7 @@ impl MathStyle {
/// The size of elements in an equation.
///
/// See the TeXbook p. 141.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Cast)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Cast, Hash)]
pub enum MathSize {
/// Second-level sub- and superscripts.
ScriptScript,
@@ -367,7 +367,7 @@ impl MathSize {
}
/// A mathematical style variant, as defined by Unicode.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Cast)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Cast, Hash)]
pub enum MathVariant {
Serif,
Sans,
diff --git a/crates/typst-library/src/math/underover.rs b/crates/typst-library/src/math/underover.rs
index 5d010c28..aeb83061 100644
--- a/crates/typst-library/src/math/underover.rs
+++ b/crates/typst-library/src/math/underover.rs
@@ -24,7 +24,7 @@ pub struct UnderlineElem {
impl LayoutMath for UnderlineElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout_underoverline(ctx, &self.body(), self.span(), LineKind::Under)
+ layout_underoverline(ctx, self.body(), self.span(), LineKind::Under)
}
}
@@ -43,7 +43,7 @@ pub struct OverlineElem {
impl LayoutMath for OverlineElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- layout_underoverline(ctx, &self.body(), self.span(), LineKind::Over)
+ layout_underoverline(ctx, self.body(), self.span(), LineKind::Over)
}
}
@@ -130,7 +130,7 @@ impl LayoutMath for UnderbraceElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout_underoverspreader(
ctx,
- &self.body(),
+ self.body(),
&self.annotation(ctx.styles()),
'⏟',
BRACE_GAP,
@@ -161,7 +161,7 @@ impl LayoutMath for OverbraceElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout_underoverspreader(
ctx,
- &self.body(),
+ self.body(),
&self.annotation(ctx.styles()),
'⏞',
BRACE_GAP,
@@ -192,7 +192,7 @@ impl LayoutMath for UnderbracketElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout_underoverspreader(
ctx,
- &self.body(),
+ self.body(),
&self.annotation(ctx.styles()),
'⎵',
BRACKET_GAP,
@@ -223,7 +223,7 @@ impl LayoutMath for OverbracketElem {
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
layout_underoverspreader(
ctx,
- &self.body(),
+ self.body(),
&self.annotation(ctx.styles()),
'⎴',
BRACKET_GAP,