summaryrefslogtreecommitdiff
path: root/library/src/math/attach.rs
diff options
context:
space:
mode:
authorsitandr <60141933+sitandr@users.noreply.github.com>2023-06-20 17:58:22 +0300
committerGitHub <noreply@github.com>2023-06-20 16:58:22 +0200
commit03675fc429bd4e7aa71890922e359940cbf3c2ca (patch)
tree12ded38940afdc682e9d9d5b616ce2499992db15 /library/src/math/attach.rs
parent6c542ea1a4a0ee85069dad6974ff331851eff406 (diff)
Created new system for limits (fixes #1443) (#1452)
Diffstat (limited to 'library/src/math/attach.rs')
-rw-r--r--library/src/math/attach.rs79
1 files changed, 54 insertions, 25 deletions
diff --git a/library/src/math/attach.rs b/library/src/math/attach.rs
index cbf083c0..eee1e80e 100644
--- a/library/src/math/attach.rs
+++ b/library/src/math/attach.rs
@@ -77,18 +77,9 @@ impl LayoutMath for AttachElem {
let b = layout_attachment(ctx, Self::b)?;
ctx.unstyle();
- let as_limits = self.base().is::<LimitsElem>()
- || (!self.base().is::<ScriptsElem>()
- && ctx.style.size == MathSize::Display
- && base.class() == Some(MathClass::Large)
- && match &base {
- MathFragment::Variant(variant) => LIMITS.contains(&variant.c),
- MathFragment::Frame(fragment) => fragment.limits,
- _ => false,
- });
-
- let (t, tr) = if as_limits || tr.is_some() { (t, tr) } else { (None, t) };
- let (b, br) = if as_limits || br.is_some() { (b, br) } else { (None, b) };
+ let limits = base.limits().active(ctx);
+ let (t, tr) = if limits || tr.is_some() { (t, tr) } else { (None, t) };
+ let (b, br) = if limits || br.is_some() { (b, br) } else { (None, b) };
layout_attachments(ctx, base, [tl, t, tr, bl, b, br])
}
}
@@ -112,7 +103,10 @@ pub struct ScriptsElem {
impl LayoutMath for ScriptsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- self.body().layout_math(ctx)
+ let mut fragment = ctx.layout_fragment(&self.body())?;
+ fragment.set_limits(Limits::Never);
+ ctx.push(fragment);
+ Ok(())
}
}
@@ -135,10 +129,56 @@ pub struct LimitsElem {
impl LayoutMath for LimitsElem {
#[tracing::instrument(skip(ctx))]
fn layout_math(&self, ctx: &mut MathContext) -> SourceResult<()> {
- self.body().layout_math(ctx)
+ let mut fragment = ctx.layout_fragment(&self.body())?;
+ fragment.set_limits(Limits::Always);
+ ctx.push(fragment);
+ Ok(())
}
}
+/// Describes in which situation a frame should use limits for attachments.
+#[derive(Debug, Copy, Clone)]
+pub enum Limits {
+ /// Always scripts.
+ Never,
+ /// Display limits only in `display` math.
+ Display,
+ /// Always limits.
+ Always,
+}
+
+impl Limits {
+ /// The default limit configuration if the given character is the base.
+ pub fn for_char(c: char) -> Self {
+ if Self::DEFAULT_TO_LIMITS.contains(&c) {
+ Limits::Display
+ } else {
+ Limits::Never
+ }
+ }
+
+ /// Whether limits should be displayed in this context
+ pub fn active(&self, ctx: &MathContext) -> bool {
+ match self {
+ Self::Always => true,
+ Self::Display => ctx.style.size == MathSize::Display,
+ Self::Never => false,
+ }
+ }
+
+ /// Unicode codepoints that should show attachments as limits in display
+ /// mode.
+ #[rustfmt::skip]
+ const DEFAULT_TO_LIMITS: &[char] = &[
+ /* ∏ */ '\u{220F}', /* ∐ */ '\u{2210}', /* ∑ */ '\u{2211}',
+ /* ⋀ */ '\u{22C0}', /* ⋁ */ '\u{22C1}',
+ /* ⋂ */ '\u{22C2}', /* ⋃ */ '\u{22C3}',
+ /* ⨀ */ '\u{2A00}', /* ⨁ */ '\u{2A01}', /* ⨂ */ '\u{2A02}',
+ /* ⨃ */ '\u{2A03}', /* ⨄ */ '\u{2A04}',
+ /* ⨅ */ '\u{2A05}', /* ⨆ */ '\u{2A06}',
+ ];
+}
+
macro_rules! measure {
($e: ident, $attr: ident) => {
$e.as_ref().map(|e| e.$attr()).unwrap_or_default()
@@ -358,14 +398,3 @@ fn is_atomic_text_frame(frame: &Frame) -> bool {
.filter(|item| !matches!(item, FrameItem::Meta(_, _)));
matches!(iter.next(), Some(FrameItem::Text(_))) && iter.next().is_none()
}
-
-/// Unicode codepoints that should have sub- and superscripts attached as limits.
-#[rustfmt::skip]
-const LIMITS: &[char] = &[
- /* ∏ */ '\u{220F}', /* ∐ */ '\u{2210}', /* ∑ */ '\u{2211}',
- /* ⋀ */ '\u{22C0}', /* ⋁ */ '\u{22C1}',
- /* ⋂ */ '\u{22C2}', /* ⋃ */ '\u{22C3}',
- /* ⨀ */ '\u{2A00}', /* ⨁ */ '\u{2A01}', /* ⨂ */ '\u{2A02}',
- /* ⨃ */ '\u{2A03}', /* ⨄ */ '\u{2A04}',
- /* ⨅ */ '\u{2A05}', /* ⨆ */ '\u{2A06}',
-];