summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-02 14:48:12 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-02 14:48:12 +0100
commitbfa9962632dd3c2e9110f9c3667d7e3cf6b133d4 (patch)
treec48de05a4ae1e5c97eb4f6ddc9ede32ee65cf3ef /src
parentf3bdc9d3daca2c26c4cc745be48a5ce1c8a10641 (diff)
Remove baseline weirdness
Diffstat (limited to 'src')
-rw-r--r--src/frame.rs24
-rw-r--r--src/geom/point.rs9
-rw-r--r--src/geom/spec.rs5
-rw-r--r--src/library/flow.rs22
-rw-r--r--src/library/pad.rs1
-rw-r--r--src/library/par.rs33
-rw-r--r--src/library/text.rs4
7 files changed, 48 insertions, 50 deletions
diff --git a/src/frame.rs b/src/frame.rs
index e02fdf46..b0442a06 100644
--- a/src/frame.rs
+++ b/src/frame.rs
@@ -14,8 +14,9 @@ use crate::image::ImageId;
pub struct Frame {
/// The size of the frame.
pub size: Size,
- /// The baseline of the frame measured from the top.
- pub baseline: Length,
+ /// The baseline of the frame measured from the top. If this is `None`, the
+ /// frame's implicit baseline is at the bottom.
+ pub baseline: Option<Length>,
/// The elements composing this layout.
pub elements: Vec<(Point, Element)>,
}
@@ -25,7 +26,12 @@ impl Frame {
#[track_caller]
pub fn new(size: Size) -> Self {
assert!(size.is_finite());
- Self { size, baseline: size.y, elements: vec![] }
+ Self { size, baseline: None, elements: vec![] }
+ }
+
+ /// The baseline of the frame.
+ pub fn baseline(&self) -> Length {
+ self.baseline.unwrap_or(self.size.y)
}
/// Add an element at a position in the background.
@@ -64,15 +70,19 @@ impl Frame {
aligns.y.resolve(target.y - self.size.y),
);
self.size = target;
- self.baseline += offset.y;
self.translate(offset);
}
}
- /// Move the contents of the frame by an offset.
+ /// Move the baseline and contents of the frame by an offset.
pub fn translate(&mut self, offset: Point) {
- for (point, _) in &mut self.elements {
- *point += offset;
+ if !offset.is_zero() {
+ if let Some(baseline) = &mut self.baseline {
+ *baseline += offset.y;
+ }
+ for (point, _) in &mut self.elements {
+ *point += offset;
+ }
}
}
diff --git a/src/geom/point.rs b/src/geom/point.rs
index 30e3f9b6..ab8f4439 100644
--- a/src/geom/point.rs
+++ b/src/geom/point.rs
@@ -35,12 +35,9 @@ impl Point {
Self { x: Length::zero(), y }
}
- /// Convert to the generic representation.
- pub const fn to_gen(self, main: SpecAxis) -> Gen<Length> {
- match main {
- SpecAxis::Horizontal => Gen::new(self.y, self.x),
- SpecAxis::Vertical => Gen::new(self.x, self.y),
- }
+ /// Whether both components are zero.
+ pub fn is_zero(self) -> bool {
+ self.x.is_zero() && self.y.is_zero()
}
/// Transform the point with the given transformation.
diff --git a/src/geom/spec.rs b/src/geom/spec.rs
index 5d89c894..40d7386b 100644
--- a/src/geom/spec.rs
+++ b/src/geom/spec.rs
@@ -193,6 +193,11 @@ impl Size {
self.x.fits(other.x) && self.y.fits(other.y)
}
+ /// Whether both components are zero.
+ pub fn is_zero(self) -> bool {
+ self.x.is_zero() && self.y.is_zero()
+ }
+
/// Whether both components are finite.
pub fn is_finite(self) -> bool {
self.x.is_finite() && self.y.is_finite()
diff --git a/src/library/flow.rs b/src/library/flow.rs
index 9494d6c0..98b518b7 100644
--- a/src/library/flow.rs
+++ b/src/library/flow.rs
@@ -214,38 +214,28 @@ impl<'a> FlowLayouter<'a> {
}
let mut output = Frame::new(size);
- let mut before = Length::zero();
+ let mut offset = Length::zero();
let mut ruler = Align::Top;
- let mut first = true;
// Place all frames.
for item in self.items.drain(..) {
match item {
FlowItem::Absolute(v) => {
- before += v;
+ offset += v;
}
FlowItem::Fractional(v) => {
- before += v.resolve(self.fr, remaining);
+ offset += v.resolve(self.fr, remaining);
}
FlowItem::Frame(frame, aligns) => {
ruler = ruler.max(aligns.y);
-
- // Align horizontally and vertically.
let x = aligns.x.resolve(size.x - frame.size.x);
- let y = before + ruler.resolve(size.y - self.used.y);
+ let y = offset + ruler.resolve(size.y - self.used.y);
let pos = Point::new(x, y);
- before += frame.size.y;
-
- // The baseline of the flow is that of the first frame.
- if first {
- output.baseline = pos.y + frame.baseline;
- first = false;
- }
-
+ offset += frame.size.y;
output.push_frame(pos, frame);
}
FlowItem::Placed(frame) => {
- output.push_frame(Point::with_y(before), frame);
+ output.push_frame(Point::with_y(offset), frame);
}
}
}
diff --git a/src/library/pad.rs b/src/library/pad.rs
index 05cc30b7..681da73e 100644
--- a/src/library/pad.rs
+++ b/src/library/pad.rs
@@ -51,7 +51,6 @@ impl Layout for PadNode {
// Grow the frame and translate everything in the frame inwards.
let frame = Rc::make_mut(frame);
frame.size = padded;
- frame.baseline += offset.y;
frame.translate(offset);
// Set exact and base constraints if the child had them. Also set
diff --git a/src/library/par.rs b/src/library/par.rs
index c29e5f9e..6abfa7af 100644
--- a/src/library/par.rs
+++ b/src/library/par.rs
@@ -466,14 +466,18 @@ impl<'a> LineLayout<'a> {
// Measure the size of the line.
for item in first.iter().chain(items).chain(&last) {
- match *item {
- ParItem::Absolute(v) => width += v,
- ParItem::Fractional(v) => fr += v,
- ParItem::Text(ShapedText { size, baseline, .. })
- | ParItem::Frame(Frame { size, baseline, .. }) => {
- width += size.x;
- top.set_max(baseline);
- bottom.set_max(size.y - baseline);
+ match item {
+ ParItem::Absolute(v) => width += *v,
+ ParItem::Fractional(v) => fr += *v,
+ ParItem::Text(shaped) => {
+ width += shaped.size.x;
+ top.set_max(shaped.baseline);
+ bottom.set_max(shaped.size.y - shaped.baseline);
+ }
+ ParItem::Frame(frame) => {
+ width += frame.size.x;
+ top.set_max(frame.baseline());
+ bottom.set_max(frame.size.y - frame.baseline());
}
}
}
@@ -496,9 +500,9 @@ impl<'a> LineLayout<'a> {
let size = Size::new(self.size.x.max(width), self.size.y);
let remaining = size.x - self.size.x;
- let mut output = Frame::new(size);
let mut offset = Length::zero();
- output.baseline = self.baseline;
+ let mut output = Frame::new(size);
+ output.baseline = Some(self.baseline);
for (range, item) in self.reordered() {
let mut position = |mut frame: Frame| {
@@ -510,7 +514,7 @@ impl<'a> LineLayout<'a> {
}
let x = offset + self.par.align.resolve(remaining);
- let y = self.baseline - frame.baseline;
+ let y = self.baseline - frame.baseline();
offset += frame.size.x;
// Add to the line's frame.
@@ -633,17 +637,10 @@ impl<'a> LineStack<'a> {
let mut output = Frame::new(self.size);
let mut offset = Length::zero();
- let mut first = true;
for line in self.lines.drain(..) {
let frame = line.build(ctx, self.size.x);
-
let pos = Point::with_y(offset);
- if first {
- output.baseline = pos.y + frame.baseline;
- first = false;
- }
-
offset += frame.size.y + self.leading;
output.merge_frame(pos, frame);
}
diff --git a/src/library/text.rs b/src/library/text.rs
index aac99e8a..0790196d 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -305,9 +305,9 @@ pub struct ShapedGlyph {
impl<'a> ShapedText<'a> {
/// Build the shaped text's frame.
pub fn build(&self) -> Frame {
- let mut frame = Frame::new(self.size);
let mut offset = Length::zero();
- frame.baseline = self.baseline;
+ let mut frame = Frame::new(self.size);
+ frame.baseline = Some(self.baseline);
for (face_id, group) in self.glyphs.as_ref().group_by_key(|g| g.face_id) {
let pos = Point::new(offset, self.baseline);