diff options
Diffstat (limited to 'library/src/layout/pad.rs')
| -rw-r--r-- | library/src/layout/pad.rs | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/library/src/layout/pad.rs b/library/src/layout/pad.rs deleted file mode 100644 index a3d5646b..00000000 --- a/library/src/layout/pad.rs +++ /dev/null @@ -1,125 +0,0 @@ -use crate::prelude::*; - -/// Adds spacing around content. -/// -/// The spacing can be specified for each side individually, or for all sides at -/// once by specifying a positional argument. -/// -/// ## Example { #example } -/// ```example -/// #set align(center) -/// -/// #pad(x: 16pt, image("typing.jpg")) -/// _Typing speeds can be -/// measured in words per minute._ -/// ``` -/// -/// Display: Padding -/// Category: layout -#[element(Layout)] -pub struct PadElem { - /// The padding at the left side. - #[parse( - let all = args.named("rest")?.or(args.find()?); - let x = args.named("x")?.or(all); - let y = args.named("y")?.or(all); - args.named("left")?.or(x) - )] - pub left: Rel<Length>, - - /// The padding at the top side. - #[parse(args.named("top")?.or(y))] - pub top: Rel<Length>, - - /// The padding at the right side. - #[parse(args.named("right")?.or(x))] - pub right: Rel<Length>, - - /// The padding at the bottom side. - #[parse(args.named("bottom")?.or(y))] - pub bottom: Rel<Length>, - - /// The horizontal padding. Both `left` and `right` take precedence over - /// this. - #[external] - pub x: Rel<Length>, - - /// The vertical padding. Both `top` and `bottom` take precedence over this. - #[external] - pub y: Rel<Length>, - - /// The padding for all sides. All other parameters take precedence over - /// this. - #[external] - pub rest: Rel<Length>, - - /// The content to pad at the sides. - #[required] - pub body: Content, -} - -impl Layout for PadElem { - #[tracing::instrument(name = "PadElem::layout", skip_all)] - fn layout( - &self, - vt: &mut Vt, - styles: StyleChain, - regions: Regions, - ) -> SourceResult<Fragment> { - let sides = Sides::new( - self.left(styles), - self.top(styles), - self.right(styles), - self.bottom(styles), - ); - - // Layout child into padded regions. - let mut backlog = vec![]; - let padding = sides.resolve(styles); - let pod = regions.map(&mut backlog, |size| shrink(size, padding)); - let mut fragment = self.body().layout(vt, styles, pod)?; - - for frame in &mut fragment { - // Apply the padding inversely such that the grown size padded - // yields the frame's size. - let padded = grow(frame.size(), padding); - let padding = padding.relative_to(padded); - let offset = Point::new(padding.left, padding.top); - - // Grow the frame and translate everything in the frame inwards. - frame.set_size(padded); - frame.translate(offset); - } - - Ok(fragment) - } -} - -/// Shrink a size by padding relative to the size itself. -fn shrink(size: Size, padding: Sides<Rel<Abs>>) -> Size { - size - padding.relative_to(size).sum_by_axis() -} - -/// Grow a size by padding relative to the grown size. -/// This is the inverse operation to `shrink()`. -/// -/// For the horizontal axis the derivation looks as follows. -/// (Vertical axis is analogous.) -/// -/// Let w be the grown target width, -/// s be the given width, -/// l be the left padding, -/// r be the right padding, -/// p = l + r. -/// -/// We want that: w - l.resolve(w) - r.resolve(w) = s -/// -/// Thus: w - l.resolve(w) - r.resolve(w) = s -/// <=> w - p.resolve(w) = s -/// <=> w - p.rel * w - p.abs = s -/// <=> (1 - p.rel) * w = s + p.abs -/// <=> w = (s + p.abs) / (1 - p.rel) -fn grow(size: Size, padding: Sides<Rel<Abs>>) -> Size { - size.zip(padding.sum_by_axis()) - .map(|(s, p)| (s + p.abs).safe_div(1.0 - p.rel.get())) -} |
