Skip to content

Commit

Permalink
canvas: Support custom coordinate systems
Browse files Browse the repository at this point in the history
  • Loading branch information
johannes-wolf committed Oct 12, 2024
1 parent 57a73be commit d14797a
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 47 deletions.
4 changes: 3 additions & 1 deletion src/canvas.typ
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@
marks: (
mnemonics: (:),
marks: (:),
)
),
// coordinate resolver
resolve-coordinate: none,
)

let (ctx, bounds, drawables) = process.many(ctx, body)
Expand Down
16 changes: 13 additions & 3 deletions src/coordinate.typ
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@
/// Figures out what system a coordinate belongs to and returns the corresponding string.
/// - c (coordinate): The coordinate to find the system of.
/// -> str
#let resolve-system(c) = {
#let resolve-system(ctx, c) = {
let t = if type(c) == dictionary {
let keys = c.keys()
let len = c.len()
Expand Down Expand Up @@ -294,6 +294,9 @@
} else {
"element"
}
} else if ctx.at("resolve-system", default: none) != none {
ctx.resolve-system = none
resolve-system(ctx, c)
}

if t == none {
Expand All @@ -319,9 +322,16 @@
/// - update (bool): Update the context's last position
/// -> array
#let resolve(ctx, ..coordinates, update: true) = {
let ctx-resolver = ctx.at("resolve-coordinate", default: none)
let coordinates = if ctx-resolver != none {
coordinates.pos().map(ctx-resolver.with(ctx))
} else {
coordinates.pos()
}

let result = ()
for c in coordinates.pos() {
let t = resolve-system(c)
for c in coordinates {
let t = resolve-system(ctx, c)
let out = if t == "xyz" {
resolve-xyz(c)
} else if t == "previous" {
Expand Down
1 change: 0 additions & 1 deletion src/draw/grouping.typ
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@
assert(name != none and name != "" and not name.starts-with("."),
message: "Anchors must not be none, \"\" or start with \".\"!")

coordinate.resolve-system(position)
return (ctx => {
let (ctx, position) = coordinate.resolve(ctx, position)
position = util.apply-transform(ctx.transform, position)
Expand Down
33 changes: 1 addition & 32 deletions src/draw/shapes.typ
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@
assert.eq(style.pos(), (), message: "Unexpected positional arguments: " + repr(style.pos()))
style = style.named()

(a, b, c).map(coordinate.resolve-system)

return (ctx => {
let (ctx, a, b, c) = coordinate.resolve(ctx, a, b, c)

Expand Down Expand Up @@ -220,9 +218,6 @@
)
let style = style.named()

// Coordinate check
let t = coordinate.resolve-system(position)

let start-angle = if start == auto { stop - delta } else { start }
let stop-angle = if stop == auto { start + delta } else { stop }
// Border angles can break if the angle is 0.
Expand Down Expand Up @@ -445,8 +440,6 @@
to = ((rel: (to, 1), to: from))
}

(from, to).map(coordinate.resolve-system)

return (ctx => {
let (ctx, ..pts) = coordinate.resolve(ctx, from, to)
let style = styles.resolve(ctx.style, merge: style, root: "mark")
Expand Down Expand Up @@ -506,9 +499,6 @@

assert(pts.len() >= 2, message: "Line must have a minimum of two points")

// Coordinate check
let pts-system = pts.map(coordinate.resolve-system)

// Find the intersection between line a-b next to b
// if no intersection could be found, return a.
let element-line-intersection(ctx, elem, a, b) = {
Expand All @@ -534,6 +524,7 @@
return (ctx => {
let first-elem = pts.first()
let last-elem = pts.last()
let pts-system = pts.map(coordinate.resolve-system.with(ctx))
let (ctx, ..pts) = coordinate.resolve(ctx, ..pts)

// If the first/last element, test for intersection
Expand Down Expand Up @@ -610,8 +601,6 @@
/// ## Anchors
/// Supports border anchors.
#let grid(from, to, name: none, ..style) = {
(from, to).map(coordinate.resolve-system)

assert.eq(style.pos(), (), message: "Unexpected positional arguments: " + repr(style.pos()))
style = style.named()

Expand Down Expand Up @@ -770,16 +759,6 @@
panic("Expected 2 or 3 positional arguments, got " + str(args.len()))
}

coordinate.resolve-system(a)

if b != auto {
coordinate.resolve-system(b)
}

if type(angle) != typst-angle {
coordinate.resolve-system(angle)
}

return (ctx => {
let style = styles.resolve(ctx.style, merge: style, root: "content")
let padding = util.as-padding-dict(style.padding)
Expand Down Expand Up @@ -1016,9 +995,6 @@
/// Supports border and path anchors. It's default is the `"center"` anchor.
///
#let rect(a, b, name: none, anchor: none, ..style) = {
// Coordinate check
let t = (a, b).map(coordinate.resolve-system)

// No extra positional arguments from the style sink
assert.eq(
style.pos(),
Expand Down Expand Up @@ -1208,9 +1184,6 @@
)
let coordinates = (start, ..ctrl, end)

// Coordinates check
let t = coordinates.map(coordinate.resolve-system)

return (
ctx => {
let (ctx, start, ..ctrl, end) = coordinate.resolve(ctx, ..coordinates)
Expand Down Expand Up @@ -1310,8 +1283,6 @@

assert(pts.len() >= 2, message: "Catmull-rom curve requires at least two points. Got " + repr(pts.len()) + "instead.")

pts.map(coordinate.resolve-system)

return (ctx => {
let (ctx, ..pts) = coordinate.resolve(ctx, ..pts)
let style = styles.resolve(ctx.style, merge: style, root: "catmull")
Expand Down Expand Up @@ -1385,8 +1356,6 @@

assert(pts.len() >= 2, message: "Hobby curve requires at least two points. Got " + repr(pts.len()) + "instead.")

pts.map(coordinate.resolve-system)

return (ctx => {
let (ctx, ..pts) = coordinate.resolve(ctx, ..pts)
let style = styles.resolve(ctx.style, merge: style, root: "hobby")
Expand Down
4 changes: 0 additions & 4 deletions src/draw/transformations.typ
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,6 @@
///
/// - pt (coordinate): The coordinate to move to.
#let move-to(pt) = {
let t = coordinate.resolve-system(pt)

return (ctx => {
let (ctx, pt) = coordinate.resolve(ctx, pt)
return (ctx: ctx)
Expand All @@ -244,8 +242,6 @@
/// - bounds (vector): Viewport bounds vector that describes the inner width,
/// height and depth of the viewport
#let set-viewport(from, to, bounds: (1, 1, 1)) = {
(from, to).map(coordinate.resolve-system)

return (ctx => {
let bounds = vector.as-vec(bounds, init: (1, 1, 1))

Expand Down
6 changes: 0 additions & 6 deletions src/lib/decorations/brace.typ
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@
assert.eq(style.pos().len(), 0,
message: "Brace takes no additional positional arugments.")

// Validate coordinates
let _ = (start, end).map(coordinate.resolve-system)

group(name: name, ctx => {
// Resolve all coordinates
let (ctx, start, end) = coordinate.resolve(ctx, start, end)
Expand Down Expand Up @@ -195,9 +192,6 @@
name: none,
..style,
) = {
// Validate coordinates
let _ = (start, end).map(coordinate.resolve-system)

group(name: name, ctx => {
// Get styles and validate their types and values
let style = styles.resolve(ctx.style, merge: style.named(),
Expand Down
Binary file added tests/coordinate/custom/ref/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions tests/coordinate/custom/test.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#set page(width: auto, height: auto)
#import "/src/lib.typ": *
#import "/tests/helper.typ": *

#test-case({
import draw: *
grid((-2,-1), (7,1), stroke: gray)

let log-resolver(ctx, coordinate) = {
if type(coordinate) == dictionary and "log" in coordinate {
coordinate = coordinate.log
coordinate = coordinate.map(n => calc.log(calc.max(n, util.float-epsilon), base: 10))
}

return coordinate
}

set-ctx(ctx => {
ctx.resolve-coordinate = log-resolver
return ctx
})

set-style(circle: (radius: .1))
for i in (.1, 1, 10, 100, 1000, 10000) {
let pt = (log: (i * 1, 1))
circle(pt)
content(pt, repr(i), anchor: "north", padding: (top: .5))
}
})

0 comments on commit d14797a

Please sign in to comment.