summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst-layout/src/flow/block.rs18
-rw-r--r--crates/typst-layout/src/flow/mod.rs20
-rw-r--r--tests/ref/issue-5262-block-negative-height-implicit.pngbin0 -> 72 bytes
-rw-r--r--tests/ref/issue-5262-block-negative-height-in-flow.pngbin0 -> 236 bytes
-rw-r--r--tests/ref/issue-5262-block-negative-height.pngbin0 -> 73 bytes
-rw-r--r--tests/ref/issue-5262-text-negative-size.pngbin0 -> 73 bytes
-rw-r--r--tests/suite/layout/container.typ14
-rw-r--r--tests/suite/text/font.typ5
8 files changed, 55 insertions, 2 deletions
diff --git a/crates/typst-layout/src/flow/block.rs b/crates/typst-layout/src/flow/block.rs
index 71eacc1c..6c2c3923 100644
--- a/crates/typst-layout/src/flow/block.rs
+++ b/crates/typst-layout/src/flow/block.rs
@@ -364,6 +364,12 @@ fn breakable_pod<'a>(
/// Distribute a fixed height spread over existing regions into a new first
/// height and a new backlog.
+///
+/// Note that, if the given height fits within the first region, no backlog is
+/// generated and the first region's height shrinks to fit exactly the given
+/// height. In particular, negative and zero heights always fit in any region,
+/// so such heights are always directly returned as the new first region
+/// height.
fn distribute<'a>(
height: Abs,
mut regions: Regions,
@@ -371,7 +377,19 @@ fn distribute<'a>(
) -> (Abs, &'a mut [Abs]) {
// Build new region heights from old regions.
let mut remaining = height;
+
+ // Negative and zero heights always fit, so just keep them.
+ // No backlog is generated.
+ if remaining <= Abs::zero() {
+ buf.push(remaining);
+ return (buf[0], &mut buf[1..]);
+ }
+
loop {
+ // This clamp is safe (min <= max), as 'remaining' won't be negative
+ // due to the initial check above (on the first iteration) and due to
+ // stopping on 'remaining.approx_empty()' below (for the second
+ // iteration onwards).
let limited = regions.size.y.clamp(Abs::zero(), remaining);
buf.push(limited);
remaining -= limited;
diff --git a/crates/typst-layout/src/flow/mod.rs b/crates/typst-layout/src/flow/mod.rs
index df716b33..2f0ec39a 100644
--- a/crates/typst-layout/src/flow/mod.rs
+++ b/crates/typst-layout/src/flow/mod.rs
@@ -203,8 +203,14 @@ pub(crate) fn layout_flow(
} else {
PageElem::width_in(shared)
};
- (0.026 * width.unwrap_or_default())
- .clamp(Em::new(0.75).resolve(shared), Em::new(2.5).resolve(shared))
+
+ // Clamp below is safe (min <= max): if the font size is
+ // negative, we set min = max = 0; otherwise,
+ // `0.75 * size <= 2.5 * size` for zero and positive sizes.
+ (0.026 * width.unwrap_or_default()).clamp(
+ Em::new(0.75).resolve(shared).max(Abs::zero()),
+ Em::new(2.5).resolve(shared).max(Abs::zero()),
+ )
},
}),
};
@@ -354,6 +360,16 @@ struct LineNumberConfig {
/// Where line numbers are reset.
scope: LineNumberingScope,
/// The default clearance for `auto`.
+ ///
+ /// This value should be relative to the page's width, such that the
+ /// clearance between line numbers and text is small when the page is,
+ /// itself, small. However, that could cause the clearance to be too small
+ /// or too large when considering the current text size; in particular, a
+ /// larger text size would require more clearance to be able to tell line
+ /// numbers apart from text, whereas a smaller text size requires less
+ /// clearance so they aren't way too far apart. Therefore, the default
+ /// value is a percentage of the page width clamped between `0.75em` and
+ /// `2.5em`.
default_clearance: Abs,
}
diff --git a/tests/ref/issue-5262-block-negative-height-implicit.png b/tests/ref/issue-5262-block-negative-height-implicit.png
new file mode 100644
index 00000000..3b7b289b
--- /dev/null
+++ b/tests/ref/issue-5262-block-negative-height-implicit.png
Binary files differ
diff --git a/tests/ref/issue-5262-block-negative-height-in-flow.png b/tests/ref/issue-5262-block-negative-height-in-flow.png
new file mode 100644
index 00000000..402c5810
--- /dev/null
+++ b/tests/ref/issue-5262-block-negative-height-in-flow.png
Binary files differ
diff --git a/tests/ref/issue-5262-block-negative-height.png b/tests/ref/issue-5262-block-negative-height.png
new file mode 100644
index 00000000..1a1146d8
--- /dev/null
+++ b/tests/ref/issue-5262-block-negative-height.png
Binary files differ
diff --git a/tests/ref/issue-5262-text-negative-size.png b/tests/ref/issue-5262-text-negative-size.png
new file mode 100644
index 00000000..61e6dbae
--- /dev/null
+++ b/tests/ref/issue-5262-text-negative-size.png
Binary files differ
diff --git a/tests/suite/layout/container.typ b/tests/suite/layout/container.typ
index 9948a00e..bb53a041 100644
--- a/tests/suite/layout/container.typ
+++ b/tests/suite/layout/container.typ
@@ -304,3 +304,17 @@ b
#block(sticky: true)[*A*]
b
+
+--- issue-5262-block-negative-height ---
+#block(height: -1pt)[]
+
+--- issue-5262-block-negative-height-implicit ---
+#set page(height: 10pt, margin: (top: 9pt))
+#block(height: 100%)[]
+
+--- issue-5262-block-negative-height-in-flow ---
+// The contents after the block should be pushed upwards.
+#set page(height: 60pt)
+a
+#block(height: -25pt)[b]
+c
diff --git a/tests/suite/text/font.typ b/tests/suite/text/font.typ
index 5af8dcb9..9e5c0150 100644
--- a/tests/suite/text/font.typ
+++ b/tests/suite/text/font.typ
@@ -149,3 +149,8 @@ The number 123.
// Error: 17-65 coverage regex may only use dot, letters, and character classes
// Hint: 17-65 the regex is applied to each letter individually
#set text(font: (name: "Ubuntu", covers: regex("\u{20}-\u{10}")))
+
+--- issue-5262-text-negative-size ---
+#set text(-1pt)
+
+a