mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Fix crash when block or text have negative sizes (#5610)
This commit is contained in:
parent
370aa5929f
commit
6c2d54bbe3
@ -364,6 +364,12 @@ fn breakable_pod<'a>(
|
|||||||
|
|
||||||
/// Distribute a fixed height spread over existing regions into a new first
|
/// Distribute a fixed height spread over existing regions into a new first
|
||||||
/// height and a new backlog.
|
/// 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>(
|
fn distribute<'a>(
|
||||||
height: Abs,
|
height: Abs,
|
||||||
mut regions: Regions,
|
mut regions: Regions,
|
||||||
@ -371,7 +377,19 @@ fn distribute<'a>(
|
|||||||
) -> (Abs, &'a mut [Abs]) {
|
) -> (Abs, &'a mut [Abs]) {
|
||||||
// Build new region heights from old regions.
|
// Build new region heights from old regions.
|
||||||
let mut remaining = height;
|
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 {
|
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);
|
let limited = regions.size.y.clamp(Abs::zero(), remaining);
|
||||||
buf.push(limited);
|
buf.push(limited);
|
||||||
remaining -= limited;
|
remaining -= limited;
|
||||||
|
@ -203,8 +203,14 @@ pub(crate) fn layout_flow(
|
|||||||
} else {
|
} else {
|
||||||
PageElem::width_in(shared)
|
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.
|
/// Where line numbers are reset.
|
||||||
scope: LineNumberingScope,
|
scope: LineNumberingScope,
|
||||||
/// The default clearance for `auto`.
|
/// 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,
|
default_clearance: Abs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BIN
tests/ref/issue-5262-block-negative-height-implicit.png
Normal file
BIN
tests/ref/issue-5262-block-negative-height-implicit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 B |
BIN
tests/ref/issue-5262-block-negative-height-in-flow.png
Normal file
BIN
tests/ref/issue-5262-block-negative-height-in-flow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 236 B |
BIN
tests/ref/issue-5262-block-negative-height.png
Normal file
BIN
tests/ref/issue-5262-block-negative-height.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 B |
BIN
tests/ref/issue-5262-text-negative-size.png
Normal file
BIN
tests/ref/issue-5262-text-negative-size.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 73 B |
@ -304,3 +304,17 @@ b
|
|||||||
#block(sticky: true)[*A*]
|
#block(sticky: true)[*A*]
|
||||||
|
|
||||||
b
|
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
|
||||||
|
@ -149,3 +149,8 @@ The number 123.
|
|||||||
// Error: 17-65 coverage regex may only use dot, letters, and character classes
|
// Error: 17-65 coverage regex may only use dot, letters, and character classes
|
||||||
// Hint: 17-65 the regex is applied to each letter individually
|
// Hint: 17-65 the regex is applied to each letter individually
|
||||||
#set text(font: (name: "Ubuntu", covers: regex("\u{20}-\u{10}")))
|
#set text(font: (name: "Ubuntu", covers: regex("\u{20}-\u{10}")))
|
||||||
|
|
||||||
|
--- issue-5262-text-negative-size ---
|
||||||
|
#set text(-1pt)
|
||||||
|
|
||||||
|
a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user