summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-02-06 13:07:25 +0100
committerGitHub <noreply@github.com>2021-02-06 13:07:25 +0100
commitbfc2f5aefc6c407de0b699b31dafd835fc2c9be3 (patch)
tree67c23ec9df3b9f535faf5fbd443e85d9a7813d37 /src/layout
parentdacd7dadc04d4538f1063a86afd676695c7471ab (diff)
parenta6cae89b47246a235ed7b1093747c6f3bcb64da4 (diff)
Merge pull request #17 from typst/rects
Add rectangle function 🎛
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/background.rs37
-rw-r--r--src/layout/mod.rs60
-rw-r--r--src/layout/pad.rs10
3 files changed, 95 insertions, 12 deletions
diff --git a/src/layout/background.rs b/src/layout/background.rs
new file mode 100644
index 00000000..07248e02
--- /dev/null
+++ b/src/layout/background.rs
@@ -0,0 +1,37 @@
+use super::*;
+
+/// A node that represents a rectangular box.
+#[derive(Debug, Clone, PartialEq)]
+pub struct NodeBackground {
+ /// The background fill.
+ pub fill: Fill,
+ /// The child node to be filled in.
+ pub child: Node,
+}
+
+impl Layout for NodeBackground {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+ let mut layouted = self.child.layout(ctx, areas);
+
+ if let Some(first) = layouted.frames_mut().first_mut() {
+ first.elements.insert(
+ 0,
+ (
+ Point::ZERO,
+ Element::Geometry(Geometry {
+ shape: Shape::Rect(first.size),
+ fill: self.fill.clone(),
+ }),
+ ),
+ )
+ }
+
+ layouted
+ }
+}
+
+impl From<NodeBackground> for NodeAny {
+ fn from(background: NodeBackground) -> Self {
+ Self::new(background)
+ }
+}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 44960de7..30295841 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1,5 +1,6 @@
//! Layouting.
+mod background;
mod fixed;
mod node;
mod pad;
@@ -8,10 +9,12 @@ mod spacing;
mod stack;
mod text;
+use crate::color::Color;
use crate::env::{Env, ResourceId};
use crate::geom::*;
use crate::shaping::Shaped;
+pub use background::*;
pub use fixed::*;
pub use node::*;
pub use pad::*;
@@ -54,7 +57,7 @@ impl NodePages {
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> {
let areas = Areas::repeat(self.size);
let layouted = self.child.layout(ctx, &areas);
- layouted.frames()
+ layouted.into_frames()
}
}
@@ -157,9 +160,27 @@ pub enum Layouted {
}
impl Layouted {
- /// Return all frames contained in this variant (zero, one or arbitrarily
- /// many).
- pub fn frames(self) -> Vec<Frame> {
+ /// Return a reference to all frames contained in this variant (zero, one or
+ /// arbitrarily many).
+ pub fn frames(&self) -> &[Frame] {
+ match self {
+ Self::Spacing(_) => &[],
+ Self::Frame(frame, _) => std::slice::from_ref(frame),
+ Self::Frames(frames, _) => frames,
+ }
+ }
+
+ /// Return a mutable reference to all frames contained in this variant.
+ pub fn frames_mut(&mut self) -> &mut [Frame] {
+ match self {
+ Self::Spacing(_) => &mut [],
+ Self::Frame(frame, _) => std::slice::from_mut(frame),
+ Self::Frames(frames, _) => frames,
+ }
+ }
+
+ /// Return all frames contained in this varian.
+ pub fn into_frames(self) -> Vec<Frame> {
match self {
Self::Spacing(_) => vec![],
Self::Frame(frame, _) => vec![frame],
@@ -204,6 +225,37 @@ pub enum Element {
Text(Shaped),
/// An image.
Image(Image),
+ /// Some shape that could hold another frame.
+ Geometry(Geometry),
+}
+
+/// The kind of graphic fill to be applied to a [`Shape`].
+#[derive(Debug, Clone, PartialEq)]
+pub enum Fill {
+ /// The fill is a color.
+ Color(Color),
+ /// The fill is an image.
+ Image(Image),
+}
+
+/// A shape with some kind of fill.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Geometry {
+ /// The shape to draw.
+ pub shape: Shape,
+ /// How the shape looks on the inside.
+ //
+ // TODO: This could be made into a Vec<Fill> or something such that
+ // the user can compose multiple fills with alpha values less
+ // than one to achieve cool effects.
+ pub fill: Fill,
+}
+
+/// Some shape.
+#[derive(Debug, Clone, PartialEq)]
+pub enum Shape {
+ /// A rectangle.
+ Rect(Size),
}
/// An image element.
diff --git a/src/layout/pad.rs b/src/layout/pad.rs
index f8a623e3..425fa41b 100644
--- a/src/layout/pad.rs
+++ b/src/layout/pad.rs
@@ -15,14 +15,8 @@ impl Layout for NodePad {
let areas = shrink(areas, self.padding);
let mut layouted = self.child.layout(ctx, &areas);
- match &mut layouted {
- Layouted::Spacing(_) => {}
- Layouted::Frame(frame, _) => pad(frame, self.padding),
- Layouted::Frames(frames, _) => {
- for frame in frames {
- pad(frame, self.padding);
- }
- }
+ for frame in layouted.frames_mut() {
+ pad(frame, self.padding);
}
layouted