mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Remove base width
This commit is contained in:
parent
697ae1f925
commit
f4856c18b9
@ -83,16 +83,16 @@ impl Layout for ColumnsNode {
|
|||||||
) -> SourceResult<Fragment> {
|
) -> SourceResult<Fragment> {
|
||||||
// Separating the infinite space into infinite columns does not make
|
// Separating the infinite space into infinite columns does not make
|
||||||
// much sense.
|
// much sense.
|
||||||
if !regions.first.x.is_finite() {
|
if !regions.size.x.is_finite() {
|
||||||
return self.body.layout(vt, styles, regions);
|
return self.body.layout(vt, styles, regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the width of the gutter and each column.
|
// Determine the width of the gutter and each column.
|
||||||
let columns = self.count.get();
|
let columns = self.count.get();
|
||||||
let gutter = styles.get(Self::GUTTER).relative_to(regions.base.x);
|
let gutter = styles.get(Self::GUTTER).relative_to(regions.base().x);
|
||||||
let width = (regions.first.x - gutter * (columns - 1) as f64) / columns as f64;
|
let width = (regions.size.x - gutter * (columns - 1) as f64) / columns as f64;
|
||||||
|
|
||||||
let backlog: Vec<_> = std::iter::once(®ions.first.y)
|
let backlog: Vec<_> = std::iter::once(®ions.size.y)
|
||||||
.chain(regions.backlog)
|
.chain(regions.backlog)
|
||||||
.flat_map(|&height| std::iter::repeat(height).take(columns))
|
.flat_map(|&height| std::iter::repeat(height).take(columns))
|
||||||
.skip(1)
|
.skip(1)
|
||||||
@ -100,8 +100,8 @@ impl Layout for ColumnsNode {
|
|||||||
|
|
||||||
// Create the pod regions.
|
// Create the pod regions.
|
||||||
let pod = Regions {
|
let pod = Regions {
|
||||||
first: Size::new(width, regions.first.y),
|
size: Size::new(width, regions.size.y),
|
||||||
base: Size::new(width, regions.base.y),
|
full: regions.full,
|
||||||
backlog: &backlog,
|
backlog: &backlog,
|
||||||
last: regions.last,
|
last: regions.last,
|
||||||
expand: Axes::new(true, regions.expand.y),
|
expand: Axes::new(true, regions.expand.y),
|
||||||
@ -121,7 +121,7 @@ impl Layout for ColumnsNode {
|
|||||||
// case, the frame is first created with zero height and then
|
// case, the frame is first created with zero height and then
|
||||||
// resized.
|
// resized.
|
||||||
let height = if regions.expand.y { region.y } else { Abs::zero() };
|
let height = if regions.expand.y { region.y } else { Abs::zero() };
|
||||||
let mut output = Frame::new(Size::new(regions.first.x, height));
|
let mut output = Frame::new(Size::new(regions.size.x, height));
|
||||||
let mut cursor = Abs::zero();
|
let mut cursor = Abs::zero();
|
||||||
|
|
||||||
for _ in 0..columns {
|
for _ in 0..columns {
|
||||||
@ -134,7 +134,7 @@ impl Layout for ColumnsNode {
|
|||||||
let x = if dir == Dir::LTR {
|
let x = if dir == Dir::LTR {
|
||||||
cursor
|
cursor
|
||||||
} else {
|
} else {
|
||||||
regions.first.x - cursor - width
|
regions.size.x - cursor - width
|
||||||
};
|
};
|
||||||
|
|
||||||
output.push_frame(Point::with_x(x), frame);
|
output.push_frame(Point::with_x(x), frame);
|
||||||
|
@ -77,24 +77,22 @@ impl Layout for BoxNode {
|
|||||||
let size = self
|
let size = self
|
||||||
.sizing
|
.sizing
|
||||||
.resolve(styles)
|
.resolve(styles)
|
||||||
.zip(regions.base)
|
.zip(regions.base())
|
||||||
.map(|(s, b)| s.map(|v| v.relative_to(b)))
|
.map(|(s, b)| s.map(|v| v.relative_to(b)))
|
||||||
.unwrap_or(regions.first);
|
.unwrap_or(regions.size);
|
||||||
|
|
||||||
// Select the appropriate base and expansion for the child depending
|
// Select the appropriate base and expansion for the child depending
|
||||||
// on whether it is automatically or relatively sized.
|
// on whether it is automatically or relatively sized.
|
||||||
let is_auto = self.sizing.as_ref().map(Option::is_none);
|
let is_auto = self.sizing.as_ref().map(Option::is_none);
|
||||||
let base = is_auto.select(regions.base, size);
|
|
||||||
let expand = regions.expand | !is_auto;
|
let expand = regions.expand | !is_auto;
|
||||||
|
Regions::one(size, expand)
|
||||||
Regions::one(size, base, expand)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Layout the child.
|
// Layout the child.
|
||||||
let mut frame = self.body.layout(vt, styles, pod)?.into_frame();
|
let mut frame = self.body.layout(vt, styles, pod)?.into_frame();
|
||||||
|
|
||||||
// Ensure frame size matches regions size if expansion is on.
|
// Ensure frame size matches regions size if expansion is on.
|
||||||
let target = regions.expand.select(regions.first, frame.size());
|
let target = regions.expand.select(regions.size, frame.size());
|
||||||
frame.resize(target, Align::LEFT_TOP);
|
frame.resize(target, Align::LEFT_TOP);
|
||||||
|
|
||||||
Ok(Fragment::frame(frame))
|
Ok(Fragment::frame(frame))
|
||||||
|
@ -85,7 +85,7 @@ impl<'a> FlowLayouter<'a> {
|
|||||||
/// Create a new flow layouter.
|
/// Create a new flow layouter.
|
||||||
fn new(mut regions: Regions<'a>) -> Self {
|
fn new(mut regions: Regions<'a>) -> Self {
|
||||||
let expand = regions.expand;
|
let expand = regions.expand;
|
||||||
let full = regions.first;
|
let full = regions.size;
|
||||||
|
|
||||||
// Disable vertical expansion for children.
|
// Disable vertical expansion for children.
|
||||||
regions.expand.y = false;
|
regions.expand.y = false;
|
||||||
@ -122,14 +122,7 @@ impl<'a> FlowLayouter<'a> {
|
|||||||
let leading = styles.get(ParNode::LEADING);
|
let leading = styles.get(ParNode::LEADING);
|
||||||
let consecutive = self.last_was_par;
|
let consecutive = self.last_was_par;
|
||||||
let frames = par
|
let frames = par
|
||||||
.layout(
|
.layout(vt, styles, consecutive, self.regions.base(), self.regions.expand.x)?
|
||||||
vt,
|
|
||||||
styles,
|
|
||||||
consecutive,
|
|
||||||
self.regions.first.x,
|
|
||||||
self.regions.base,
|
|
||||||
self.regions.expand.x,
|
|
||||||
)?
|
|
||||||
.into_frames();
|
.into_frames();
|
||||||
|
|
||||||
let mut sticky = self.items.len();
|
let mut sticky = self.items.len();
|
||||||
@ -142,7 +135,7 @@ impl<'a> FlowLayouter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let [first, ..] = frames.as_slice() {
|
if let [first, ..] = frames.as_slice() {
|
||||||
if !self.regions.first.y.fits(first.height()) && !self.regions.in_last() {
|
if !self.regions.size.y.fits(first.height()) && !self.regions.in_last() {
|
||||||
let carry: Vec<_> = self.items.drain(sticky..).collect();
|
let carry: Vec<_> = self.items.drain(sticky..).collect();
|
||||||
self.finish_region();
|
self.finish_region();
|
||||||
for item in carry {
|
for item in carry {
|
||||||
@ -199,15 +192,15 @@ impl<'a> FlowLayouter<'a> {
|
|||||||
/// Layout a finished frame.
|
/// Layout a finished frame.
|
||||||
fn layout_item(&mut self, item: FlowItem) {
|
fn layout_item(&mut self, item: FlowItem) {
|
||||||
match item {
|
match item {
|
||||||
FlowItem::Absolute(v, _) => self.regions.first.y -= v,
|
FlowItem::Absolute(v, _) => self.regions.size.y -= v,
|
||||||
FlowItem::Fractional(_) => {}
|
FlowItem::Fractional(_) => {}
|
||||||
FlowItem::Frame(ref frame, ..) => {
|
FlowItem::Frame(ref frame, ..) => {
|
||||||
let size = frame.size();
|
let size = frame.size();
|
||||||
if !self.regions.first.y.fits(size.y) && !self.regions.in_last() {
|
if !self.regions.size.y.fits(size.y) && !self.regions.in_last() {
|
||||||
self.finish_region();
|
self.finish_region();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.regions.first.y -= size.y;
|
self.regions.size.y -= size.y;
|
||||||
}
|
}
|
||||||
FlowItem::Placed(_) => {}
|
FlowItem::Placed(_) => {}
|
||||||
}
|
}
|
||||||
@ -284,7 +277,7 @@ impl<'a> FlowLayouter<'a> {
|
|||||||
// Advance to the next region.
|
// Advance to the next region.
|
||||||
self.finished.push(output);
|
self.finished.push(output);
|
||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first;
|
self.full = self.regions.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finish layouting and return the resulting fragment.
|
/// Finish layouting and return the resulting fragment.
|
||||||
|
@ -235,8 +235,6 @@ struct GridLayouter<'a, 'v> {
|
|||||||
rcols: Vec<Abs>,
|
rcols: Vec<Abs>,
|
||||||
/// Rows in the current region.
|
/// Rows in the current region.
|
||||||
lrows: Vec<Row>,
|
lrows: Vec<Row>,
|
||||||
/// The full height of the current region.
|
|
||||||
full: Abs,
|
|
||||||
/// The used-up size of the current region. The horizontal size is
|
/// The used-up size of the current region. The horizontal size is
|
||||||
/// determined once after columns are resolved and not touched again.
|
/// determined once after columns are resolved and not touched again.
|
||||||
used: Size,
|
used: Size,
|
||||||
@ -317,7 +315,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
cols.reverse();
|
cols.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
let full = regions.first.y;
|
|
||||||
let rcols = vec![Abs::zero(); cols.len()];
|
let rcols = vec![Abs::zero(); cols.len()];
|
||||||
let lrows = vec![];
|
let lrows = vec![];
|
||||||
|
|
||||||
@ -337,7 +334,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
styles,
|
styles,
|
||||||
rcols,
|
rcols,
|
||||||
lrows,
|
lrows,
|
||||||
full,
|
|
||||||
used: Size::zero(),
|
used: Size::zero(),
|
||||||
fr: Fr::zero(),
|
fr: Fr::zero(),
|
||||||
finished: vec![],
|
finished: vec![],
|
||||||
@ -384,7 +380,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
TrackSizing::Auto => {}
|
TrackSizing::Auto => {}
|
||||||
TrackSizing::Relative(v) => {
|
TrackSizing::Relative(v) => {
|
||||||
let resolved =
|
let resolved =
|
||||||
v.resolve(self.styles).relative_to(self.regions.base.x);
|
v.resolve(self.styles).relative_to(self.regions.base().x);
|
||||||
*rcol = resolved;
|
*rcol = resolved;
|
||||||
rel += resolved;
|
rel += resolved;
|
||||||
}
|
}
|
||||||
@ -393,7 +389,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Size that is not used by fixed-size columns.
|
// Size that is not used by fixed-size columns.
|
||||||
let available = self.regions.first.x - rel;
|
let available = self.regions.size.x - rel;
|
||||||
if available >= Abs::zero() {
|
if available >= Abs::zero() {
|
||||||
// Determine size of auto columns.
|
// Determine size of auto columns.
|
||||||
let (auto, count) = self.measure_auto_columns(available)?;
|
let (auto, count) = self.measure_auto_columns(available)?;
|
||||||
@ -429,16 +425,17 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
let mut resolved = Abs::zero();
|
let mut resolved = Abs::zero();
|
||||||
for y in 0..self.rows.len() {
|
for y in 0..self.rows.len() {
|
||||||
if let Some(cell) = self.cell(x, y) {
|
if let Some(cell) = self.cell(x, y) {
|
||||||
let size = Size::new(available, self.regions.base.y);
|
|
||||||
let mut pod = Regions::one(size, size, Axes::splat(false));
|
|
||||||
|
|
||||||
// For relative rows, we can already resolve the correct
|
// For relative rows, we can already resolve the correct
|
||||||
// base and for auto and fr we could only guess anyway.
|
// base and for auto and fr we could only guess anyway.
|
||||||
if let TrackSizing::Relative(v) = self.rows[y] {
|
let height = match self.rows[y] {
|
||||||
pod.base.y =
|
TrackSizing::Relative(v) => {
|
||||||
v.resolve(self.styles).relative_to(self.regions.base.y);
|
v.resolve(self.styles).relative_to(self.regions.base().y)
|
||||||
}
|
}
|
||||||
|
_ => self.regions.base().y,
|
||||||
|
};
|
||||||
|
|
||||||
|
let size = Size::new(available, height);
|
||||||
|
let pod = Regions::one(size, Axes::splat(false));
|
||||||
let frame = cell.layout(self.vt, self.styles, pod)?.into_frame();
|
let frame = cell.layout(self.vt, self.styles, pod)?.into_frame();
|
||||||
resolved.set_max(frame.width());
|
resolved.set_max(frame.width());
|
||||||
}
|
}
|
||||||
@ -508,8 +505,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
for (x, &rcol) in self.rcols.iter().enumerate() {
|
for (x, &rcol) in self.rcols.iter().enumerate() {
|
||||||
if let Some(cell) = self.cell(x, y) {
|
if let Some(cell) = self.cell(x, y) {
|
||||||
let mut pod = self.regions;
|
let mut pod = self.regions;
|
||||||
pod.first.x = rcol;
|
pod.size.x = rcol;
|
||||||
pod.base.x = rcol;
|
|
||||||
|
|
||||||
let frames = cell.layout(self.vt, self.styles, pod)?.into_frames();
|
let frames = cell.layout(self.vt, self.styles, pod)?.into_frames();
|
||||||
if let [first, rest @ ..] = frames.as_slice() {
|
if let [first, rest @ ..] = frames.as_slice() {
|
||||||
@ -573,12 +569,12 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
/// Layout a row with relative height. Such a row cannot break across
|
/// Layout a row with relative height. Such a row cannot break across
|
||||||
/// multiple regions, but it may force a region break.
|
/// multiple regions, but it may force a region break.
|
||||||
fn layout_relative_row(&mut self, v: Rel<Length>, y: usize) -> SourceResult<()> {
|
fn layout_relative_row(&mut self, v: Rel<Length>, y: usize) -> SourceResult<()> {
|
||||||
let resolved = v.resolve(self.styles).relative_to(self.regions.base.y);
|
let resolved = v.resolve(self.styles).relative_to(self.regions.base().y);
|
||||||
let frame = self.layout_single_row(resolved, y)?;
|
let frame = self.layout_single_row(resolved, y)?;
|
||||||
|
|
||||||
// Skip to fitting region.
|
// Skip to fitting region.
|
||||||
let height = frame.height();
|
let height = frame.height();
|
||||||
while !self.regions.first.y.fits(height) && !self.regions.in_last() {
|
while !self.regions.size.y.fits(height) && !self.regions.in_last() {
|
||||||
self.finish_region()?;
|
self.finish_region()?;
|
||||||
|
|
||||||
// Don't skip multiple regions for gutter and don't push a row.
|
// Don't skip multiple regions for gutter and don't push a row.
|
||||||
@ -600,14 +596,10 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
for (x, &rcol) in self.rcols.iter().enumerate() {
|
for (x, &rcol) in self.rcols.iter().enumerate() {
|
||||||
if let Some(cell) = self.cell(x, y) {
|
if let Some(cell) = self.cell(x, y) {
|
||||||
let size = Size::new(rcol, height);
|
let size = Size::new(rcol, height);
|
||||||
let base = Size::new(
|
let mut pod = Regions::one(size, Axes::splat(true));
|
||||||
rcol,
|
if self.rows[y] == TrackSizing::Auto {
|
||||||
match self.rows[y] {
|
pod.full = self.regions.full;
|
||||||
TrackSizing::Auto => self.regions.base.y,
|
}
|
||||||
_ => height,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
let pod = Regions::one(size, base, Axes::splat(true));
|
|
||||||
let frame = cell.layout(self.vt, self.styles, pod)?.into_frame();
|
let frame = cell.layout(self.vt, self.styles, pod)?.into_frame();
|
||||||
output.push_frame(pos, frame);
|
output.push_frame(pos, frame);
|
||||||
}
|
}
|
||||||
@ -628,15 +620,15 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
|
|
||||||
// Prepare regions.
|
// Prepare regions.
|
||||||
let size = Size::new(self.used.x, heights[0]);
|
let size = Size::new(self.used.x, heights[0]);
|
||||||
let mut pod = Regions::one(size, self.regions.base, Axes::splat(true));
|
let mut pod = Regions::one(size, Axes::splat(true));
|
||||||
|
pod.full = self.regions.full;
|
||||||
pod.backlog = &heights[1..];
|
pod.backlog = &heights[1..];
|
||||||
|
|
||||||
// Layout the row.
|
// Layout the row.
|
||||||
let mut pos = Point::zero();
|
let mut pos = Point::zero();
|
||||||
for (x, &rcol) in self.rcols.iter().enumerate() {
|
for (x, &rcol) in self.rcols.iter().enumerate() {
|
||||||
if let Some(cell) = self.cell(x, y) {
|
if let Some(cell) = self.cell(x, y) {
|
||||||
pod.first.x = rcol;
|
pod.size.x = rcol;
|
||||||
pod.base.x = rcol;
|
|
||||||
|
|
||||||
// Push the layouted frames into the individual output frames.
|
// Push the layouted frames into the individual output frames.
|
||||||
let fragment = cell.layout(self.vt, self.styles, pod)?;
|
let fragment = cell.layout(self.vt, self.styles, pod)?;
|
||||||
@ -653,7 +645,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
|
|
||||||
/// Push a row frame into the current region.
|
/// Push a row frame into the current region.
|
||||||
fn push_row(&mut self, frame: Frame) {
|
fn push_row(&mut self, frame: Frame) {
|
||||||
self.regions.first.y -= frame.height();
|
self.regions.size.y -= frame.height();
|
||||||
self.used.y += frame.height();
|
self.used.y += frame.height();
|
||||||
self.lrows.push(Row::Frame(frame));
|
self.lrows.push(Row::Frame(frame));
|
||||||
}
|
}
|
||||||
@ -663,8 +655,8 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
// Determine the size of the grid in this region, expanding fully if
|
// Determine the size of the grid in this region, expanding fully if
|
||||||
// there are fr rows.
|
// there are fr rows.
|
||||||
let mut size = self.used;
|
let mut size = self.used;
|
||||||
if self.fr.get() > 0.0 && self.full.is_finite() {
|
if self.fr.get() > 0.0 && self.regions.full.is_finite() {
|
||||||
size.y = self.full;
|
size.y = self.regions.full;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The frame for the region.
|
// The frame for the region.
|
||||||
@ -676,7 +668,7 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
let frame = match row {
|
let frame = match row {
|
||||||
Row::Frame(frame) => frame,
|
Row::Frame(frame) => frame,
|
||||||
Row::Fr(v, y) => {
|
Row::Fr(v, y) => {
|
||||||
let remaining = self.full - self.used.y;
|
let remaining = self.regions.full - self.used.y;
|
||||||
let height = v.share(self.fr, remaining);
|
let height = v.share(self.fr, remaining);
|
||||||
self.layout_single_row(height, y)?
|
self.layout_single_row(height, y)?
|
||||||
}
|
}
|
||||||
@ -689,7 +681,6 @@ impl<'a, 'v> GridLayouter<'a, 'v> {
|
|||||||
|
|
||||||
self.finished.push(output);
|
self.finished.push(output);
|
||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first.y;
|
|
||||||
self.used.y = Abs::zero();
|
self.used.y = Abs::zero();
|
||||||
self.fr = Fr::zero();
|
self.fr = Fr::zero();
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ impl PageNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Layout the child.
|
// Layout the child.
|
||||||
let regions = Regions::repeat(size, size, size.map(Abs::is_finite));
|
let regions = Regions::repeat(size, size.map(Abs::is_finite));
|
||||||
let mut fragment = child.layout(vt, styles, regions)?;
|
let mut fragment = child.layout(vt, styles, regions)?;
|
||||||
|
|
||||||
let header = styles.get(Self::HEADER);
|
let header = styles.get(Self::HEADER);
|
||||||
@ -316,7 +316,7 @@ impl PageNode {
|
|||||||
let in_background = std::ptr::eq(marginal, background);
|
let in_background = std::ptr::eq(marginal, background);
|
||||||
let Some(marginal) = marginal else { continue };
|
let Some(marginal) = marginal else { continue };
|
||||||
let content = marginal.resolve(vt, page)?;
|
let content = marginal.resolve(vt, page)?;
|
||||||
let pod = Regions::one(area, area, Axes::splat(true));
|
let pod = Regions::one(area, Axes::splat(true));
|
||||||
let sub = content.layout(vt, styles, pod)?.into_frame();
|
let sub = content.layout(vt, styles, pod)?.into_frame();
|
||||||
if in_background {
|
if in_background {
|
||||||
frame.prepend_frame(pos, sub);
|
frame.prepend_frame(pos, sub);
|
||||||
|
@ -120,8 +120,7 @@ impl ParNode {
|
|||||||
vt: &mut Vt,
|
vt: &mut Vt,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
consecutive: bool,
|
consecutive: bool,
|
||||||
width: Abs,
|
region: Size,
|
||||||
base: Size,
|
|
||||||
expand: bool,
|
expand: bool,
|
||||||
) -> SourceResult<Fragment> {
|
) -> SourceResult<Fragment> {
|
||||||
#[comemo::memoize]
|
#[comemo::memoize]
|
||||||
@ -132,8 +131,7 @@ impl ParNode {
|
|||||||
introspector: Tracked<Introspector>,
|
introspector: Tracked<Introspector>,
|
||||||
styles: StyleChain,
|
styles: StyleChain,
|
||||||
consecutive: bool,
|
consecutive: bool,
|
||||||
width: Abs,
|
region: Size,
|
||||||
base: Size,
|
|
||||||
expand: bool,
|
expand: bool,
|
||||||
) -> SourceResult<Fragment> {
|
) -> SourceResult<Fragment> {
|
||||||
let mut vt = Vt { world, provider, introspector };
|
let mut vt = Vt { world, provider, introspector };
|
||||||
@ -144,13 +142,13 @@ impl ParNode {
|
|||||||
// Perform BiDi analysis and then prepare paragraph layout by building a
|
// Perform BiDi analysis and then prepare paragraph layout by building a
|
||||||
// representation on which we can do line breaking without layouting
|
// representation on which we can do line breaking without layouting
|
||||||
// each and every line from scratch.
|
// each and every line from scratch.
|
||||||
let p = prepare(&mut vt, par, &text, segments, styles, width, base)?;
|
let p = prepare(&mut vt, par, &text, segments, styles, region)?;
|
||||||
|
|
||||||
// Break the paragraph into lines.
|
// Break the paragraph into lines.
|
||||||
let lines = linebreak(&vt, &p, width);
|
let lines = linebreak(&vt, &p, region.x);
|
||||||
|
|
||||||
// Stack the lines into one frame per region.
|
// Stack the lines into one frame per region.
|
||||||
finalize(&mut vt, &p, &lines, width, base, expand)
|
finalize(&mut vt, &p, &lines, region, expand)
|
||||||
}
|
}
|
||||||
|
|
||||||
cached(
|
cached(
|
||||||
@ -160,8 +158,7 @@ impl ParNode {
|
|||||||
vt.introspector,
|
vt.introspector,
|
||||||
styles,
|
styles,
|
||||||
consecutive,
|
consecutive,
|
||||||
width,
|
region,
|
||||||
base,
|
|
||||||
expand,
|
expand,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -595,8 +592,7 @@ fn prepare<'a>(
|
|||||||
text: &'a str,
|
text: &'a str,
|
||||||
segments: Vec<(Segment<'a>, StyleChain<'a>)>,
|
segments: Vec<(Segment<'a>, StyleChain<'a>)>,
|
||||||
styles: StyleChain<'a>,
|
styles: StyleChain<'a>,
|
||||||
width: Abs,
|
region: Size,
|
||||||
base: Size,
|
|
||||||
) -> SourceResult<Preparation<'a>> {
|
) -> SourceResult<Preparation<'a>> {
|
||||||
let bidi = BidiInfo::new(
|
let bidi = BidiInfo::new(
|
||||||
text,
|
text,
|
||||||
@ -619,7 +615,7 @@ fn prepare<'a>(
|
|||||||
}
|
}
|
||||||
Segment::Spacing(spacing) => match spacing {
|
Segment::Spacing(spacing) => match spacing {
|
||||||
Spacing::Relative(v) => {
|
Spacing::Relative(v) => {
|
||||||
let resolved = v.resolve(styles).relative_to(base.x);
|
let resolved = v.resolve(styles).relative_to(region.x);
|
||||||
items.push(Item::Absolute(resolved));
|
items.push(Item::Absolute(resolved));
|
||||||
}
|
}
|
||||||
Spacing::Fractional(v) => {
|
Spacing::Fractional(v) => {
|
||||||
@ -630,8 +626,7 @@ fn prepare<'a>(
|
|||||||
if let Some(repeat) = inline.to::<RepeatNode>() {
|
if let Some(repeat) = inline.to::<RepeatNode>() {
|
||||||
items.push(Item::Repeat(repeat, styles));
|
items.push(Item::Repeat(repeat, styles));
|
||||||
} else {
|
} else {
|
||||||
let size = Size::new(width, base.y);
|
let pod = Regions::one(region, Axes::splat(false));
|
||||||
let pod = Regions::one(size, base, Axes::splat(false));
|
|
||||||
let mut frame = inline.layout(vt, styles, pod)?.into_frame();
|
let mut frame = inline.layout(vt, styles, pod)?.into_frame();
|
||||||
frame.translate(Point::with_y(styles.get(TextNode::BASELINE)));
|
frame.translate(Point::with_y(styles.get(TextNode::BASELINE)));
|
||||||
items.push(Item::Frame(frame));
|
items.push(Item::Frame(frame));
|
||||||
@ -1116,20 +1111,20 @@ fn finalize(
|
|||||||
vt: &mut Vt,
|
vt: &mut Vt,
|
||||||
p: &Preparation,
|
p: &Preparation,
|
||||||
lines: &[Line],
|
lines: &[Line],
|
||||||
mut width: Abs,
|
mut region: Size,
|
||||||
base: Size,
|
|
||||||
expand: bool,
|
expand: bool,
|
||||||
) -> SourceResult<Fragment> {
|
) -> SourceResult<Fragment> {
|
||||||
// Determine the paragraph's width: Full width of the region if we
|
// Determine the paragraph's width: Full width of the region if we
|
||||||
// should expand or there's fractional spacing, fit-to-width otherwise.
|
// should expand or there's fractional spacing, fit-to-width otherwise.
|
||||||
if !width.is_finite() || (!expand && lines.iter().all(|line| line.fr().is_zero())) {
|
if !region.x.is_finite() || (!expand && lines.iter().all(|line| line.fr().is_zero()))
|
||||||
width = lines.iter().map(|line| line.width).max().unwrap_or_default();
|
{
|
||||||
|
region.x = lines.iter().map(|line| line.width).max().unwrap_or_default();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stack the lines into one frame per region.
|
// Stack the lines into one frame per region.
|
||||||
let mut frames: Vec<Frame> = lines
|
let mut frames: Vec<Frame> = lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|line| commit(vt, p, line, base, width))
|
.map(|line| commit(vt, p, line, region))
|
||||||
.collect::<SourceResult<_>>()?;
|
.collect::<SourceResult<_>>()?;
|
||||||
|
|
||||||
// Prevent orphans.
|
// Prevent orphans.
|
||||||
@ -1164,10 +1159,9 @@ fn commit(
|
|||||||
vt: &mut Vt,
|
vt: &mut Vt,
|
||||||
p: &Preparation,
|
p: &Preparation,
|
||||||
line: &Line,
|
line: &Line,
|
||||||
base: Size,
|
region: Size,
|
||||||
width: Abs,
|
|
||||||
) -> SourceResult<Frame> {
|
) -> SourceResult<Frame> {
|
||||||
let mut remaining = width - line.width;
|
let mut remaining = region.x - line.width;
|
||||||
let mut offset = Abs::zero();
|
let mut offset = Abs::zero();
|
||||||
|
|
||||||
// Reorder the line from logical to visual order.
|
// Reorder the line from logical to visual order.
|
||||||
@ -1242,8 +1236,8 @@ fn commit(
|
|||||||
Item::Repeat(repeat, styles) => {
|
Item::Repeat(repeat, styles) => {
|
||||||
let before = offset;
|
let before = offset;
|
||||||
let fill = Fr::one().share(fr, remaining);
|
let fill = Fr::one().share(fr, remaining);
|
||||||
let size = Size::new(fill, base.y);
|
let size = Size::new(fill, region.y);
|
||||||
let pod = Regions::one(size, base, Axes::new(false, false));
|
let pod = Regions::one(size, Axes::new(false, false));
|
||||||
let frame = repeat.layout(vt, *styles, pod)?.into_frame();
|
let frame = repeat.layout(vt, *styles, pod)?.into_frame();
|
||||||
let width = frame.width();
|
let width = frame.width();
|
||||||
let count = (fill / width).floor();
|
let count = (fill / width).floor();
|
||||||
@ -1268,7 +1262,7 @@ fn commit(
|
|||||||
remaining = Abs::zero();
|
remaining = Abs::zero();
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = Size::new(width, top + bottom);
|
let size = Size::new(region.x, top + bottom);
|
||||||
let mut output = Frame::new(size);
|
let mut output = Frame::new(size);
|
||||||
output.set_baseline(top);
|
output.set_baseline(top);
|
||||||
|
|
||||||
|
@ -92,16 +92,16 @@ impl Layout for PlaceNode {
|
|||||||
// The pod is the base area of the region because for absolute
|
// The pod is the base area of the region because for absolute
|
||||||
// placement we don't really care about the already used area.
|
// placement we don't really care about the already used area.
|
||||||
let pod = {
|
let pod = {
|
||||||
let finite = regions.base.map(Abs::is_finite);
|
let finite = regions.base().map(Abs::is_finite);
|
||||||
let expand = finite & (regions.expand | out_of_flow);
|
let expand = finite & (regions.expand | out_of_flow);
|
||||||
Regions::one(regions.base, regions.base, expand)
|
Regions::one(regions.base(), expand)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut frame = self.0.layout(vt, styles, pod)?.into_frame();
|
let mut frame = self.0.layout(vt, styles, pod)?.into_frame();
|
||||||
|
|
||||||
// If expansion is off, zero all sizes so that we don't take up any
|
// If expansion is off, zero all sizes so that we don't take up any
|
||||||
// space in our parent. Otherwise, respect the expand settings.
|
// space in our parent. Otherwise, respect the expand settings.
|
||||||
let target = regions.expand.select(regions.first, Size::zero());
|
let target = regions.expand.select(regions.size, Size::zero());
|
||||||
frame.resize(target, Align::LEFT_TOP);
|
frame.resize(target, Align::LEFT_TOP);
|
||||||
|
|
||||||
Ok(Fragment::frame(frame))
|
Ok(Fragment::frame(frame))
|
||||||
|
@ -5,10 +5,10 @@ use typst::geom::{Abs, Axes, Size};
|
|||||||
/// A sequence of regions to layout into.
|
/// A sequence of regions to layout into.
|
||||||
#[derive(Copy, Clone, Hash)]
|
#[derive(Copy, Clone, Hash)]
|
||||||
pub struct Regions<'a> {
|
pub struct Regions<'a> {
|
||||||
/// The (remaining) size of the first region.
|
/// The remaining size of the first region.
|
||||||
pub first: Size,
|
pub size: Size,
|
||||||
/// The base size for relative sizing.
|
/// The full height of the region for relative sizing.
|
||||||
pub base: Size,
|
pub full: Abs,
|
||||||
/// The height of followup regions. The width is the same for all regions.
|
/// The height of followup regions. The width is the same for all regions.
|
||||||
pub backlog: &'a [Abs],
|
pub backlog: &'a [Abs],
|
||||||
/// The height of the final region that is repeated once the backlog is
|
/// The height of the final region that is repeated once the backlog is
|
||||||
@ -19,12 +19,12 @@ pub struct Regions<'a> {
|
|||||||
pub expand: Axes<bool>,
|
pub expand: Axes<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Regions<'a> {
|
impl Regions<'_> {
|
||||||
/// Create a new region sequence with exactly one region.
|
/// Create a new region sequence with exactly one region.
|
||||||
pub fn one(size: Size, base: Size, expand: Axes<bool>) -> Self {
|
pub fn one(size: Size, expand: Axes<bool>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
first: size,
|
size,
|
||||||
base,
|
full: size.y,
|
||||||
backlog: &[],
|
backlog: &[],
|
||||||
last: None,
|
last: None,
|
||||||
expand,
|
expand,
|
||||||
@ -32,16 +32,24 @@ impl<'a> Regions<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new sequence of same-size regions that repeats indefinitely.
|
/// Create a new sequence of same-size regions that repeats indefinitely.
|
||||||
pub fn repeat(size: Size, base: Size, expand: Axes<bool>) -> Self {
|
pub fn repeat(size: Size, expand: Axes<bool>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
first: size,
|
size,
|
||||||
base,
|
full: size.y,
|
||||||
backlog: &[],
|
backlog: &[],
|
||||||
last: Some(size.y),
|
last: Some(size.y),
|
||||||
expand,
|
expand,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The base size, which doesn't take into account that the regions is
|
||||||
|
/// already partially used up.
|
||||||
|
///
|
||||||
|
/// This is also used for relative sizing.
|
||||||
|
pub fn base(&self) -> Size {
|
||||||
|
Size::new(self.size.x, self.full)
|
||||||
|
}
|
||||||
|
|
||||||
/// Create new regions where all sizes are mapped with `f`.
|
/// Create new regions where all sizes are mapped with `f`.
|
||||||
///
|
///
|
||||||
/// Note that since all regions must have the same width, the width returned
|
/// Note that since all regions must have the same width, the width returned
|
||||||
@ -50,12 +58,12 @@ impl<'a> Regions<'a> {
|
|||||||
where
|
where
|
||||||
F: FnMut(Size) -> Size,
|
F: FnMut(Size) -> Size,
|
||||||
{
|
{
|
||||||
let x = self.first.x;
|
let x = self.size.x;
|
||||||
backlog.clear();
|
backlog.clear();
|
||||||
backlog.extend(self.backlog.iter().map(|&y| f(Size::new(x, y)).y));
|
backlog.extend(self.backlog.iter().map(|&y| f(Size::new(x, y)).y));
|
||||||
Regions {
|
Regions {
|
||||||
first: f(self.first),
|
size: f(self.size),
|
||||||
base: f(self.base),
|
full: f(Size::new(x, self.full)).y,
|
||||||
backlog,
|
backlog,
|
||||||
last: self.last.map(|y| f(Size::new(x, y)).y),
|
last: self.last.map(|y| f(Size::new(x, y)).y),
|
||||||
expand: self.expand,
|
expand: self.expand,
|
||||||
@ -64,14 +72,14 @@ impl<'a> Regions<'a> {
|
|||||||
|
|
||||||
/// Whether the first region is full and a region break is called for.
|
/// Whether the first region is full and a region break is called for.
|
||||||
pub fn is_full(&self) -> bool {
|
pub fn is_full(&self) -> bool {
|
||||||
Abs::zero().fits(self.first.y) && !self.in_last()
|
Abs::zero().fits(self.size.y) && !self.in_last()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the first region is the last usable region.
|
/// Whether the first region is the last usable region.
|
||||||
///
|
///
|
||||||
/// If this is true, calling `next()` will have no effect.
|
/// If this is true, calling `next()` will have no effect.
|
||||||
pub fn in_last(&self) -> bool {
|
pub fn in_last(&self) -> bool {
|
||||||
self.backlog.is_empty() && self.last.map_or(true, |height| self.first.y == height)
|
self.backlog.is_empty() && self.last.map_or(true, |height| self.size.y == height)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Advance to the next region if there is any.
|
/// Advance to the next region if there is any.
|
||||||
@ -85,8 +93,8 @@ impl<'a> Regions<'a> {
|
|||||||
})
|
})
|
||||||
.or(self.last)
|
.or(self.last)
|
||||||
{
|
{
|
||||||
self.first.y = height;
|
self.size.y = height;
|
||||||
self.base.y = height;
|
self.full = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,10 +103,10 @@ impl<'a> Regions<'a> {
|
|||||||
/// [`next()`](Self::next) repeatedly until all regions are exhausted.
|
/// [`next()`](Self::next) repeatedly until all regions are exhausted.
|
||||||
/// This iterator may be infinite.
|
/// This iterator may be infinite.
|
||||||
pub fn iter(&self) -> impl Iterator<Item = Size> + '_ {
|
pub fn iter(&self) -> impl Iterator<Item = Size> + '_ {
|
||||||
let first = std::iter::once(self.first);
|
let first = std::iter::once(self.size);
|
||||||
let backlog = self.backlog.iter();
|
let backlog = self.backlog.iter();
|
||||||
let last = self.last.iter().cycle();
|
let last = self.last.iter().cycle();
|
||||||
first.chain(backlog.chain(last).map(|&h| Size::new(self.first.x, h)))
|
first.chain(backlog.chain(last).map(|&h| Size::new(self.size.x, h)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,15 +114,15 @@ impl Debug for Regions<'_> {
|
|||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str("Regions ")?;
|
f.write_str("Regions ")?;
|
||||||
let mut list = f.debug_list();
|
let mut list = f.debug_list();
|
||||||
let mut prev = self.first.y;
|
let mut prev = self.size.y;
|
||||||
list.entry(&self.first);
|
list.entry(&self.size);
|
||||||
for &height in self.backlog {
|
for &height in self.backlog {
|
||||||
list.entry(&Size::new(self.first.x, height));
|
list.entry(&Size::new(self.size.x, height));
|
||||||
prev = height;
|
prev = height;
|
||||||
}
|
}
|
||||||
if let Some(last) = self.last {
|
if let Some(last) = self.last {
|
||||||
if last != prev {
|
if last != prev {
|
||||||
list.entry(&Size::new(self.first.x, last));
|
list.entry(&Size::new(self.size.x, last));
|
||||||
}
|
}
|
||||||
list.entry(&(..));
|
list.entry(&(..));
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,7 @@ impl<'a> StackLayouter<'a> {
|
|||||||
fn new(dir: Dir, regions: Regions<'a>, styles: StyleChain<'a>) -> Self {
|
fn new(dir: Dir, regions: Regions<'a>, styles: StyleChain<'a>) -> Self {
|
||||||
let axis = dir.axis();
|
let axis = dir.axis();
|
||||||
let expand = regions.expand;
|
let expand = regions.expand;
|
||||||
let full = regions.first;
|
let full = regions.size;
|
||||||
|
|
||||||
// Disable expansion along the block axis for children.
|
// Disable expansion along the block axis for children.
|
||||||
let mut regions = regions.clone();
|
let mut regions = regions.clone();
|
||||||
@ -202,11 +202,14 @@ impl<'a> StackLayouter<'a> {
|
|||||||
match spacing {
|
match spacing {
|
||||||
Spacing::Relative(v) => {
|
Spacing::Relative(v) => {
|
||||||
// Resolve the spacing and limit it to the remaining space.
|
// Resolve the spacing and limit it to the remaining space.
|
||||||
let resolved =
|
let resolved = v
|
||||||
v.resolve(self.styles).relative_to(self.regions.base.get(self.axis));
|
.resolve(self.styles)
|
||||||
let remaining = self.regions.first.get_mut(self.axis);
|
.relative_to(self.regions.base().get(self.axis));
|
||||||
|
let remaining = self.regions.size.get_mut(self.axis);
|
||||||
let limited = resolved.min(*remaining);
|
let limited = resolved.min(*remaining);
|
||||||
*remaining -= limited;
|
if self.dir.axis() == Axis::Y {
|
||||||
|
*remaining -= limited;
|
||||||
|
}
|
||||||
self.used.main += limited;
|
self.used.main += limited;
|
||||||
self.items.push(StackItem::Absolute(resolved));
|
self.items.push(StackItem::Absolute(resolved));
|
||||||
}
|
}
|
||||||
@ -242,14 +245,18 @@ impl<'a> StackLayouter<'a> {
|
|||||||
for (i, frame) in fragment.into_iter().enumerate() {
|
for (i, frame) in fragment.into_iter().enumerate() {
|
||||||
// Grow our size, shrink the region and save the frame for later.
|
// Grow our size, shrink the region and save the frame for later.
|
||||||
let size = frame.size();
|
let size = frame.size();
|
||||||
let size = match self.axis {
|
if self.dir.axis() == Axis::Y {
|
||||||
|
self.regions.size.y -= size.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gen = match self.axis {
|
||||||
Axis::X => Gen::new(size.y, size.x),
|
Axis::X => Gen::new(size.y, size.x),
|
||||||
Axis::Y => Gen::new(size.x, size.y),
|
Axis::Y => Gen::new(size.x, size.y),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.used.main += size.main;
|
self.used.main += gen.main;
|
||||||
self.used.cross.set_max(size.cross);
|
self.used.cross.set_max(gen.cross);
|
||||||
*self.regions.first.get_mut(self.axis) -= size.main;
|
|
||||||
self.items.push(StackItem::Frame(frame, align));
|
self.items.push(StackItem::Frame(frame, align));
|
||||||
|
|
||||||
if i + 1 < len {
|
if i + 1 < len {
|
||||||
@ -310,7 +317,7 @@ impl<'a> StackLayouter<'a> {
|
|||||||
|
|
||||||
// Advance to the next region.
|
// Advance to the next region.
|
||||||
self.regions.next();
|
self.regions.next();
|
||||||
self.full = self.regions.first;
|
self.full = self.regions.size;
|
||||||
self.used = Gen::zero();
|
self.used = Gen::zero();
|
||||||
self.fr = Fr::zero();
|
self.fr = Fr::zero();
|
||||||
self.finished.push(output);
|
self.finished.push(output);
|
||||||
|
@ -78,7 +78,7 @@ impl Layout for MoveNode {
|
|||||||
let mut fragment = self.body.layout(vt, styles, regions)?;
|
let mut fragment = self.body.layout(vt, styles, regions)?;
|
||||||
for frame in &mut fragment {
|
for frame in &mut fragment {
|
||||||
let delta = self.delta.resolve(styles);
|
let delta = self.delta.resolve(styles);
|
||||||
let delta = delta.zip(regions.base).map(|(d, s)| d.relative_to(s));
|
let delta = delta.zip(regions.base()).map(|(d, s)| d.relative_to(s));
|
||||||
frame.translate(delta.to_point());
|
frame.translate(delta.to_point());
|
||||||
}
|
}
|
||||||
Ok(fragment)
|
Ok(fragment)
|
||||||
|
@ -25,7 +25,7 @@ macro_rules! percent {
|
|||||||
/// The context for math layout.
|
/// The context for math layout.
|
||||||
pub struct MathContext<'a, 'b, 'v> {
|
pub struct MathContext<'a, 'b, 'v> {
|
||||||
pub vt: &'v mut Vt<'b>,
|
pub vt: &'v mut Vt<'b>,
|
||||||
pub regions: Regions<'a>,
|
pub regions: Regions<'static>,
|
||||||
pub font: &'a Font,
|
pub font: &'a Font,
|
||||||
pub ttf: &'a ttf_parser::Face<'a>,
|
pub ttf: &'a ttf_parser::Face<'a>,
|
||||||
pub table: ttf_parser::math::Table<'a>,
|
pub table: ttf_parser::math::Table<'a>,
|
||||||
@ -60,10 +60,7 @@ impl<'a, 'b, 'v> MathContext<'a, 'b, 'v> {
|
|||||||
let variant = variant(styles);
|
let variant = variant(styles);
|
||||||
Self {
|
Self {
|
||||||
vt,
|
vt,
|
||||||
regions: {
|
regions: Regions::one(regions.base(), Axes::splat(false)),
|
||||||
let size = Size::new(regions.first.x, regions.base.y);
|
|
||||||
Regions::one(size, regions.base, Axes::splat(false))
|
|
||||||
},
|
|
||||||
font: &font,
|
font: &font,
|
||||||
ttf: font.ttf(),
|
ttf: font.ttf(),
|
||||||
table,
|
table,
|
||||||
|
@ -76,7 +76,7 @@ impl Layout for ImageNode {
|
|||||||
let px_ratio = pxw / pxh;
|
let px_ratio = pxw / pxh;
|
||||||
|
|
||||||
// Find out whether the image is wider or taller than the target size.
|
// Find out whether the image is wider or taller than the target size.
|
||||||
let Regions { first, expand, .. } = regions;
|
let Regions { size: first, expand, .. } = regions;
|
||||||
let region_ratio = first.x / first.y;
|
let region_ratio = first.x / first.y;
|
||||||
let wide = px_ratio > region_ratio;
|
let wide = px_ratio > region_ratio;
|
||||||
|
|
||||||
|
@ -87,17 +87,17 @@ impl Layout for LineNode {
|
|||||||
let origin = self
|
let origin = self
|
||||||
.start
|
.start
|
||||||
.resolve(styles)
|
.resolve(styles)
|
||||||
.zip(regions.base)
|
.zip(regions.base())
|
||||||
.map(|(l, b)| l.relative_to(b));
|
.map(|(l, b)| l.relative_to(b));
|
||||||
|
|
||||||
let delta = self
|
let delta = self
|
||||||
.delta
|
.delta
|
||||||
.resolve(styles)
|
.resolve(styles)
|
||||||
.zip(regions.base)
|
.zip(regions.base())
|
||||||
.map(|(l, b)| l.relative_to(b));
|
.map(|(l, b)| l.relative_to(b));
|
||||||
|
|
||||||
let size = origin.max(origin + delta).max(Size::zero());
|
let size = origin.max(origin + delta).max(Size::zero());
|
||||||
let target = regions.expand.select(regions.first, size);
|
let target = regions.expand.select(regions.size, size);
|
||||||
|
|
||||||
let mut frame = Frame::new(target);
|
let mut frame = Frame::new(target);
|
||||||
let shape = Geometry::Line(delta.to_point()).stroked(stroke);
|
let shape = Geometry::Line(delta.to_point()).stroked(stroke);
|
||||||
|
@ -555,41 +555,40 @@ fn layout(
|
|||||||
|
|
||||||
// Pad the child.
|
// Pad the child.
|
||||||
let child = child.clone().padded(inset.map(|side| side.map(Length::from)));
|
let child = child.clone().padded(inset.map(|side| side.map(Length::from)));
|
||||||
|
let pod = Regions::one(regions.size, regions.expand);
|
||||||
let pod = Regions::one(regions.first, regions.base, regions.expand);
|
|
||||||
frame = child.layout(vt, styles, pod)?.into_frame();
|
frame = child.layout(vt, styles, pod)?.into_frame();
|
||||||
|
|
||||||
// Relayout with full expansion into square region to make sure
|
// Relayout with full expansion into square region to make sure
|
||||||
// the result is really a square or circle.
|
// the result is really a square or circle.
|
||||||
if kind.is_quadratic() {
|
if kind.is_quadratic() {
|
||||||
let length = if regions.expand.x || regions.expand.y {
|
let length = if regions.expand.x || regions.expand.y {
|
||||||
let target = regions.expand.select(regions.first, Size::zero());
|
let target = regions.expand.select(regions.size, Size::zero());
|
||||||
target.x.max(target.y)
|
target.x.max(target.y)
|
||||||
} else {
|
} else {
|
||||||
let size = frame.size();
|
let size = frame.size();
|
||||||
let desired = size.x.max(size.y);
|
let desired = size.x.max(size.y);
|
||||||
desired.min(regions.first.x).min(regions.first.y)
|
desired.min(regions.size.x).min(regions.size.y)
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = Size::splat(length);
|
let size = Size::splat(length);
|
||||||
let pod = Regions::one(size, size, Axes::splat(true));
|
let pod = Regions::one(size, Axes::splat(true));
|
||||||
frame = child.layout(vt, styles, pod)?.into_frame();
|
frame = child.layout(vt, styles, pod)?.into_frame();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// The default size that a shape takes on if it has no child and
|
// The default size that a shape takes on if it has no child and
|
||||||
// enough space.
|
// enough space.
|
||||||
let mut size = Size::new(Abs::pt(45.0), Abs::pt(30.0)).min(regions.first);
|
let mut size = Size::new(Abs::pt(45.0), Abs::pt(30.0)).min(regions.size);
|
||||||
|
|
||||||
if kind.is_quadratic() {
|
if kind.is_quadratic() {
|
||||||
let length = if regions.expand.x || regions.expand.y {
|
let length = if regions.expand.x || regions.expand.y {
|
||||||
let target = regions.expand.select(regions.first, Size::zero());
|
let target = regions.expand.select(regions.size, Size::zero());
|
||||||
target.x.max(target.y)
|
target.x.max(target.y)
|
||||||
} else {
|
} else {
|
||||||
size.x.min(size.y)
|
size.x.min(size.y)
|
||||||
};
|
};
|
||||||
size = Size::splat(length);
|
size = Size::splat(length);
|
||||||
} else {
|
} else {
|
||||||
size = regions.expand.select(regions.first, size);
|
size = regions.expand.select(regions.size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
frame = Frame::new(size);
|
frame = Frame::new(size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user