Fix zero-sized patterns

This commit is contained in:
Laurenz 2023-12-04 12:41:19 +01:00
parent 7f10d3282e
commit 962108d168
2 changed files with 16 additions and 9 deletions

View File

@ -134,6 +134,8 @@ impl Pattern {
#[func(constructor)] #[func(constructor)]
pub fn construct( pub fn construct(
engine: &mut Engine, engine: &mut Engine,
/// The callsite span.
span: Span,
/// The bounding box of each cell of the pattern. /// The bounding box of each cell of the pattern.
#[named] #[named]
#[default(Spanned::new(Smart::Auto, Span::detached()))] #[default(Spanned::new(Smart::Auto, Span::detached()))]
@ -154,11 +156,11 @@ impl Pattern {
/// The content of each cell of the pattern. /// The content of each cell of the pattern.
body: Content, body: Content,
) -> SourceResult<Pattern> { ) -> SourceResult<Pattern> {
let span = size.span; let size_span = size.span;
if let Smart::Custom(size) = size.v { if let Smart::Custom(size) = size.v {
// Ensure that sizes are absolute. // Ensure that sizes are absolute.
if !size.x.em.is_zero() || !size.y.em.is_zero() { if !size.x.em.is_zero() || !size.y.em.is_zero() {
bail!(span, "pattern tile size must be absolute"); bail!(size_span, "pattern tile size must be absolute");
} }
// Ensure that sizes are non-zero and finite. // Ensure that sizes are non-zero and finite.
@ -167,7 +169,7 @@ impl Pattern {
|| !size.x.is_finite() || !size.x.is_finite()
|| !size.y.is_finite() || !size.y.is_finite()
{ {
bail!(span, "pattern tile size must be non-zero and non-infinite"); bail!(size_span, "pattern tile size must be non-zero and non-infinite");
} }
} }
@ -192,19 +194,19 @@ impl Pattern {
let pod = Regions::one(region, Axes::splat(false)); let pod = Regions::one(region, Axes::splat(false));
let mut frame = body.layout(engine, styles, pod)?.into_frame(); let mut frame = body.layout(engine, styles, pod)?.into_frame();
// Set the size of the frame if the size is enforced.
if let Smart::Custom(size) = size {
frame.set_size(size);
}
// Check that the frame is non-zero. // Check that the frame is non-zero.
if size.is_auto() && frame.size().is_zero() { if frame.width().is_zero() || frame.height().is_zero() {
bail!( bail!(
span, "pattern tile size must be non-zero"; span, "pattern tile size must be non-zero";
hint: "try setting the size manually" hint: "try setting the size manually"
); );
} }
// Set the size of the frame if the size is enforced.
if let Smart::Custom(size) = size {
frame.set_size(size);
}
Ok(Self(Arc::new(Repr { Ok(Self(Arc::new(Repr {
size: frame.size(), size: frame.size(),
frame: Prehashed::new(frame), frame: Prehashed::new(frame),

View File

@ -12,3 +12,8 @@
height: 1pt, height: 1pt,
fill: pattern(size: (2pt, 1pt), square(size: 1pt, fill: black)) fill: pattern(size: (2pt, 1pt), square(size: 1pt, fill: black))
) )
---
// Error: 22-52 pattern tile size must be non-zero
// Hint: 22-52 try setting the size manually
#line(stroke: pattern(path((0pt, 0pt), (1em, 0pt))))