From ebfdb1dafa430786db10dad2ef7d5467c1bdbed1 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 2 Jul 2023 19:59:52 +0200 Subject: Move everything into `crates/` directory --- library/src/math/ctx.rs | 268 ------------------------------------------------ 1 file changed, 268 deletions(-) delete mode 100644 library/src/math/ctx.rs (limited to 'library/src/math/ctx.rs') diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs deleted file mode 100644 index a1dc6cf4..00000000 --- a/library/src/math/ctx.rs +++ /dev/null @@ -1,268 +0,0 @@ -use ttf_parser::math::MathValue; -use typst::font::{FontStyle, FontWeight}; -use typst::model::realize; -use unicode_segmentation::UnicodeSegmentation; - -use super::*; - -macro_rules! scaled { - ($ctx:expr, text: $text:ident, display: $display:ident $(,)?) => { - match $ctx.style.size { - MathSize::Display => scaled!($ctx, $display), - _ => scaled!($ctx, $text), - } - }; - ($ctx:expr, $name:ident) => { - $ctx.constants.$name().scaled($ctx) - }; -} - -macro_rules! percent { - ($ctx:expr, $name:ident) => { - $ctx.constants.$name() as f64 / 100.0 - }; -} - -/// The context for math layout. -pub struct MathContext<'a, 'b, 'v> { - pub vt: &'v mut Vt<'b>, - pub regions: Regions<'static>, - pub font: &'a Font, - pub ttf: &'a ttf_parser::Face<'a>, - pub table: ttf_parser::math::Table<'a>, - pub constants: ttf_parser::math::Constants<'a>, - pub ssty_table: Option>, - pub space_width: Em, - pub fragments: Vec, - pub local: Styles, - pub style: MathStyle, - pub size: Abs, - outer: StyleChain<'a>, - style_stack: Vec<(MathStyle, Abs)>, -} - -impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { - pub fn new( - vt: &'v mut Vt<'b>, - styles: StyleChain<'a>, - regions: Regions, - font: &'a Font, - block: bool, - ) -> Self { - let table = font.ttf().tables().math.unwrap(); - let constants = table.constants.unwrap(); - - let ssty_table = font - .ttf() - .tables() - .gsub - .and_then(|gsub| { - gsub.features - .find(ttf_parser::Tag::from_bytes(b"ssty")) - .and_then(|feature| feature.lookup_indices.get(0)) - .and_then(|index| gsub.lookups.get(index)) - }) - .and_then(|ssty| { - ssty.subtables.get::(0) - }) - .and_then(|ssty| match ssty { - ttf_parser::gsub::SubstitutionSubtable::Alternate(alt_glyphs) => { - Some(alt_glyphs) - } - _ => None, - }); - - let size = TextElem::size_in(styles); - let ttf = font.ttf(); - let space_width = ttf - .glyph_index(' ') - .and_then(|id| ttf.glyph_hor_advance(id)) - .map(|advance| font.to_em(advance)) - .unwrap_or(THICK); - - let variant = variant(styles); - Self { - vt, - regions: Regions::one(regions.base(), Axes::splat(false)), - font, - ttf: font.ttf(), - table, - constants, - ssty_table, - space_width, - fragments: vec![], - local: Styles::new(), - style: MathStyle { - variant: MathVariant::Serif, - size: if block { MathSize::Display } else { MathSize::Text }, - cramped: false, - bold: variant.weight >= FontWeight::BOLD, - italic: match variant.style { - FontStyle::Normal => Smart::Auto, - FontStyle::Italic | FontStyle::Oblique => Smart::Custom(true), - }, - }, - size, - outer: styles, - style_stack: vec![], - } - } - - pub fn push(&mut self, fragment: impl Into) { - self.fragments.push(fragment.into()); - } - - pub fn extend(&mut self, fragments: Vec) { - self.fragments.extend(fragments); - } - - pub fn layout_fragment( - &mut self, - elem: &dyn LayoutMath, - ) -> SourceResult { - let row = self.layout_fragments(elem)?; - Ok(MathRow::new(row).into_fragment(self)) - } - - pub fn layout_fragments( - &mut self, - elem: &dyn LayoutMath, - ) -> SourceResult> { - let prev = std::mem::take(&mut self.fragments); - elem.layout_math(self)?; - Ok(std::mem::replace(&mut self.fragments, prev)) - } - - pub fn layout_row(&mut self, elem: &dyn LayoutMath) -> SourceResult { - let fragments = self.layout_fragments(elem)?; - Ok(MathRow::new(fragments)) - } - - pub fn layout_frame(&mut self, elem: &dyn LayoutMath) -> SourceResult { - Ok(self.layout_fragment(elem)?.into_frame()) - } - - pub fn layout_content(&mut self, content: &Content) -> SourceResult { - Ok(content - .layout(self.vt, self.outer.chain(&self.local), self.regions)? - .into_frame()) - } - - pub fn layout_text(&mut self, elem: &TextElem) -> SourceResult { - let text = elem.text(); - let span = elem.span(); - let mut chars = text.chars(); - let fragment = if let Some(mut glyph) = chars - .next() - .filter(|_| chars.next().is_none()) - .map(|c| self.style.styled_char(c)) - .and_then(|c| GlyphFragment::try_new(self, c, span)) - { - // A single letter that is available in the math font. - match self.style.size { - MathSize::Display => { - if glyph.class == Some(MathClass::Large) { - let height = scaled!(self, display_operator_min_height); - glyph.stretch_vertical(self, height, Abs::zero()).into() - } else { - glyph.into() - } - } - MathSize::Script => { - glyph.make_scriptsize(self); - glyph.into() - } - MathSize::ScriptScript => { - glyph.make_scriptscriptsize(self); - glyph.into() - } - _ => glyph.into(), - } - } else if text.chars().all(|c| c.is_ascii_digit()) { - // Numbers aren't that difficult. - let mut fragments = vec![]; - for c in text.chars() { - let c = self.style.styled_char(c); - fragments.push(GlyphFragment::new(self, c, span).into()); - } - let frame = MathRow::new(fragments).into_frame(self); - 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 frame = self.layout_content(&TextElem::packed(text).spanned(span))?; - FrameFragment::new(self, frame) - .with_class(MathClass::Alphabetic) - .with_spaced(spaced) - .into() - }; - Ok(fragment) - } - - pub fn styles(&self) -> StyleChain { - self.outer.chain(&self.local) - } - - pub fn realize(&mut self, content: &Content) -> SourceResult> { - realize(self.vt, content, self.outer.chain(&self.local)) - } - - pub fn style(&mut self, style: MathStyle) { - self.style_stack.push((self.style, self.size)); - let base_size = TextElem::size_in(self.styles()) / self.style.size.factor(self); - self.size = base_size * style.size.factor(self); - self.local.set(TextElem::set_size(TextSize(self.size.into()))); - self.local - .set(TextElem::set_style(if style.italic == Smart::Custom(true) { - FontStyle::Italic - } else { - FontStyle::Normal - })); - self.local.set(TextElem::set_weight(if style.bold { - FontWeight::BOLD - } else { - FontWeight::REGULAR - })); - self.style = style; - } - - pub fn unstyle(&mut self) { - (self.style, self.size) = self.style_stack.pop().unwrap(); - self.local.unset(); - self.local.unset(); - self.local.unset(); - } -} - -pub(super) trait Scaled { - fn scaled(self, ctx: &MathContext) -> Abs; -} - -impl Scaled for i16 { - fn scaled(self, ctx: &MathContext) -> Abs { - ctx.font.to_em(self).scaled(ctx) - } -} - -impl Scaled for u16 { - fn scaled(self, ctx: &MathContext) -> Abs { - ctx.font.to_em(self).scaled(ctx) - } -} - -impl Scaled for Em { - fn scaled(self, ctx: &MathContext) -> Abs { - self.at(ctx.size) - } -} - -impl Scaled for MathValue<'_> { - fn scaled(self, ctx: &MathContext) -> Abs { - self.value.scaled(ctx) - } -} -- cgit v1.2.3