diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-12 12:53:50 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-12 13:20:36 +0100 |
| commit | ad05ba59256a67f429b71a8aba2cd92ed2cafac7 (patch) | |
| tree | 019ccf26f7308d907c042624ccbb647f76d3491b /library/src/math | |
| parent | 2720a44b965d29e9c3453c732e38554fdb6413bb (diff) | |
Spans in math
Diffstat (limited to 'library/src/math')
| -rw-r--r-- | library/src/math/accent.rs | 2 | ||||
| -rw-r--r-- | library/src/math/ctx.rs | 10 | ||||
| -rw-r--r-- | library/src/math/delimited.rs | 4 | ||||
| -rw-r--r-- | library/src/math/frac.rs | 13 | ||||
| -rw-r--r-- | library/src/math/fragment.rs | 16 | ||||
| -rw-r--r-- | library/src/math/matrix.rs | 26 | ||||
| -rw-r--r-- | library/src/math/mod.rs | 2 | ||||
| -rw-r--r-- | library/src/math/root.rs | 9 | ||||
| -rw-r--r-- | library/src/math/stretch.rs | 5 | ||||
| -rw-r--r-- | library/src/math/underover.rs | 47 |
10 files changed, 99 insertions, 35 deletions
diff --git a/library/src/math/accent.rs b/library/src/math/accent.rs index 03caf411..9ef76279 100644 --- a/library/src/math/accent.rs +++ b/library/src/math/accent.rs @@ -66,7 +66,7 @@ impl LayoutMath for AccentNode { // 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); + 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; diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs index 991d582c..bd44546d 100644 --- a/library/src/math/ctx.rs +++ b/library/src/math/ctx.rs @@ -124,13 +124,15 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { .into_frame()) } - pub fn layout_text(&mut self, text: &str) -> SourceResult<()> { + pub fn layout_text(&mut self, node: &TextNode) -> SourceResult<()> { + let text = node.text(); + let span = node.span(); let mut chars = text.chars(); if let Some(glyph) = chars .next() .filter(|_| chars.next().is_none()) .map(|c| self.style.styled_char(c)) - .and_then(|c| GlyphFragment::try_new(self, c)) + .and_then(|c| GlyphFragment::try_new(self, c, span)) { // A single letter that is available in the math font. if self.style.size == MathSize::Display @@ -146,7 +148,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { let mut fragments = vec![]; for c in text.chars() { let c = self.style.styled_char(c); - fragments.push(GlyphFragment::new(self, c).into()); + fragments.push(GlyphFragment::new(self, c, span).into()); } let frame = MathRow::new(fragments).to_frame(self); self.push(FrameFragment::new(self, frame)); @@ -158,7 +160,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { style = style.with_italic(false); } let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect(); - let frame = self.layout_content(&TextNode::packed(text))?; + let frame = self.layout_content(&TextNode::packed(text).spanned(span))?; self.push( FrameFragment::new(self, frame) .with_class(MathClass::Alphabetic) diff --git a/library/src/math/delimited.rs b/library/src/math/delimited.rs index 6f468af7..2b9ee5ed 100644 --- a/library/src/math/delimited.rs +++ b/library/src/math/delimited.rs @@ -89,7 +89,9 @@ fn scale( ) { let glyph = match fragment { MathFragment::Glyph(glyph) => glyph.clone(), - MathFragment::Variant(variant) => GlyphFragment::new(ctx, variant.c), + MathFragment::Variant(variant) => { + GlyphFragment::new(ctx, variant.c, variant.span) + } _ => return, }; diff --git a/library/src/math/frac.rs b/library/src/math/frac.rs index 0624832a..f670159d 100644 --- a/library/src/math/frac.rs +++ b/library/src/math/frac.rs @@ -32,7 +32,7 @@ pub struct FracNode { impl LayoutMath for FracNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.num(), &self.denom(), false) + layout(ctx, &self.num(), &self.denom(), false, self.span()) } } @@ -58,7 +58,7 @@ pub struct BinomNode { impl LayoutMath for BinomNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.upper(), &self.lower(), true) + layout(ctx, &self.upper(), &self.lower(), true, self.span()) } } @@ -68,6 +68,7 @@ fn layout( num: &Content, denom: &Content, binom: bool, + span: Span, ) -> SourceResult<()> { let short_fall = DELIM_SHORT_FALL.scaled(ctx); let axis = scaled!(ctx, axis_height); @@ -121,9 +122,13 @@ fn layout( frame.push_frame(denom_pos, denom); if binom { - ctx.push(GlyphFragment::new(ctx, '(').stretch_vertical(ctx, height, short_fall)); + ctx.push( + GlyphFragment::new(ctx, '(', span).stretch_vertical(ctx, height, short_fall), + ); ctx.push(FrameFragment::new(ctx, frame)); - ctx.push(GlyphFragment::new(ctx, ')').stretch_vertical(ctx, height, short_fall)); + ctx.push( + GlyphFragment::new(ctx, ')', span).stretch_vertical(ctx, height, short_fall), + ); } else { frame.push( line_pos, diff --git a/library/src/math/fragment.rs b/library/src/math/fragment.rs index de456b82..87e28555 100644 --- a/library/src/math/fragment.rs +++ b/library/src/math/fragment.rs @@ -147,21 +147,22 @@ pub struct GlyphFragment { pub style: MathStyle, pub font_size: Abs, pub class: Option<MathClass>, + pub span: Span, } impl GlyphFragment { - pub fn new(ctx: &MathContext, c: char) -> Self { + pub fn new(ctx: &MathContext, c: char, span: Span) -> Self { let id = ctx.ttf.glyph_index(c).unwrap_or_default(); - Self::with_id(ctx, c, id) + Self::with_id(ctx, c, id, span) } - pub fn try_new(ctx: &MathContext, c: char) -> Option<Self> { + pub fn try_new(ctx: &MathContext, c: char, span: Span) -> Option<Self> { let c = ctx.style.styled_char(c); let id = ctx.ttf.glyph_index(c)?; - Some(Self::with_id(ctx, c, id)) + Some(Self::with_id(ctx, c, id, span)) } - pub fn with_id(ctx: &MathContext, c: char, id: GlyphId) -> Self { + pub fn with_id(ctx: &MathContext, c: char, id: GlyphId, span: Span) -> Self { let advance = ctx.ttf.glyph_hor_advance(id).unwrap_or_default(); let italics = italics_correction(ctx, id).unwrap_or_default(); let bbox = ctx.ttf.glyph_bounding_box(id).unwrap_or(Rect { @@ -192,6 +193,7 @@ impl GlyphFragment { ':' => Some(MathClass::Relation), _ => unicode_math_class::class(c), }, + span, } } @@ -208,6 +210,7 @@ impl GlyphFragment { font_size: self.font_size, italics_correction: self.italics_correction, class: self.class, + span: self.span, } } @@ -222,7 +225,7 @@ impl GlyphFragment { c: self.c, x_advance: Em::from_length(self.width, self.font_size), x_offset: Em::zero(), - span: Span::detached(), + span: self.span, offset: 0, }], }; @@ -249,6 +252,7 @@ pub struct VariantFragment { pub style: MathStyle, pub font_size: Abs, pub class: Option<MathClass>, + pub span: Span, } impl Debug for VariantFragment { diff --git a/library/src/math/matrix.rs b/library/src/math/matrix.rs index 6dec645c..148d79e8 100644 --- a/library/src/math/matrix.rs +++ b/library/src/math/matrix.rs @@ -36,7 +36,13 @@ impl LayoutMath for VecNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_vec_body(ctx, &self.children(), Align::Center)?; - layout_delimiters(ctx, frame, Some(delim.open()), Some(delim.close())) + layout_delimiters( + ctx, + frame, + Some(delim.open()), + Some(delim.close()), + self.span(), + ) } } @@ -112,7 +118,13 @@ impl LayoutMath for MatNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_mat_body(ctx, &self.rows())?; - layout_delimiters(ctx, frame, Some(delim.open()), Some(delim.close())) + layout_delimiters( + ctx, + frame, + Some(delim.open()), + Some(delim.close()), + self.span(), + ) } } @@ -152,7 +164,7 @@ impl LayoutMath for CasesNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { let delim = self.delim(ctx.styles()); let frame = layout_vec_body(ctx, &self.children(), Align::Left)?; - layout_delimiters(ctx, frame, Some(delim.open()), None) + layout_delimiters(ctx, frame, Some(delim.open()), None, self.span()) } } @@ -288,6 +300,7 @@ fn layout_delimiters( mut frame: Frame, left: Option<char>, right: Option<char>, + span: Span, ) -> SourceResult<()> { let axis = scaled!(ctx, axis_height); let short_fall = DELIM_SHORT_FALL.scaled(ctx); @@ -296,14 +309,17 @@ fn layout_delimiters( frame.set_baseline(height / 2.0 + axis); if let Some(left) = left { - ctx.push(GlyphFragment::new(ctx, left).stretch_vertical(ctx, target, short_fall)); + ctx.push( + GlyphFragment::new(ctx, left, span).stretch_vertical(ctx, target, short_fall), + ); } ctx.push(FrameFragment::new(ctx, frame)); if let Some(right) = right { ctx.push( - GlyphFragment::new(ctx, right).stretch_vertical(ctx, target, short_fall), + GlyphFragment::new(ctx, right, span) + .stretch_vertical(ctx, target, short_fall), ); } diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index c11bea79..0cc7f43c 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -264,7 +264,7 @@ impl LayoutMath for Content { } if let Some(node) = self.to::<TextNode>() { - ctx.layout_text(&node.text())?; + ctx.layout_text(node)?; return Ok(()); } diff --git a/library/src/math/root.rs b/library/src/math/root.rs index cb01e6a1..1ab99b2b 100644 --- a/library/src/math/root.rs +++ b/library/src/math/root.rs @@ -18,7 +18,7 @@ pub struct SqrtNode { impl LayoutMath for SqrtNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, None, &self.radicand()) + layout(ctx, None, &self.radicand(), self.span()) } } @@ -44,7 +44,7 @@ pub struct RootNode { impl LayoutMath for RootNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, Some(&self.index()), &self.radicand()) + layout(ctx, Some(&self.index()), &self.radicand(), self.span()) } } @@ -55,6 +55,7 @@ fn layout( ctx: &mut MathContext, mut index: Option<&Content>, radicand: &Content, + span: Span, ) -> SourceResult<()> { let gap = scaled!( ctx, @@ -80,7 +81,7 @@ fn layout( frame }) .unwrap_or_else(|| { - let glyph = GlyphFragment::new(ctx, '√'); + let glyph = GlyphFragment::new(ctx, '√', span); glyph.stretch_vertical(ctx, target, Abs::zero()).frame }); @@ -145,7 +146,7 @@ fn precomposed(ctx: &MathContext, index: Option<&Content>, target: Abs) -> Optio }; ctx.ttf.glyph_index(c)?; - let glyph = GlyphFragment::new(ctx, c); + let glyph = GlyphFragment::new(ctx, c, node.span()); let variant = glyph.stretch_vertical(ctx, target, Abs::zero()).frame; if variant.height() < target { return None; diff --git a/library/src/math/stretch.rs b/library/src/math/stretch.rs index 1c994802..7ba6e5c1 100644 --- a/library/src/math/stretch.rs +++ b/library/src/math/stretch.rs @@ -73,7 +73,7 @@ fn stretch_glyph( // This is either good or the best we've got. if short_target <= best_advance || construction.assembly.is_none() { - return GlyphFragment::with_id(ctx, base.c, best_id).to_variant(); + return GlyphFragment::with_id(ctx, base.c, best_id, base.span).to_variant(); } // Assemble from parts. @@ -142,7 +142,7 @@ fn assemble( advance += ratio * (max_overlap - min_overlap); } - let fragment = GlyphFragment::with_id(ctx, base.c, part.glyph_id); + let fragment = GlyphFragment::with_id(ctx, base.c, part.glyph_id, base.span); selected.push((fragment, advance)); } @@ -181,6 +181,7 @@ fn assemble( font_size: base.font_size, italics_correction: Abs::zero(), class: base.class, + span: base.span, } } diff --git a/library/src/math/underover.rs b/library/src/math/underover.rs index a723ae97..cfbb30b6 100644 --- a/library/src/math/underover.rs +++ b/library/src/math/underover.rs @@ -22,7 +22,7 @@ pub struct UnderlineNode { impl LayoutMath for UnderlineNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false) + layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false, self.span()) } } @@ -44,7 +44,7 @@ pub struct OverlineNode { impl LayoutMath for OverlineNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true) + layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true, self.span()) } } @@ -70,7 +70,15 @@ pub struct UnderbraceNode { impl LayoutMath for UnderbraceNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &self.annotation(ctx.styles()), '⏟', BRACE_GAP, false) + layout( + ctx, + &self.body(), + &self.annotation(ctx.styles()), + '⏟', + BRACE_GAP, + false, + self.span(), + ) } } @@ -96,7 +104,15 @@ pub struct OverbraceNode { impl LayoutMath for OverbraceNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &self.annotation(ctx.styles()), '⏞', BRACE_GAP, true) + layout( + ctx, + &self.body(), + &self.annotation(ctx.styles()), + '⏞', + BRACE_GAP, + true, + self.span(), + ) } } @@ -122,7 +138,15 @@ pub struct UnderbracketNode { impl LayoutMath for UnderbracketNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &self.annotation(ctx.styles()), '⎵', BRACKET_GAP, false) + layout( + ctx, + &self.body(), + &self.annotation(ctx.styles()), + '⎵', + BRACKET_GAP, + false, + self.span(), + ) } } @@ -148,7 +172,15 @@ pub struct OverbracketNode { impl LayoutMath for OverbracketNode { fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &self.annotation(ctx.styles()), '⎴', BRACKET_GAP, true) + layout( + ctx, + &self.body(), + &self.annotation(ctx.styles()), + '⎴', + BRACKET_GAP, + true, + self.span(), + ) } } @@ -160,10 +192,11 @@ fn layout( c: char, gap: Em, reverse: bool, + span: Span, ) -> SourceResult<()> { let gap = gap.scaled(ctx); let body = ctx.layout_row(body)?; - let glyph = GlyphFragment::new(ctx, c); + let glyph = GlyphFragment::new(ctx, c, span); let stretched = glyph.stretch_horizontal(ctx, body.width(), Abs::zero()); let mut rows = vec![body, stretched.into()]; |
