diff options
Diffstat (limited to 'crates/typst-layout/src/math/text.rs')
| -rw-r--r-- | crates/typst-layout/src/math/text.rs | 73 |
1 files changed, 31 insertions, 42 deletions
diff --git a/crates/typst-layout/src/math/text.rs b/crates/typst-layout/src/math/text.rs index e191ec17..67dc0a2c 100644 --- a/crates/typst-layout/src/math/text.rs +++ b/crates/typst-layout/src/math/text.rs @@ -12,7 +12,10 @@ use typst_syntax::{is_newline, Span}; use unicode_math_class::MathClass; use unicode_segmentation::UnicodeSegmentation; -use super::{FrameFragment, GlyphFragment, MathContext, MathFragment, MathRun}; +use super::{ + has_dtls_feat, style_dtls, FrameFragment, GlyphFragment, MathContext, MathFragment, + MathRun, +}; /// Lays out a [`TextElem`]. pub fn layout_text( @@ -67,12 +70,7 @@ fn layout_inline_text( let mut fragments = vec![]; for unstyled_c in text.chars() { let c = styled_char(styles, unstyled_c, false); - let mut glyph = GlyphFragment::new(ctx, styles, c, span); - match EquationElem::size_in(styles) { - MathSize::Script => glyph.make_script_size(ctx), - MathSize::ScriptScript => glyph.make_script_script_size(ctx), - _ => {} - } + let glyph = GlyphFragment::new_char(ctx.font, styles, c, span)?; fragments.push(glyph.into()); } let frame = MathRun::new(fragments).into_frame(styles); @@ -121,54 +119,45 @@ pub fn layout_symbol( ) -> SourceResult<()> { // Switch dotless char to normal when we have the dtls OpenType feature. // This should happen before the main styling pass. - let (unstyled_c, dtls) = match try_dotless(elem.text) { - Some(c) if ctx.dtls_table.is_some() => (c, true), - _ => (elem.text, false), + let dtls = style_dtls(); + let (unstyled_c, symbol_styles) = match try_dotless(elem.text) { + Some(c) if has_dtls_feat(ctx.font) => (c, styles.chain(&dtls)), + _ => (elem.text, styles), }; let c = styled_char(styles, unstyled_c, true); - let fragment = match GlyphFragment::try_new(ctx, styles, c, elem.span()) { - Some(glyph) => layout_glyph(glyph, dtls, ctx, styles), - None => { - // Not in the math font, fallback to normal inline text layout. - layout_inline_text(c.encode_utf8(&mut [0; 4]), elem.span(), ctx, styles)? - .into() - } - }; + let fragment: MathFragment = + match GlyphFragment::new_char(ctx.font, symbol_styles, c, elem.span()) { + Ok(mut glyph) => { + adjust_glyph_layout(&mut glyph, ctx, styles); + glyph.into() + } + Err(_) => { + // Not in the math font, fallback to normal inline text layout. + // TODO: Should replace this with proper fallback in [`GlyphFragment::new`]. + layout_inline_text(c.encode_utf8(&mut [0; 4]), elem.span(), ctx, styles)? + .into() + } + }; ctx.push(fragment); Ok(()) } -/// Layout a [`GlyphFragment`]. -fn layout_glyph( - mut glyph: GlyphFragment, - dtls: bool, +/// Centers large glyphs vertically on the axis, scaling them if in display +/// style. +fn adjust_glyph_layout( + glyph: &mut GlyphFragment, ctx: &mut MathContext, styles: StyleChain, -) -> MathFragment { - if dtls { - glyph.make_dotless_form(ctx); - } - let math_size = EquationElem::size_in(styles); - match math_size { - MathSize::Script => glyph.make_script_size(ctx), - MathSize::ScriptScript => glyph.make_script_script_size(ctx), - _ => {} - } - +) { if glyph.class == MathClass::Large { - let mut variant = if math_size == MathSize::Display { + if EquationElem::size_in(styles) == MathSize::Display { let height = scaled!(ctx, styles, display_operator_min_height) - .max(SQRT_2 * glyph.height()); - glyph.stretch_vertical(ctx, height) - } else { - glyph.into_variant() + .max(SQRT_2 * glyph.size.y); + glyph.stretch_vertical(ctx, height); }; // TeXbook p 155. Large operators are always vertically centered on the // axis. - variant.center_on_axis(ctx); - variant.into() - } else { - glyph.into() + glyph.center_on_axis(); } } |
