summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2022-05-02 16:51:14 +0200
committerMartin Haug <mhaug@live.de>2022-05-02 17:20:47 +0200
commitf07395f9a47502c50f767f78a233d0e2a6e4445f (patch)
treec54fe2afeaaf265780279c893c272f1abfd12393
parent7b6f3a0ab9ae0dac19f62b62b9ecc96ea942a89e (diff)
Move rounding logic out of exporters
-rw-r--r--src/export/pdf.rs46
-rw-r--r--src/export/render.rs42
-rw-r--r--src/frame.rs211
-rw-r--r--src/geom/mod.rs46
-rw-r--r--src/geom/rect.rs212
-rw-r--r--src/library/graphics/shape.rs26
-rw-r--r--src/model/layout.rs12
7 files changed, 311 insertions, 284 deletions
diff --git a/src/export/pdf.rs b/src/export/pdf.rs
index f5401dfb..7cd6fbfc 100644
--- a/src/export/pdf.rs
+++ b/src/export/pdf.rs
@@ -16,9 +16,10 @@ use ttf_parser::{name_id, GlyphId, Tag};
use super::subset::subset;
use crate::font::{find_name, FaceId, FontStore};
-use crate::frame::{rect_path, rect_paths, Element, Frame, Geometry, Group, Shape, Text};
+use crate::frame::{Element, Frame, Group, Text};
use crate::geom::{
- self, Color, Em, Length, Numeric, Paint, Point, Sides, Size, Stroke, Transform,
+ self, Color, Em, Geometry, Length, Numeric, Paint, Point, Shape, Size, Stroke,
+ Transform,
};
use crate::image::{Image, ImageId, ImageStore, RasterImage};
use crate::Context;
@@ -499,16 +500,16 @@ impl<'a> PageExporter<'a> {
}
fn write_shape(&mut self, x: f32, y: f32, shape: &Shape) {
- if shape.fill.is_none() && shape.stroke.iter().all(Option::is_none) {
+ if shape.fill.is_none() && shape.stroke.is_none() {
return;
}
match shape.geometry {
- Geometry::Rect(size, radius) => {
+ Geometry::Rect(size) => {
let w = size.x.to_f32();
let h = size.y.to_f32();
if w > 0.0 && h > 0.0 {
- self.write_path(x, y, &rect_path(size, radius));
+ self.content.rect(x, y, w, h);
}
}
Geometry::Ellipse(size) => {
@@ -530,37 +531,16 @@ impl<'a> PageExporter<'a> {
self.set_fill(fill);
}
- // The stroke does not exist or is non-uniform.
- let mut use_stroke = false;
- if shape.stroke.is_uniform() || !matches!(shape.geometry, Geometry::Rect(_, _)) {
- if let Some(stroke) = shape.stroke.top {
- self.set_stroke(stroke);
- use_stroke = true;
- }
+ if let Some(stroke) = shape.stroke {
+ self.set_stroke(stroke);
}
- match (shape.fill, use_stroke) {
- (None, false) => self.content.end_path(),
- (Some(_), false) => self.content.fill_nonzero(),
- (None, true) => self.content.stroke(),
- (Some(_), true) => self.content.fill_nonzero_and_stroke(),
+ match (shape.fill, shape.stroke) {
+ (None, None) => unreachable!(),
+ (Some(_), None) => self.content.fill_nonzero(),
+ (None, Some(_)) => self.content.stroke(),
+ (Some(_), Some(_)) => self.content.fill_nonzero_and_stroke(),
};
-
- if let Geometry::Rect(size, radius) = shape.geometry {
- if !use_stroke {
- for (path, stroke) in rect_paths(size, radius, Some(shape.stroke)) {
- if let Some(stroke) = stroke {
- self.write_shape(x, y, &Shape {
- geometry: Geometry::Path(path),
- fill: None,
- stroke: Sides::splat(Some(stroke)),
- });
- } else {
- continue;
- }
- }
- }
- }
}
fn write_path(&mut self, x: f32, y: f32, path: &geom::Path) {
diff --git a/src/export/render.rs b/src/export/render.rs
index 9c674acb..50257e1c 100644
--- a/src/export/render.rs
+++ b/src/export/render.rs
@@ -7,10 +7,11 @@ use tiny_skia as sk;
use ttf_parser::{GlyphId, OutlineBuilder};
use usvg::FitTo;
-use crate::frame::{Element, Frame, Geometry, Group, Shape, Text};
-use crate::geom::{self, Length, Paint, PathElement, Sides, Size, Stroke, Transform};
+use crate::frame::{Element, Frame, Group, Text};
+use crate::geom::{
+ self, Geometry, Length, Paint, PathElement, Shape, Size, Stroke, Transform,
+};
use crate::image::{Image, RasterImage, Svg};
-use crate::library::prelude::{rect_path, rect_paths};
use crate::Context;
/// Export a frame into a rendered image.
@@ -299,7 +300,12 @@ fn render_shape(
shape: &Shape,
) -> Option<()> {
let path = match shape.geometry {
- Geometry::Rect(size, radius) => convert_path(&rect_path(size, radius))?,
+ Geometry::Rect(size) => {
+ let w = size.x.to_f32();
+ let h = size.y.to_f32();
+ let rect = sk::Rect::from_xywh(0.0, 0.0, w, h)?;
+ sk::PathBuilder::from_rect(rect)
+ }
Geometry::Ellipse(size) => convert_path(&geom::Path::ellipse(size))?,
Geometry::Line(target) => {
let mut builder = sk::PathBuilder::new();
@@ -311,7 +317,7 @@ fn render_shape(
if let Some(fill) = shape.fill {
let mut paint: sk::Paint = fill.into();
- if matches!(shape.geometry, Geometry::Rect(_, _)) {
+ if matches!(shape.geometry, Geometry::Rect(_)) {
paint.anti_alias = false;
}
@@ -319,27 +325,11 @@ fn render_shape(
canvas.fill_path(&path, &paint, rule, ts, mask);
}
- if shape.stroke.is_uniform() || !matches!(shape.geometry, Geometry::Rect(_, _)) {
- if let Some(Stroke { paint, thickness }) = shape.stroke.top {
- let paint = paint.into();
- let mut stroke = sk::Stroke::default();
- stroke.width = thickness.to_f32();
- canvas.stroke_path(&path, &paint, &stroke, ts, mask);
- }
- } else {
- if let Geometry::Rect(size, radius) = shape.geometry {
- for (path, stroke) in rect_paths(size, radius, Some(shape.stroke)) {
- if let Some(stroke) = stroke {
- render_shape(canvas, ts, mask, &Shape {
- geometry: Geometry::Path(path),
- fill: None,
- stroke: Sides::splat(Some(stroke)),
- })?;
- } else {
- continue;
- }
- }
- }
+ if let Some(Stroke { paint, thickness }) = shape.stroke {
+ let paint = paint.into();
+ let mut stroke = sk::Stroke::default();
+ stroke.width = thickness.to_f32();
+ canvas.stroke_path(&path, &paint, &stroke, ts, mask);
}
Some(())
diff --git a/src/frame.rs b/src/frame.rs
index 2cf584d8..dcaa7581 100644
--- a/src/frame.rs
+++ b/src/frame.rs
@@ -1,13 +1,11 @@
//! Finished layouts.
use std::fmt::{self, Debug, Formatter, Write};
-use std::mem;
use std::sync::Arc;
use crate::font::FaceId;
use crate::geom::{
- Align, Angle, Em, Get, Length, Numeric, Paint, Path, Point, Side, Sides, Size, Spec,
- Stroke, Transform,
+ Align, Em, Length, Numeric, Paint, Point, Shape, Size, Spec, Transform,
};
use crate::image::ImageId;
use crate::util::{EcoString, MaybeShared};
@@ -299,210 +297,3 @@ pub struct Glyph {
/// The first character of the glyph's cluster.
pub c: char,
}
-
-/// A geometric shape with optional fill and stroke.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Shape {
- /// The shape's geometry.
- pub geometry: Geometry,
- /// The shape's background fill.
- pub fill: Option<Paint>,
- /// The shape's border stroke.
- pub stroke: Sides<Option<Stroke>>,
-}
-
-/// A shape's geometry.
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub enum Geometry {
- /// A line to a point (relative to its position).
- Line(Point),
- /// A rectangle with its origin in the topleft corner and a border radius.
- Rect(Size, Sides<Length>),
- /// A ellipse with its origin in the topleft corner.
- Ellipse(Size),
- /// A bezier path.
- Path(Path),
-}
-
-impl Geometry {
- /// Fill the geometry without a stroke.
- pub fn filled(self, fill: Paint) -> Shape {
- Shape {
- geometry: self,
- fill: Some(fill),
- stroke: Sides::splat(None),
- }
- }
-
- /// Stroke the geometry without a fill.
- pub fn stroked(self, stroke: Stroke) -> Shape {
- Shape {
- geometry: self,
- fill: None,
- stroke: Sides::splat(Some(stroke)),
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-enum Connection {
- None,
- Left,
- Right,
- Both,
-}
-
-impl Connection {
- pub fn advance(self, right: bool) -> Self {
- match self {
- Self::Right | Self::Both => {
- if right {
- Self::Both
- } else {
- Self::Left
- }
- }
- Self::Left | Self::None => {
- if right {
- Self::Right
- } else {
- Self::None
- }
- }
- }
- }
-
- fn left(self) -> bool {
- matches!(self, Self::Left | Self::Both)
- }
-
- fn right(self) -> bool {
- matches!(self, Self::Right | Self::Both)
- }
-}
-
-/// Draws one side of the rounded rectangle. Will always draw the left arc. The
-/// right arc will be drawn halfway iff there is no connection.
-fn draw_side(
- path: &mut Path,
- side: Side,
- size: Size,
- radius_left: Length,
- radius_right: Length,
- connection: Connection,
-) {
- let reversed = |angle: Angle, radius, rotate, mirror_x, mirror_y| {
- let [a, b, c, d] = angle.bezier_arc(radius, rotate, mirror_x, mirror_y);
- [d, c, b, a]
- };
-
- let angle_left = Angle::deg(if connection.left() { 90.0 } else { 45.0 });
- let angle_right = Angle::deg(if connection.right() { 90.0 } else { 45.0 });
-
- let (arc1, arc2) = match side {
- Side::Top => {
- let arc1 = reversed(angle_left, radius_left, true, true, false)
- .map(|x| x + Point::with_x(radius_left));
- let arc2 = (-angle_right)
- .bezier_arc(radius_right, true, true, false)
- .map(|x| x + Point::with_x(size.x - radius_right));
-
- (arc1, arc2)
- }
- Side::Right => {
- let arc1 = reversed(-angle_left, radius_left, false, false, false)
- .map(|x| x + Point::new(size.x, radius_left));
-
- let arc2 = angle_right
- .bezier_arc(radius_right, false, false, false)
- .map(|x| x + Point::new(size.x, size.y - radius_right));
-
- (arc1, arc2)
- }
- Side::Bottom => {
- let arc1 = reversed(-angle_left, radius_left, true, false, false)
- .map(|x| x + Point::new(size.x - radius_left, size.y));
-
- let arc2 = angle_right
- .bezier_arc(radius_right, true, false, false)
- .map(|x| x + Point::new(radius_right, size.y));
-
- (arc1, arc2)
- }
- Side::Left => {
- let arc1 = reversed(angle_left, radius_left, false, false, true)
- .map(|x| x + Point::with_y(size.y - radius_left));
-
- let arc2 = (-angle_right)
- .bezier_arc(radius_right, false, false, true)
- .map(|x| x + Point::with_y(radius_right));
-
- (arc1, arc2)
- }
- };
-
- if !connection.left() {
- path.move_to(if radius_left.is_zero() { arc1[3] } else { arc1[0] });
- }
-
- if !radius_left.is_zero() {
- path.cubic_to(arc1[1], arc1[2], arc1[3]);
- }
-
- path.line_to(arc2[0]);
-
- if !connection.right() && !radius_right.is_zero() {
- path.cubic_to(arc2[1], arc2[2], arc2[3]);
- }
-}
-
-pub fn rect_paths(
- size: Size,
- radius: Sides<Length>,
- strokes: Option<Sides<Option<Stroke>>>,
-) -> Vec<(Path, Option<Stroke>)> {
- let strokes = strokes.unwrap_or_else(|| Sides::splat(None));
- let mut res = vec![];
-
- let mut connection = Connection::None;
- let mut path = Path::new();
- let sides = [Side::Top, Side::Right, Side::Bottom, Side::Left];
- let mut always_continuous = true;
-
- let radius = [
- radius.left,
- radius.top,
- radius.right,
- radius.bottom,
- radius.left,
- ];
-
- for (side, radius) in sides.into_iter().zip(radius.windows(2)) {
- let stroke_continuity = strokes.get(side) == strokes.get(side.next_cw());
- connection = connection.advance(stroke_continuity && side != Side::Left);
- always_continuous &= stroke_continuity;
-
- draw_side(&mut path, side, size, radius[0], radius[1], connection);
-
- if !stroke_continuity {
- res.push((mem::take(&mut path), strokes.get(side)));
- }
- }
-
- if always_continuous {
- path.close_path();
- }
-
- if !path.0.is_empty() {
- res.push((path, strokes.left));
- }
-
- res
-}
-
-pub fn rect_path(size: Size, radius: Sides<Length>) -> Path {
- let mut paths = rect_paths(size, radius, None);
- assert_eq!(paths.len(), 1);
-
- paths.pop().unwrap().0
-}
diff --git a/src/geom/mod.rs b/src/geom/mod.rs
index a6f53c87..bdd08fe5 100644
--- a/src/geom/mod.rs
+++ b/src/geom/mod.rs
@@ -13,6 +13,7 @@ mod paint;
mod path;
mod point;
mod ratio;
+mod rect;
mod relative;
mod scalar;
mod sides;
@@ -30,6 +31,7 @@ pub use paint::*;
pub use path::*;
pub use point::*;
pub use ratio::*;
+pub use rect::*;
pub use relative::*;
pub use scalar::*;
pub use sides::*;
@@ -60,6 +62,50 @@ pub trait Get<Index> {
}
}
+/// A geometric shape with optional fill and stroke.
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct Shape {
+ /// The shape's geometry.
+ pub geometry: Geometry,
+ /// The shape's background fill.
+ pub fill: Option<Paint>,
+ /// The shape's border stroke.
+ pub stroke: Option<Stroke>,
+}
+
+/// A shape's geometry.
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub enum Geometry {
+ /// A line to a point (relative to its position).
+ Line(Point),
+ /// A rectangle with its origin in the topleft corner.
+ Rect(Size),
+ /// A ellipse with its origin in the topleft corner.
+ Ellipse(Size),
+ /// A bezier path.
+ Path(Path),
+}
+
+impl Geometry {
+ /// Fill the geometry without a stroke.
+ pub fn filled(self, fill: Paint) -> Shape {
+ Shape {
+ geometry: self,
+ fill: Some(fill),
+ stroke: None,
+ }
+ }
+
+ /// Stroke the geometry without a fill.
+ pub fn stroked(self, stroke: Stroke) -> Shape {
+ Shape {
+ geometry: self,
+ fill: None,
+ stroke: Some(stroke),
+ }
+ }
+}
+
/// A numeric type.
pub trait Numeric:
Sized
diff --git a/src/geom/rect.rs b/src/geom/rect.rs
new file mode 100644
index 00000000..839feda4
--- /dev/null
+++ b/src/geom/rect.rs
@@ -0,0 +1,212 @@
+use super::*;
+
+use std::mem;
+
+/// A rectangle with rounded corners.
+#[derive(Debug, Clone)]
+pub struct Rect {
+ size: Size,
+ radius: Sides<Length>,
+}
+
+impl Rect {
+ /// Create a new rectangle.
+ pub fn new(size: Size, radius: Sides<Length>) -> Self {
+ Self { size, radius }
+ }
+
+ /// Output all constituent shapes of the rectangle in order. The last one is
+ /// in the foreground. The function will output multiple items if the stroke
+ /// properties differ by side.
+ pub fn shapes(
+ &self,
+ fill: Option<Paint>,
+ stroke: Sides<Option<Stroke>>,
+ ) -> Vec<Shape> {
+ let mut res = vec![];
+ if fill.is_some() || (stroke.iter().any(Option::is_some) && stroke.is_uniform()) {
+ res.push(Shape {
+ geometry: self.fill_geometry(),
+ fill,
+ stroke: stroke.left,
+ });
+ }
+
+ if !stroke.is_uniform() {
+ for (path, stroke) in self.stroke_segments(Some(stroke)) {
+ if !stroke.is_some() {
+ continue;
+ }
+ res.push(Shape {
+ geometry: Geometry::Path(path),
+ fill: None,
+ stroke,
+ });
+ }
+ }
+
+ res
+ }
+
+ /// Output the minimum number of paths along the rectangles border.
+ fn stroke_segments(
+ &self,
+ strokes: Option<Sides<Option<Stroke>>>,
+ ) -> Vec<(Path, Option<Stroke>)> {
+ let strokes = strokes.unwrap_or_else(|| Sides::splat(None));
+ let mut res = vec![];
+
+ let mut connection = Connection::None;
+ let mut path = Path::new();
+ let mut always_continuous = true;
+
+ for side in [Side::Top, Side::Right, Side::Bottom, Side::Left] {
+ let radius = [self.radius.get(side.next_ccw()), self.radius.get(side)];
+
+ let stroke_continuity = strokes.get(side) == strokes.get(side.next_cw());
+ connection = connection.advance(stroke_continuity && side != Side::Left);
+ always_continuous &= stroke_continuity;
+
+ draw_side(&mut path, side, self.size, radius[0], radius[1], connection);
+
+ if !stroke_continuity {
+ res.push((mem::take(&mut path), strokes.get(side)));
+ }
+ }
+
+ if always_continuous {
+ path.close_path();
+ }
+
+ if !path.0.is_empty() {
+ res.push((path, strokes.left));
+ }
+
+ res
+ }
+
+ /// Output the shape of the rectangle as a path or primitive rectangle,
+ /// depending on whether it is rounded.
+ fn fill_geometry(&self) -> Geometry {
+ if self.radius.iter().copied().all(Length::is_zero) {
+ Geometry::Rect(self.size)
+ } else {
+ let mut paths = self.stroke_segments(None);
+ assert_eq!(paths.len(), 1);
+
+ Geometry::Path(paths.pop().unwrap().0)
+ }
+ }
+}
+
+/// Draws one side of the rounded rectangle. Will always draw the left arc. The
+/// right arc will be drawn halfway iff there is no connection.
+fn draw_side(
+ path: &mut Path,
+ side: Side,
+ size: Size,
+ radius_left: Length,
+ radius_right: Length,
+ connection: Connection,
+) {
+ let reversed = |angle: Angle, radius, rotate, mirror_x, mirror_y| {
+ let [a, b, c, d] = angle.bezier_arc(radius, rotate, mirror_x, mirror_y);
+ [d, c, b, a]
+ };
+
+ let angle_left = Angle::deg(if connection.left() { 90.0 } else { 45.0 });
+ let angle_right = Angle::deg(if connection.right() { 90.0 } else { 45.0 });
+
+ let (arc1, arc2) = match side {
+ Side::Top => {
+ let arc1 = reversed(angle_left, radius_left, true, true, false)
+ .map(|x| x + Point::with_x(radius_left));
+ let arc2 = (-angle_right)
+ .bezier_arc(radius_right, true, true, false)
+ .map(|x| x + Point::with_x(size.x - radius_right));
+
+ (arc1, arc2)
+ }
+ Side::Right => {
+ let arc1 = reversed(-angle_left, radius_left, false, false, false)
+ .map(|x| x + Point::new(size.x, radius_left));
+
+ let arc2 = angle_right
+ .bezier_arc(radius_right, false, false, false)
+ .map(|x| x + Point::new(size.x, size.y - radius_right));
+
+ (arc1, arc2)
+ }
+ Side::Bottom => {
+ let arc1 = reversed(-angle_left, radius_left, true, false, false)
+ .map(|x| x + Point::new(size.x - radius_left, size.y));
+
+ let arc2 = angle_right
+ .bezier_arc(radius_right, true, false, false)
+ .map(|x| x + Point::new(radius_right, size.y));
+
+ (arc1, arc2)
+ }
+ Side::Left => {
+ let arc1 = reversed(angle_left, radius_left, false, false, true)
+ .map(|x| x + Point::with_y(size.y - radius_left));
+
+ let arc2 = (-angle_right)
+ .bezier_arc(radius_right, false, false, true)
+ .map(|x| x + Point::with_y(radius_right));
+
+ (arc1, arc2)
+ }
+ };
+
+ if !connection.left() {
+ path.move_to(if radius_left.is_zero() { arc1[3] } else { arc1[0] });
+ }
+
+ if !radius_left.is_zero() {
+ path.cubic_to(arc1[1], arc1[2], arc1[3]);
+ }
+
+ path.line_to(arc2[0]);
+
+ if !connection.right() && !radius_right.is_zero() {
+ path.cubic_to(arc2[1], arc2[2], arc2[3]);
+ }
+}
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+enum Connection {
+ None,
+ Left,
+ Right,
+ Both,
+}
+
+impl Connection {
+ pub fn advance(self, right: bool) -> Self {
+ match self {
+ Self::Right | Self::Both => {
+ if right {
+ Self::Both
+ } else {
+ Self::Left
+ }
+ }
+ Self::Left | Self::None => {
+ if right {
+ Self::Right
+ } else {
+ Self::None
+ }
+ }
+ }
+ }
+
+ fn left(self) -> bool {
+ matches!(self, Self::Left | Self::Both)
+ }
+
+ fn right(self) -> bool {
+ matches!(self, Self::Right | Self::Both)
+ }
+}
diff --git a/src/library/graphics/shape.rs b/src/library/graphics/shape.rs
index f7cda9bf..e6fd2b7d 100644
--- a/src/library/graphics/shape.rs
+++ b/src/library/graphics/shape.rs
@@ -150,7 +150,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
// Add fill and/or stroke.
let fill = styles.get(Self::FILL);
- let mut stroke = match styles.get(Self::STROKE) {
+ let stroke = match styles.get(Self::STROKE) {
Smart::Auto if fill.is_none() => Sides::splat(Some(Stroke::default())),
Smart::Auto => Sides::splat(None),
Smart::Custom(strokes) => {
@@ -179,15 +179,23 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
bottom: radius.bottom.relative_to(size.y / 2.0),
};
- if fill.is_some() || (stroke.iter().any(Option::is_some) && stroke.is_uniform()) {
- let geometry = if is_round(S) {
- Geometry::Ellipse(size)
- } else {
- Geometry::Rect(size, radius)
- };
+ let pos = Point::new(-outset.left, -outset.top);
- let shape = Shape { geometry, fill, stroke };
- frame.prepend(Point::new(-outset.left, -outset.top), Element::Shape(shape));
+ if fill.is_some() || stroke.iter().any(Option::is_some) {
+ if is_round(S) {
+ let shape = Shape {
+ geometry: Geometry::Ellipse(size),
+ fill,
+ stroke: stroke.left,
+ };
+ frame.prepend(pos, Element::Shape(shape));
+ } else {
+ for shape in
+ Rect::new(size, radius).shapes(fill, stroke).into_iter().rev()
+ {
+ frame.prepend(pos, Element::Shape(shape));
+ }
+ }
}
// Apply link if it exists.
diff --git a/src/model/layout.rs b/src/model/layout.rs
index 63e8f088..3b82ddc2 100644
--- a/src/model/layout.rs
+++ b/src/model/layout.rs
@@ -8,8 +8,10 @@ use std::sync::Arc;
use super::{Barrier, NodeId, Resolve, StyleChain, StyleEntry};
use crate::diag::TypResult;
use crate::eval::{RawAlign, RawLength};
-use crate::frame::{Element, Frame, Geometry};
-use crate::geom::{Align, Length, Paint, Point, Relative, Sides, Size, Spec, Stroke};
+use crate::frame::{Element, Frame};
+use crate::geom::{
+ Align, Geometry, Length, Paint, Point, Relative, Sides, Size, Spec, Stroke,
+};
use crate::library::graphics::MoveNode;
use crate::library::layout::{AlignNode, PadNode};
use crate::util::Prehashed;
@@ -353,8 +355,7 @@ impl Layout for FillNode {
) -> TypResult<Vec<Arc<Frame>>> {
let mut frames = self.child.layout(ctx, regions, styles)?;
for frame in &mut frames {
- let shape = Geometry::Rect(frame.size, Sides::splat(Length::zero()))
- .filled(self.fill);
+ let shape = Geometry::Rect(frame.size).filled(self.fill);
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
}
Ok(frames)
@@ -379,8 +380,7 @@ impl Layout for StrokeNode {
) -> TypResult<Vec<Arc<Frame>>> {
let mut frames = self.child.layout(ctx, regions, styles)?;
for frame in &mut frames {
- let shape = Geometry::Rect(frame.size, Sides::splat(Length::zero()))
- .stroked(self.stroke);
+ let shape = Geometry::Rect(frame.size).stroked(self.stroke);
Arc::make_mut(frame).prepend(Point::zero(), Element::Shape(shape));
}
Ok(frames)