Fix box and block sizing

This commit is contained in:
Laurenz 2023-04-06 12:25:55 +02:00
parent 23a884a67f
commit f9b9be16f9
7 changed files with 37 additions and 6 deletions

View File

@ -132,6 +132,9 @@ impl Layout for BoxElem {
let pod = Regions::one(size, expand); let pod = Regions::one(size, expand);
let mut frame = body.layout(vt, styles, pod)?.into_frame(); let mut frame = body.layout(vt, styles, pod)?.into_frame();
// Enforce correct size.
*frame.size_mut() = expand.select(size, frame.size());
// Apply baseline shift. // Apply baseline shift.
let shift = self.baseline(styles).relative_to(frame.height()); let shift = self.baseline(styles).relative_to(frame.height());
if !shift.is_zero() { if !shift.is_zero() {
@ -377,10 +380,17 @@ impl Layout for BlockElem {
pod.last = None; pod.last = None;
} }
body.layout(vt, styles, pod)?.into_frames() let mut frames = body.layout(vt, styles, pod)?.into_frames();
for (frame, &height) in frames.iter_mut().zip(&heights) {
*frame.size_mut() =
expand.select(Size::new(size.x, height), frame.size());
}
frames
} else { } else {
let pod = Regions::one(size, expand); let pod = Regions::one(size, expand);
body.layout(vt, styles, pod)?.into_frames() let mut frames = body.layout(vt, styles, pod)?.into_frames();
*frames[0].size_mut() = expand.select(size, frames[0].size());
frames
}; };
// Clip the contents // Clip the contents

View File

@ -1,6 +1,8 @@
use super::{AlignElem, BlockElem, ColbreakElem, ParElem, PlaceElem, Spacing, VElem}; use super::{AlignElem, BlockElem, ColbreakElem, ParElem, PlaceElem, Spacing, VElem};
use crate::prelude::*; use crate::prelude::*;
use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem}; use crate::visualize::{
CircleElem, EllipseElem, ImageElem, PathElem, PolygonElem, RectElem, SquareElem,
};
/// Arrange spacing, paragraphs and block-level elements into a flow. /// Arrange spacing, paragraphs and block-level elements into a flow.
/// ///
@ -42,6 +44,8 @@ impl Layout for FlowElem {
|| child.is::<EllipseElem>() || child.is::<EllipseElem>()
|| child.is::<CircleElem>() || child.is::<CircleElem>()
|| child.is::<ImageElem>() || child.is::<ImageElem>()
|| child.is::<PolygonElem>()
|| child.is::<PathElem>()
{ {
let layoutable = child.with::<dyn Layout>().unwrap(); let layoutable = child.with::<dyn Layout>().unwrap();
layouter.layout_single(vt, layoutable, styles)?; layouter.layout_single(vt, layoutable, styles)?;

View File

@ -57,6 +57,8 @@ use crate::meta::DocumentElem;
use crate::prelude::*; use crate::prelude::*;
use crate::shared::BehavedBuilder; use crate::shared::BehavedBuilder;
use crate::text::{LinebreakElem, SmartQuoteElem, SpaceElem, TextElem}; use crate::text::{LinebreakElem, SmartQuoteElem, SpaceElem, TextElem};
use crate::visualize::PathElem;
use crate::visualize::PolygonElem;
use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem}; use crate::visualize::{CircleElem, EllipseElem, ImageElem, RectElem, SquareElem};
/// Root-level layout. /// Root-level layout.
@ -192,6 +194,8 @@ fn realize_block<'a>(
&& !content.is::<EllipseElem>() && !content.is::<EllipseElem>()
&& !content.is::<CircleElem>() && !content.is::<CircleElem>()
&& !content.is::<ImageElem>() && !content.is::<ImageElem>()
&& !content.is::<PolygonElem>()
&& !content.is::<PathElem>()
&& !applicable(content, styles) && !applicable(content, styles)
{ {
return Ok((content.clone(), styles)); return Ok((content.clone(), styles));

View File

@ -483,7 +483,7 @@ fn layout(
let mut frame; let mut frame;
if let Some(child) = body { if let Some(child) = body {
let region = resolved.unwrap_or(regions.base()); let mut region = resolved.unwrap_or(regions.base());
if kind.is_round() { if kind.is_round() {
inset = inset.map(|side| side + Ratio::new(0.5 - SQRT_2 / 4.0)); inset = inset.map(|side| side + Ratio::new(0.5 - SQRT_2 / 4.0));
} }
@ -498,10 +498,13 @@ fn layout(
// the result is really a square or circle. // the result is really a square or circle.
if kind.is_quadratic() { if kind.is_quadratic() {
let length = frame.size().max_by_side().min(region.min_by_side()); let length = frame.size().max_by_side().min(region.min_by_side());
let size = Size::splat(length); region = Size::splat(length);
let pod = Regions::one(size, Axes::splat(true)); let pod = Regions::one(region, Axes::splat(true));
frame = child.layout(vt, styles, pod)?.into_frame(); frame = child.layout(vt, styles, pod)?.into_frame();
} }
// Enforce correct size.
*frame.size_mut() = expand.select(region, frame.size());
} else { } else {
// The default size that a shape takes on if it has no child and // The default size that a shape takes on if it has no child and
// enough space. // enough space.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -9,6 +9,16 @@ Spaced \
#box(height: 0.5cm) \ #box(height: 0.5cm) \
Apart Apart
---
// Test box sizing.
#box(width: 50pt, height: 50pt, fill: yellow, path(
fill: purple,
(0pt, 0pt),
(30pt, 30pt),
(0pt, 30pt),
(30pt, 0pt),
))
--- ---
// Test fr box. // Test fr box.
Hello #box(width: 1fr, rect(height: 0.7em, width: 100%)) World Hello #box(width: 1fr, rect(height: 0.7em, width: 100%)) World