mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Remove top-level stack layouter from tree layouter 🗑
This commit is contained in:
parent
bd66ebd683
commit
467d7203ee
@ -93,9 +93,11 @@ pub enum Command<'a> {
|
|||||||
Add(Layout),
|
Add(Layout),
|
||||||
AddMultiple(MultiLayout),
|
AddMultiple(MultiLayout),
|
||||||
|
|
||||||
BreakFlex,
|
FinishRun,
|
||||||
FinishFlex,
|
FinishBox,
|
||||||
BreakStack,
|
FinishLayout,
|
||||||
|
|
||||||
|
BreakParagraph,
|
||||||
|
|
||||||
SetStyle(TextStyle),
|
SetStyle(TextStyle),
|
||||||
SetAxes(LayoutAxes),
|
SetAxes(LayoutAxes),
|
||||||
|
@ -20,8 +20,8 @@ use super::*;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FlexLayouter {
|
pub struct FlexLayouter {
|
||||||
ctx: FlexContext,
|
ctx: FlexContext,
|
||||||
units: Vec<FlexUnit>,
|
|
||||||
stack: StackLayouter,
|
stack: StackLayouter,
|
||||||
|
units: Vec<FlexUnit>,
|
||||||
|
|
||||||
usable: Size,
|
usable: Size,
|
||||||
run: FlexRun,
|
run: FlexRun,
|
||||||
@ -35,6 +35,7 @@ pub struct FlexLayouter {
|
|||||||
pub struct FlexContext {
|
pub struct FlexContext {
|
||||||
pub spaces: LayoutSpaces,
|
pub spaces: LayoutSpaces,
|
||||||
pub axes: LayoutAxes,
|
pub axes: LayoutAxes,
|
||||||
|
pub shrink_to_fit: bool,
|
||||||
/// The spacing between two lines of boxes.
|
/// The spacing between two lines of boxes.
|
||||||
pub flex_spacing: Size,
|
pub flex_spacing: Size,
|
||||||
}
|
}
|
||||||
@ -63,6 +64,7 @@ impl FlexLayouter {
|
|||||||
let stack = StackLayouter::new(StackContext {
|
let stack = StackLayouter::new(StackContext {
|
||||||
spaces: ctx.spaces,
|
spaces: ctx.spaces,
|
||||||
axes: ctx.axes,
|
axes: ctx.axes,
|
||||||
|
shrink_to_fit: ctx.shrink_to_fit,
|
||||||
});
|
});
|
||||||
|
|
||||||
FlexLayouter {
|
FlexLayouter {
|
||||||
@ -88,14 +90,20 @@ impl FlexLayouter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a forced run break.
|
||||||
|
pub fn add_run_break(&mut self) {
|
||||||
|
self.units.push(FlexUnit::Break);
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a space box which can be replaced by a run break.
|
/// Add a space box which can be replaced by a run break.
|
||||||
pub fn add_space(&mut self, space: Size) {
|
pub fn add_primary_space(&mut self, space: Size) {
|
||||||
self.units.push(FlexUnit::Space(space));
|
self.units.push(FlexUnit::Space(space));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a forced run break.
|
pub fn add_secondary_space(&mut self, space: Size) -> LayoutResult<()> {
|
||||||
pub fn add_break(&mut self) {
|
self.finish_box()?;
|
||||||
self.units.push(FlexUnit::Break);
|
self.stack.add_space(space);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the axes in use by this flex layouter.
|
/// Update the axes in use by this flex layouter.
|
||||||
@ -109,6 +117,21 @@ impl FlexLayouter {
|
|||||||
/// with borrowed layouters. The state of the layouter is not reset.
|
/// with borrowed layouters. The state of the layouter is not reset.
|
||||||
/// Therefore, it should not be further used after calling `finish`.
|
/// Therefore, it should not be further used after calling `finish`.
|
||||||
pub fn finish(&mut self) -> LayoutResult<MultiLayout> {
|
pub fn finish(&mut self) -> LayoutResult<MultiLayout> {
|
||||||
|
self.finish_box()?;
|
||||||
|
Ok(self.stack.finish())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish_layout(&mut self, hard: bool) -> LayoutResult<()> {
|
||||||
|
self.finish_box()?;
|
||||||
|
self.stack.finish_layout(hard);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finish_box(&mut self) -> LayoutResult<()> {
|
||||||
|
if self.box_is_empty() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// Move the units out of the layout because otherwise, we run into
|
// Move the units out of the layout because otherwise, we run into
|
||||||
// ownership problems.
|
// ownership problems.
|
||||||
let units = std::mem::replace(&mut self.units, vec![]);
|
let units = std::mem::replace(&mut self.units, vec![]);
|
||||||
@ -131,49 +154,9 @@ impl FlexLayouter {
|
|||||||
// Finish the last flex run.
|
// Finish the last flex run.
|
||||||
self.finish_run()?;
|
self.finish_run()?;
|
||||||
|
|
||||||
Ok(self.stack.finish())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Layout a content box into the current flex run or start a new run if
|
|
||||||
/// it does not fit.
|
|
||||||
fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> {
|
|
||||||
let size = self.ctx.axes.generalize(boxed.dimensions);
|
|
||||||
|
|
||||||
let space = self.space.unwrap_or(Size::zero());
|
|
||||||
let new_run_size = self.run.size.x + space + size.x;
|
|
||||||
|
|
||||||
if new_run_size > self.usable {
|
|
||||||
self.space = None;
|
|
||||||
|
|
||||||
while size.x > self.usable {
|
|
||||||
if self.stack.in_last_space() {
|
|
||||||
Err(LayoutError::NotEnoughSpace("cannot fix box into flex run"))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.stack.add_break(true);
|
|
||||||
self.usable = self.stack.usable().x;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.finish_run()?;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(space) = self.space.take() {
|
|
||||||
if self.run.size.x > Size::zero() && self.run.size.x + space <= self.usable {
|
|
||||||
self.run.size.x += space;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.run.content.push((self.run.size.x, boxed));
|
|
||||||
self.run.size.x += size.x;
|
|
||||||
self.run.size.y = crate::size::max(self.run.size.y, size.y);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_set_axes(&mut self, axes: LayoutAxes) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finish the current flex run.
|
/// Finish the current flex run.
|
||||||
fn finish_run(&mut self) -> LayoutResult<()> {
|
fn finish_run(&mut self) -> LayoutResult<()> {
|
||||||
let mut actions = LayoutActionList::new();
|
let mut actions = LayoutActionList::new();
|
||||||
@ -195,13 +178,59 @@ impl FlexLayouter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Layout a content box into the current flex run or start a new run if
|
||||||
|
/// it does not fit.
|
||||||
|
fn layout_box(&mut self, boxed: Layout) -> LayoutResult<()> {
|
||||||
|
let size = self.ctx.axes.generalize(boxed.dimensions);
|
||||||
|
|
||||||
|
let space = self.space.unwrap_or(Size::zero());
|
||||||
|
let new_run_size = self.run.size.x + space + size.x;
|
||||||
|
|
||||||
|
if new_run_size > self.usable {
|
||||||
|
self.space = None;
|
||||||
|
|
||||||
|
while size.x > self.usable {
|
||||||
|
if self.stack.in_last_space() {
|
||||||
|
Err(LayoutError::NotEnoughSpace("cannot fix box into flex run"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.stack.finish_layout(true);
|
||||||
|
self.usable = self.stack.usable().x;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.finish_run()?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(space) = self.space.take() {
|
||||||
|
if self.run.size.x > Size::zero() && self.run.size.x + space <= self.usable {
|
||||||
|
self.run.size.x += space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.run.content.push((self.run.size.x, boxed));
|
||||||
|
self.run.size.x += size.x;
|
||||||
|
self.run.size.y = crate::size::max(self.run.size.y, size.y);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout_set_axes(&mut self, axes: LayoutAxes) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
/// This layouter's context.
|
/// This layouter's context.
|
||||||
pub fn ctx(&self) -> FlexContext {
|
pub fn ctx(&self) -> FlexContext {
|
||||||
self.ctx
|
self.ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remaining(&self) -> LayoutResult<LayoutSpaces> {
|
||||||
|
let mut future = self.clone();
|
||||||
|
future.finish_box()?;
|
||||||
|
Ok(future.stack.remaining())
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether this layouter contains any items.
|
/// Whether this layouter contains any items.
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn box_is_empty(&self) -> bool {
|
||||||
self.units.is_empty()
|
self.units.is_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,10 @@ pub struct LayoutContext<'a, 'p> {
|
|||||||
|
|
||||||
/// The axes to flow on.
|
/// The axes to flow on.
|
||||||
pub axes: LayoutAxes,
|
pub axes: LayoutAxes,
|
||||||
|
|
||||||
|
/// Whether to shrink the spaces to fit the content or to keep
|
||||||
|
/// the original dimensions.
|
||||||
|
pub shrink_to_fit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A possibly stack-allocated vector of layout spaces.
|
/// A possibly stack-allocated vector of layout spaces.
|
||||||
@ -163,10 +167,6 @@ pub struct LayoutSpace {
|
|||||||
|
|
||||||
/// Padding that should be respected on each side.
|
/// Padding that should be respected on each side.
|
||||||
pub padding: SizeBox,
|
pub padding: SizeBox,
|
||||||
|
|
||||||
/// Whether to shrink the space to fit the content or to keep
|
|
||||||
/// the original dimensions.
|
|
||||||
pub shrink_to_fit: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LayoutSpace {
|
impl LayoutSpace {
|
||||||
@ -182,11 +182,10 @@ impl LayoutSpace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A layout space without padding and dimensions reduced by the padding.
|
/// A layout space without padding and dimensions reduced by the padding.
|
||||||
pub fn usable_space(&self, shrink_to_fit: bool) -> LayoutSpace {
|
pub fn usable_space(&self) -> LayoutSpace {
|
||||||
LayoutSpace {
|
LayoutSpace {
|
||||||
dimensions: self.usable(),
|
dimensions: self.usable(),
|
||||||
padding: SizeBox::zero(),
|
padding: SizeBox::zero(),
|
||||||
shrink_to_fit,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ pub struct StackLayouter {
|
|||||||
pub struct StackContext {
|
pub struct StackContext {
|
||||||
pub spaces: LayoutSpaces,
|
pub spaces: LayoutSpaces,
|
||||||
pub axes: LayoutAxes,
|
pub axes: LayoutAxes,
|
||||||
|
pub shrink_to_fit: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StackLayouter {
|
impl StackLayouter {
|
||||||
@ -61,7 +62,7 @@ impl StackLayouter {
|
|||||||
Err(LayoutError::NotEnoughSpace("cannot fit box into stack"))?;
|
Err(LayoutError::NotEnoughSpace("cannot fit box into stack"))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.add_break(true);
|
self.finish_layout(true);
|
||||||
new_dimensions = merge_sizes(self.dimensions, size);
|
new_dimensions = merge_sizes(self.dimensions, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,16 +86,20 @@ impl StackLayouter {
|
|||||||
/// Add space after the last layout.
|
/// Add space after the last layout.
|
||||||
pub fn add_space(&mut self, space: Size) {
|
pub fn add_space(&mut self, space: Size) {
|
||||||
if self.dimensions.y + space > self.usable.y {
|
if self.dimensions.y + space > self.usable.y {
|
||||||
self.add_break(false);
|
self.finish_layout(false);
|
||||||
} else {
|
} else {
|
||||||
self.dimensions.y += space;
|
self.dimensions.y += space;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the current layout and start a new one in a new space.
|
/// Update the axes in use by this stack layouter.
|
||||||
pub fn add_break(&mut self, hard: bool) {
|
pub fn set_axes(&self, axes: LayoutAxes) {
|
||||||
self.finish_layout();
|
if axes != self.ctx.axes {
|
||||||
self.start_new_space(hard);
|
self.finish_boxes();
|
||||||
|
self.usable = self.remains();
|
||||||
|
self.dimensions = Size2D::zero();
|
||||||
|
self.ctx.axes = axes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the layouting.
|
/// Finish the layouting.
|
||||||
@ -103,19 +108,20 @@ impl StackLayouter {
|
|||||||
/// Nevertheless, it should not be used further.
|
/// Nevertheless, it should not be used further.
|
||||||
pub fn finish(&mut self) -> MultiLayout {
|
pub fn finish(&mut self) -> MultiLayout {
|
||||||
if self.hard || !self.boxes.is_empty() {
|
if self.hard || !self.boxes.is_empty() {
|
||||||
self.finish_layout();
|
self.finish_layout(false);
|
||||||
}
|
}
|
||||||
std::mem::replace(&mut self.layouts, MultiLayout::new())
|
std::mem::replace(&mut self.layouts, MultiLayout::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish_layout(&mut self) {
|
/// Finish the current layout and start a new one in a new space.
|
||||||
|
pub fn finish_layout(&mut self, hard: bool) {
|
||||||
self.finish_boxes();
|
self.finish_boxes();
|
||||||
|
|
||||||
let space = self.ctx.spaces[self.active_space];
|
let space = self.ctx.spaces[self.active_space];
|
||||||
let actions = std::mem::replace(&mut self.merged_actions, LayoutActionList::new());
|
let actions = std::mem::replace(&mut self.merged_actions, LayoutActionList::new());
|
||||||
|
|
||||||
self.layouts.add(Layout {
|
self.layouts.add(Layout {
|
||||||
dimensions: if space.shrink_to_fit {
|
dimensions: if self.ctx.shrink_to_fit {
|
||||||
self.merged_dimensions.padded(space.padding)
|
self.merged_dimensions.padded(space.padding)
|
||||||
} else {
|
} else {
|
||||||
space.dimensions
|
space.dimensions
|
||||||
@ -123,6 +129,16 @@ impl StackLayouter {
|
|||||||
actions: actions.into_vec(),
|
actions: actions.into_vec(),
|
||||||
debug_render: true,
|
debug_render: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let next_space = self.next_space();
|
||||||
|
let space = self.ctx.spaces[next_space];
|
||||||
|
|
||||||
|
self.merged_dimensions = Size2D::zero();
|
||||||
|
|
||||||
|
self.usable = self.ctx.axes.generalize(space.usable());
|
||||||
|
self.dimensions = Size2D::zero();
|
||||||
|
self.active_space = next_space;
|
||||||
|
self.hard = hard;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compose all cached boxes into a layout.
|
/// Compose all cached boxes into a layout.
|
||||||
@ -154,29 +170,6 @@ impl StackLayouter {
|
|||||||
self.merged_dimensions = merge_sizes(self.merged_dimensions, dimensions);
|
self.merged_dimensions = merge_sizes(self.merged_dimensions, dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set up layouting in the next space.
|
|
||||||
fn start_new_space(&mut self, hard: bool) {
|
|
||||||
let next_space = self.next_space();
|
|
||||||
let space = self.ctx.spaces[next_space];
|
|
||||||
|
|
||||||
self.merged_dimensions = Size2D::zero();
|
|
||||||
|
|
||||||
self.usable = self.ctx.axes.generalize(space.usable());
|
|
||||||
self.dimensions = Size2D::zero();
|
|
||||||
self.active_space = next_space;
|
|
||||||
self.hard = hard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Update the axes in use by this stack layouter.
|
|
||||||
pub fn set_axes(&self, axes: LayoutAxes) {
|
|
||||||
if axes != self.ctx.axes {
|
|
||||||
self.finish_boxes();
|
|
||||||
self.usable = self.remains();
|
|
||||||
self.dimensions = Size2D::zero();
|
|
||||||
self.ctx.axes = axes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This layouter's context.
|
/// This layouter's context.
|
||||||
pub fn ctx(&self) -> StackContext {
|
pub fn ctx(&self) -> StackContext {
|
||||||
self.ctx
|
self.ctx
|
||||||
@ -187,16 +180,15 @@ impl StackLayouter {
|
|||||||
self.usable
|
self.usable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The remaining spaces for new layouts in the current space.
|
/// The remaining usable spaces for new layouts.
|
||||||
pub fn remaining(&self, shrink_to_fit: bool) -> LayoutSpaces {
|
pub fn remaining(&self) -> LayoutSpaces {
|
||||||
let mut spaces = smallvec![LayoutSpace {
|
let mut spaces = smallvec![LayoutSpace {
|
||||||
dimensions: self.ctx.axes.specialize(self.remains()),
|
dimensions: self.ctx.axes.specialize(self.remains()),
|
||||||
padding: SizeBox::zero(),
|
padding: SizeBox::zero(),
|
||||||
shrink_to_fit,
|
|
||||||
}];
|
}];
|
||||||
|
|
||||||
for space in &self.ctx.spaces[self.next_space()..] {
|
for space in &self.ctx.spaces[self.next_space()..] {
|
||||||
spaces.push(space.usable_space(shrink_to_fit));
|
spaces.push(space.usable_space());
|
||||||
}
|
}
|
||||||
|
|
||||||
spaces
|
spaces
|
||||||
|
@ -10,7 +10,6 @@ pub fn layout_tree(tree: &SyntaxTree, ctx: LayoutContext) -> LayoutResult<MultiL
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct TreeLayouter<'a, 'p> {
|
struct TreeLayouter<'a, 'p> {
|
||||||
ctx: LayoutContext<'a, 'p>,
|
ctx: LayoutContext<'a, 'p>,
|
||||||
stack: StackLayouter,
|
|
||||||
flex: FlexLayouter,
|
flex: FlexLayouter,
|
||||||
style: Cow<'a, TextStyle>,
|
style: Cow<'a, TextStyle>,
|
||||||
}
|
}
|
||||||
@ -20,14 +19,11 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
|
|||||||
fn new(ctx: LayoutContext<'a, 'p>) -> TreeLayouter<'a, 'p> {
|
fn new(ctx: LayoutContext<'a, 'p>) -> TreeLayouter<'a, 'p> {
|
||||||
TreeLayouter {
|
TreeLayouter {
|
||||||
ctx,
|
ctx,
|
||||||
stack: StackLayouter::new(StackContext {
|
|
||||||
spaces: ctx.spaces,
|
|
||||||
axes: ctx.axes,
|
|
||||||
}),
|
|
||||||
flex: FlexLayouter::new(FlexContext {
|
flex: FlexLayouter::new(FlexContext {
|
||||||
flex_spacing: flex_spacing(&ctx.style),
|
flex_spacing: flex_spacing(&ctx.style),
|
||||||
spaces: ctx.spaces.iter().map(|space| space.usable_space(true)).collect(),
|
spaces: ctx.spaces,
|
||||||
axes: ctx.axes,
|
axes: ctx.axes,
|
||||||
|
shrink_to_fit: ctx.shrink_to_fit,
|
||||||
}),
|
}),
|
||||||
style: Cow::Borrowed(ctx.style),
|
style: Cow::Borrowed(ctx.style),
|
||||||
}
|
}
|
||||||
@ -45,13 +41,14 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node::Space => {
|
Node::Space => {
|
||||||
if !self.flex.is_empty() {
|
if !self.flex.box_is_empty() {
|
||||||
self.flex.add_space(self.style.word_spacing * self.style.font_size);
|
let space = self.style.word_spacing * self.style.font_size;
|
||||||
|
self.flex.add_primary_space(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Node::Newline => {
|
Node::Newline => {
|
||||||
if !self.flex.is_empty() {
|
if !self.flex.box_is_empty() {
|
||||||
self.finish_paragraph()?;
|
self.break_paragraph()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,15 +65,9 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
|
|||||||
|
|
||||||
/// Layout a function.
|
/// Layout a function.
|
||||||
fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> {
|
fn layout_func(&mut self, func: &FuncCall) -> LayoutResult<()> {
|
||||||
// Finish the current flex layout on a copy to find out how
|
|
||||||
// much space would be remaining if we finished.
|
|
||||||
let mut lookahead = self.stack.clone();
|
|
||||||
lookahead.add_multiple(self.flex.clone().finish()?)?;
|
|
||||||
let spaces = lookahead.remaining(true);
|
|
||||||
|
|
||||||
let commands = func.body.val.layout(LayoutContext {
|
let commands = func.body.val.layout(LayoutContext {
|
||||||
style: &self.style,
|
style: &self.style,
|
||||||
spaces,
|
spaces: self.flex.remaining()?,
|
||||||
.. self.ctx
|
.. self.ctx
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -94,16 +85,15 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
|
|||||||
Command::Add(layout) => self.flex.add(layout),
|
Command::Add(layout) => self.flex.add(layout),
|
||||||
Command::AddMultiple(layouts) => self.flex.add_multiple(layouts),
|
Command::AddMultiple(layouts) => self.flex.add_multiple(layouts),
|
||||||
|
|
||||||
Command::BreakFlex => self.flex.add_break(),
|
Command::FinishRun => self.flex.add_run_break(),
|
||||||
Command::FinishFlex => self.finish_paragraph()?,
|
Command::FinishBox => self.flex.finish_box()?,
|
||||||
Command::BreakStack => self.finish_layout()?,
|
Command::FinishLayout => self.flex.finish_layout(true)?,
|
||||||
|
|
||||||
|
Command::BreakParagraph => self.break_paragraph()?,
|
||||||
|
|
||||||
Command::SetStyle(style) => *self.style.to_mut() = style,
|
Command::SetStyle(style) => *self.style.to_mut() = style,
|
||||||
Command::SetAxes(axes) => {
|
Command::SetAxes(axes) => {
|
||||||
self.flex.set_axes(axes);
|
self.flex.set_axes(axes);
|
||||||
if axes.secondary != self.ctx.axes.secondary {
|
|
||||||
self.stack.set_axes(axes);
|
|
||||||
}
|
|
||||||
self.ctx.axes = axes;
|
self.ctx.axes = axes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,43 +103,15 @@ impl<'a, 'p> TreeLayouter<'a, 'p> {
|
|||||||
|
|
||||||
/// Finish the layout.
|
/// Finish the layout.
|
||||||
fn finish(mut self) -> LayoutResult<MultiLayout> {
|
fn finish(mut self) -> LayoutResult<MultiLayout> {
|
||||||
self.finish_flex()?;
|
self.flex.finish()
|
||||||
Ok(self.stack.finish())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finish the current stack layout with a hard break.
|
|
||||||
fn finish_layout(&mut self) -> LayoutResult<()> {
|
|
||||||
self.finish_flex()?;
|
|
||||||
self.stack.add_break(true);
|
|
||||||
self.start_new_flex();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the current flex layout and add space after it.
|
/// Finish the current flex layout and add space after it.
|
||||||
fn finish_paragraph(&mut self) -> LayoutResult<()> {
|
fn break_paragraph(&mut self) -> LayoutResult<()> {
|
||||||
self.finish_flex()?;
|
self.flex.finish_box()?;
|
||||||
self.stack.add_space(paragraph_spacing(&self.style));
|
self.flex.add_secondary_space(paragraph_spacing(&self.style))?;
|
||||||
self.start_new_flex();
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish the current flex layout and add it the stack.
|
|
||||||
fn finish_flex(&mut self) -> LayoutResult<()> {
|
|
||||||
if !self.flex.is_empty() {
|
|
||||||
let layouts = self.flex.finish()?;
|
|
||||||
self.stack.add_multiple(layouts)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start a new flex layout.
|
|
||||||
fn start_new_flex(&mut self) {
|
|
||||||
self.flex = FlexLayouter::new(FlexContext {
|
|
||||||
flex_spacing: flex_spacing(&self.style),
|
|
||||||
spaces: self.stack.remaining(true),
|
|
||||||
axes: self.ctx.axes,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flex_spacing(style: &TextStyle) -> Size {
|
fn flex_spacing(style: &TextStyle) -> Size {
|
||||||
|
@ -102,12 +102,12 @@ impl<'p> Typesetter<'p> {
|
|||||||
spaces: smallvec![LayoutSpace {
|
spaces: smallvec![LayoutSpace {
|
||||||
dimensions: self.page_style.dimensions,
|
dimensions: self.page_style.dimensions,
|
||||||
padding: self.page_style.margins,
|
padding: self.page_style.margins,
|
||||||
shrink_to_fit: false,
|
|
||||||
}],
|
}],
|
||||||
axes: LayoutAxes {
|
axes: LayoutAxes {
|
||||||
primary: AlignedAxis::new(Axis::LeftToRight, Alignment::Origin),
|
primary: AlignedAxis::new(Axis::LeftToRight, Alignment::Origin),
|
||||||
secondary: AlignedAxis::new(Axis::TopToBottom, Alignment::Origin),
|
secondary: AlignedAxis::new(Axis::TopToBottom, Alignment::Origin),
|
||||||
},
|
},
|
||||||
|
shrink_to_fit: false,
|
||||||
},
|
},
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user