Add move function

This commit is contained in:
Laurenz 2021-10-28 16:51:57 +02:00
parent 5c534fb428
commit d1ecb7e52e
4 changed files with 57 additions and 3 deletions

View File

@ -143,7 +143,7 @@ pub fn v(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
}
/// `box`: Place content in a rectangular box.
pub fn boxed(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
pub fn box_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let fill = args.named("fill")?;
@ -191,6 +191,48 @@ pub fn pad(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
})))
}
/// `move`: Move content without affecting layout.
pub fn move_(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
#[derive(Debug, Hash)]
struct MoveNode {
offset: Spec<Option<Linear>>,
child: ShapeNode,
}
impl InlineLevel for MoveNode {
fn layout(&self, ctx: &mut LayoutContext, space: Length, base: Size) -> Frame {
let offset = Point::new(
self.offset.x.map(|x| x.resolve(base.w)).unwrap_or_default(),
self.offset.y.map(|y| y.resolve(base.h)).unwrap_or_default(),
);
let mut frame = self.child.layout(ctx, space, base);
for (point, _) in &mut frame.children {
*point += offset;
}
frame
}
}
let x = args.named("x")?;
let y = args.named("y")?;
let body: Template = args.expect("body")?;
Ok(Value::Template(Template::from_inline(move |style| {
MoveNode {
offset: Spec::new(x, y),
child: ShapeNode {
shape: ShapeKind::Rect,
width: None,
height: None,
fill: None,
child: Some(body.to_stack(style).pack()),
},
}
})))
}
/// `stack`: Stack children along an axis.
pub fn stack(_: &mut EvalContext, args: &mut Args) -> TypResult<Value> {
enum Child {

View File

@ -20,7 +20,7 @@ use crate::diag::{At, TypResult};
use crate::eval::{Args, Array, EvalContext, Scope, Str, Template, Value};
use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric};
use crate::geom::*;
use crate::layout::{BlockLevel, Spacing};
use crate::layout::{BlockLevel, Frame, InlineLevel, LayoutContext, Spacing};
use crate::style::Style;
use crate::syntax::{Span, Spanned};
@ -43,9 +43,10 @@ pub fn new() -> Scope {
std.def_func("h", h);
std.def_func("v", v);
std.def_func("align", align);
std.def_func("box", boxed);
std.def_func("box", box_);
std.def_func("block", block);
std.def_func("pad", pad);
std.def_func("move", move_);
std.def_func("stack", stack);
std.def_func("grid", grid);

BIN
tests/ref/layout/move.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

11
tests/typ/layout/move.typ Normal file
View File

@ -0,0 +1,11 @@
#let size = 11pt
#let tex = [{
[T]
h(-0.14 * size)
move(y: 0.22 * size)[E]
h(-0.12 * size)
[X]
}]
#font("Latin Modern Math", size)
Not #tex!