diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-02-06 13:07:25 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-06 13:07:25 +0100 |
| commit | bfc2f5aefc6c407de0b699b31dafd835fc2c9be3 (patch) | |
| tree | 67c23ec9df3b9f535faf5fbd443e85d9a7813d37 /src/layout | |
| parent | dacd7dadc04d4538f1063a86afd676695c7471ab (diff) | |
| parent | a6cae89b47246a235ed7b1093747c6f3bcb64da4 (diff) | |
Merge pull request #17 from typst/rects
Add rectangle function 🎛
Diffstat (limited to 'src/layout')
| -rw-r--r-- | src/layout/background.rs | 37 | ||||
| -rw-r--r-- | src/layout/mod.rs | 60 | ||||
| -rw-r--r-- | src/layout/pad.rs | 10 |
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 |
