summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author+merlan #flirora <uruwi@protonmail.com>2024-06-04 11:22:56 -0400
committerGitHub <noreply@github.com>2024-06-04 15:22:56 +0000
commit99b393110e622971c29d34dfb9d9d7b660131b20 (patch)
treeee906e68a9354cda6edbbfe857ef5ae9f610ba41
parent1e2e07adffcaf28704af2b26450c293711cc1352 (diff)
Align corner brackets to the top and bottom when scaling (#4200)
-rw-r--r--crates/typst/src/layout/align.rs10
-rw-r--r--crates/typst/src/math/fragment.rs12
-rw-r--r--crates/typst/src/math/lr.rs4
-rw-r--r--crates/typst/src/math/matrix.rs6
-rw-r--r--crates/typst/src/math/mod.rs10
-rw-r--r--tests/ref/issue-4188-lr-corner-brackets.pngbin0 -> 368 bytes
-rw-r--r--tests/suite/math/delimited.typ4
7 files changed, 40 insertions, 6 deletions
diff --git a/crates/typst/src/layout/align.rs b/crates/typst/src/layout/align.rs
index 95744412..18879692 100644
--- a/crates/typst/src/layout/align.rs
+++ b/crates/typst/src/layout/align.rs
@@ -416,6 +416,16 @@ impl VAlignment {
Self::Bottom => Self::Top,
}
}
+
+ /// Returns the position of this alignment in a container with the given
+ /// extent.
+ pub fn position(self, extent: Abs) -> Abs {
+ match self {
+ Self::Top => Abs::zero(),
+ Self::Horizon => extent / 2.0,
+ Self::Bottom => extent,
+ }
+ }
}
impl FixAlignment for VAlignment {
diff --git a/crates/typst/src/math/fragment.rs b/crates/typst/src/math/fragment.rs
index ef865b38..63c42cbc 100644
--- a/crates/typst/src/math/fragment.rs
+++ b/crates/typst/src/math/fragment.rs
@@ -6,7 +6,9 @@ use ttf_parser::{GlyphId, Rect};
use unicode_math_class::MathClass;
use crate::foundations::StyleChain;
-use crate::layout::{Abs, Corner, Em, Frame, FrameItem, HideElem, Point, Size};
+use crate::layout::{
+ Abs, Corner, Em, Frame, FrameItem, HideElem, Point, Size, VAlignment,
+};
use crate::math::{
scaled_font_size, EquationElem, Limits, MathContext, MathSize, Scaled,
};
@@ -408,9 +410,15 @@ impl VariantFragment {
/// Vertically adjust the fragment's frame so that it is centered
/// on the axis.
pub fn center_on_axis(&mut self, ctx: &MathContext) {
+ self.align_on_axis(ctx, VAlignment::Horizon)
+ }
+
+ /// Vertically adjust the fragment's frame so that it is aligned
+ /// to the given alignment on the axis.
+ pub fn align_on_axis(&mut self, ctx: &MathContext, align: VAlignment) {
let h = self.frame.height();
let axis = ctx.constants.axis_height().scaled(ctx, self.font_size);
- self.frame.set_baseline(h / 2.0 + axis);
+ self.frame.set_baseline(align.inv().position(h + axis * 2.0));
}
}
diff --git a/crates/typst/src/math/lr.rs b/crates/typst/src/math/lr.rs
index 671aa7df..e542b8db 100644
--- a/crates/typst/src/math/lr.rs
+++ b/crates/typst/src/math/lr.rs
@@ -10,6 +10,8 @@ use crate::math::{
};
use crate::text::TextElem;
+use super::delimiter_alignment;
+
/// How much less high scaled delimiters can be than what they wrap.
pub(super) const DELIM_SHORT_FALL: Em = Em::new(0.1);
@@ -160,7 +162,7 @@ fn scale(
let short_fall = DELIM_SHORT_FALL.at(glyph.font_size);
let mut stretched = glyph.stretch_vertical(ctx, height, short_fall);
- stretched.center_on_axis(ctx);
+ stretched.align_on_axis(ctx, delimiter_alignment(stretched.c));
*fragment = MathFragment::Variant(stretched);
if let Some(class) = apply {
diff --git a/crates/typst/src/math/matrix.rs b/crates/typst/src/math/matrix.rs
index 138a494b..2581cfee 100644
--- a/crates/typst/src/math/matrix.rs
+++ b/crates/typst/src/math/matrix.rs
@@ -20,6 +20,8 @@ use crate::text::TextElem;
use crate::utils::Numeric;
use crate::visualize::{FixedStroke, Geometry, LineCap, Shape, Stroke};
+use super::delimiter_alignment;
+
const DEFAULT_ROW_GAP: Em = Em::new(0.5);
const DEFAULT_COL_GAP: Em = Em::new(0.5);
const VERTICAL_PADDING: Ratio = Ratio::new(0.1);
@@ -610,7 +612,7 @@ fn layout_delimiters(
if let Some(left) = left {
let mut left = GlyphFragment::new(ctx, styles, left, span)
.stretch_vertical(ctx, target, short_fall);
- left.center_on_axis(ctx);
+ left.align_on_axis(ctx, delimiter_alignment(left.c));
ctx.push(left);
}
@@ -619,7 +621,7 @@ fn layout_delimiters(
if let Some(right) = right {
let mut right = GlyphFragment::new(ctx, styles, right, span)
.stretch_vertical(ctx, target, short_fall);
- right.center_on_axis(ctx);
+ right.align_on_axis(ctx, delimiter_alignment(right.c));
ctx.push(right);
}
diff --git a/crates/typst/src/math/mod.rs b/crates/typst/src/math/mod.rs
index a97f56dc..3b493b81 100644
--- a/crates/typst/src/math/mod.rs
+++ b/crates/typst/src/math/mod.rs
@@ -46,7 +46,7 @@ use crate::foundations::{
StyledElem,
};
use crate::introspection::TagElem;
-use crate::layout::{BoxElem, Frame, FrameItem, HElem, Point, Size, Spacing};
+use crate::layout::{BoxElem, Frame, FrameItem, HElem, Point, Size, Spacing, VAlignment};
use crate::realize::{process, BehavedBuilder};
use crate::text::{LinebreakElem, SpaceElem, TextElem};
@@ -317,3 +317,11 @@ impl LayoutMath for Content {
Ok(())
}
}
+
+fn delimiter_alignment(delimiter: char) -> VAlignment {
+ match delimiter {
+ '\u{231c}' | '\u{231d}' => VAlignment::Top,
+ '\u{231e}' | '\u{231f}' => VAlignment::Bottom,
+ _ => VAlignment::Horizon,
+ }
+}
diff --git a/tests/ref/issue-4188-lr-corner-brackets.png b/tests/ref/issue-4188-lr-corner-brackets.png
new file mode 100644
index 00000000..c932def2
--- /dev/null
+++ b/tests/ref/issue-4188-lr-corner-brackets.png
Binary files differ
diff --git a/tests/suite/math/delimited.typ b/tests/suite/math/delimited.typ
index 42a67c4e..632fbd40 100644
--- a/tests/suite/math/delimited.typ
+++ b/tests/suite/math/delimited.typ
@@ -62,3 +62,7 @@ $ 1/(2 y (x) (2(3)) $
// Test ignoring weak spacing immediately after the opening
// and immediately before the closing.
$ [#h(1em, weak: true)A(dif x, f(x) dif x)sum#h(1em, weak: true)] $
+
+--- issue-4188-lr-corner-brackets ---
+// Test positioning of U+231C to U+231F
+$⌜a⌟⌞b⌝$ = $⌜$$a$$⌟$$⌞$$b$$⌝$