mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Fix panic due to bad alignments in stack function
This commit is contained in:
parent
ff37a2893d
commit
e10b3d838a
@ -181,13 +181,13 @@ pub fn div(lhs: Value, rhs: Value) -> StrResult<Value> {
|
|||||||
(Relative(a), Float(b)) => Relative(a / b),
|
(Relative(a), Float(b)) => Relative(a / b),
|
||||||
(Relative(a), Relative(b)) => Float(a / b),
|
(Relative(a), Relative(b)) => Float(a / b),
|
||||||
|
|
||||||
|
(Linear(a), Int(b)) => Linear(a / b as f64),
|
||||||
|
(Linear(a), Float(b)) => Linear(a / b),
|
||||||
|
|
||||||
(Fractional(a), Int(b)) => Fractional(a / b as f64),
|
(Fractional(a), Int(b)) => Fractional(a / b as f64),
|
||||||
(Fractional(a), Float(b)) => Fractional(a / b),
|
(Fractional(a), Float(b)) => Fractional(a / b),
|
||||||
(Fractional(a), Fractional(b)) => Float(a / b),
|
(Fractional(a), Fractional(b)) => Float(a / b),
|
||||||
|
|
||||||
(Linear(a), Int(b)) => Linear(a / b as f64),
|
|
||||||
(Linear(a), Float(b)) => Linear(a / b),
|
|
||||||
|
|
||||||
(a, b) => mismatch!("cannot divide {} by {}", a, b),
|
(a, b) => mismatch!("cannot divide {} by {}", a, b),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,9 @@ impl From<ParNode> for LayoutNode {
|
|||||||
impl Debug for ParChild {
|
impl Debug for ParChild {
|
||||||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ParChild::Spacing(v) => write!(f, "Spacing({:?})", v),
|
Self::Spacing(v) => write!(f, "Spacing({:?})", v),
|
||||||
ParChild::Text(text, ..) => write!(f, "Text({:?})", text),
|
Self::Text(text, ..) => write!(f, "Text({:?})", text),
|
||||||
ParChild::Any(node, ..) => f.debug_tuple("Any").field(node).finish(),
|
Self::Any(node, ..) => node.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::fmt::{self, Debug, Formatter};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
/// A node that stacks its children.
|
/// A node that stacks its children.
|
||||||
@ -14,7 +16,6 @@ pub struct StackNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A child of a stack node.
|
/// A child of a stack node.
|
||||||
#[derive(Debug)]
|
|
||||||
#[cfg_attr(feature = "layout-cache", derive(Hash))]
|
#[cfg_attr(feature = "layout-cache", derive(Hash))]
|
||||||
pub enum StackChild {
|
pub enum StackChild {
|
||||||
/// Spacing between other nodes.
|
/// Spacing between other nodes.
|
||||||
@ -39,6 +40,15 @@ impl From<StackNode> for LayoutNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Debug for StackChild {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Spacing(v) => write!(f, "Spacing({:?})", v),
|
||||||
|
Self::Any(node, _) => node.fmt(f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Performs stack layout.
|
/// Performs stack layout.
|
||||||
struct StackLayouter<'a> {
|
struct StackLayouter<'a> {
|
||||||
/// The stack node to layout.
|
/// The stack node to layout.
|
||||||
|
@ -192,11 +192,6 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
let children: Vec<Template> = args.all().collect();
|
let children: Vec<Template> = args.all().collect();
|
||||||
|
|
||||||
Ok(Value::Template(Template::from_block(move |state| {
|
Ok(Value::Template(Template::from_block(move |state| {
|
||||||
let children = children
|
|
||||||
.iter()
|
|
||||||
.map(|child| StackChild::Any(child.to_stack(state).into(), state.aligns))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let mut dirs = Gen::new(None, dir).unwrap_or(state.dirs);
|
let mut dirs = Gen::new(None, dir).unwrap_or(state.dirs);
|
||||||
|
|
||||||
// If the directions become aligned, fix up the inline direction since
|
// If the directions become aligned, fix up the inline direction since
|
||||||
@ -205,6 +200,19 @@ pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
dirs.inline = state.dirs.block;
|
dirs.inline = state.dirs.block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use the current alignments for all children, but take care to apply
|
||||||
|
// them to the correct axes (by swapping them if the stack axes are
|
||||||
|
// different from the state axes).
|
||||||
|
let mut aligns = state.aligns;
|
||||||
|
if dirs.block.axis() == state.dirs.inline.axis() {
|
||||||
|
aligns = Gen::new(aligns.block, aligns.inline);
|
||||||
|
}
|
||||||
|
|
||||||
|
let children = children
|
||||||
|
.iter()
|
||||||
|
.map(|child| StackChild::Any(child.to_stack(state).into(), aligns))
|
||||||
|
.collect();
|
||||||
|
|
||||||
StackNode { dirs, children }
|
StackNode { dirs, children }
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
@ -233,9 +241,6 @@ pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Ok(Value::Template(Template::from_block(move |state| {
|
Ok(Value::Template(Template::from_block(move |state| {
|
||||||
let children =
|
|
||||||
children.iter().map(|child| child.to_stack(&state).into()).collect();
|
|
||||||
|
|
||||||
// If the directions become aligned, try to fix up the direction which
|
// If the directions become aligned, try to fix up the direction which
|
||||||
// is not user-defined.
|
// is not user-defined.
|
||||||
let mut dirs = Gen::new(column_dir, row_dir).unwrap_or(state.dirs);
|
let mut dirs = Gen::new(column_dir, row_dir).unwrap_or(state.dirs);
|
||||||
@ -253,6 +258,9 @@ pub fn grid(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let children =
|
||||||
|
children.iter().map(|child| child.to_stack(&state).into()).collect();
|
||||||
|
|
||||||
GridNode {
|
GridNode {
|
||||||
dirs,
|
dirs,
|
||||||
tracks: tracks.clone(),
|
tracks: tracks.clone(),
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 325 B After Width: | Height: | Size: 318 B |
@ -1,18 +1,32 @@
|
|||||||
// Test stack layouts.
|
// Test stack layouts.
|
||||||
|
|
||||||
---
|
---
|
||||||
#let rect(width, fill) = rect(width: width, height: 1cm, fill: fill)
|
// Test stacks with different directions.
|
||||||
#stack(
|
#let widths = (
|
||||||
rect(2cm, rgb("2a631a")),
|
30pt, 20pt, 40pt, 15pt,
|
||||||
rect(3cm, forest),
|
30pt, 50%, 20pt, 100%,
|
||||||
rect(1cm, conifer),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#let shaded = {
|
||||||
|
let v = 0
|
||||||
|
let next() = { v += 0.1; rgb(v, v, v) }
|
||||||
|
w => rect(width: w, height: 10pt, fill: next())
|
||||||
|
}
|
||||||
|
|
||||||
|
#let items = for w in widths { (shaded(w),) }
|
||||||
|
|
||||||
|
#align(right)
|
||||||
|
#page(width: 50pt, margins: 0pt)
|
||||||
|
#stack(dir: btt, ..items)
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
// Currently stack works like flexbox apparently.
|
||||||
|
#stack(dir: ltr, ..items)
|
||||||
|
|
||||||
---
|
---
|
||||||
// Test overflowing stack.
|
// Test overflowing stack.
|
||||||
|
#page(width: 50pt, height: 30pt, margins: 0pt)
|
||||||
#let rect(width, fill) = rect(width: 1cm, height: 0.4cm, fill: fill)
|
#box(stack(
|
||||||
#box(height: 0.5cm, stack(
|
rect(width: 40pt, height: 20pt, fill: conifer),
|
||||||
rect(3cm, forest),
|
rect(width: 30pt, height: 13pt, fill: forest),
|
||||||
rect(1cm, conifer),
|
|
||||||
))
|
))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user