summaryrefslogtreecommitdiff
path: root/src/layout
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2019-11-30 18:54:46 +0100
committerLaurenz <laurmaedje@gmail.com>2019-11-30 18:54:46 +0100
commit5782b82770f6923677942c3b4e2bf4f7258e47d8 (patch)
tree2b477fc285e9da5380e556648056b985ecbccfe0 /src/layout
parentb13ed627fff73a599b34d760cd99aa2f08d58ea8 (diff)
Refactor layouting base ♻
Diffstat (limited to 'src/layout')
-rw-r--r--src/layout/actions.rs13
-rw-r--r--src/layout/flex.rs14
-rw-r--r--src/layout/mod.rs270
-rw-r--r--src/layout/stack.rs59
-rw-r--r--src/layout/text.rs1
-rw-r--r--src/layout/tree.rs44
6 files changed, 174 insertions, 227 deletions
diff --git a/src/layout/actions.rs b/src/layout/actions.rs
index c668cf75..2528fc85 100644
--- a/src/layout/actions.rs
+++ b/src/layout/actions.rs
@@ -1,10 +1,8 @@
//! Drawing and cofiguration actions composing layouts.
use std::fmt::{self, Display, Formatter};
-use std::io::{self, Write};
-use super::Layout;
-use crate::size::{Size, Size2D};
+use super::*;
use LayoutAction::*;
/// A layouting action.
@@ -21,9 +19,8 @@ pub enum LayoutAction {
DebugBox(Size2D, Size2D),
}
-impl LayoutAction {
- /// Serialize this layout action into an easy-to-parse string representation.
- pub fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
+impl Serialize for LayoutAction {
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
match self {
MoveAbsolute(s) => write!(f, "m {:.4} {:.4}", s.x.to_pt(), s.y.to_pt()),
SetFont(i, s) => write!(f, "f {} {}", i, s.to_pt()),
@@ -121,10 +118,6 @@ impl LayoutActionList {
self.origin = position;
self.next_pos = Some(position);
- if layout.debug_render {
- self.actions.push(DebugBox(position, layout.dimensions));
- }
-
self.extend(layout.actions);
}
diff --git a/src/layout/flex.rs b/src/layout/flex.rs
index 53f6dfdf..96b2aa85 100644
--- a/src/layout/flex.rs
+++ b/src/layout/flex.rs
@@ -41,7 +41,7 @@ struct PartialLine {
usable: Size,
content: Vec<(Size, Layout)>,
dimensions: Size2D,
- space: SpaceState,
+ space: LastSpacing,
}
impl PartialLine {
@@ -50,7 +50,7 @@ impl PartialLine {
usable,
content: vec![],
dimensions: Size2D::zero(),
- space: SpaceState::Forbidden,
+ space: LastSpacing::Forbidden,
}
}
}
@@ -237,7 +237,7 @@ impl FlexLayouter {
}
}
- if let SpaceState::Soft(space) = self.part.space {
+ if let LastSpacing::Soft(space) = self.part.space {
self.layout_space(space, SpaceKind::Hard);
}
@@ -246,15 +246,15 @@ impl FlexLayouter {
self.part.dimensions.x += size.x;
self.part.dimensions.y.max_eq(size.y);
- self.part.space = SpaceState::Allowed;
+ self.part.space = LastSpacing::Allowed;
Ok(())
}
fn layout_space(&mut self, space: Size, kind: SpaceKind) {
if kind == SpaceKind::Soft {
- if self.part.space != SpaceState::Forbidden {
- self.part.space = SpaceState::Soft(space);
+ if self.part.space != LastSpacing::Forbidden {
+ self.part.space = LastSpacing::Soft(space);
}
} else {
if self.part.dimensions.x + space > self.part.usable {
@@ -264,7 +264,7 @@ impl FlexLayouter {
}
if kind == SpaceKind::Hard {
- self.part.space = SpaceState::Forbidden;
+ self.part.space = LastSpacing::Forbidden;
}
}
}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index cd4986d9..31064d40 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -9,7 +9,7 @@ use toddle::Error as FontError;
use crate::func::Command;
use crate::size::{Size, Size2D, SizeBox};
-use crate::style::{PageStyle, TextStyle};
+use crate::style::{LayoutStyle, TextStyle};
use crate::syntax::{FuncCall, Node, SyntaxTree};
mod actions;
@@ -29,99 +29,20 @@ pub mod layouters {
pub use actions::{LayoutAction, LayoutActionList};
pub use layouters::*;
+/// A collection of layouts.
+pub type MultiLayout = Vec<Layout>;
+
/// A sequence of layouting actions inside a box.
#[derive(Debug, Clone)]
pub struct Layout {
/// The size of the box.
pub dimensions: Size2D,
+ /// The baseline of the layout (as an offset from the top-left).
+ pub baseline: Option<Size>,
+ /// How to align this layout in a parent container.
+ pub alignment: LayoutAlignment,
/// The actions composing this layout.
pub actions: Vec<LayoutAction>,
- /// Whether to debug-render this box.
- pub debug_render: bool,
-}
-
-impl Layout {
- /// Serialize this layout into an output buffer.
- pub fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
- writeln!(
- f,
- "{:.4} {:.4}",
- self.dimensions.x.to_pt(),
- self.dimensions.y.to_pt()
- )?;
- writeln!(f, "{}", self.actions.len())?;
- for action in &self.actions {
- action.serialize(f)?;
- writeln!(f)?;
- }
- Ok(())
- }
-}
-
-/// A collection of layouts.
-#[derive(Debug, Clone)]
-pub struct MultiLayout {
- pub layouts: Vec<Layout>,
-}
-
-impl MultiLayout {
- /// Create an empty multi-layout.
- pub fn new() -> MultiLayout {
- MultiLayout { layouts: vec![] }
- }
-
- /// Extract the single sublayout. This panics if the layout does not have
- /// exactly one child.
- pub fn into_single(mut self) -> Layout {
- if self.layouts.len() != 1 {
- panic!("into_single: contains not exactly one layout");
- }
- self.layouts.pop().unwrap()
- }
-
- /// Add a sublayout.
- pub fn add(&mut self, layout: Layout) {
- self.layouts.push(layout);
- }
-
- /// The count of sublayouts.
- pub fn count(&self) -> usize {
- self.layouts.len()
- }
-
- /// Whether this layout contains any sublayouts.
- pub fn is_empty(&self) -> bool {
- self.layouts.is_empty()
- }
-}
-
-impl MultiLayout {
- /// Serialize this collection of layouts into an output buffer.
- pub fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
- writeln!(f, "{}", self.count())?;
- for layout in self {
- layout.serialize(f)?;
- }
- Ok(())
- }
-}
-
-impl IntoIterator for MultiLayout {
- type Item = Layout;
- type IntoIter = std::vec::IntoIter<Layout>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.layouts.into_iter()
- }
-}
-
-impl<'a> IntoIterator for &'a MultiLayout {
- type Item = &'a Layout;
- type IntoIter = std::slice::Iter<'a, Layout>;
-
- fn into_iter(self) -> Self::IntoIter {
- self.layouts.iter()
- }
}
/// The general context for layouting.
@@ -130,20 +51,16 @@ pub struct LayoutContext<'a, 'p> {
/// The font loader to retrieve fonts from when typesetting text
/// using [`layout_text`].
pub loader: &'a SharedFontLoader<'p>,
+ /// The style for pages and text.
+ pub style: &'a LayoutStyle,
/// Whether this layouting process handles the top-level pages.
pub top_level: bool,
- /// The style to set text with. This includes sizes and font classes
- /// which determine which font from the loaders selection is used.
- pub text_style: &'a TextStyle,
- /// The current size and margins of the top-level pages.
- pub page_style: PageStyle,
/// The spaces to layout in.
pub spaces: LayoutSpaces,
- /// The axes to flow on.
+ /// The initial axes along which content is laid out.
pub axes: LayoutAxes,
- /// Whether layouts should expand to the full dimensions of the space
- /// they lie on or whether should tightly fit the content.
- pub expand: bool,
+ /// The alignment for the two axes.
+ pub alignment: LayoutAlignment,
}
/// A possibly stack-allocated vector of layout spaces.
@@ -154,26 +71,31 @@ pub type LayoutSpaces = SmallVec<[LayoutSpace; 2]>;
pub struct LayoutSpace {
/// The maximum size of the box to layout in.
pub dimensions: Size2D,
+ /// Whether to expand the dimensions of the resulting layout to the full
+ /// dimensions of this space or to shrink them to fit the content for the
+ /// vertical and horizontal axis.
+ pub expand: (bool, bool),
/// Padding that should be respected on each side.
pub padding: SizeBox,
}
impl LayoutSpace {
- /// The actually usable area (dimensions minus padding).
- pub fn usable(&self) -> Size2D {
- self.dimensions.unpadded(self.padding)
- }
-
/// The offset from the origin to the start of content, that is,
/// `(padding.left, padding.top)`.
pub fn start(&self) -> Size2D {
Size2D::new(self.padding.left, self.padding.right)
}
+ /// The actually usable area (dimensions minus padding).
+ pub fn usable(&self) -> Size2D {
+ self.dimensions.unpadded(self.padding)
+ }
+
/// A layout space without padding and dimensions reduced by the padding.
pub fn usable_space(&self) -> LayoutSpace {
LayoutSpace {
dimensions: self.usable(),
+ expand: (false, false),
padding: SizeBox::zero(),
}
}
@@ -182,17 +104,21 @@ impl LayoutSpace {
/// The axes along which the content is laid out.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct LayoutAxes {
- pub primary: AlignedAxis,
- pub secondary: AlignedAxis,
+ pub primary: Axis,
+ pub secondary: Axis,
}
impl LayoutAxes {
+ pub fn new(primary: Axis, secondary: Axis) -> LayoutAxes {
+ LayoutAxes { primary, secondary }
+ }
+
/// Returns the generalized version of a `Size2D` dependent on
/// the layouting axes, that is:
/// - The x coordinate describes the primary axis instead of the horizontal one.
/// - The y coordinate describes the secondary axis instead of the vertical one.
pub fn generalize(&self, size: Size2D) -> Size2D {
- if self.primary.axis.is_horizontal() {
+ if self.primary.is_horizontal() {
size
} else {
Size2D { x: size.y, y: size.x }
@@ -206,58 +132,9 @@ impl LayoutAxes {
// at the call site, we still have this second function.
self.generalize(size)
}
-
- /// The position of the anchor specified by the two aligned axes
- /// in the given generalized space.
- pub fn anchor(&self, space: Size2D) -> Size2D {
- Size2D::new(self.primary.anchor(space.x), self.secondary.anchor(space.y))
- }
-
- /// This axes with `expand` set to the given value for both axes.
- pub fn expanding(&self, expand: bool) -> LayoutAxes {
- LayoutAxes {
- primary: self.primary.expanding(expand),
- secondary: self.secondary.expanding(expand),
- }
- }
-}
-
-/// An axis with an alignment.
-#[derive(Debug, Copy, Clone, Eq, PartialEq)]
-pub struct AlignedAxis {
- pub axis: Axis,
- pub alignment: Alignment,
- pub expand: bool,
-}
-
-impl AlignedAxis {
- /// Creates an aligned axis from its three components.
- pub fn new(axis: Axis, alignment: Alignment, expand: bool) -> AlignedAxis {
- AlignedAxis { axis, alignment, expand }
- }
-
- /// The position of the anchor specified by this axis on the given line.
- pub fn anchor(&self, line: Size) -> Size {
- use Alignment::*;
- match (self.axis.is_positive(), self.alignment) {
- (true, Origin) | (false, End) => Size::zero(),
- (_, Center) => line / 2,
- (true, End) | (false, Origin) => line,
- }
- }
-
- /// This axis with `expand` set to the given value.
- pub fn expanding(&self, expand: bool) -> AlignedAxis {
- AlignedAxis { expand, ..*self }
- }
-
- /// Whether this axis needs expansion.
- pub fn needs_expansion(&self) -> bool {
- self.expand || self.alignment != Alignment::Origin
- }
}
-/// Where to put content.
+/// Directions along which content is laid out.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Axis {
LeftToRight,
@@ -292,6 +169,19 @@ impl Axis {
}
}
+/// The place to put a layout in a container.
+#[derive(Debug, Copy, Clone, Eq, PartialEq)]
+pub struct LayoutAlignment {
+ pub primary: Alignment,
+ pub secondary: Alignment,
+}
+
+impl LayoutAlignment {
+ pub fn new(primary: Alignment, secondary: Alignment) -> LayoutAlignment {
+ LayoutAlignment { primary, secondary }
+ }
+}
+
/// Where to align content.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Alignment {
@@ -300,26 +190,74 @@ pub enum Alignment {
End,
}
+/// The specialized anchor position for an item with the given alignment in a
+/// container with a given size along the given axis.
+pub fn anchor(axis: Axis, size: Size, alignment: Alignment) -> Size {
+ use Alignment::*;
+ match (axis.is_positive(), alignment) {
+ (true, Origin) | (false, End) => Size::zero(),
+ (_, Center) => size / 2,
+ (true, End) | (false, Origin) => size,
+ }
+}
+
+/// Whitespace between boxes with different interaction properties.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum SpaceKind {
- /// Soft spaces are eaten up by hard spaces before or after them.
- Soft,
- /// Independent do not eat up soft spaces and are not eaten up by hard spaces.
- Independent,
- /// Hard spaces eat up soft spaces before or after them.
+pub enum SpacingKind {
+ /// A hard space consumes surrounding soft spaces and is always layouted.
Hard,
+ /// A soft space consumes surrounding soft spaces with higher value.
+ Soft(u32),
}
+/// The standard spacing kind used for paragraph spacing.
+const PARAGRAPH_KIND: SpacingKind = SpacingKind::Soft(1);
+
+/// The standard spacing kind used for normal spaces between boxes.
+const SPACE_KIND: SpacingKind = SpacingKind::Soft(2);
+
+/// The last appeared spacing.
#[derive(Debug, Copy, Clone, PartialEq)]
-enum SpaceState {
- Soft(Size),
- Forbidden,
- Allowed,
+enum LastSpacing {
+ Hard,
+ Soft(Size, u32),
+ None,
}
-impl SpaceState {
+impl LastSpacing {
fn soft_or_zero(&self) -> Size {
- if let SpaceState::Soft(space) = self { *space } else { Size::zero() }
+ match self {
+ LastSpacing::Soft(space, _) => *space,
+ _ => Size::zero(),
+ }
+ }
+}
+
+/// Layout components that can be serialized.
+trait Serialize {
+ /// Serialize the data structure into an output writable.
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()>;
+}
+
+impl Serialize for Layout {
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
+ writeln!(f, "{:.4} {:.4}", self.dimensions.x.to_pt(), self.dimensions.y.to_pt())?;
+ writeln!(f, "{}", self.actions.len())?;
+ for action in &self.actions {
+ action.serialize(f)?;
+ writeln!(f)?;
+ }
+ Ok(())
+ }
+}
+
+impl Serialize for MultiLayout {
+ fn serialize<W: Write>(&self, f: &mut W) -> io::Result<()> {
+ writeln!(f, "{}", self.len())?;
+ for layout in self {
+ layout.serialize(f)?;
+ }
+ Ok(())
}
}
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index f46c3da0..fd88ce98 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -1,23 +1,54 @@
use smallvec::smallvec;
use super::*;
+/// The stack layouter arranges boxes stacked onto each other.
+///
+/// The boxes are laid out in the direction of the secondary layouting axis and
+/// are aligned along both axes.
#[derive(Debug, Clone)]
pub struct StackLayouter {
+ /// The context for layouter.
ctx: StackContext,
+ /// The output layouts.
layouts: MultiLayout,
-
+ /// The full layout space.
space: Space,
+ /// The currently active subspace.
sub: Subspace,
}
#[derive(Debug, Clone)]
struct Space {
+ /// The index of this space in the list of spaces.
index: usize,
+ /// Whether to add the layout for this space even if it would be empty.
hard: bool,
+ /// The layouting actions accumulated from the subspaces.
actions: LayoutActionList,
+ /// The used size of this space from the top-left corner to
+ /// the bottomright-most point of used space (specialized).
combined_dimensions: Size2D,
}
+#[derive(Debug, Clone)]
+struct Subspace {
+ /// The axes along which contents in this subspace are laid out.
+ axes: LayoutAxes,
+ /// The beginning of this subspace in the parent space (specialized).
+ origin: Size2D,
+ /// The total usable space of this subspace (generalized).
+ usable: Size2D,
+ /// The used size of this subspace (generalized), with
+ /// - `x` being the maximum of the primary size of all boxes.
+ /// - `y` being the total extent of all boxes and space in the secondary
+ /// direction.
+ size: Size2D,
+ /// The so-far accumulated (offset, anchor, box) triples.
+ boxes: Vec<(Size, Size, Layout)>,
+ /// The last added spacing if the last was spacing.
+ last_spacing: LastSpacing,
+}
+
impl Space {
fn new(index: usize, hard: bool) -> Space {
Space {
@@ -29,20 +60,6 @@ impl Space {
}
}
-#[derive(Debug, Clone)]
-struct Subspace {
- origin: Size2D,
- anchor: Size2D,
- factor: i32,
-
- boxes: Vec<(Size, Size, Layout)>,
-
- usable: Size2D,
- dimensions: Size2D,
-
- space: SpaceState,
-}
-
impl Subspace {
fn new(origin: Size2D, usable: Size2D, axes: LayoutAxes) -> Subspace {
Subspace {
@@ -52,7 +69,7 @@ impl Subspace {
boxes: vec![],
usable: axes.generalize(usable),
dimensions: Size2D::zero(),
- space: SpaceState::Forbidden,
+ space: LastSpacing::Forbidden,
}
}
}
@@ -82,7 +99,7 @@ impl StackLayouter {
}
pub fn add(&mut self, layout: Layout) -> LayoutResult<()> {
- if let SpaceState::Soft(space) = self.sub.space {
+ if let LastSpacing::Soft(space) = self.sub.space {
self.add_space(space, SpaceKind::Hard);
}
@@ -107,7 +124,7 @@ impl StackLayouter {
self.sub.boxes.push((offset, anchor, layout));
self.sub.dimensions = new_dimensions;
- self.sub.space = SpaceState::Allowed;
+ self.sub.space = LastSpacing::Allowed;
Ok(())
}
@@ -121,8 +138,8 @@ impl StackLayouter {
pub fn add_space(&mut self, space: Size, kind: SpaceKind) {
if kind == SpaceKind::Soft {
- if self.sub.space != SpaceState::Forbidden {
- self.sub.space = SpaceState::Soft(space);
+ if self.sub.space != LastSpacing::Forbidden {
+ self.sub.space = LastSpacing::Soft(space);
}
} else {
if self.sub.dimensions.y + space > self.sub.usable.y {
@@ -132,7 +149,7 @@ impl StackLayouter {
}
if kind == SpaceKind::Hard {
- self.sub.space = SpaceState::Forbidden;
+ self.sub.space = LastSpacing::Forbidden;
}
}
}
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 66ff75fd..3ca826ca 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -73,7 +73,6 @@ impl<'a, 'p> TextLayouter<'a, 'p> {
Ok(Layout {
dimensions: Size2D::new(self.width, self.ctx.style.font_size),
actions: self.actions.to_vec(),
- debug_render: false,
})
}
diff --git a/src/layout/tree.rs b/src/layout/tree.rs
index 56fb120c..9a818963 100644
--- a/src/layout/tree.rs
+++ b/src/layout/tree.rs
@@ -11,7 +11,7 @@ pub fn layout_tree(tree: &SyntaxTree, ctx: LayoutContext) -> LayoutResult<MultiL
struct TreeLayouter<'a, 'p> {
ctx: LayoutContext<'a, 'p>,
flex: FlexLayouter,
- style: TextStyle,
+ style: LayoutStyle,
}
impl<'a, 'p> TreeLayouter<'a, 'p> {
@@ -19,12 +19,12 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
fn new(ctx: LayoutContext<'a, 'p>) -> TreeLayouter<'a, 'p> {
TreeLayouter {
flex: FlexLayouter::new(FlexContext {
- flex_spacing: flex_spacing(&ctx.text_style),
+ flex_spacing: flex_spacing(&ctx.style.text),
spaces: ctx.spaces.clone(),
axes: ctx.axes,
expand: ctx.expand,
}),
- style: ctx.text_style.clone(),
+ style: ctx.style.clone(),
ctx,
}
}
@@ -37,9 +37,9 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
Node::Space => self.layout_space(),
Node::Newline => self.layout_paragraph()?,
- Node::ToggleItalics => self.style.toggle_class(FontClass::Italic),
- Node::ToggleBold => self.style.toggle_class(FontClass::Bold),
- Node::ToggleMonospace => self.style.toggle_class(FontClass::Monospace),
+ Node::ToggleItalics => self.style.text.toggle_class(FontClass::Italic),
+ Node::ToggleBold => self.style.text.toggle_class(FontClass::Bold),
+ Node::ToggleMonospace => self.style.text.toggle_class(FontClass::Monospace),
Node::Func(func) => self.layout_func(func)?,
}
@@ -51,34 +51,35 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
fn layout_text(&mut self, text: &str) -> LayoutResult<()> {
let layout = layout_text(text, TextContext {
loader: &self.ctx.loader,
- style: &self.style,
+ style: &self.style.text,
})?;
Ok(self.flex.add(layout))
}
fn layout_space(&mut self) {
- self.flex.add_primary_space(word_spacing(&self.style), SpaceKind::Soft);
+ self.flex.add_primary_space(
+ word_spacing(&self.style.text),
+ SPACE_KIND,
+ );
}
fn layout_paragraph(&mut self) -> LayoutResult<()> {
- self.flex.add_secondary_space(paragraph_spacing(&self.style), SpaceKind::Soft)
+ self.flex.add_secondary_space(
+ paragraph_spacing(&self.style.text),
+ PARAGRAPH_KIND,
+ )
}
fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> {
let spaces = self.flex.remaining();
- let mut axes = self.ctx.axes.expanding(false);
- axes.secondary.alignment = Alignment::Origin;
-
let commands = func.body.val.layout(LayoutContext {
loader: self.ctx.loader,
+ style: &self.style,
top_level: false,
- text_style: &self.style,
- page_style: self.ctx.page_style,
spaces,
- axes,
- expand: false,
+ .. self.ctx
})?;
for command in commands {
@@ -95,10 +96,8 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
Command::Add(layout) => self.flex.add(layout),
Command::AddMultiple(layouts) => self.flex.add_multiple(layouts),
- Command::AddPrimarySpace(space)
- => self.flex.add_primary_space(space, SpaceKind::Hard),
- Command::AddSecondarySpace(space)
- => self.flex.add_secondary_space(space, SpaceKind::Hard)?,
+ Command::AddPrimarySpace(space) => self.flex.add_primary_space(space, SpacingKind::Hard),
+ Command::AddSecondarySpace(space) => self.flex.add_secondary_space(space, SpacingKind::Hard)?,
Command::FinishLine => self.flex.add_break(),
Command::FinishRun => { self.flex.finish_run()?; },
@@ -106,16 +105,17 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
Command::BreakParagraph => self.layout_paragraph()?,
- Command::SetTextStyle(style) => self.style = style,
+ Command::SetTextStyle(style) => self.style.text = style,
Command::SetPageStyle(style) => {
if !self.ctx.top_level {
lerr!("page style cannot only be altered in the top-level context");
}
- self.ctx.page_style = style;
+ self.style.page = style;
self.flex.set_spaces(smallvec![
LayoutSpace {
dimensions: style.dimensions,
+ expand: (true, true),
padding: style.margins,
}
], true);