mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
parent
d03af848eb
commit
9a71e7263d
@ -925,18 +925,22 @@ fn breakable_pod<'a>(
|
||||
/// height and a new backlog.
|
||||
fn distribute<'a>(
|
||||
height: Abs,
|
||||
regions: Regions,
|
||||
mut regions: Regions,
|
||||
buf: &'a mut SmallVec<[Abs; 2]>,
|
||||
) -> (Abs, &'a mut [Abs]) {
|
||||
// Build new region heights from old regions.
|
||||
let mut remaining = height;
|
||||
for region in regions.iter() {
|
||||
let limited = region.y.min(remaining);
|
||||
loop {
|
||||
let limited = regions.size.y.clamp(Abs::zero(), remaining);
|
||||
buf.push(limited);
|
||||
remaining -= limited;
|
||||
if remaining.approx_empty() {
|
||||
if remaining.approx_empty()
|
||||
|| !regions.may_break()
|
||||
|| (!regions.may_progress() && limited.approx_empty())
|
||||
{
|
||||
break;
|
||||
}
|
||||
regions.next();
|
||||
}
|
||||
|
||||
// If there is still something remaining, apply it to the
|
||||
|
@ -282,7 +282,7 @@ impl<'a, 'b> Composer<'a, 'b, '_, '_> {
|
||||
let need = frame.height() + clearance;
|
||||
|
||||
// If the float doesn't fit, queue it for the next region.
|
||||
if !remaining.fits(need) && !regions.in_last() {
|
||||
if !remaining.fits(need) && regions.may_progress() {
|
||||
self.work.floats.push(placed);
|
||||
return Ok(());
|
||||
}
|
||||
@ -343,7 +343,7 @@ impl<'a, 'b> Composer<'a, 'b, '_, '_> {
|
||||
|
||||
let mut relayout = false;
|
||||
let mut regions = *regions;
|
||||
let mut migratable = !breakable && !regions.in_last();
|
||||
let mut migratable = !breakable && regions.may_progress();
|
||||
|
||||
for (y, elem) in notes {
|
||||
// The amount of space used by the in-flow content that contains the
|
||||
|
@ -194,9 +194,9 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
|
||||
|
||||
/// Processes a line of a paragraph.
|
||||
fn line(&mut self, line: &'b LineChild) -> FlowResult<()> {
|
||||
// If the line doesn't fit and we're allowed to break, finish the
|
||||
// region.
|
||||
if !self.regions.size.y.fits(line.frame.height()) && !self.regions.in_last() {
|
||||
// If the line doesn't fit and a followup region may improve things,
|
||||
// finish the region.
|
||||
if !self.regions.size.y.fits(line.frame.height()) && self.regions.may_progress() {
|
||||
return Err(Stop::Finish(false));
|
||||
}
|
||||
|
||||
@ -228,9 +228,9 @@ impl<'a, 'b> Distributor<'a, 'b, '_, '_, '_> {
|
||||
// Lay out the block.
|
||||
let frame = single.layout(self.composer.engine, self.regions.base())?;
|
||||
|
||||
// If the block doesn't fit and we're allowed to break, finish the
|
||||
// region.
|
||||
if !self.regions.size.y.fits(frame.height()) && !self.regions.in_last() {
|
||||
// If the block doesn't fit and a followup region may improve things,
|
||||
// finish the region.
|
||||
if !self.regions.size.y.fits(frame.height()) && self.regions.may_progress() {
|
||||
return Err(Stop::Finish(false));
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ impl<'a> GridLayouter<'a> {
|
||||
let mut skipped_region = false;
|
||||
while self.unbreakable_rows_left == 0
|
||||
&& !self.regions.size.y.fits(header_rows.height + self.footer_height)
|
||||
&& !self.regions.in_last()
|
||||
&& self.regions.may_progress()
|
||||
{
|
||||
// Advance regions without any output until we can place the
|
||||
// header and the footer.
|
||||
@ -124,7 +124,7 @@ impl<'a> GridLayouter<'a> {
|
||||
let mut skipped_region = false;
|
||||
while self.unbreakable_rows_left == 0
|
||||
&& !self.regions.size.y.fits(footer_height)
|
||||
&& !self.regions.in_last()
|
||||
&& self.regions.may_progress()
|
||||
{
|
||||
// Advance regions without any output until we can place the
|
||||
// footer.
|
||||
|
@ -1147,7 +1147,7 @@ impl<'a> RowspanSimulator<'a> {
|
||||
|
||||
// Skip until we reach a fitting region for both header and footer.
|
||||
while !self.regions.size.y.fits(header_height + footer_height)
|
||||
&& !self.regions.in_last()
|
||||
&& self.regions.may_progress()
|
||||
{
|
||||
self.regions.next();
|
||||
self.finished += 1;
|
||||
|
@ -96,14 +96,18 @@ impl Regions<'_> {
|
||||
|
||||
/// Whether the first region is full and a region break is called for.
|
||||
pub fn is_full(&self) -> bool {
|
||||
Abs::zero().fits(self.size.y) && !self.in_last()
|
||||
Abs::zero().fits(self.size.y) && self.may_progress()
|
||||
}
|
||||
|
||||
/// Whether the first region is the last usable region.
|
||||
///
|
||||
/// If this is true, calling `next()` will have no effect.
|
||||
pub fn in_last(&self) -> bool {
|
||||
self.backlog.is_empty() && self.last.map_or(true, |height| self.size.y == height)
|
||||
/// Whether a region break is permitted.
|
||||
pub fn may_break(&self) -> bool {
|
||||
!self.backlog.is_empty() || self.last.is_some()
|
||||
}
|
||||
|
||||
/// Whether calling `next()` may improve a situation where there is a lack
|
||||
/// of space.
|
||||
pub fn may_progress(&self) -> bool {
|
||||
!self.backlog.is_empty() || self.last.is_some_and(|height| self.size.y != height)
|
||||
}
|
||||
|
||||
/// Advance to the next region if there is any.
|
||||
|
@ -327,8 +327,9 @@ fn layout_equation_block(
|
||||
let mut rows = full_equation_builder.frames.into_iter().peekable();
|
||||
let mut equation_builders = vec![];
|
||||
let mut last_first_pos = Point::zero();
|
||||
let mut regions = regions;
|
||||
|
||||
for region in regions.iter() {
|
||||
loop {
|
||||
// Keep track of the position of the first row in this region,
|
||||
// so that the offset can be reverted later.
|
||||
let Some(&(_, first_pos)) = rows.peek() else { break };
|
||||
@ -344,8 +345,9 @@ fn layout_equation_block(
|
||||
// we placed at least one line _or_ we still have non-last
|
||||
// regions. Crucially, we don't want to infinitely create
|
||||
// new regions which are too small.
|
||||
if !region.y.fits(sub.height() + pos.y)
|
||||
&& (!frames.is_empty() || !regions.in_last())
|
||||
if !regions.size.y.fits(sub.height() + pos.y)
|
||||
&& (regions.may_progress()
|
||||
|| (regions.may_break() && !frames.is_empty()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -357,6 +359,7 @@ fn layout_equation_block(
|
||||
|
||||
equation_builders
|
||||
.push(MathRunFrameBuilder { frames, size: Size::new(width, height) });
|
||||
regions.next();
|
||||
}
|
||||
|
||||
// Append remaining rows to the equation builder of the last region.
|
||||
|
BIN
tests/ref/issue-5044-pad-100-percent.png
Normal file
BIN
tests/ref/issue-5044-pad-100-percent.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 B |
@ -28,3 +28,7 @@ Hi #box(pad(left: 10pt)[A]) there
|
||||
--- pad-adding-to-100-percent ---
|
||||
// Test that padding adding up to 100% does not panic.
|
||||
#pad(50%)[]
|
||||
|
||||
--- issue-5044-pad-100-percent ---
|
||||
#set page(width: 30pt, height: 30pt)
|
||||
#pad(100%, block(width: 1cm, height: 1cm, fill: red))
|
||||
|
Loading…
x
Reference in New Issue
Block a user