diff options
| -rw-r--r-- | library/src/math/ctx.rs | 50 | ||||
| -rw-r--r-- | library/src/math/fragment.rs | 30 | ||||
| -rw-r--r-- | tests/ref/bugs/math-realize.png | bin | 21147 -> 21228 bytes | |||
| -rw-r--r-- | tests/ref/compiler/content-field.png | bin | 2502 -> 2423 bytes | |||
| -rw-r--r-- | tests/ref/layout/enum-numbering.png | bin | 18891 -> 19079 bytes | |||
| -rw-r--r-- | tests/ref/math/accent.png | bin | 7994 -> 8038 bytes | |||
| -rw-r--r-- | tests/ref/math/attach.png | bin | 28331 -> 28615 bytes | |||
| -rw-r--r-- | tests/ref/math/cancel.png | bin | 24698 -> 24765 bytes | |||
| -rw-r--r-- | tests/ref/math/cases.png | bin | 3134 -> 2947 bytes | |||
| -rw-r--r-- | tests/ref/math/content.png | bin | 8357 -> 7883 bytes | |||
| -rw-r--r-- | tests/ref/math/delimited.png | bin | 22993 -> 23111 bytes | |||
| -rw-r--r-- | tests/ref/math/frac.png | bin | 24197 -> 24117 bytes | |||
| -rw-r--r-- | tests/ref/math/matrix.png | bin | 25677 -> 25872 bytes | |||
| -rw-r--r-- | tests/ref/math/multiline.png | bin | 13698 -> 13479 bytes | |||
| -rw-r--r-- | tests/ref/math/numbering.png | bin | 12028 -> 12019 bytes | |||
| -rw-r--r-- | tests/ref/math/op.png | bin | 6817 -> 6730 bytes | |||
| -rw-r--r-- | tests/ref/math/opticalsize.png | bin | 0 -> 6897 bytes | |||
| -rw-r--r-- | tests/ref/math/root.png | bin | 12274 -> 12575 bytes | |||
| -rw-r--r-- | tests/ref/math/spacing.png | bin | 17618 -> 18271 bytes | |||
| -rw-r--r-- | tests/ref/math/style.png | bin | 27879 -> 23804 bytes | |||
| -rw-r--r-- | tests/ref/math/syntax.png | bin | 4850 -> 4977 bytes | |||
| -rw-r--r-- | tests/ref/math/unbalanced.png | bin | 2482 -> 2443 bytes | |||
| -rw-r--r-- | tests/ref/math/underover.png | bin | 4819 -> 4797 bytes | |||
| -rw-r--r-- | tests/ref/meta/figure.png | bin | 59579 -> 49894 bytes | |||
| -rw-r--r-- | tests/typ/math/op.typ | 1 | ||||
| -rw-r--r-- | tests/typ/math/opticalsize.typ | 30 |
26 files changed, 103 insertions, 8 deletions
diff --git a/library/src/math/ctx.rs b/library/src/math/ctx.rs index a6487476..a1dc6cf4 100644 --- a/library/src/math/ctx.rs +++ b/library/src/math/ctx.rs @@ -31,6 +31,7 @@ pub struct MathContext<'a, 'b, 'v> { 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<ttf_parser::gsub::AlternateSubstitution<'a>>, pub space_width: Em, pub fragments: Vec<MathFragment>, pub local: Styles, @@ -50,6 +51,27 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { ) -> 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::<ttf_parser::gsub::SubstitutionSubtable>(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 @@ -66,6 +88,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { ttf: font.ttf(), table, constants, + ssty_table, space_width, fragments: vec![], local: Styles::new(), @@ -129,20 +152,31 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> { let text = elem.text(); let span = elem.span(); let mut chars = text.chars(); - let fragment = if let Some(glyph) = 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. - if self.style.size == MathSize::Display - && glyph.class == Some(MathClass::Large) - { - let height = scaled!(self, display_operator_min_height); - glyph.stretch_vertical(self, height, Abs::zero()).into() - } else { - glyph.into() + 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. diff --git a/library/src/math/fragment.rs b/library/src/math/fragment.rs index b70a3f7d..139ce07b 100644 --- a/library/src/math/fragment.rs +++ b/library/src/math/fragment.rs @@ -1,4 +1,5 @@ use super::*; +use ttf_parser::gsub::AlternateSet; #[derive(Debug, Clone)] pub enum MathFragment { @@ -272,6 +273,25 @@ impl GlyphFragment { frame.meta_iter(self.meta); frame } + + pub fn make_scriptsize(&mut self, ctx: &MathContext) { + let alt_id = + script_alternatives(ctx, self.id).and_then(|alts| alts.alternates.get(0)); + + if let Some(alt_id) = alt_id { + self.set_id(ctx, alt_id); + } + } + + pub fn make_scriptscriptsize(&mut self, ctx: &MathContext) { + let alts = script_alternatives(ctx, self.id); + let alt_id = alts + .and_then(|alts| alts.alternates.get(1).or_else(|| alts.alternates.get(0))); + + if let Some(alt_id) = alt_id { + self.set_id(ctx, alt_id); + } + } } impl Debug for GlyphFragment { @@ -347,6 +367,16 @@ fn italics_correction(ctx: &MathContext, id: GlyphId) -> Option<Abs> { Some(ctx.table.glyph_info?.italic_corrections?.get(id)?.scaled(ctx)) } +/// Look up the script/scriptscript alternates for a glyph +fn script_alternatives<'a>( + ctx: &MathContext<'a, '_, '_>, + id: GlyphId, +) -> Option<AlternateSet<'a>> { + ctx.ssty_table.and_then(|ssty| { + ssty.coverage.get(id).and_then(|index| ssty.alternate_sets.get(index)) + }) +} + /// Look up the italics correction for a glyph. fn is_extended_shape(ctx: &MathContext, id: GlyphId) -> bool { ctx.table diff --git a/tests/ref/bugs/math-realize.png b/tests/ref/bugs/math-realize.png Binary files differindex 4f5b887e..2a17f629 100644 --- a/tests/ref/bugs/math-realize.png +++ b/tests/ref/bugs/math-realize.png diff --git a/tests/ref/compiler/content-field.png b/tests/ref/compiler/content-field.png Binary files differindex d2f696b4..cef3274a 100644 --- a/tests/ref/compiler/content-field.png +++ b/tests/ref/compiler/content-field.png diff --git a/tests/ref/layout/enum-numbering.png b/tests/ref/layout/enum-numbering.png Binary files differindex 28755dcb..e1b2103b 100644 --- a/tests/ref/layout/enum-numbering.png +++ b/tests/ref/layout/enum-numbering.png diff --git a/tests/ref/math/accent.png b/tests/ref/math/accent.png Binary files differindex 11de9e28..5a963b38 100644 --- a/tests/ref/math/accent.png +++ b/tests/ref/math/accent.png diff --git a/tests/ref/math/attach.png b/tests/ref/math/attach.png Binary files differindex 894f553f..9d01e7bf 100644 --- a/tests/ref/math/attach.png +++ b/tests/ref/math/attach.png diff --git a/tests/ref/math/cancel.png b/tests/ref/math/cancel.png Binary files differindex 96b29c45..571edcc2 100644 --- a/tests/ref/math/cancel.png +++ b/tests/ref/math/cancel.png diff --git a/tests/ref/math/cases.png b/tests/ref/math/cases.png Binary files differindex c9eca24c..c824a801 100644 --- a/tests/ref/math/cases.png +++ b/tests/ref/math/cases.png diff --git a/tests/ref/math/content.png b/tests/ref/math/content.png Binary files differindex f7af513b..ce727e66 100644 --- a/tests/ref/math/content.png +++ b/tests/ref/math/content.png diff --git a/tests/ref/math/delimited.png b/tests/ref/math/delimited.png Binary files differindex e9f6e2c1..31d15b41 100644 --- a/tests/ref/math/delimited.png +++ b/tests/ref/math/delimited.png diff --git a/tests/ref/math/frac.png b/tests/ref/math/frac.png Binary files differindex a116c876..80327578 100644 --- a/tests/ref/math/frac.png +++ b/tests/ref/math/frac.png diff --git a/tests/ref/math/matrix.png b/tests/ref/math/matrix.png Binary files differindex d3d2681c..bf90e712 100644 --- a/tests/ref/math/matrix.png +++ b/tests/ref/math/matrix.png diff --git a/tests/ref/math/multiline.png b/tests/ref/math/multiline.png Binary files differindex ae847434..84dcb87d 100644 --- a/tests/ref/math/multiline.png +++ b/tests/ref/math/multiline.png diff --git a/tests/ref/math/numbering.png b/tests/ref/math/numbering.png Binary files differindex 6256310f..3952dea0 100644 --- a/tests/ref/math/numbering.png +++ b/tests/ref/math/numbering.png diff --git a/tests/ref/math/op.png b/tests/ref/math/op.png Binary files differindex 08d8b93b..15c7329d 100644 --- a/tests/ref/math/op.png +++ b/tests/ref/math/op.png diff --git a/tests/ref/math/opticalsize.png b/tests/ref/math/opticalsize.png Binary files differnew file mode 100644 index 00000000..9fec5520 --- /dev/null +++ b/tests/ref/math/opticalsize.png diff --git a/tests/ref/math/root.png b/tests/ref/math/root.png Binary files differindex 8a6a6e13..017582a4 100644 --- a/tests/ref/math/root.png +++ b/tests/ref/math/root.png diff --git a/tests/ref/math/spacing.png b/tests/ref/math/spacing.png Binary files differindex 2fd30e53..abcfae80 100644 --- a/tests/ref/math/spacing.png +++ b/tests/ref/math/spacing.png diff --git a/tests/ref/math/style.png b/tests/ref/math/style.png Binary files differindex 39ecc441..cec04ba5 100644 --- a/tests/ref/math/style.png +++ b/tests/ref/math/style.png diff --git a/tests/ref/math/syntax.png b/tests/ref/math/syntax.png Binary files differindex 3d09723d..028e21d6 100644 --- a/tests/ref/math/syntax.png +++ b/tests/ref/math/syntax.png diff --git a/tests/ref/math/unbalanced.png b/tests/ref/math/unbalanced.png Binary files differindex 5b4d7736..de0ee1db 100644 --- a/tests/ref/math/unbalanced.png +++ b/tests/ref/math/unbalanced.png diff --git a/tests/ref/math/underover.png b/tests/ref/math/underover.png Binary files differindex 5c825b18..24c96b21 100644 --- a/tests/ref/math/underover.png +++ b/tests/ref/math/underover.png diff --git a/tests/ref/meta/figure.png b/tests/ref/meta/figure.png Binary files differindex 524f6cfd..90f59d14 100644 --- a/tests/ref/meta/figure.png +++ b/tests/ref/meta/figure.png diff --git a/tests/typ/math/op.typ b/tests/typ/math/op.typ index 08395de0..2a0f84fc 100644 --- a/tests/typ/math/op.typ +++ b/tests/typ/math/op.typ @@ -11,6 +11,7 @@ $ &sin x + log_2 x \ --- // Test scripts vs limits. +#set page(width: auto) #set text(font: "New Computer Modern") Discuss $lim_(n->oo) 1/n$ now. $ lim_(n->infinity) 1/n = 0 $ diff --git a/tests/typ/math/opticalsize.typ b/tests/typ/math/opticalsize.typ new file mode 100644 index 00000000..c96e4a32 --- /dev/null +++ b/tests/typ/math/opticalsize.typ @@ -0,0 +1,30 @@ +// test optical sized variants in sub/superscripts + +--- + +// Test transition from script to scriptscript. +#[ +#set text(size:20pt) +$ e^(e^(e^(e))) $ +] +A large number: $e^(e^(e^(e)))$. + +--- +// Test prime/double prime via scriptsize +#let prime = [ \u{2032} ] +#let dprime = [ \u{2033} ] +#let tprime = [ \u{2034} ] +$ y^dprime-2y^prime + y = 0 $ +$y^dprime-2y^prime + y = 0$ +$ y^tprime_3 + g^(prime 2) $ + +--- +// Test prime superscript on large symbol +$ scripts(sum_(k in NN))^prime 1/k^2 $ +$sum_(k in NN)^prime 1/k^2$ + +--- +// Test script-script in a fraction. +$ 1/(x^A) $ +#[#set text(size:18pt); $1/(x^A)$] vs. #[#set text(size:14pt); $x^A$] + |
