diff options
| author | Sébastien d'Herbais de Thun <sebastien.d.herbais@gmail.com> | 2023-11-06 21:37:50 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-06 21:37:50 +0100 |
| commit | c0f6d2004afebfa9412ba0c2d598ef8287197c42 (patch) | |
| tree | 4bb034ca671e7d1982a306f5aecfc4f78a01841d /crates/typst-library/src/math | |
| parent | 8fd546760c7c425398f0114997c8085a481d8d2a (diff) | |
Content rework 2 - Electric Boogaloo (#2504)
Diffstat (limited to 'crates/typst-library/src/math')
| -rw-r--r-- | crates/typst-library/src/math/accent.rs | 7 | ||||
| -rw-r--r-- | crates/typst-library/src/math/attach.rs | 8 | ||||
| -rw-r--r-- | crates/typst-library/src/math/cancel.rs | 3 | ||||
| -rw-r--r-- | crates/typst-library/src/math/class.rs | 6 | ||||
| -rw-r--r-- | crates/typst-library/src/math/ctx.rs | 3 | ||||
| -rw-r--r-- | crates/typst-library/src/math/frac.rs | 4 | ||||
| -rw-r--r-- | crates/typst-library/src/math/fragment.rs | 2 | ||||
| -rw-r--r-- | crates/typst-library/src/math/lr.rs | 2 | ||||
| -rw-r--r-- | crates/typst-library/src/math/matrix.rs | 36 | ||||
| -rw-r--r-- | crates/typst-library/src/math/mod.rs | 14 | ||||
| -rw-r--r-- | crates/typst-library/src/math/op.rs | 2 | ||||
| -rw-r--r-- | crates/typst-library/src/math/root.rs | 2 | ||||
| -rw-r--r-- | crates/typst-library/src/math/style.rs | 4 | ||||
| -rw-r--r-- | crates/typst-library/src/math/underover.rs | 12 |
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, |
