diff options
| author | damaxwell <damaxwell@alaska.edu> | 2023-06-26 03:42:38 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-26 13:42:38 +0200 |
| commit | 1861ceb1792d2a42979dff2fa721246ada922a42 (patch) | |
| tree | f98868b246ff9eed2d7f6de3c78634be2cae492d | |
| parent | 5ee41e57e821fbbfaafc9cc2ad3f682112258fc4 (diff) | |
math under/overline now draws simple lines based on parameters in math font table (#1568)
| -rw-r--r-- | library/src/math/underover.rs | 85 | ||||
| -rw-r--r-- | tests/ref/math/spacing.png | bin | 17745 -> 17618 bytes | |||
| -rw-r--r-- | tests/ref/math/syntax.png | bin | 5036 -> 4850 bytes | |||
| -rw-r--r-- | tests/ref/math/underover.png | bin | 4944 -> 4819 bytes |
4 files changed, 76 insertions, 9 deletions
diff --git a/library/src/math/underover.rs b/library/src/math/underover.rs index 29c0e543..796c9ebc 100644 --- a/library/src/math/underover.rs +++ b/library/src/math/underover.rs @@ -1,9 +1,14 @@ use super::*; -const LINE_GAP: Em = Em::new(0.15); const BRACE_GAP: Em = Em::new(0.25); const BRACKET_GAP: Em = Em::new(0.25); +/// A marker to distinguish under- vs. overlines. +enum LineKind { + Over, + Under, +} + /// A horizontal line under content. /// /// ## Example { #example } @@ -23,7 +28,7 @@ pub struct UnderlineElem { impl LayoutMath for UnderlineElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &None, '\u{305}', LINE_GAP, false, self.span()) + layout_underoverline(ctx, &self.body(), self.span(), LineKind::Under) } } @@ -46,10 +51,72 @@ pub struct OverlineElem { impl LayoutMath for OverlineElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout(ctx, &self.body(), &None, '\u{332}', LINE_GAP, true, self.span()) + layout_underoverline(ctx, &self.body(), self.span(), LineKind::Over) } } +/// layout under- or overlined content +fn layout_underoverline( + ctx: &mut MathContext, + body: &Content, + span: Span, + line: LineKind, +) -> SourceResult<()> { + let (extra_height, content, line_pos, content_pos, baseline, bar_height); + match line { + LineKind::Under => { + let sep = scaled!(ctx, underbar_extra_descender); + bar_height = scaled!(ctx, underbar_rule_thickness); + let gap = scaled!(ctx, underbar_vertical_gap); + extra_height = sep + bar_height + gap; + + content = ctx.layout_fragment(body)?; + + line_pos = Point::with_y(content.height() + gap + bar_height / 2.0); + content_pos = Point::zero(); + baseline = content.ascent() + } + LineKind::Over => { + let sep = scaled!(ctx, overbar_extra_ascender); + bar_height = scaled!(ctx, overbar_rule_thickness); + let gap = scaled!(ctx, overbar_vertical_gap); + extra_height = sep + bar_height + gap; + + ctx.style(ctx.style.with_cramped(true)); + content = ctx.layout_fragment(body)?; + ctx.unstyle(); + + line_pos = Point::with_y(sep + bar_height / 2.0); + content_pos = Point::with_y(extra_height); + baseline = content.ascent() + extra_height; + } + } + + let width = content.width(); + let height = content.height() + extra_height; + let size = Size::new(width, height); + + let content_class = content.class().unwrap_or(MathClass::Normal); + let mut frame = Frame::new(size); + frame.set_baseline(baseline); + frame.push_frame(content_pos, content.into_frame()); + frame.push( + line_pos, + FrameItem::Shape( + Geometry::Line(Point::with_x(width)).stroked(Stroke { + paint: TextElem::fill_in(ctx.styles()), + thickness: bar_height, + ..Stroke::default() + }), + span, + ), + ); + + ctx.push(FrameFragment::new(ctx, frame).with_class(content_class)); + + Ok(()) +} + /// A horizontal brace under content, with an optional annotation below. /// /// ## Example { #example } @@ -73,7 +140,7 @@ pub struct UnderbraceElem { impl LayoutMath for UnderbraceElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout( + layout_underoverspreader( ctx, &self.body(), &self.annotation(ctx.styles()), @@ -108,7 +175,7 @@ pub struct OverbraceElem { impl LayoutMath for OverbraceElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout( + layout_underoverspreader( ctx, &self.body(), &self.annotation(ctx.styles()), @@ -143,7 +210,7 @@ pub struct UnderbracketElem { impl LayoutMath for UnderbracketElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout( + layout_underoverspreader( ctx, &self.body(), &self.annotation(ctx.styles()), @@ -178,7 +245,7 @@ pub struct OverbracketElem { impl LayoutMath for OverbracketElem { #[tracing::instrument(skip(ctx))] fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> { - layout( + layout_underoverspreader( ctx, &self.body(), &self.annotation(ctx.styles()), @@ -190,8 +257,8 @@ impl LayoutMath for OverbracketElem { } } -/// Layout an over- or underthing. -fn layout( +/// Layout an over- or underbrace-like object. +fn layout_underoverspreader( ctx: &mut MathContext, body: &Content, annotation: &Option<Content>, diff --git a/tests/ref/math/spacing.png b/tests/ref/math/spacing.png Binary files differindex d15d6607..2fd30e53 100644 --- a/tests/ref/math/spacing.png +++ b/tests/ref/math/spacing.png diff --git a/tests/ref/math/syntax.png b/tests/ref/math/syntax.png Binary files differindex b843185a..3d09723d 100644 --- a/tests/ref/math/syntax.png +++ b/tests/ref/math/syntax.png diff --git a/tests/ref/math/underover.png b/tests/ref/math/underover.png Binary files differindex 7c92c982..5c825b18 100644 --- a/tests/ref/math/underover.png +++ b/tests/ref/math/underover.png |
