From a41330caa99423266b119242214e4329887d4af2 Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Sun, 13 Oct 2024 00:51:19 +0200 Subject: [PATCH 1/4] canvas: Support custom coordinate systems --- src/canvas.typ | 4 +++- src/coordinate.typ | 16 ++++++++++++--- src/draw/grouping.typ | 1 - src/draw/shapes.typ | 33 +----------------------------- src/draw/transformations.typ | 4 ---- src/lib/decorations/brace.typ | 6 ------ tests/coordinate/custom/ref/1.png | Bin 0 -> 6146 bytes tests/coordinate/custom/test.typ | 29 ++++++++++++++++++++++++++ 8 files changed, 46 insertions(+), 47 deletions(-) create mode 100644 tests/coordinate/custom/ref/1.png create mode 100644 tests/coordinate/custom/test.typ diff --git a/src/canvas.typ b/src/canvas.typ index 57c7df766..0c6fe55b1 100644 --- a/src/canvas.typ +++ b/src/canvas.typ @@ -58,7 +58,9 @@ marks: ( mnemonics: (:), marks: (:), - ) + ), + // coordinate resolver + resolve-coordinate: none, ) let (ctx, bounds, drawables) = process.many(ctx, body) diff --git a/src/coordinate.typ b/src/coordinate.typ index 7bd23113e..078191e26 100644 --- a/src/coordinate.typ +++ b/src/coordinate.typ @@ -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() @@ -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 { @@ -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" { diff --git a/src/draw/grouping.typ b/src/draw/grouping.typ index d3dc791fa..c2038201d 100644 --- a/src/draw/grouping.typ +++ b/src/draw/grouping.typ @@ -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) diff --git a/src/draw/shapes.typ b/src/draw/shapes.typ index f52779cb5..7052a7a82 100644 --- a/src/draw/shapes.typ +++ b/src/draw/shapes.typ @@ -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) @@ -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. @@ -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") @@ -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) = { @@ -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 @@ -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() @@ -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) @@ -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(), @@ -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) @@ -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") @@ -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") diff --git a/src/draw/transformations.typ b/src/draw/transformations.typ index b8c07f020..7c9c748d7 100644 --- a/src/draw/transformations.typ +++ b/src/draw/transformations.typ @@ -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) @@ -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)) diff --git a/src/lib/decorations/brace.typ b/src/lib/decorations/brace.typ index 5571d38f4..4b9765299 100644 --- a/src/lib/decorations/brace.typ +++ b/src/lib/decorations/brace.typ @@ -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) @@ -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(), diff --git a/tests/coordinate/custom/ref/1.png b/tests/coordinate/custom/ref/1.png new file mode 100644 index 0000000000000000000000000000000000000000..c179a466e152aa41cb70f9b06a8b8de91980d948 GIT binary patch literal 6146 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 literal 0 HcmV?d00001 diff --git a/tests/coordinate/custom/test.typ b/tests/coordinate/custom/test.typ new file mode 100644 index 000000000..930f6c00b --- /dev/null +++ b/tests/coordinate/custom/test.typ @@ -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)) + } +}) From 0f3372c3e1cfeaeb778193574d2e053bad6c40cc Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Sun, 13 Oct 2024 17:01:07 +0200 Subject: [PATCH 2/4] coordinate: Clean up resolve function --- src/coordinate.typ | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/coordinate.typ b/src/coordinate.typ index 078191e26..382b2e9a2 100644 --- a/src/coordinate.typ +++ b/src/coordinate.typ @@ -322,17 +322,21 @@ /// - 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 resolver = () + if type(ctx.resolve-coordinate) == array { + resolver += ctx.resolve-coordinate + } else if type(ctx.resolve-coordinate) == function { + resolver.push(ctx.resolve-coordinate) } let result = () - for c in coordinates { + for c in coordinates.pos() { + for i in range(1, resolver.len() + 1) { + c = (resolver.at(resolver.len() - i))(ctx, c) + } + let t = resolve-system(ctx, c) - let out = if t == "xyz" { + c = if t == "xyz" { resolve-xyz(c) } else if t == "previous" { ctx.prev.pt @@ -358,9 +362,10 @@ }.map(util.resolve-number.with(ctx)) if update { - ctx.prev.pt = out + ctx.prev.pt = c } - result.push(out) + + result.push(c) } return (ctx, ..result) From c22d5061955999e714761b97a3433890fdd13a0b Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Sun, 13 Oct 2024 17:17:30 +0200 Subject: [PATCH 3/4] coordinate: Add register function --- src/coordinate.typ | 9 ++++---- src/draw.typ | 2 +- src/draw/util.typ | 38 ++++++++++++++++++++++++++++++++ tests/coordinate/custom/test.typ | 5 +---- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/coordinate.typ b/src/coordinate.typ index 382b2e9a2..725d4f9ae 100644 --- a/src/coordinate.typ +++ b/src/coordinate.typ @@ -322,11 +322,10 @@ /// - update (bool): Update the context's last position /// -> array #let resolve(ctx, ..coordinates, update: true) = { - let resolver = () - if type(ctx.resolve-coordinate) == array { - resolver += ctx.resolve-coordinate - } else if type(ctx.resolve-coordinate) == function { - resolver.push(ctx.resolve-coordinate) + let resolver = if type(ctx.resolve-coordinate) == array { + ctx.resolve-coordinate + } else { + () } let result = () diff --git a/src/draw.typ b/src/draw.typ index e46b87de9..cef4e6d2d 100644 --- a/src/draw.typ +++ b/src/draw.typ @@ -3,4 +3,4 @@ #import "draw/styling.typ": set-style, fill, stroke, register-mark #import "draw/shapes.typ": circle, circle-through, arc, arc-through, mark, line, grid, content, rect, bezier, bezier-through, catmull, hobby, merge-path #import "draw/projection.typ": ortho, on-xy, on-xz, on-yz -#import "draw/util.typ": assert-version +#import "draw/util.typ": assert-version, register-coordinate-resolver diff --git a/src/draw/util.typ b/src/draw/util.typ index 3f2c0d1df..3d4a99cb6 100644 --- a/src/draw/util.typ +++ b/src/draw/util.typ @@ -18,3 +18,41 @@ return (ctx: ctx) },) } + +/// Push a custom coordinate resolve function to the list of coordinate +/// resolvers. This resolver is scoped to the current context scope! +/// +/// A coordinate resolver must be a function of the format `(context, coordinate) => coordinate`. And must _always_ return a valid coordinate or panic, in case of an error. +/// +/// If multiple resolvers are registered, coordinates get passed through all +/// resolvers in reverse registering order. All coordinates get paased to cetz' +/// default coordinate resolvers. +/// +/// ```typc example +/// register-coordinate-resolver((ctx, c) => { +/// if type(c) == dictionary and "log" in c { +/// c = c.log.map(n => calc.log(n, base: 10)) +/// } +/// return c +/// }) +/// +/// circle((log: (10, 0)), radius: .25) +/// circle((log: (100, 0)), radius: .25) +/// circle((log: (1000, 0)), radius: .25) +/// ``` +/// +/// - resolver (function): The resolver function, taking a context and a single coordinate and returning a single coordinate +#let register-coordinate-resolver(resolver) = { + assert.eq(type(resolver), function, + message: "Coordinate resolver must be of type function (ctx, coordinate) => coordinate.") + + return (ctx => { + if type(ctx.resolve-coordinate) == array { + ctx.resolve-coordinate.push(resolver) + } else { + ctx.resolve-coordinate = (resolver,) + } + + return (ctx: ctx) + },) +} diff --git a/tests/coordinate/custom/test.typ b/tests/coordinate/custom/test.typ index 930f6c00b..0c2137946 100644 --- a/tests/coordinate/custom/test.typ +++ b/tests/coordinate/custom/test.typ @@ -15,10 +15,7 @@ return coordinate } - set-ctx(ctx => { - ctx.resolve-coordinate = log-resolver - return ctx - }) + register-coordinate-resolver(log-resolver) set-style(circle: (radius: .1)) for i in (.1, 1, 10, 100, 1000, 10000) { From 645b1114db49e99c9487dfa8cb6179248256fbb2 Mon Sep 17 00:00:00 2001 From: Johannes Wolf Date: Fri, 18 Oct 2024 13:37:14 +0200 Subject: [PATCH 4/4] coordinate: Fixups --- src/coordinate.typ | 9 +++------ tests/coordinate/custom/ref/1.png | Bin 6146 -> 6166 bytes 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/coordinate.typ b/src/coordinate.typ index 725d4f9ae..2fe937e53 100644 --- a/src/coordinate.typ +++ b/src/coordinate.typ @@ -294,9 +294,6 @@ } else { "element" } - } else if ctx.at("resolve-system", default: none) != none { - ctx.resolve-system = none - resolve-system(ctx, c) } if t == none { @@ -322,7 +319,7 @@ /// - update (bool): Update the context's last position /// -> array #let resolve(ctx, ..coordinates, update: true) = { - let resolver = if type(ctx.resolve-coordinate) == array { + let resolvers = if type(ctx.resolve-coordinate) == array { ctx.resolve-coordinate } else { () @@ -330,8 +327,8 @@ let result = () for c in coordinates.pos() { - for i in range(1, resolver.len() + 1) { - c = (resolver.at(resolver.len() - i))(ctx, c) + for resolver in resolvers.rev() { + c = resolver(ctx, c) } let t = resolve-system(ctx, c) diff --git a/tests/coordinate/custom/ref/1.png b/tests/coordinate/custom/ref/1.png index c179a466e152aa41cb70f9b06a8b8de91980d948..10c1cd30780e9f20f1d29ac573143966290efba0 100644 GIT binary patch delta 4422 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 GB>Wehu>vgs delta 4396 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