Cleaner separation between single and multi-region layout
This commit is contained in:
parent
6ac71eeaf7
commit
fae358968f
@ -4,7 +4,8 @@ use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Behave, Behaviour, Content, Packed, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, Axes, Dir, Fragment, Frame, Layout, Length, Point, Ratio, Regions, Rel, Size,
|
||||
Abs, Axes, Dir, Fragment, Frame, LayoutMultiple, Length, Point, Ratio, Regions, Rel,
|
||||
Size,
|
||||
};
|
||||
use crate::text::TextElem;
|
||||
use crate::util::Numeric;
|
||||
@ -40,7 +41,7 @@ use crate::util::Numeric;
|
||||
/// increasingly been used to solve a
|
||||
/// variety of problems.
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
pub struct ColumnsElem {
|
||||
/// The number of columns.
|
||||
#[positional]
|
||||
@ -57,7 +58,7 @@ pub struct ColumnsElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<ColumnsElem> {
|
||||
impl LayoutMultiple for Packed<ColumnsElem> {
|
||||
#[typst_macros::time(name = "columns", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -4,8 +4,8 @@ use crate::foundations::{
|
||||
cast, elem, AutoValue, Content, Packed, Resolve, Smart, StyleChain, Value,
|
||||
};
|
||||
use crate::layout::{
|
||||
Abs, Axes, Corners, Em, Fr, Fragment, FrameKind, Layout, Length, Ratio, Regions, Rel,
|
||||
Sides, Size, Spacing, VElem,
|
||||
Abs, Axes, Corners, Em, Fr, Fragment, Frame, FrameKind, LayoutMultiple, Length,
|
||||
Ratio, Regions, Rel, Sides, Size, Spacing, VElem,
|
||||
};
|
||||
use crate::util::Numeric;
|
||||
use crate::visualize::{clip_rect, Paint, Stroke};
|
||||
@ -26,7 +26,7 @@ use crate::visualize::{clip_rect, Paint, Stroke};
|
||||
/// )
|
||||
/// for more information.
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem]
|
||||
pub struct BoxElem {
|
||||
/// The width of the box.
|
||||
///
|
||||
@ -109,14 +109,14 @@ pub struct BoxElem {
|
||||
pub body: Option<Content>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<BoxElem> {
|
||||
impl Packed<BoxElem> {
|
||||
#[typst_macros::time(name = "box", span = self.span())]
|
||||
fn layout(
|
||||
pub fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let width = match self.width(styles) {
|
||||
Sizing::Auto => Smart::Auto,
|
||||
Sizing::Rel(rel) => Smart::Custom(rel),
|
||||
@ -174,7 +174,7 @@ impl Layout for Packed<BoxElem> {
|
||||
// Apply metadata.
|
||||
frame.set_kind(FrameKind::Hard);
|
||||
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ impl Layout for Packed<BoxElem> {
|
||||
/// = Blocky
|
||||
/// More text.
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
pub struct BlockElem {
|
||||
/// The block's width.
|
||||
///
|
||||
@ -340,7 +340,7 @@ pub struct BlockElem {
|
||||
pub sticky: bool,
|
||||
}
|
||||
|
||||
impl Layout for Packed<BlockElem> {
|
||||
impl LayoutMultiple for Packed<BlockElem> {
|
||||
#[typst_macros::time(name = "block", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -10,28 +10,24 @@ use crate::foundations::{
|
||||
use crate::introspection::{Meta, MetaElem};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Axes, BlockElem, ColbreakElem, ColumnsElem, FixedAlignment, Fr,
|
||||
Fragment, Frame, FrameItem, Layout, PlaceElem, Point, Regions, Rel, Size, Spacing,
|
||||
VAlignment, VElem,
|
||||
Fragment, Frame, FrameItem, LayoutMultiple, LayoutSingle, PlaceElem, Point, Regions,
|
||||
Rel, Size, Spacing, VAlignment, VElem,
|
||||
};
|
||||
use crate::model::{FootnoteElem, FootnoteEntry, ParElem};
|
||||
use crate::util::Numeric;
|
||||
use crate::visualize::{
|
||||
CircleElem, EllipseElem, ImageElem, LineElem, PathElem, PolygonElem, RectElem,
|
||||
SquareElem,
|
||||
};
|
||||
|
||||
/// Arranges spacing, paragraphs and block-level elements into a flow.
|
||||
///
|
||||
/// This element is responsible for layouting both the top-level content flow
|
||||
/// and the contents of boxes.
|
||||
#[elem(Debug, Layout)]
|
||||
#[elem(Debug, LayoutMultiple)]
|
||||
pub struct FlowElem {
|
||||
/// The children that will be arranges into a flow.
|
||||
#[variadic]
|
||||
pub children: Vec<Prehashed<Content>>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<FlowElem> {
|
||||
impl LayoutMultiple for Packed<FlowElem> {
|
||||
#[typst_macros::time(name = "flow", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
@ -45,8 +41,8 @@ impl Layout for Packed<FlowElem> {
|
||||
if !regions.size.y.is_finite() && regions.expand.y {
|
||||
bail!(self.span(), "cannot expand into infinite height");
|
||||
}
|
||||
let mut layouter = FlowLayouter::new(regions, styles);
|
||||
|
||||
let mut layouter = FlowLayouter::new(regions, styles);
|
||||
for mut child in self.children().iter().map(|c| &**c) {
|
||||
let outer = styles;
|
||||
let mut styles = styles;
|
||||
@ -55,32 +51,23 @@ impl Layout for Packed<FlowElem> {
|
||||
styles = outer.chain(map);
|
||||
}
|
||||
|
||||
if let Some(elem) = child.to_packed::<VElem>() {
|
||||
layouter.layout_spacing(engine, elem, styles)?;
|
||||
} else if let Some(elem) = child.to_packed::<ParElem>() {
|
||||
layouter.layout_par(engine, elem, styles)?;
|
||||
} else if child.is::<LineElem>()
|
||||
|| child.is::<RectElem>()
|
||||
|| child.is::<SquareElem>()
|
||||
|| child.is::<EllipseElem>()
|
||||
|| child.is::<CircleElem>()
|
||||
|| child.is::<ImageElem>()
|
||||
|| child.is::<PolygonElem>()
|
||||
|| child.is::<PathElem>()
|
||||
{
|
||||
let layoutable = child.with::<dyn Layout>().unwrap();
|
||||
layouter.layout_single(engine, layoutable, styles)?;
|
||||
} else if child.is::<MetaElem>() {
|
||||
if child.is::<MetaElem>() {
|
||||
layouter.layout_meta(styles);
|
||||
} else if let Some(elem) = child.to_packed::<VElem>() {
|
||||
layouter.layout_spacing(engine, elem, styles)?;
|
||||
} else if let Some(placed) = child.to_packed::<PlaceElem>() {
|
||||
layouter.layout_placed(engine, placed, styles)?;
|
||||
} else if child.can::<dyn Layout>() {
|
||||
layouter.layout_multiple(engine, child, styles)?;
|
||||
} else if child.is::<ColbreakElem>() {
|
||||
if !layouter.regions.backlog.is_empty() || layouter.regions.last.is_some()
|
||||
{
|
||||
layouter.finish_region(engine, true)?;
|
||||
}
|
||||
} else if let Some(elem) = child.to_packed::<ParElem>() {
|
||||
layouter.layout_par(engine, elem, styles)?;
|
||||
} else if let Some(layoutable) = child.with::<dyn LayoutSingle>() {
|
||||
layouter.layout_single(engine, layoutable, styles)?;
|
||||
} else if child.can::<dyn LayoutMultiple>() {
|
||||
layouter.layout_multiple(engine, child, styles)?;
|
||||
} else {
|
||||
bail!(child.span(), "unexpected flow child");
|
||||
}
|
||||
@ -207,6 +194,18 @@ impl<'a> FlowLayouter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Place explicit metadata into the flow.
|
||||
fn layout_meta(&mut self, styles: StyleChain) {
|
||||
let mut frame = Frame::soft(Size::zero());
|
||||
frame.meta(styles, true);
|
||||
self.items.push(FlowItem::Frame {
|
||||
frame,
|
||||
align: Axes::splat(FixedAlignment::Start),
|
||||
sticky: true,
|
||||
movable: false,
|
||||
});
|
||||
}
|
||||
|
||||
/// Layout vertical spacing.
|
||||
fn layout_spacing(
|
||||
&mut self,
|
||||
@ -284,13 +283,13 @@ impl<'a> FlowLayouter<'a> {
|
||||
fn layout_single(
|
||||
&mut self,
|
||||
engine: &mut Engine,
|
||||
content: &dyn Layout,
|
||||
layoutable: &dyn LayoutSingle,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<()> {
|
||||
let align = AlignElem::alignment_in(styles).resolve(styles);
|
||||
let sticky = BlockElem::sticky_in(styles);
|
||||
let pod = Regions::one(self.regions.base(), Axes::splat(false));
|
||||
let mut frame = content.layout(engine, styles, pod)?.into_frame();
|
||||
let mut frame = layoutable.layout(engine, styles, pod)?;
|
||||
frame.meta(styles, false);
|
||||
self.layout_item(
|
||||
engine,
|
||||
@ -300,18 +299,6 @@ impl<'a> FlowLayouter<'a> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Place explicit metadata into the flow.
|
||||
fn layout_meta(&mut self, styles: StyleChain) {
|
||||
let mut frame = Frame::soft(Size::zero());
|
||||
frame.meta(styles, true);
|
||||
self.items.push(FlowItem::Frame {
|
||||
frame,
|
||||
align: Axes::splat(FixedAlignment::Start),
|
||||
sticky: true,
|
||||
movable: false,
|
||||
});
|
||||
}
|
||||
|
||||
/// Layout a placed element.
|
||||
fn layout_placed(
|
||||
&mut self,
|
||||
@ -337,12 +324,12 @@ impl<'a> FlowLayouter<'a> {
|
||||
fn layout_multiple(
|
||||
&mut self,
|
||||
engine: &mut Engine,
|
||||
block: &Content,
|
||||
child: &Content,
|
||||
styles: StyleChain,
|
||||
) -> SourceResult<()> {
|
||||
// Temporarily delegerate rootness to the columns.
|
||||
let is_root = self.root;
|
||||
if is_root && block.is::<ColumnsElem>() {
|
||||
if is_root && child.is::<ColumnsElem>() {
|
||||
self.root = false;
|
||||
self.regions.root = true;
|
||||
}
|
||||
@ -355,9 +342,9 @@ impl<'a> FlowLayouter<'a> {
|
||||
}
|
||||
|
||||
// How to align the block.
|
||||
let align = if let Some(align) = block.to_packed::<AlignElem>() {
|
||||
let align = if let Some(align) = child.to_packed::<AlignElem>() {
|
||||
align.alignment(styles)
|
||||
} else if let Some((_, local)) = block.to_styled() {
|
||||
} else if let Some((_, local)) = child.to_styled() {
|
||||
AlignElem::alignment_in(styles.chain(local))
|
||||
} else {
|
||||
AlignElem::alignment_in(styles)
|
||||
@ -366,7 +353,7 @@ impl<'a> FlowLayouter<'a> {
|
||||
|
||||
// Layout the block itself.
|
||||
let sticky = BlockElem::sticky_in(styles);
|
||||
let fragment = block.layout(engine, styles, self.regions)?;
|
||||
let fragment = child.layout(engine, styles, self.regions)?;
|
||||
|
||||
for (i, mut frame) in fragment.into_iter().enumerate() {
|
||||
// Find footnotes in the frame.
|
||||
|
@ -9,8 +9,8 @@ use crate::foundations::{
|
||||
StyleChain, Value,
|
||||
};
|
||||
use crate::layout::{
|
||||
Abs, Alignment, Axes, Dir, Fr, Fragment, Frame, FrameItem, Layout, Length, Point,
|
||||
Regions, Rel, Sides, Size, Sizing,
|
||||
Abs, Alignment, Axes, Dir, Fr, Fragment, Frame, FrameItem, LayoutMultiple, Length,
|
||||
Point, Regions, Rel, Sides, Size, Sizing,
|
||||
};
|
||||
use crate::syntax::Span;
|
||||
use crate::text::TextElem;
|
||||
@ -102,7 +102,7 @@ impl From<Content> for Cell {
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Cell {
|
||||
impl LayoutMultiple for Cell {
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
|
@ -13,8 +13,8 @@ use crate::foundations::{
|
||||
cast, elem, scope, Array, Content, Fold, Packed, Show, Smart, StyleChain, Value,
|
||||
};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Alignment, Axes, Fragment, Layout, Length, Regions, Rel, Sides,
|
||||
Sizing,
|
||||
Abs, AlignElem, Alignment, Axes, Fragment, LayoutMultiple, Length, Regions, Rel,
|
||||
Sides, Sizing,
|
||||
};
|
||||
use crate::syntax::Span;
|
||||
use crate::visualize::{Paint, Stroke};
|
||||
@ -154,7 +154,7 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// grid.cell(y: 2, fill: aqua)[Walk],
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(scope, Layout)]
|
||||
#[elem(scope, LayoutMultiple)]
|
||||
pub struct GridElem {
|
||||
/// The column sizes.
|
||||
///
|
||||
@ -279,7 +279,7 @@ impl GridElem {
|
||||
type GridCell;
|
||||
}
|
||||
|
||||
impl Layout for Packed<GridElem> {
|
||||
impl LayoutMultiple for Packed<GridElem> {
|
||||
#[typst_macros::time(name = "grid", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -17,7 +17,7 @@ use crate::foundations::{Content, Packed, Resolve, Smart, StyleChain};
|
||||
use crate::introspection::{Introspector, Locator, MetaElem};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Axes, BoxElem, Dir, Em, FixedAlignment, Fr, Fragment, Frame, HElem,
|
||||
Layout, Point, Regions, Size, Sizing, Spacing,
|
||||
Point, Regions, Size, Sizing, Spacing,
|
||||
};
|
||||
use crate::math::{EquationElem, MathParItem};
|
||||
use crate::model::{Linebreaks, ParElem};
|
||||
@ -594,7 +594,7 @@ fn prepare<'a>(
|
||||
items.push(Item::Fractional(v, Some((elem, styles))));
|
||||
} else {
|
||||
let pod = Regions::one(region, Axes::splat(false));
|
||||
let mut frame = elem.layout(engine, styles, pod)?.into_frame();
|
||||
let mut frame = elem.layout(engine, styles, pod)?;
|
||||
frame.meta(styles, false);
|
||||
frame.translate(Point::with_y(TextElem::baseline_in(styles)));
|
||||
items.push(Item::Frame(frame));
|
||||
@ -1319,7 +1319,7 @@ fn commit(
|
||||
if let Some((elem, styles)) = elem {
|
||||
let region = Size::new(amount, full);
|
||||
let pod = Regions::one(region, Axes::new(true, false));
|
||||
let mut frame = elem.layout(engine, *styles, pod)?.into_frame();
|
||||
let mut frame = elem.layout(engine, *styles, pod)?;
|
||||
frame.meta(*styles, false);
|
||||
frame.translate(Point::with_y(TextElem::baseline_in(*styles)));
|
||||
push(&mut offset, frame);
|
||||
|
@ -3,7 +3,7 @@ use crate::engine::Engine;
|
||||
use crate::foundations::{
|
||||
dict, elem, func, Content, Func, NativeElement, Packed, StyleChain,
|
||||
};
|
||||
use crate::layout::{Fragment, Layout, Regions, Size};
|
||||
use crate::layout::{Fragment, LayoutMultiple, Regions, Size};
|
||||
use crate::syntax::Span;
|
||||
|
||||
/// Provides access to the current outer container's (or page's, if none) size
|
||||
@ -63,14 +63,14 @@ pub fn layout(
|
||||
}
|
||||
|
||||
/// Executes a `layout` call.
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
struct LayoutElem {
|
||||
/// The function to call with the outer container's (or page's) size.
|
||||
#[required]
|
||||
func: Func,
|
||||
}
|
||||
|
||||
impl Layout for Packed<LayoutElem> {
|
||||
impl LayoutMultiple for Packed<LayoutElem> {
|
||||
#[typst_macros::time(name = "layout", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{dict, func, Content, Dict, StyleChain, Styles};
|
||||
use crate::layout::{Abs, Axes, Layout, Regions, Size};
|
||||
use crate::layout::{Abs, Axes, LayoutMultiple, Regions, Size};
|
||||
|
||||
/// Measures the layouted size of content.
|
||||
///
|
||||
|
@ -120,7 +120,7 @@ pub fn define(global: &mut Scope) {
|
||||
|
||||
/// Root-level layout.
|
||||
pub trait LayoutRoot {
|
||||
/// Layout into one frame per page.
|
||||
/// Layout into a document with one frame per page.
|
||||
fn layout_root(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
@ -128,8 +128,8 @@ pub trait LayoutRoot {
|
||||
) -> SourceResult<Document>;
|
||||
}
|
||||
|
||||
/// Layout into regions.
|
||||
pub trait Layout {
|
||||
/// Layout into multiple regions.
|
||||
pub trait LayoutMultiple {
|
||||
/// Layout into one frame per region.
|
||||
fn layout(
|
||||
&self,
|
||||
@ -160,8 +160,18 @@ pub trait Layout {
|
||||
}
|
||||
}
|
||||
|
||||
/// Layout into a single region.
|
||||
pub trait LayoutSingle {
|
||||
/// Layout into one frame per region.
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Frame>;
|
||||
}
|
||||
|
||||
impl LayoutRoot for Content {
|
||||
#[typst_macros::time(name = "layout root", span = self.span())]
|
||||
fn layout_root(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
@ -186,12 +196,9 @@ impl LayoutRoot for Content {
|
||||
tracer,
|
||||
};
|
||||
let scratch = Scratch::default();
|
||||
let (realized, styles) =
|
||||
let (document, styles) =
|
||||
realize_root(&mut engine, &scratch, content, styles)?;
|
||||
realized
|
||||
.with::<dyn LayoutRoot>()
|
||||
.unwrap()
|
||||
.layout_root(&mut engine, styles)
|
||||
document.layout_root(&mut engine, styles)
|
||||
}
|
||||
|
||||
cached(
|
||||
@ -206,7 +213,7 @@ impl LayoutRoot for Content {
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Content {
|
||||
impl LayoutMultiple for Content {
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
@ -244,10 +251,11 @@ impl Layout for Content {
|
||||
let scratch = Scratch::default();
|
||||
let (realized, styles) =
|
||||
realize_block(&mut engine, &scratch, content, styles)?;
|
||||
realized
|
||||
.with::<dyn Layout>()
|
||||
.unwrap()
|
||||
.layout(&mut engine, styles, regions)
|
||||
realized.with::<dyn LayoutMultiple>().unwrap().layout(
|
||||
&mut engine,
|
||||
styles,
|
||||
regions,
|
||||
)
|
||||
}
|
||||
|
||||
let fragment = cached(
|
||||
|
@ -1,7 +1,9 @@
|
||||
use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Content, Packed, Resolve, StyleChain};
|
||||
use crate::layout::{Abs, Fragment, Layout, Length, Point, Regions, Rel, Sides, Size};
|
||||
use crate::layout::{
|
||||
Abs, Fragment, LayoutMultiple, Length, Point, Regions, Rel, Sides, Size,
|
||||
};
|
||||
|
||||
/// Adds spacing around content.
|
||||
///
|
||||
@ -16,7 +18,7 @@ use crate::layout::{Abs, Fragment, Layout, Length, Point, Regions, Rel, Sides, S
|
||||
/// _Typing speeds can be
|
||||
/// measured in words per minute._
|
||||
/// ```
|
||||
#[elem(title = "Padding", Layout)]
|
||||
#[elem(title = "Padding", LayoutMultiple)]
|
||||
pub struct PadElem {
|
||||
/// The padding at the left side.
|
||||
#[parse(
|
||||
@ -58,7 +60,7 @@ pub struct PadElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<PadElem> {
|
||||
impl LayoutMultiple for Packed<PadElem> {
|
||||
#[typst_macros::time(name = "pad", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -11,8 +11,8 @@ use crate::foundations::{
|
||||
};
|
||||
use crate::introspection::{Counter, CounterKey, ManualPageCounter};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Alignment, Axes, ColumnsElem, Dir, Frame, HAlignment, Layout, Length,
|
||||
Point, Ratio, Regions, Rel, Sides, Size, VAlignment,
|
||||
Abs, AlignElem, Alignment, Axes, ColumnsElem, Dir, Frame, HAlignment, LayoutMultiple,
|
||||
Length, Point, Ratio, Regions, Rel, Sides, Size, VAlignment,
|
||||
};
|
||||
|
||||
use crate::model::Numbering;
|
||||
|
@ -2,7 +2,7 @@ use crate::diag::{bail, At, Hint, SourceResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Behave, Behaviour, Content, Packed, Smart, StyleChain};
|
||||
use crate::layout::{
|
||||
Alignment, Axes, Em, Fragment, Layout, Length, Regions, Rel, VAlignment,
|
||||
Alignment, Axes, Em, Fragment, LayoutMultiple, Length, Regions, Rel, VAlignment,
|
||||
};
|
||||
|
||||
/// Places content at an absolute position.
|
||||
@ -25,7 +25,7 @@ use crate::layout::{
|
||||
/// ),
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(Layout, Behave)]
|
||||
#[elem(Behave)]
|
||||
pub struct PlaceElem {
|
||||
/// Relative to which position in the parent container to place the content.
|
||||
///
|
||||
@ -86,9 +86,9 @@ pub struct PlaceElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<PlaceElem> {
|
||||
impl Packed<PlaceElem> {
|
||||
#[typst_macros::time(name = "place", span = self.span())]
|
||||
fn layout(
|
||||
pub fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
|
@ -2,7 +2,7 @@ use crate::diag::{bail, SourceResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Content, Packed, Resolve, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Axes, Fragment, Frame, Layout, Point, Regions, Size,
|
||||
Abs, AlignElem, Axes, Fragment, Frame, LayoutMultiple, Point, Regions, Size,
|
||||
};
|
||||
use crate::util::Numeric;
|
||||
|
||||
@ -27,14 +27,14 @@ use crate::util::Numeric;
|
||||
/// Berlin, the 22nd of December, 2022
|
||||
/// ]
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
pub struct RepeatElem {
|
||||
/// The content to repeat.
|
||||
#[required]
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<RepeatElem> {
|
||||
impl LayoutMultiple for Packed<RepeatElem> {
|
||||
#[typst_macros::time(name = "repeat", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -4,8 +4,8 @@ use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{cast, elem, Content, Packed, Resolve, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Axes, Axis, Dir, FixedAlignment, Fr, Fragment, Frame, Layout, Point,
|
||||
Regions, Size, Spacing,
|
||||
Abs, AlignElem, Axes, Axis, Dir, FixedAlignment, Fr, Fragment, Frame, LayoutMultiple,
|
||||
Point, Regions, Size, Spacing,
|
||||
};
|
||||
use crate::util::{Get, Numeric};
|
||||
|
||||
@ -23,7 +23,7 @@ use crate::util::{Get, Numeric};
|
||||
/// rect(width: 90pt),
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
pub struct StackElem {
|
||||
/// The direction along which the items are stacked. Possible values are:
|
||||
///
|
||||
@ -51,7 +51,7 @@ pub struct StackElem {
|
||||
pub children: Vec<StackChild>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<StackElem> {
|
||||
impl LayoutMultiple for Packed<StackElem> {
|
||||
#[typst_macros::time(name = "stack", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -2,8 +2,8 @@ use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Content, Packed, Resolve, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, Alignment, Angle, Axes, FixedAlignment, Fragment, Frame, HAlignment, Layout,
|
||||
Length, Point, Ratio, Regions, Rel, Size, VAlignment,
|
||||
Abs, Alignment, Angle, Axes, FixedAlignment, Frame, HAlignment, LayoutMultiple,
|
||||
LayoutSingle, Length, Point, Ratio, Regions, Rel, Size, VAlignment,
|
||||
};
|
||||
|
||||
/// Moves content without affecting layout.
|
||||
@ -24,7 +24,7 @@ use crate::layout::{
|
||||
/// )
|
||||
/// ))
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct MoveElem {
|
||||
/// The horizontal displacement of the content.
|
||||
pub dx: Rel<Length>,
|
||||
@ -37,20 +37,20 @@ pub struct MoveElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<MoveElem> {
|
||||
impl LayoutSingle for Packed<MoveElem> {
|
||||
#[typst_macros::time(name = "move", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let pod = Regions::one(regions.base(), Axes::splat(false));
|
||||
let mut frame = self.body().layout(engine, styles, pod)?.into_frame();
|
||||
let delta = Axes::new(self.dx(styles), self.dy(styles)).resolve(styles);
|
||||
let delta = delta.zip_map(regions.base(), Rel::relative_to);
|
||||
frame.translate(delta.to_point());
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ impl Layout for Packed<MoveElem> {
|
||||
/// .map(i => rotate(24deg * i)[X]),
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct RotateElem {
|
||||
/// The amount of rotation.
|
||||
///
|
||||
@ -115,14 +115,14 @@ pub struct RotateElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<RotateElem> {
|
||||
impl LayoutSingle for Packed<RotateElem> {
|
||||
#[typst_macros::time(name = "rotate", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let angle = self.angle(styles);
|
||||
let align = self.origin(styles).resolve(styles);
|
||||
|
||||
@ -157,7 +157,7 @@ impl Layout for Packed<RotateElem> {
|
||||
/// #scale(x: -100%)[This is mirrored.]
|
||||
/// #scale(x: -100%, reflow: true)[This is mirrored.]
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct ScaleElem {
|
||||
/// The horizontal scaling factor.
|
||||
///
|
||||
@ -203,14 +203,14 @@ pub struct ScaleElem {
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Layout for Packed<ScaleElem> {
|
||||
impl LayoutSingle for Packed<ScaleElem> {
|
||||
#[typst_macros::time(name = "scale", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let sx = self.x(styles);
|
||||
let sy = self.y(styles);
|
||||
let align = self.origin(styles).resolve(styles);
|
||||
@ -370,7 +370,7 @@ fn measure_and_layout(
|
||||
transform: Transform,
|
||||
align: Axes<FixedAlignment>,
|
||||
reflow: bool,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
if !reflow {
|
||||
// Layout the body.
|
||||
let pod = Regions::one(base_size, Axes::splat(false));
|
||||
@ -383,7 +383,7 @@ fn measure_and_layout(
|
||||
.pre_concat(Transform::translate(-x, -y));
|
||||
frame.transform(ts);
|
||||
|
||||
return Ok(Fragment::frame(frame));
|
||||
return Ok(frame);
|
||||
}
|
||||
|
||||
// Measure the size of the body.
|
||||
@ -405,7 +405,7 @@ fn measure_and_layout(
|
||||
frame.transform(ts);
|
||||
frame.translate(offset);
|
||||
frame.set_size(size);
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
|
||||
/// Computes the bounding box and offset of a transformed frame.
|
||||
|
@ -13,7 +13,7 @@ use unicode_segmentation::UnicodeSegmentation;
|
||||
use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{Content, Packed, Smart, StyleChain, Styles};
|
||||
use crate::layout::{Abs, Axes, BoxElem, Em, Frame, Layout, Regions, Size};
|
||||
use crate::layout::{Abs, Axes, BoxElem, Em, Frame, LayoutMultiple, Regions, Size};
|
||||
use crate::math::{
|
||||
FrameFragment, GlyphFragment, LayoutMath, MathFragment, MathRow, MathSize, MathStyle,
|
||||
MathVariant, THICK,
|
||||
@ -174,9 +174,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
||||
}
|
||||
|
||||
pub fn layout_box(&mut self, boxed: &Packed<BoxElem>) -> SourceResult<Frame> {
|
||||
Ok(boxed
|
||||
.layout(self.engine, self.outer.chain(&self.local), self.regions)?
|
||||
.into_frame())
|
||||
boxed.layout(self.engine, self.outer.chain(&self.local), self.regions)
|
||||
}
|
||||
|
||||
pub fn layout_content(&mut self, content: &Content) -> SourceResult<Frame> {
|
||||
|
@ -8,8 +8,8 @@ use crate::foundations::{
|
||||
};
|
||||
use crate::introspection::{Count, Counter, CounterUpdate, Locatable};
|
||||
use crate::layout::{
|
||||
Abs, AlignElem, Alignment, Axes, Dir, Em, FixedAlignment, Fragment, Frame, Layout,
|
||||
Point, Regions, Size,
|
||||
Abs, AlignElem, Alignment, Axes, Dir, Em, FixedAlignment, Frame, LayoutMultiple,
|
||||
LayoutSingle, Point, Regions, Size,
|
||||
};
|
||||
use crate::math::{LayoutMath, MathContext};
|
||||
use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement};
|
||||
@ -45,7 +45,15 @@ use crate::World;
|
||||
/// horizontally. For more details about math syntax, see the
|
||||
/// [main math page]($category/math).
|
||||
#[elem(
|
||||
Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName, Refable,
|
||||
Locatable,
|
||||
Synthesize,
|
||||
Show,
|
||||
Finalize,
|
||||
LayoutSingle,
|
||||
LayoutMath,
|
||||
Count,
|
||||
LocalName,
|
||||
Refable,
|
||||
Outlinable
|
||||
)]
|
||||
pub struct EquationElem {
|
||||
@ -194,14 +202,14 @@ impl Packed<EquationElem> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Packed<EquationElem> {
|
||||
impl LayoutSingle for Packed<EquationElem> {
|
||||
#[typst_macros::time(name = "math.equation", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
const NUMBER_GUTTER: Em = Em::new(0.5);
|
||||
|
||||
assert!(self.block(styles));
|
||||
@ -248,7 +256,7 @@ impl Layout for Packed<EquationElem> {
|
||||
frame.push_frame(Point::new(x, y), counter)
|
||||
}
|
||||
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,6 @@ impl Construct for DocumentElem {
|
||||
}
|
||||
|
||||
impl LayoutRoot for Packed<DocumentElem> {
|
||||
/// Layout the document into a sequence of frames, one per page.
|
||||
#[typst_macros::time(name = "document", span = self.span())]
|
||||
fn layout_root(
|
||||
&self,
|
||||
|
@ -7,7 +7,7 @@ use crate::foundations::{
|
||||
};
|
||||
use crate::layout::{
|
||||
Alignment, Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment,
|
||||
Layout, Length, Regions, Sizing, Spacing, VAlignment,
|
||||
LayoutMultiple, Length, Regions, Sizing, Spacing, VAlignment,
|
||||
};
|
||||
use crate::model::{Numbering, NumberingPattern, ParElem};
|
||||
use crate::text::TextElem;
|
||||
@ -68,7 +68,7 @@ use crate::text::TextElem;
|
||||
/// Enumeration items can contain multiple paragraphs and other block-level
|
||||
/// content. All content that is indented more than an item's marker becomes
|
||||
/// part of that item.
|
||||
#[elem(scope, title = "Numbered List", Layout)]
|
||||
#[elem(scope, title = "Numbered List", LayoutMultiple)]
|
||||
pub struct EnumElem {
|
||||
/// If this is `{false}`, the items are spaced apart with
|
||||
/// [enum spacing]($enum.spacing). If it is `{true}`, they use normal
|
||||
@ -208,7 +208,7 @@ impl EnumElem {
|
||||
type EnumItem;
|
||||
}
|
||||
|
||||
impl Layout for Packed<EnumElem> {
|
||||
impl LayoutMultiple for Packed<EnumElem> {
|
||||
#[typst_macros::time(name = "enum", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -4,8 +4,8 @@ use crate::foundations::{
|
||||
cast, elem, scope, Array, Content, Fold, Func, Packed, Smart, StyleChain, Value,
|
||||
};
|
||||
use crate::layout::{
|
||||
Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment, Layout,
|
||||
Length, Regions, Sizing, Spacing, VAlignment,
|
||||
Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment,
|
||||
LayoutMultiple, Length, Regions, Sizing, Spacing, VAlignment,
|
||||
};
|
||||
use crate::model::ParElem;
|
||||
use crate::text::TextElem;
|
||||
@ -41,7 +41,7 @@ use crate::text::TextElem;
|
||||
/// followed by a space to create a list item. A list item can contain multiple
|
||||
/// paragraphs and other block-level content. All content that is indented
|
||||
/// more than an item's marker becomes part of that item.
|
||||
#[elem(scope, title = "Bullet List", Layout)]
|
||||
#[elem(scope, title = "Bullet List", LayoutMultiple)]
|
||||
pub struct ListElem {
|
||||
/// If this is `{false}`, the items are spaced apart with
|
||||
/// [list spacing]($list.spacing). If it is `{true}`, they use normal
|
||||
@ -133,7 +133,7 @@ impl ListElem {
|
||||
type ListItem;
|
||||
}
|
||||
|
||||
impl Layout for Packed<ListElem> {
|
||||
impl LayoutMultiple for Packed<ListElem> {
|
||||
#[typst_macros::time(name = "list", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -7,7 +7,7 @@ use crate::foundations::{
|
||||
};
|
||||
use crate::layout::{
|
||||
show_grid_cell, Abs, Alignment, Axes, Cell, CellGrid, Celled, Fragment, GridLayouter,
|
||||
Layout, Length, Regions, Rel, ResolvableCell, Sides, TrackSizings,
|
||||
LayoutMultiple, Length, Regions, Rel, ResolvableCell, Sides, TrackSizings,
|
||||
};
|
||||
use crate::model::Figurable;
|
||||
use crate::syntax::Span;
|
||||
@ -86,7 +86,7 @@ use crate::visualize::{Paint, Stroke};
|
||||
/// ..(table.cell(y: 4, fill: aqua)[B],) * 2,
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(scope, Layout, LocalName, Figurable)]
|
||||
#[elem(scope, LayoutMultiple, LocalName, Figurable)]
|
||||
pub struct TableElem {
|
||||
/// The column sizes. See the [grid documentation]($grid) for more
|
||||
/// information on track sizing.
|
||||
@ -205,7 +205,7 @@ impl TableElem {
|
||||
type TableCell;
|
||||
}
|
||||
|
||||
impl Layout for Packed<TableElem> {
|
||||
impl LayoutMultiple for Packed<TableElem> {
|
||||
#[typst_macros::time(name = "table", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
@ -240,7 +240,6 @@ impl Layout for Packed<TableElem> {
|
||||
.trace(engine.world, tracepoint, self.span())?;
|
||||
|
||||
let layouter = GridLayouter::new(&grid, &stroke, regions, styles, self.span());
|
||||
|
||||
layouter.layout(engine)
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::foundations::{
|
||||
cast, elem, scope, Array, Content, NativeElement, Packed, Smart, StyleChain,
|
||||
};
|
||||
use crate::layout::{
|
||||
BlockElem, Em, Fragment, HElem, Layout, Length, Regions, Spacing, VElem,
|
||||
BlockElem, Em, Fragment, HElem, LayoutMultiple, Length, Regions, Spacing, VElem,
|
||||
};
|
||||
use crate::model::ParElem;
|
||||
use crate::util::Numeric;
|
||||
@ -25,7 +25,7 @@ use crate::util::Numeric;
|
||||
/// # Syntax
|
||||
/// This function also has dedicated syntax: Starting a line with a slash,
|
||||
/// followed by a term, a colon and a description creates a term list item.
|
||||
#[elem(scope, title = "Term List", Layout)]
|
||||
#[elem(scope, title = "Term List", LayoutMultiple)]
|
||||
pub struct TermsElem {
|
||||
/// If this is `{false}`, the items are spaced apart with
|
||||
/// [term list spacing]($terms.spacing). If it is `{true}`, they use normal
|
||||
@ -107,7 +107,7 @@ impl TermsElem {
|
||||
type TermItem;
|
||||
}
|
||||
|
||||
impl Layout for Packed<TermsElem> {
|
||||
impl LayoutMultiple for Packed<TermsElem> {
|
||||
#[typst_macros::time(name = "terms", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -18,8 +18,8 @@ use crate::foundations::{
|
||||
};
|
||||
use crate::introspection::{Locatable, Meta, MetaElem};
|
||||
use crate::layout::{
|
||||
AlignElem, BlockElem, BoxElem, ColbreakElem, FlowElem, HElem, Layout, LayoutRoot,
|
||||
PageElem, PagebreakElem, Parity, PlaceElem, VElem,
|
||||
AlignElem, BlockElem, BoxElem, ColbreakElem, FlowElem, HElem, LayoutMultiple,
|
||||
LayoutSingle, PageElem, PagebreakElem, Parity, PlaceElem, VElem,
|
||||
};
|
||||
use crate::math::{EquationElem, LayoutMath};
|
||||
use crate::model::{
|
||||
@ -29,10 +29,6 @@ use crate::model::{
|
||||
use crate::syntax::Span;
|
||||
use crate::text::{LinebreakElem, SmartQuoteElem, SpaceElem, TextElem};
|
||||
use crate::util::hash128;
|
||||
use crate::visualize::{
|
||||
CircleElem, EllipseElem, ImageElem, LineElem, PathElem, PolygonElem, RectElem,
|
||||
SquareElem,
|
||||
};
|
||||
|
||||
/// Realize into an element that is capable of root-level layout.
|
||||
#[typst_macros::time(name = "realize root")]
|
||||
@ -41,17 +37,13 @@ pub fn realize_root<'a>(
|
||||
scratch: &'a Scratch<'a>,
|
||||
content: &'a Content,
|
||||
styles: StyleChain<'a>,
|
||||
) -> SourceResult<(Cow<'a, Content>, StyleChain<'a>)> {
|
||||
if content.can::<dyn LayoutRoot>() && !applicable(content, styles) {
|
||||
return Ok((Cow::Borrowed(content), styles));
|
||||
}
|
||||
|
||||
) -> SourceResult<(Packed<DocumentElem>, StyleChain<'a>)> {
|
||||
let mut builder = Builder::new(engine, scratch, true);
|
||||
builder.accept(content, styles)?;
|
||||
builder.interrupt_page(Some(styles), true)?;
|
||||
let (pages, shared) = builder.doc.unwrap().pages.finish();
|
||||
let span = first_span(&pages);
|
||||
Ok((Cow::Owned(DocumentElem::new(pages.to_vec()).pack().spanned(span)), shared))
|
||||
Ok((Packed::new(DocumentElem::new(pages.to_vec())).spanned(span), shared))
|
||||
}
|
||||
|
||||
/// Realize into an element that is capable of block-level layout.
|
||||
@ -64,19 +56,7 @@ pub fn realize_block<'a>(
|
||||
) -> SourceResult<(Cow<'a, Content>, StyleChain<'a>)> {
|
||||
// These elements implement `Layout` but still require a flow for
|
||||
// proper layout.
|
||||
if content.can::<dyn Layout>()
|
||||
&& !content.is::<BoxElem>()
|
||||
&& !content.is::<LineElem>()
|
||||
&& !content.is::<RectElem>()
|
||||
&& !content.is::<SquareElem>()
|
||||
&& !content.is::<EllipseElem>()
|
||||
&& !content.is::<CircleElem>()
|
||||
&& !content.is::<ImageElem>()
|
||||
&& !content.is::<PolygonElem>()
|
||||
&& !content.is::<PathElem>()
|
||||
&& !content.is::<PlaceElem>()
|
||||
&& !applicable(content, styles)
|
||||
{
|
||||
if content.can::<dyn LayoutMultiple>() && !applicable(content, styles) {
|
||||
return Ok((Cow::Borrowed(content), styles));
|
||||
}
|
||||
|
||||
@ -560,7 +540,10 @@ impl<'a> FlowBuilder<'a> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if content.can::<dyn Layout>() || content.is::<ParElem>() {
|
||||
if content.can::<dyn LayoutSingle>()
|
||||
|| content.can::<dyn LayoutMultiple>()
|
||||
|| content.is::<ParElem>()
|
||||
{
|
||||
let is_tight_list = if let Some(elem) = content.to_packed::<ListElem>() {
|
||||
elem.tight(styles)
|
||||
} else if let Some(elem) = content.to_packed::<EnumElem>() {
|
||||
|
@ -20,8 +20,8 @@ use crate::foundations::{
|
||||
StyleChain,
|
||||
};
|
||||
use crate::layout::{
|
||||
Abs, Axes, FixedAlignment, Fragment, Frame, FrameItem, Layout, Length, Point,
|
||||
Regions, Rel, Size,
|
||||
Abs, Axes, FixedAlignment, Frame, FrameItem, LayoutSingle, Length, Point, Regions,
|
||||
Rel, Size,
|
||||
};
|
||||
use crate::loading::Readable;
|
||||
use crate::model::Figurable;
|
||||
@ -51,7 +51,7 @@ use crate::World;
|
||||
/// ```
|
||||
///
|
||||
/// [gh-svg]: https://github.com/typst/typst/issues?q=is%3Aopen+is%3Aissue+label%3Asvg
|
||||
#[elem(scope, Layout, LocalName, Figurable)]
|
||||
#[elem(scope, LayoutSingle, LocalName, Figurable)]
|
||||
pub struct ImageElem {
|
||||
/// Path to an image file.
|
||||
#[required]
|
||||
@ -144,14 +144,14 @@ impl ImageElem {
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Packed<ImageElem> {
|
||||
impl LayoutSingle for Packed<ImageElem> {
|
||||
#[typst_macros::time(name = "image", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
// Take the format that was explicitly defined, or parse the extension,
|
||||
// or try to detect the format.
|
||||
let data = self.data();
|
||||
@ -239,7 +239,7 @@ impl Layout for Packed<ImageElem> {
|
||||
frame.clip(Path::rect(frame.size()));
|
||||
}
|
||||
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use crate::diag::{bail, SourceResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Packed, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, Angle, Axes, Fragment, Frame, FrameItem, Layout, Length, Regions, Rel, Size,
|
||||
Abs, Angle, Axes, Frame, FrameItem, LayoutSingle, Length, Regions, Rel, Size,
|
||||
};
|
||||
use crate::util::Numeric;
|
||||
use crate::visualize::{Geometry, Stroke};
|
||||
@ -20,7 +20,7 @@ use crate::visualize::{Geometry, Stroke};
|
||||
/// stroke: 2pt + maroon,
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct LineElem {
|
||||
/// The start point of the line.
|
||||
///
|
||||
@ -58,14 +58,14 @@ pub struct LineElem {
|
||||
pub stroke: Stroke,
|
||||
}
|
||||
|
||||
impl Layout for Packed<LineElem> {
|
||||
impl LayoutSingle for Packed<LineElem> {
|
||||
#[typst_macros::time(name = "line", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
_: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let resolve =
|
||||
|axes: Axes<Rel<Abs>>| axes.zip_map(regions.base(), Rel::relative_to);
|
||||
let start = resolve(self.start(styles));
|
||||
@ -89,6 +89,6 @@ impl Layout for Packed<LineElem> {
|
||||
let mut frame = Frame::soft(target);
|
||||
let shape = Geometry::Line(delta.to_point()).stroked(stroke);
|
||||
frame.push(start.to_point(), FrameItem::Shape(shape, self.span()));
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,8 @@ use crate::foundations::{
|
||||
array, cast, elem, Array, Packed, Reflect, Resolve, Smart, StyleChain,
|
||||
};
|
||||
use crate::layout::{
|
||||
Abs, Axes, Fragment, Frame, FrameItem, Layout, Length, Point, Regions, Rel, Size,
|
||||
Abs, Axes, Fragment, Frame, FrameItem, LayoutMultiple, Length, Point, Regions, Rel,
|
||||
Size,
|
||||
};
|
||||
use crate::visualize::{FixedStroke, Geometry, Paint, Shape, Stroke};
|
||||
|
||||
@ -25,7 +26,7 @@ use PathVertex::{AllControlPoints, MirroredControlPoint, Vertex};
|
||||
/// ((50%, 0pt), (40pt, 0pt)),
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutMultiple)]
|
||||
pub struct PathElem {
|
||||
/// How to fill the path.
|
||||
///
|
||||
@ -70,7 +71,7 @@ pub struct PathElem {
|
||||
pub vertices: Vec<PathVertex>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<PathElem> {
|
||||
impl LayoutMultiple for Packed<PathElem> {
|
||||
#[typst_macros::time(name = "path", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
|
@ -7,7 +7,7 @@ use ecow::{eco_format, EcoString};
|
||||
use crate::diag::{bail, SourceResult};
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{func, repr, scope, ty, Content, Smart, StyleChain};
|
||||
use crate::layout::{Abs, Axes, Frame, Layout, Length, Regions, Size};
|
||||
use crate::layout::{Abs, Axes, Frame, LayoutMultiple, Length, Regions, Size};
|
||||
use crate::syntax::{Span, Spanned};
|
||||
use crate::util::Numeric;
|
||||
use crate::visualize::RelativeTo;
|
||||
|
@ -6,7 +6,7 @@ use crate::foundations::{
|
||||
elem, func, scope, Content, NativeElement, Packed, Resolve, Smart, StyleChain,
|
||||
};
|
||||
use crate::layout::{
|
||||
Axes, Em, Fragment, Frame, FrameItem, Layout, Length, Point, Regions, Rel,
|
||||
Axes, Em, Frame, FrameItem, LayoutSingle, Length, Point, Regions, Rel,
|
||||
};
|
||||
use crate::syntax::Span;
|
||||
use crate::util::Numeric;
|
||||
@ -27,7 +27,7 @@ use crate::visualize::{FixedStroke, Geometry, Paint, Path, Shape, Stroke};
|
||||
/// (0%, 2cm),
|
||||
/// )
|
||||
/// ```
|
||||
#[elem(scope, Layout)]
|
||||
#[elem(scope, LayoutSingle)]
|
||||
pub struct PolygonElem {
|
||||
/// How to fill the polygon.
|
||||
///
|
||||
@ -125,14 +125,14 @@ impl PolygonElem {
|
||||
}
|
||||
}
|
||||
|
||||
impl Layout for Packed<PolygonElem> {
|
||||
impl LayoutSingle for Packed<PolygonElem> {
|
||||
#[typst_macros::time(name = "polygon", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
_: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let points: Vec<Point> = self
|
||||
.vertices()
|
||||
.iter()
|
||||
@ -150,7 +150,7 @@ impl Layout for Packed<PolygonElem> {
|
||||
|
||||
// Only create a path if there are more than zero points.
|
||||
if points.is_empty() {
|
||||
return Ok(Fragment::frame(frame));
|
||||
return Ok(frame);
|
||||
}
|
||||
|
||||
// Prepare fill and stroke.
|
||||
@ -171,7 +171,6 @@ impl Layout for Packed<PolygonElem> {
|
||||
|
||||
let shape = Shape { geometry: Geometry::Path(path), stroke, fill };
|
||||
frame.push(Point::zero(), FrameItem::Shape(shape, self.span()));
|
||||
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ use crate::diag::SourceResult;
|
||||
use crate::engine::Engine;
|
||||
use crate::foundations::{elem, Content, Packed, Resolve, Smart, StyleChain};
|
||||
use crate::layout::{
|
||||
Abs, Axes, Corner, Corners, Fragment, Frame, FrameItem, Layout, Length, Point, Ratio,
|
||||
Regions, Rel, Sides, Size,
|
||||
Abs, Axes, Corner, Corners, Frame, FrameItem, LayoutMultiple, LayoutSingle, Length,
|
||||
Point, Ratio, Regions, Rel, Sides, Size,
|
||||
};
|
||||
use crate::syntax::Span;
|
||||
use crate::util::Get;
|
||||
@ -24,7 +24,7 @@ use crate::visualize::{FixedStroke, Paint, Path, Stroke};
|
||||
/// to fit the content.
|
||||
/// ]
|
||||
/// ```
|
||||
#[elem(title = "Rectangle", Layout)]
|
||||
#[elem(title = "Rectangle", LayoutSingle)]
|
||||
pub struct RectElem {
|
||||
/// The rectangle's width, relative to its parent container.
|
||||
pub width: Smart<Rel<Length>>,
|
||||
@ -131,14 +131,14 @@ pub struct RectElem {
|
||||
pub body: Option<Content>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<RectElem> {
|
||||
impl LayoutSingle for Packed<RectElem> {
|
||||
#[typst_macros::time(name = "rect", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
layout(
|
||||
engine,
|
||||
styles,
|
||||
@ -169,7 +169,7 @@ impl Layout for Packed<RectElem> {
|
||||
/// sized to fit.
|
||||
/// ]
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct SquareElem {
|
||||
/// The square's side length. This is mutually exclusive with `width` and
|
||||
/// `height`.
|
||||
@ -237,14 +237,14 @@ pub struct SquareElem {
|
||||
pub body: Option<Content>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<SquareElem> {
|
||||
impl LayoutSingle for Packed<SquareElem> {
|
||||
#[typst_macros::time(name = "square", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
layout(
|
||||
engine,
|
||||
styles,
|
||||
@ -276,7 +276,7 @@ impl Layout for Packed<SquareElem> {
|
||||
/// to fit the content.
|
||||
/// ]
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct EllipseElem {
|
||||
/// The ellipse's width, relative to its parent container.
|
||||
pub width: Smart<Rel<Length>>,
|
||||
@ -315,14 +315,14 @@ pub struct EllipseElem {
|
||||
pub body: Option<Content>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<EllipseElem> {
|
||||
impl LayoutSingle for Packed<EllipseElem> {
|
||||
#[typst_macros::time(name = "ellipse", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
layout(
|
||||
engine,
|
||||
styles,
|
||||
@ -354,7 +354,7 @@ impl Layout for Packed<EllipseElem> {
|
||||
/// sized to fit.
|
||||
/// ]
|
||||
/// ```
|
||||
#[elem(Layout)]
|
||||
#[elem(LayoutSingle)]
|
||||
pub struct CircleElem {
|
||||
/// The circle's radius. This is mutually exclusive with `width` and
|
||||
/// `height`.
|
||||
@ -418,14 +418,14 @@ pub struct CircleElem {
|
||||
pub body: Option<Content>,
|
||||
}
|
||||
|
||||
impl Layout for Packed<CircleElem> {
|
||||
impl LayoutSingle for Packed<CircleElem> {
|
||||
#[typst_macros::time(name = "circle", span = self.span())]
|
||||
fn layout(
|
||||
&self,
|
||||
engine: &mut Engine,
|
||||
styles: StyleChain,
|
||||
regions: Regions,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
layout(
|
||||
engine,
|
||||
styles,
|
||||
@ -458,7 +458,7 @@ fn layout(
|
||||
outset: Sides<Rel<Abs>>,
|
||||
radius: Corners<Rel<Abs>>,
|
||||
span: Span,
|
||||
) -> SourceResult<Fragment> {
|
||||
) -> SourceResult<Frame> {
|
||||
let resolved = sizing
|
||||
.zip_map(regions.base(), |s, r| s.map(|v| v.resolve(styles).relative_to(r)));
|
||||
|
||||
@ -523,7 +523,7 @@ fn layout(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Fragment::frame(frame))
|
||||
Ok(frame)
|
||||
}
|
||||
|
||||
/// A category of shape.
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 58 KiB |
Loading…
x
Reference in New Issue
Block a user