summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exec/context.rs2
-rw-r--r--src/exec/state.rs4
-rw-r--r--src/geom/gen.rs12
-rw-r--r--src/geom/length.rs10
-rw-r--r--src/geom/path.rs38
-rw-r--r--src/geom/point.rs6
-rw-r--r--src/geom/sides.rs2
-rw-r--r--src/geom/size.rs6
-rw-r--r--src/geom/spec.rs6
-rw-r--r--src/layout/fixed.rs8
-rw-r--r--src/layout/mod.rs57
-rw-r--r--src/layout/pad.rs44
-rw-r--r--src/layout/par.rs54
-rw-r--r--src/layout/shaping.rs5
-rw-r--r--src/layout/stack.rs95
-rw-r--r--src/library/image.rs8
-rw-r--r--src/library/page.rs2
-rw-r--r--src/library/shapes.rs2
-rw-r--r--src/pdf/mod.rs2
-rw-r--r--tests/typ/library/square.typ2
-rw-r--r--tests/typeset.rs6
21 files changed, 182 insertions, 189 deletions
diff --git a/src/exec/context.rs b/src/exec/context.rs
index 7dc51796..b5298313 100644
--- a/src/exec/context.rs
+++ b/src/exec/context.rs
@@ -167,7 +167,7 @@ struct StackBuilder {
impl StackBuilder {
fn new(state: &State) -> Self {
Self {
- dirs: Gen::new(Dir::TTB, state.lang.dir),
+ dirs: Gen::new(state.lang.dir, Dir::TTB),
children: vec![],
last: Last::None,
par: ParBuilder::new(state),
diff --git a/src/exec/state.rs b/src/exec/state.rs
index f4bc6b7b..f0b060af 100644
--- a/src/exec/state.rs
+++ b/src/exec/state.rs
@@ -29,7 +29,7 @@ impl Default for State {
page: PageState::default(),
par: ParState::default(),
font: FontState::default(),
- aligns: Gen::new(Align::Start, Align::Start),
+ aligns: Gen::splat(Align::Start),
}
}
}
@@ -65,7 +65,7 @@ impl PageState {
Self {
class: paper.class,
size: paper.size(),
- margins: Sides::uniform(None),
+ margins: Sides::splat(None),
}
}
diff --git a/src/geom/gen.rs b/src/geom/gen.rs
index 7e021412..91f7499c 100644
--- a/src/geom/gen.rs
+++ b/src/geom/gen.rs
@@ -3,24 +3,24 @@ use super::*;
/// A container with a main and cross component.
#[derive(Default, Copy, Clone, Eq, PartialEq)]
pub struct Gen<T> {
- /// The main component.
- pub main: T,
/// The cross component.
pub cross: T,
+ /// The main component.
+ pub main: T,
}
impl<T> Gen<T> {
/// Create a new instance from the two components.
- pub fn new(main: T, cross: T) -> Self {
- Self { main, cross }
+ pub fn new(cross: T, main: T) -> Self {
+ Self { cross, main }
}
/// Create a new instance with two equal components.
- pub fn uniform(value: T) -> Self
+ pub fn splat(value: T) -> Self
where
T: Clone,
{
- Self { main: value.clone(), cross: value }
+ Self { cross: value.clone(), main: value }
}
}
diff --git a/src/geom/length.rs b/src/geom/length.rs
index c75f79b5..8bc50e97 100644
--- a/src/geom/length.rs
+++ b/src/geom/length.rs
@@ -79,11 +79,21 @@ impl Length {
Self { raw: self.raw.min(other.raw) }
}
+ /// Set to the minimum of this and another length.
+ pub fn set_min(&mut self, other: Self) {
+ *self = self.min(other);
+ }
+
/// The maximum of this and another length.
pub fn max(self, other: Self) -> Self {
Self { raw: self.raw.max(other.raw) }
}
+ /// Set to the maximum of this and another length.
+ pub fn set_max(&mut self, other: Self) {
+ *self = self.max(other);
+ }
+
/// Whether the other length fits into this one (i.e. is smaller).
pub fn fits(self, other: Self) -> bool {
self.raw + 1e-6 >= other.raw
diff --git a/src/geom/path.rs b/src/geom/path.rs
index dcabb9cf..8878b6f1 100644
--- a/src/geom/path.rs
+++ b/src/geom/path.rs
@@ -22,6 +22,25 @@ impl Path {
Self(vec![])
}
+ /// Create a path that approximates an axis-aligned ellipse.
+ pub fn ellipse(size: Size) -> Self {
+ // https://stackoverflow.com/a/2007782
+ let rx = size.width / 2.0;
+ let ry = size.height / 2.0;
+ let m = 0.551784;
+ let mx = m * rx;
+ let my = m * ry;
+ let z = Length::ZERO;
+ let point = Point::new;
+ let mut path = Self::new();
+ path.move_to(point(-rx, z));
+ path.cubic_to(point(-rx, my), point(-mx, ry), point(z, ry));
+ path.cubic_to(point(mx, ry), point(rx, my), point(rx, z));
+ path.cubic_to(point(rx, -my), point(mx, -ry), point(z, -ry));
+ path.cubic_to(point(-mx, -ry), point(-rx, -my), point(z - rx, z));
+ path
+ }
+
/// Push a [`MoveTo`](PathElement::MoveTo) element.
pub fn move_to(&mut self, p: Point) {
self.0.push(PathElement::MoveTo(p));
@@ -42,22 +61,3 @@ impl Path {
self.0.push(PathElement::ClosePath);
}
}
-
-/// Create a path that approximates an axis-aligned ellipse.
-pub fn ellipse_path(size: Size) -> Path {
- // https://stackoverflow.com/a/2007782
- let rx = size.width / 2.0;
- let ry = size.height / 2.0;
- let m = 0.551784;
- let mx = m * rx;
- let my = m * ry;
- let z = Length::ZERO;
- let point = Point::new;
- let mut path = Path::new();
- path.move_to(point(-rx, z));
- path.cubic_to(point(-rx, my), point(-mx, ry), point(z, ry));
- path.cubic_to(point(mx, ry), point(rx, my), point(rx, z));
- path.cubic_to(point(rx, -my), point(mx, -ry), point(z, -ry));
- path.cubic_to(point(-mx, -ry), point(-rx, -my), point(z - rx, z));
- path
-}
diff --git a/src/geom/point.rs b/src/geom/point.rs
index 5ed8bf1d..479bb137 100644
--- a/src/geom/point.rs
+++ b/src/geom/point.rs
@@ -21,7 +21,7 @@ impl Point {
}
/// Create an instance with two equal components.
- pub fn uniform(value: Length) -> Self {
+ pub fn splat(value: Length) -> Self {
Self { x: value, y: value }
}
}
@@ -49,8 +49,8 @@ impl Switch for Point {
fn switch(self, main: SpecAxis) -> Self::Other {
match main {
- SpecAxis::Horizontal => Gen::new(self.x, self.y),
- SpecAxis::Vertical => Gen::new(self.y, self.x),
+ SpecAxis::Horizontal => Gen::new(self.y, self.x),
+ SpecAxis::Vertical => Gen::new(self.x, self.y),
}
}
}
diff --git a/src/geom/sides.rs b/src/geom/sides.rs
index deeced45..af728ed4 100644
--- a/src/geom/sides.rs
+++ b/src/geom/sides.rs
@@ -20,7 +20,7 @@ impl<T> Sides<T> {
}
/// Create an instance with four equal components.
- pub fn uniform(value: T) -> Self
+ pub fn splat(value: T) -> Self
where
T: Clone,
{
diff --git a/src/geom/size.rs b/src/geom/size.rs
index 0a64e6b9..d81525e6 100644
--- a/src/geom/size.rs
+++ b/src/geom/size.rs
@@ -24,7 +24,7 @@ impl Size {
}
/// Create an instance with two equal components.
- pub fn uniform(value: Length) -> Self {
+ pub fn splat(value: Length) -> Self {
Self { width: value, height: value }
}
@@ -77,8 +77,8 @@ impl Switch for Size {
fn switch(self, main: SpecAxis) -> Self::Other {
match main {
- SpecAxis::Horizontal => Gen::new(self.width, self.height),
- SpecAxis::Vertical => Gen::new(self.height, self.width),
+ SpecAxis::Horizontal => Gen::new(self.height, self.width),
+ SpecAxis::Vertical => Gen::new(self.width, self.height),
}
}
}
diff --git a/src/geom/spec.rs b/src/geom/spec.rs
index 546eac7b..e5479ba4 100644
--- a/src/geom/spec.rs
+++ b/src/geom/spec.rs
@@ -16,7 +16,7 @@ impl<T> Spec<T> {
}
/// Create a new instance with two equal components.
- pub fn uniform(value: T) -> Self
+ pub fn splat(value: T) -> Self
where
T: Clone,
{
@@ -68,8 +68,8 @@ impl<T> Switch for Spec<T> {
fn switch(self, main: SpecAxis) -> Self::Other {
match main {
- SpecAxis::Horizontal => Gen::new(self.horizontal, self.vertical),
- SpecAxis::Vertical => Gen::new(self.vertical, self.horizontal),
+ SpecAxis::Horizontal => Gen::new(self.vertical, self.horizontal),
+ SpecAxis::Vertical => Gen::new(self.horizontal, self.vertical),
}
}
}
diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs
index a42eab5a..cdd1033b 100644
--- a/src/layout/fixed.rs
+++ b/src/layout/fixed.rs
@@ -13,14 +13,14 @@ pub struct FixedNode {
impl Layout for FixedNode {
fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> {
- let Areas { current, full, .. } = areas;
+ let Areas { current, base, .. } = areas;
let size = Size::new(
- self.width.map_or(current.width, |w| w.resolve(full.width)),
- self.height.map_or(current.height, |h| h.resolve(full.height)),
+ self.width.map_or(current.width, |w| w.resolve(base.width)),
+ self.height.map_or(current.height, |h| h.resolve(base.height)),
);
let fixed = Spec::new(self.width.is_some(), self.height.is_some());
- let areas = Areas::once(size, size, fixed);
+ let areas = Areas::once(size, fixed);
self.child.layout(ctx, &areas)
}
}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index cb138753..83334a9f 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -144,67 +144,63 @@ pub struct LayoutContext<'a> {
pub struct Areas {
/// The remaining size of the current area.
pub current: Size,
- /// The full size the current area once had (used for relative sizing).
- pub full: Size,
- /// A stack of followup areas (the next area is the last element).
+ /// The base size for relative sizing.
+ pub base: Size,
+ /// A stack of followup areas.
+ ///
+ /// Note that this is a stack and not a queue! The size of the next area is
+ /// `backlog.last()`.
pub backlog: Vec<Size>,
- /// The final area that is repeated when the backlog is empty.
+ /// The final area that is repeated once the backlog is drained.
pub last: Option<Size>,
- /// Whether the frames resulting from layouting into this areas should
- /// expand to the fixed size defined by `current`.
+ /// Whether layouting into these areas should produce frames of the exact
+ /// size of `current` instead of shrinking to fit the content.
///
- /// If this is false, the frame will shrink to fit its content.
+ /// This property is only handled by nodes that have the ability to control
+ /// their own size.
pub fixed: Spec<bool>,
}
impl Areas {
- /// Create a new length-1 sequence of areas with just one `area`.
- pub fn once(size: Size, full: Size, fixed: Spec<bool>) -> Self {
+ /// Create a new area sequence of length one.
+ pub fn once(size: Size, fixed: Spec<bool>) -> Self {
Self {
current: size,
- full,
+ base: size,
backlog: vec![],
last: None,
fixed,
}
}
- /// Create a new sequence of areas that repeats `area` indefinitely.
+ /// Create a new sequence of same-size areas that repeats indefinitely.
pub fn repeat(size: Size, fixed: Spec<bool>) -> Self {
Self {
current: size,
- full: size,
+ base: size,
backlog: vec![],
last: Some(size),
fixed,
}
}
- /// Map all areas.
+ /// Map the size of all areas.
pub fn map<F>(&self, mut f: F) -> Self
where
F: FnMut(Size) -> Size,
{
Self {
current: f(self.current),
- full: f(self.full),
+ base: f(self.base),
backlog: self.backlog.iter().copied().map(|s| f(s)).collect(),
last: self.last.map(f),
fixed: self.fixed,
}
}
- /// Advance to the next area if there is any.
- pub fn next(&mut self) {
- if let Some(size) = self.backlog.pop().or(self.last) {
- self.current = size;
- self.full = size;
- }
- }
-
/// Whether `current` is a fully sized (untouched) copy of the last area.
///
- /// If this is false calling `next()` will have no effect.
+ /// If this is true, calling `next()` will have no effect.
pub fn in_full_last(&self) -> bool {
self.backlog.is_empty()
&& self.last.map_or(true, |size| {
@@ -212,9 +208,18 @@ impl Areas {
})
}
+ /// Advance to the next area if there is any.
+ pub fn next(&mut self) {
+ if let Some(size) = self.backlog.pop().or(self.last) {
+ self.current = size;
+ self.base = size;
+ }
+ }
+
/// Shrink `current` to ensure that the aspect ratio can be satisfied.
- pub fn apply_aspect_ratio(&mut self, ratio: f64) {
- let Size { width, height } = self.current;
- self.current = Size::new(width.min(ratio * height), height.min(width / ratio));
+ pub fn apply_aspect_ratio(&mut self, aspect: f64) {
+ let width = self.current.width.min(aspect * self.current.height);
+ let height = width / aspect;
+ self.current = Size::new(width, height);
}
}
diff --git a/src/layout/pad.rs b/src/layout/pad.rs
index d24ca654..7ceb3d1b 100644
--- a/src/layout/pad.rs
+++ b/src/layout/pad.rs
@@ -11,37 +11,23 @@ pub struct PadNode {
impl Layout for PadNode {
fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Vec<Frame> {
- let areas = shrink(areas, self.padding);
+ let areas = areas.map(|size| size - self.padding.resolve(size).size());
+
let mut frames = self.child.layout(ctx, &areas);
for frame in &mut frames {
- pad(frame, self.padding);
- }
- frames
- }
-}
+ let padded = solve(self.padding, frame.size);
+ let padding = self.padding.resolve(padded);
+ let origin = Point::new(padding.left, padding.top);
-impl From<PadNode> for AnyNode {
- fn from(pad: PadNode) -> Self {
- Self::new(pad)
- }
-}
+ frame.size = padded;
+ frame.baseline += origin.y;
-/// Shrink all areas by the padding.
-fn shrink(areas: &Areas, padding: Sides<Linear>) -> Areas {
- areas.map(|size| size - padding.resolve(size).size())
-}
-
-/// Pad the frame and move all elements inwards.
-fn pad(frame: &mut Frame, padding: Sides<Linear>) {
- let padded = solve(padding, frame.size);
- let padding = padding.resolve(padded);
- let origin = Point::new(padding.left, padding.top);
-
- frame.size = padded;
- frame.baseline += origin.y;
+ for (point, _) in &mut frame.elements {
+ *point += origin;
+ }
+ }
- for (point, _) in &mut frame.elements {
- *point += origin;
+ frames
}
}
@@ -57,3 +43,9 @@ fn solve(padding: Sides<Linear>, size: Size) -> Size {
solve_axis(size.height, padding.top + padding.bottom),
)
}
+
+impl From<PadNode> for AnyNode {
+ fn from(pad: PadNode) -> Self {
+ Self::new(pad)
+ }
+}
diff --git a/src/layout/par.rs b/src/layout/par.rs
index 7d7f5951..eb220cf9 100644
--- a/src/layout/par.rs
+++ b/src/layout/par.rs
@@ -1,5 +1,4 @@
use std::fmt::{self, Debug, Formatter};
-use std::mem;
use unicode_bidi::{BidiInfo, Level};
use xi_unicode::LineBreakIterator;
@@ -142,10 +141,9 @@ impl<'a> ParLayout<'a> {
}
}
ParChild::Any(ref node, align) => {
- let frames = node.layout(ctx, areas);
- assert_eq!(frames.len(), 1);
-
- let frame = frames.into_iter().next().unwrap();
+ let mut frames = node.layout(ctx, areas).into_iter();
+ let frame = frames.next().unwrap();
+ assert!(frames.next().is_none());
items.push(ParItem::Frame(frame, align));
ranges.push(range);
}
@@ -184,16 +182,16 @@ impl<'a> ParLayout<'a> {
}
// If the line does not fit vertically, we start a new area.
- if !stack.areas.current.height.fits(line.size.height)
+ while !stack.areas.current.height.fits(line.size.height)
&& !stack.areas.in_full_last()
{
stack.finish_area(ctx);
}
+ // If the line does not fit horizontally or we have a mandatory
+ // line break (i.e. due to "\n"), we push the line into the
+ // stack.
if mandatory || !stack.areas.current.width.fits(line.size.width) {
- // If the line does not fit horizontally or we have a mandatory
- // line break (i.e. due to "\n"), we push the line into the
- // stack.
stack.push(line);
start = end;
last = None;
@@ -289,14 +287,13 @@ impl<'a> LineStack<'a> {
}
fn push(&mut self, line: LineLayout<'a>) {
- self.areas.current.height -= line.size.height + self.line_spacing;
-
- self.size.width = self.size.width.max(line.size.width);
self.size.height += line.size.height;
+ self.size.width.set_max(line.size.width);
if !self.lines.is_empty() {
self.size.height += self.line_spacing;
}
+ self.areas.current.height -= line.size.height + self.line_spacing;
self.lines.push(line);
}
@@ -306,22 +303,20 @@ impl<'a> LineStack<'a> {
}
let mut output = Frame::new(self.size, self.size.height);
- let mut first = true;
let mut offset = Length::ZERO;
+ let mut first = true;
- for line in mem::take(&mut self.lines) {
+ for line in std::mem::take(&mut self.lines) {
let frame = line.build(ctx, self.size.width);
- let Frame { size, baseline, .. } = frame;
let pos = Point::new(Length::ZERO, offset);
- output.push_frame(pos, frame);
-
if first {
- output.baseline = offset + baseline;
+ output.baseline = pos.y + frame.baseline;
first = false;
}
- offset += size.height + self.line_spacing;
+ offset += frame.size.height + self.line_spacing;
+ output.push_frame(pos, frame);
}
self.finished.push(output);
@@ -430,8 +425,8 @@ impl<'a> LineLayout<'a> {
let size = item.size();
let baseline = item.baseline();
width += size.width;
- top = top.max(baseline);
- bottom = bottom.max(size.height - baseline);
+ top.set_max(baseline);
+ bottom.set_max(size.height - baseline);
}
Self {
@@ -448,13 +443,12 @@ impl<'a> LineLayout<'a> {
/// Build the line's frame.
fn build(&self, ctx: &mut LayoutContext, width: Length) -> Frame {
- let full_width = self.size.width.max(width);
- let full_size = Size::new(full_width, self.size.height);
- let free_width = full_width - self.size.width;
+ let size = Size::new(self.size.width.max(width), self.size.height);
+ let free = size.width - self.size.width;
- let mut output = Frame::new(full_size, self.baseline);
- let mut ruler = Align::Start;
+ let mut output = Frame::new(size, self.baseline);
let mut offset = Length::ZERO;
+ let mut ruler = Align::Start;
self.reordered(|item| {
let frame = match *item {
@@ -472,14 +466,14 @@ impl<'a> LineLayout<'a> {
}
};
- let Frame { size, baseline, .. } = frame;
+ // FIXME: Ruler alignment for RTL.
let pos = Point::new(
- ruler.resolve(self.par.dir, offset .. free_width + offset),
- self.baseline - baseline,
+ ruler.resolve(self.par.dir, offset .. free + offset),
+ self.baseline - frame.baseline,
);
+ offset += frame.size.width;
output.push_frame(pos, frame);
- offset += size.width;
});
output
diff --git a/src/layout/shaping.rs b/src/layout/shaping.rs
index 8a407260..dd6c55bd 100644
--- a/src/layout/shaping.rs
+++ b/src/layout/shaping.rs
@@ -336,9 +336,8 @@ fn measure(
let mut top = Length::ZERO;
let mut bottom = Length::ZERO;
let mut expand_vertical = |face: &Face| {
- top = top.max(face.vertical_metric(props.top_edge).to_length(props.size));
- bottom =
- bottom.max(-face.vertical_metric(props.bottom_edge).to_length(props.size));
+ top.set_max(face.vertical_metric(props.top_edge).to_length(props.size));
+ bottom.set_max(-face.vertical_metric(props.bottom_edge).to_length(props.size));
};
if glyphs.is_empty() {
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index 463f38a7..38e9a517 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -61,6 +61,7 @@ struct StackLayouter {
areas: Areas,
finished: Vec<Frame>,
frames: Vec<(Length, Frame, Gen<Align>)>,
+ full: Size,
size: Gen<Length>,
ruler: Align,
}
@@ -75,18 +76,19 @@ impl StackLayouter {
dirs,
aspect,
main: dirs.main.axis(),
- areas,
finished: vec![],
frames: vec![],
+ full: areas.current,
size: Gen::ZERO,
ruler: Align::Start,
+ areas,
}
}
fn push_spacing(&mut self, amount: Length) {
- let main_rest = self.areas.current.get_mut(self.main);
- let capped = amount.min(*main_rest);
- *main_rest -= capped;
+ let remaining = self.areas.current.get_mut(self.main);
+ let capped = amount.min(*remaining);
+ *remaining -= capped;
self.size.main += capped;
}
@@ -95,71 +97,64 @@ impl StackLayouter {
self.finish_area();
}
- while !self.areas.current.fits(frame.size) {
- if self.areas.in_full_last() {
- // TODO: Diagnose once the necessary spans exist.
- break;
- } else {
- self.finish_area();
- }
+ while !self.areas.current.fits(frame.size) && !self.areas.in_full_last() {
+ self.finish_area();
}
+ let offset = self.size.main;
let size = frame.size.switch(self.main);
- self.frames.push((self.size.main, frame, aligns));
- self.ruler = aligns.main;
self.size.main += size.main;
- self.size.cross = self.size.cross.max(size.cross);
+ self.size.cross.set_max(size.cross);
+ self.ruler = aligns.main;
*self.areas.current.get_mut(self.main) -= size.main;
+ self.frames.push((offset, frame, aligns));
}
fn finish_area(&mut self) {
- let full_size = {
- let Areas { current, full, fixed, .. } = self.areas;
+ let fixed = self.areas.fixed;
- let used = self.size.switch(self.main).to_size();
- let mut size = Size::new(
- if fixed.horizontal { full.width } else { used.width },
- if fixed.vertical { full.height } else { used.height },
- );
+ let used = self.size.switch(self.main).to_size();
+ let mut size = Size::new(
+ if fixed.horizontal { self.full.width } else { used.width },
+ if fixed.vertical { self.full.height } else { used.height },
+ );
- if let Some(aspect) = self.aspect {
- let width = size
- .width
- .max(aspect * size.height)
- .min(current.width)
- .min((current.height + used.height) / aspect);
-
- size = Size::new(width, width / aspect);
- }
+ if let Some(aspect) = self.aspect {
+ let width = size
+ .width
+ .max(aspect * size.height)
+ .min(self.full.width)
+ .min(aspect * self.full.height);
- size
- };
+ size = Size::new(width, width / aspect);
+ }
- let mut output = Frame::new(full_size, full_size.height);
+ let mut output = Frame::new(size, size.height);
let mut first = true;
- let full_size = full_size.switch(self.main);
- for (before, frame, aligns) in std::mem::take(&mut self.frames) {
- let child_size = frame.size.switch(self.main);
+ let used = self.size;
+ let size = size.switch(self.main);
+
+ for (offset, frame, aligns) in std::mem::take(&mut self.frames) {
+ let child = frame.size.switch(self.main);
+
+ // Align along the cross axis.
+ let cross = aligns
+ .cross
+ .resolve(self.dirs.cross, Length::ZERO .. size.cross - child.cross);
// Align along the main axis.
let main = aligns.main.resolve(
self.dirs.main,
if self.dirs.main.is_positive() {
- before .. before + full_size.main - self.size.main
+ offset .. size.main - used.main + offset
} else {
- self.size.main - (before + child_size.main)
- .. full_size.main - (before + child_size.main)
+ let offset_with_self = offset + child.main;
+ used.main - offset_with_self .. size.main - offset_with_self
},
);
- // Align along the cross axis.
- let cross = aligns.cross.resolve(
- self.dirs.cross,
- Length::ZERO .. full_size.cross - child_size.cross,
- );
-
- let pos = Gen::new(main, cross).switch(self.main).to_point();
+ let pos = Gen::new(cross, main).switch(self.main).to_point();
if first {
output.baseline = pos.y + frame.baseline;
first = false;
@@ -168,14 +163,14 @@ impl StackLayouter {
output.push_frame(pos, frame);
}
- self.finished.push(output);
- self.areas.next();
- self.ruler = Align::Start;
self.size = Gen::ZERO;
-
+ self.ruler = Align::Start;
+ self.areas.next();
if let Some(aspect) = self.aspect {
self.areas.apply_aspect_ratio(aspect);
}
+
+ self.finished.push(output);
}
fn finish(mut self) -> Vec<Frame> {
diff --git a/src/library/image.rs b/src/library/image.rs
index a7388abb..0287eaf5 100644
--- a/src/library/image.rs
+++ b/src/library/image.rs
@@ -46,15 +46,14 @@ struct ImageNode {
impl Layout for ImageNode {
fn layout(&self, _: &mut LayoutContext, areas: &Areas) -> Vec<Frame> {
- let Areas { current, full, .. } = areas;
+ let Areas { current, base, .. } = areas;
+ let width = self.width.map(|w| w.resolve(base.width));
+ let height = self.height.map(|w| w.resolve(base.height));
let pixel_width = self.dimensions.0 as f64;
let pixel_height = self.dimensions.1 as f64;
let pixel_ratio = pixel_width / pixel_height;
- let width = self.width.map(|w| w.resolve(full.width));
- let height = self.height.map(|w| w.resolve(full.height));
-
let size = match (width, height) {
(Some(width), Some(height)) => Size::new(width, height),
(Some(width), None) => Size::new(width, width / pixel_ratio),
@@ -75,7 +74,6 @@ impl Layout for ImageNode {
let mut frame = Frame::new(size, size.height);
frame.push(Point::ZERO, Element::Image(self.id, size));
-
vec![frame]
}
}
diff --git a/src/library/page.rs b/src/library/page.rs
index 7b8557be..1694b7d4 100644
--- a/src/library/page.rs
+++ b/src/library/page.rs
@@ -59,7 +59,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
if let Some(margins) = margins {
- ctx.state.page.margins = Sides::uniform(Some(margins));
+ ctx.state.page.margins = Sides::splat(Some(margins));
}
if let Some(left) = left {
diff --git a/src/library/shapes.rs b/src/library/shapes.rs
index c87a0ac3..d6cdba8e 100644
--- a/src/library/shapes.rs
+++ b/src/library/shapes.rs
@@ -142,7 +142,7 @@ fn ellipse_impl(
width,
height,
child: PadNode {
- padding: Sides::uniform(Relative::new(PAD).into()),
+ padding: Sides::splat(Relative::new(PAD).into()),
child: stack.into(),
}
.into(),
diff --git a/src/pdf/mod.rs b/src/pdf/mod.rs
index 2b32f101..19c8499b 100644
--- a/src/pdf/mod.rs
+++ b/src/pdf/mod.rs
@@ -177,7 +177,7 @@ impl<'a> PdfExporter<'a> {
}
Shape::Ellipse(size) => {
- let path = geom::ellipse_path(size);
+ let path = geom::Path::ellipse(size);
write_path(&mut content, x, y, &path, false, true);
}
diff --git a/tests/typ/library/square.typ b/tests/typ/library/square.typ
index 5f224b56..deb97853 100644
--- a/tests/typ/library/square.typ
+++ b/tests/typ/library/square.typ
@@ -6,7 +6,7 @@ Auto-sized square. \
#align(center)
#pad(5pt)[
#font(color: #fff, weight: bold)
- Typst \
+ Typst
]
]
diff --git a/tests/typeset.rs b/tests/typeset.rs
index 4572e81b..f60b81f7 100644
--- a/tests/typeset.rs
+++ b/tests/typeset.rs
@@ -220,7 +220,7 @@ fn test_part(
// large and fit them to match their content.
let mut state = State::default();
state.page.size = Size::new(Length::pt(120.0), Length::raw(f64::INFINITY));
- state.page.margins = Sides::uniform(Some(Length::pt(10.0).into()));
+ state.page.margins = Sides::splat(Some(Length::pt(10.0).into()));
let Pass { output: mut frames, diags } = typeset(env, &src, &scope, state);
if !compare_ref {
@@ -368,7 +368,7 @@ fn draw(env: &Env, frames: &[Frame], dpi: f32) -> Pixmap {
let ts = Transform::from_scale(dpi, dpi);
canvas.fill(Color::BLACK);
- let mut origin = Point::new(pad, pad);
+ let mut origin = Point::splat(pad);
for frame in frames {
let mut paint = Paint::default();
paint.set_color(Color::WHITE);
@@ -469,7 +469,7 @@ fn draw_geometry(canvas: &mut Pixmap, ts: Transform, shape: &Shape, fill: Fill)
canvas.fill_rect(rect, &paint, ts, None);
}
Shape::Ellipse(size) => {
- let path = convert_typst_path(&geom::ellipse_path(size));
+ let path = convert_typst_path(&geom::Path::ellipse(size));
canvas.fill_path(&path, &paint, rule, ts, None);
}
Shape::Path(ref path) => {