parent
8fb225feb4
commit
68b365b351
@ -2,6 +2,7 @@ use ttf_parser::gsub::SubstitutionSubtable;
|
||||
use ttf_parser::math::MathValue;
|
||||
use typst::font::{FontStyle, FontWeight};
|
||||
use typst::model::realize;
|
||||
use typst::syntax::is_newline;
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
|
||||
use super::*;
|
||||
@ -207,41 +208,64 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
||||
FrameFragment::new(self, frame).into()
|
||||
} else {
|
||||
// Anything else is handled by Typst's standard text layout.
|
||||
let spaced = text.graphemes(true).nth(1).is_some();
|
||||
let mut style = self.style;
|
||||
if self.style.italic == Smart::Auto {
|
||||
style = style.with_italic(false);
|
||||
}
|
||||
let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect();
|
||||
let text = TextElem::packed(text)
|
||||
.styled(TextElem::set_top_edge(TopEdge::Metric(TopEdgeMetric::Bounds)))
|
||||
.styled(TextElem::set_bottom_edge(BottomEdge::Metric(
|
||||
BottomEdgeMetric::Bounds,
|
||||
)))
|
||||
.spanned(span);
|
||||
let par = ParElem::new(vec![text]);
|
||||
|
||||
// There isn't a natural width for a paragraph in a math environment;
|
||||
// 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 = par
|
||||
.layout(
|
||||
self.vt,
|
||||
self.outer.chain(&self.local),
|
||||
false,
|
||||
Size::splat(Abs::inf()),
|
||||
false,
|
||||
)?
|
||||
.into_frame();
|
||||
FrameFragment::new(self, frame)
|
||||
.with_class(MathClass::Alphabetic)
|
||||
.with_spaced(spaced)
|
||||
.into()
|
||||
if text.contains(is_newline) {
|
||||
let mut fragments = vec![];
|
||||
for (i, piece) in text.split(is_newline).enumerate() {
|
||||
if i != 0 {
|
||||
fragments.push(MathFragment::Linebreak);
|
||||
}
|
||||
if !piece.is_empty() {
|
||||
fragments.push(self.layout_complex_text(piece, span)?.into());
|
||||
}
|
||||
}
|
||||
let mut frame = MathRow::new(fragments).into_frame(self);
|
||||
let axis = scaled!(self, axis_height);
|
||||
frame.set_baseline(frame.height() / 2.0 + axis);
|
||||
FrameFragment::new(self, frame).into()
|
||||
} else {
|
||||
self.layout_complex_text(&text, span)?.into()
|
||||
}
|
||||
};
|
||||
Ok(fragment)
|
||||
}
|
||||
|
||||
pub fn layout_complex_text(
|
||||
&mut self,
|
||||
text: &str,
|
||||
span: Span,
|
||||
) -> SourceResult<FrameFragment> {
|
||||
let spaced = text.graphemes(true).nth(1).is_some();
|
||||
let elem = TextElem::packed(text)
|
||||
.styled(TextElem::set_top_edge(TopEdge::Metric(TopEdgeMetric::Bounds)))
|
||||
.styled(TextElem::set_bottom_edge(BottomEdge::Metric(
|
||||
BottomEdgeMetric::Bounds,
|
||||
)))
|
||||
.spanned(span);
|
||||
|
||||
// There isn't a natural width for a paragraph in a math environment;
|
||||
// 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])
|
||||
.layout(
|
||||
self.vt,
|
||||
self.outer.chain(&self.local),
|
||||
false,
|
||||
Size::splat(Abs::inf()),
|
||||
false,
|
||||
)?
|
||||
.into_frame();
|
||||
|
||||
Ok(FrameFragment::new(self, frame)
|
||||
.with_class(MathClass::Alphabetic)
|
||||
.with_spaced(spaced))
|
||||
}
|
||||
|
||||
pub fn styles(&self) -> StyleChain {
|
||||
self.outer.chain(&self.local)
|
||||
}
|
||||
|
BIN
tests/ref/bugs/math-text-break.png
Normal file
BIN
tests/ref/bugs/math-text-break.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 900 B |
4
tests/typ/bugs/math-text-break.typ
Normal file
4
tests/typ/bugs/math-text-break.typ
Normal file
@ -0,0 +1,4 @@
|
||||
// Test text with linebreaks in math.
|
||||
|
||||
---
|
||||
$ x := "a\nb\nc\nd\ne" $
|
@ -21,11 +21,11 @@ $#here[f] := #here[Hi there]$.
|
||||
---
|
||||
// Test boxes without a baseline act as if the baseline is at the base
|
||||
#{
|
||||
box(stroke: 0.2pt, $a #box(stroke: 0.2pt, $a$)$)
|
||||
h(12pt)
|
||||
box(stroke: 0.2pt, $a #box(stroke: 0.2pt, $g$)$)
|
||||
h(12pt)
|
||||
box(stroke: 0.2pt, $g #box(stroke: 0.2pt, $g$)$)
|
||||
box(stroke: 0.2pt, $a #box(stroke: 0.2pt, $a$)$)
|
||||
h(12pt)
|
||||
box(stroke: 0.2pt, $a #box(stroke: 0.2pt, $g$)$)
|
||||
h(12pt)
|
||||
box(stroke: 0.2pt, $g #box(stroke: 0.2pt, $g$)$)
|
||||
}
|
||||
|
||||
---
|
||||
|
Loading…
x
Reference in New Issue
Block a user