mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
parent
8fb225feb4
commit
68b365b351
@ -2,6 +2,7 @@ use ttf_parser::gsub::SubstitutionSubtable;
|
|||||||
use ttf_parser::math::MathValue;
|
use ttf_parser::math::MathValue;
|
||||||
use typst::font::{FontStyle, FontWeight};
|
use typst::font::{FontStyle, FontWeight};
|
||||||
use typst::model::realize;
|
use typst::model::realize;
|
||||||
|
use typst::syntax::is_newline;
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -207,25 +208,50 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
FrameFragment::new(self, frame).into()
|
FrameFragment::new(self, frame).into()
|
||||||
} else {
|
} else {
|
||||||
// Anything else is handled by Typst's standard text layout.
|
// Anything else is handled by Typst's standard text layout.
|
||||||
let spaced = text.graphemes(true).nth(1).is_some();
|
|
||||||
let mut style = self.style;
|
let mut style = self.style;
|
||||||
if self.style.italic == Smart::Auto {
|
if self.style.italic == Smart::Auto {
|
||||||
style = style.with_italic(false);
|
style = style.with_italic(false);
|
||||||
}
|
}
|
||||||
let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect();
|
let text: EcoString = text.chars().map(|c| style.styled_char(c)).collect();
|
||||||
let text = TextElem::packed(text)
|
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_top_edge(TopEdge::Metric(TopEdgeMetric::Bounds)))
|
||||||
.styled(TextElem::set_bottom_edge(BottomEdge::Metric(
|
.styled(TextElem::set_bottom_edge(BottomEdge::Metric(
|
||||||
BottomEdgeMetric::Bounds,
|
BottomEdgeMetric::Bounds,
|
||||||
)))
|
)))
|
||||||
.spanned(span);
|
.spanned(span);
|
||||||
let par = ParElem::new(vec![text]);
|
|
||||||
|
|
||||||
// There isn't a natural width for a paragraph in a math environment;
|
// 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
|
// because it will be placed somewhere probably not at the left margin
|
||||||
// it will overflow. So emulate an `hbox` instead and allow the paragraph
|
// it will overflow. So emulate an `hbox` instead and allow the paragraph
|
||||||
// to extend as far as needed.
|
// to extend as far as needed.
|
||||||
let frame = par
|
let frame = ParElem::new(vec![elem])
|
||||||
.layout(
|
.layout(
|
||||||
self.vt,
|
self.vt,
|
||||||
self.outer.chain(&self.local),
|
self.outer.chain(&self.local),
|
||||||
@ -234,12 +260,10 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
false,
|
false,
|
||||||
)?
|
)?
|
||||||
.into_frame();
|
.into_frame();
|
||||||
FrameFragment::new(self, frame)
|
|
||||||
|
Ok(FrameFragment::new(self, frame)
|
||||||
.with_class(MathClass::Alphabetic)
|
.with_class(MathClass::Alphabetic)
|
||||||
.with_spaced(spaced)
|
.with_spaced(spaced))
|
||||||
.into()
|
|
||||||
};
|
|
||||||
Ok(fragment)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn styles(&self) -> StyleChain {
|
pub fn styles(&self) -> StyleChain {
|
||||||
|
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" $
|
Loading…
x
Reference in New Issue
Block a user