From b55f085e024e35775e54047d05ec579658ccfc6e Mon Sep 17 00:00:00 2001 From: Johannes Wolf <519002+johannes-wolf@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:37:03 +0100 Subject: [PATCH] mark: Support placing marks post-transform (#493) This allows placing marks _after_ the path got transformed. Use-Case: drawing marks on scaled paths, drawing marks insides plots (which use a scaled viewport). The behavior is disabled by default and can be enabled by setting marks `post-transform` style key to `true`. Maybe the implementation has too much copied code, but doing the transform insides `mark.typ` is also not that clean I think. --- CHANGES.md | 11 ++++-- manual.typ | 1 + src/draw/shapes.typ | 56 +++++++++++---------------- src/drawable.typ | 8 +++- src/lib/plot/annotation.typ | 5 ++- src/mark.typ | 23 ++++++++++- src/styles.typ | 4 ++ tests/mark/shape-transform/ref/1.png | Bin 0 -> 5008 bytes tests/mark/shape-transform/test.typ | 29 ++++++++++++++ tests/plot/annotation/ref/1.png | Bin 18260 -> 18589 bytes tests/plot/annotation/test.typ | 3 ++ 11 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 tests/mark/shape-transform/ref/1.png create mode 100644 tests/mark/shape-transform/test.typ diff --git a/CHANGES.md b/CHANGES.md index ee59a95e..b03ebb97 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,14 +7,19 @@ - Open arcs are no longer modified for anchors, invalid border anchors will panic. - Grids now actually support border anchors. +## Marks +- Marks can now be placed on a path after that path got transformed. See the new `transform-shape` style key. + +## Misc +- The `hide` function now support an additional `bounds:` parameter to enable canvas bounds adjustment for hidden elements + ## Libs ### Plot - The default style of plots changed - New style keys for enabling/disabling the shared zero tick for "school-book" style plots - New style keys for specifying the layer of different plot elements (`grid-layer`, `axis-layer`, `background-layer`) - -## Misc -- The `hide` function now support an additional `bounds:` parameter to enable canvas bounds adjustment for hidden elements +- Fixed annotation bounds calculation +- Marks insides annotations are now unaffected by the plots canvas scaling by default (see marks new post-transform style key) # 0.2.0 CeTZ 0.2.0 requires Typst 0.10.0 diff --git a/manual.typ b/manual.typ index dfe29f2d..09a65aa1 100644 --- a/manual.typ +++ b/manual.typ @@ -278,6 +278,7 @@ line(..c) #doc-style.show-parameter-block("shorten-to", ("integer", "auto", "none"), [Which mark to shorten the path to when multiple marks are given. `auto` will shorten to the last mark, `none` will shorten to the first mark (effectively disabling path shortening). An integer can be given to select the mark's index.]) +#doc-style.show-parameter-block("transform-shape", "bool", [When false marks will not be streched/affected by the current transformation, marks will be placed after the path is transformed.], default: true) #pagebreak() diff --git a/src/draw/shapes.typ b/src/draw/shapes.typ index 617c80f5..03fe0fdc 100644 --- a/src/draw/shapes.typ +++ b/src/draw/shapes.typ @@ -313,19 +313,16 @@ ) if mark_.check-mark(style.mark) { - let (marks, segments) = mark_.place-marks-along-path(ctx, style.mark, drawables.segments) - drawables.segments = segments - drawables = (drawables,) + marks + drawables = mark_.place-marks-along-path(ctx, style.mark, transform, drawables) + } else { + drawables = drawable.apply-transform(transform, drawables) } return ( ctx: ctx, name: name, anchors: anchors, - drawables: drawable.apply-transform( - transform, - drawables, - ) + drawables: drawables, ) },) } @@ -457,8 +454,8 @@ style.start = none style.symbol = none - let segments = (path-util.line-segment(pts),) - let (drawables, _) = mark_.place-marks-along-path(ctx, style, segments) + let drawables = drawable.path((path-util.line-segment(pts),)) + drawables = mark_.place-marks-along-path(ctx, style, none, drawables, add-path: false) return ( ctx: ctx, drawables: drawable.apply-transform(ctx.transform, drawables) @@ -568,16 +565,16 @@ // Place marks and adjust segments if mark_.check-mark(style.mark) { - let (marks, segments) = mark_.place-marks-along-path(ctx, style.mark, drawables.segments) - drawables.segments = segments - drawables = (drawables,) + marks + drawables = mark_.place-marks-along-path(ctx, style.mark, transform, drawables) + } else { + drawables = drawable.apply-transform(transform, drawables) } return ( ctx: ctx, name: name, anchors: anchors, - drawables: drawable.apply-transform(transform, drawables) + drawables: drawables, ) },) } @@ -1197,19 +1194,16 @@ ) if mark_.check-mark(style.mark) { - let (marks, segments) = mark_.place-marks-along-path(ctx, style.mark, drawables.segments) - drawables.segments = segments - drawables = (drawables,) + marks + drawables = mark_.place-marks-along-path(ctx, style.mark, transform, drawables) + } else { + drawables = drawable.apply-transform(transform, drawables) } return ( ctx: ctx, name: name, anchors: anchors, - drawables: drawable.apply-transform( - transform, - drawables - ) + drawables: drawables, ) }, ) @@ -1305,19 +1299,16 @@ } if mark_.check-mark(style.mark) { - let (marks, segments) = mark_.place-marks-along-path(ctx, style.mark, drawables.segments) - drawables.segments = segments - drawables = (drawables,) + marks + drawables = mark_.place-marks-along-path(ctx, style.mark, transform, drawables) + } else { + drawables = drawable.apply-transform(transform, drawables) } return ( ctx: ctx, name: name, anchors: anchors, - drawables: drawable.apply-transform( - transform, - drawables - ) + drawables: drawables, ) },) } @@ -1391,19 +1382,16 @@ } if mark_.check-mark(style.mark) { - let (marks, segments) = mark_.place-marks-along-path(ctx, style.mark, drawables.segments) - drawables.segments = segments - drawables = (drawables,) + marks + drawables = mark_.place-marks-along-path(ctx, style.mark, transform, drawables) + } else { + drawables = drawable.apply-transform(transform, drawables) } return ( ctx: ctx, name: name, anchors: anchors, - drawables: drawable.apply-transform( - transform, - drawables - ) + drawables: drawables, ) },) } diff --git a/src/drawable.typ b/src/drawable.typ index 0928cc1f..2c768e34 100644 --- a/src/drawable.typ +++ b/src/drawable.typ @@ -10,12 +10,16 @@ if drawables.len() == 0 { return () } + if transform == none { + return drawables + } for drawable in drawables { assert(type(drawable) != array, message: "Expected drawable, got array: " + repr(drawable)) if drawable.type == "path" { - drawable.segments = drawable.segments.map(s => { - return (s.at(0),) + util.apply-transform(transform, ..s.slice(1)) + drawable.segments = drawable.segments.map(segment => { + let (kind, ..pts) = segment + return (kind,) + util.apply-transform(transform, ..pts) }) } else if drawable.type == "content" { drawable.pos = util.apply-transform(transform, drawable.pos) diff --git a/src/lib/plot/annotation.typ b/src/lib/plot/annotation.typ index 66df17f1..1dcddb06 100644 --- a/src/lib/plot/annotation.typ +++ b/src/lib/plot/annotation.typ @@ -36,7 +36,10 @@ #let annotate(body, axes: ("x", "y"), resize: true, padding: none, background: false) = { (( type: "annotation", - body: body, + body: { + draw.set-style(mark: (transform-shape: false)) + body; + }, axes: axes, resize: resize, background: background, diff --git a/src/mark.typ b/src/mark.typ index 83872ba9..fa5f2099 100644 --- a/src/mark.typ +++ b/src/mark.typ @@ -255,10 +255,18 @@ ) } -#let place-marks-along-path(ctx, style, segments) = { +#let place-marks-along-path(ctx, style, transform, path, add-path: true) = { let distance = (0, 0) let snap-to = (none, none) let drawables = () + + let (path, is-transformed) = if not style.transform-shape and transform != none { + (drawable.apply-transform(transform, path).first(), true) + } else { + (path, false) + } + + let segments = path.segments if style.start != none or style.symbol != none { let (drawables: start-drawables, distance: start-distance, pos: pt) = place-mark-on-path( ctx, @@ -289,5 +297,16 @@ snap-to: snap-to) } - return (drawables, segments) + if add-path { + path.segments = segments + drawables.insert(0, path) + } + + // If not transformed pre mark placement, + // transform everything after mark placement. + if not is-transformed { + drawables = drawable.apply-transform(transform, drawables) + } + + return drawables } diff --git a/src/styles.typ b/src/styles.typ index 6b9ac600..8506e761 100644 --- a/src/styles.typ +++ b/src/styles.typ @@ -45,6 +45,10 @@ /// set the default to `0` and to `auto` for the mark you want to /// shorten the path to. Set to `none` to disable path shortening. shorten-to: auto, + /// Apply shape transforms for marks. This is not honored per mark, but + /// for all marks on a path. If set to false, marks get placed after the + /// shape they are placed on got transformed. + transform-shape: true, ), circle: ( radius: auto, diff --git a/tests/mark/shape-transform/ref/1.png b/tests/mark/shape-transform/ref/1.png new file mode 100644 index 0000000000000000000000000000000000000000..a057d4e8393737395facefa14cd0c6311a52ed54 GIT binary patch literal 5008 zcmeHKeLRzU8=o>S%X^lW!%A zQc_Av3TSd%w1GYZqWs1M<4BI~e|b9|ut6AkA9-rLMIih?UcvlupJzoQ5C!&NJN1Wt zEbg9}djQAEb?siukOW;LA9Eyb$7)1~vyz}#Qf)L&Us-ZncvYF50~!iHc&Yj<4q1za za#Pl|bZ)h~*H}rzCyjXzjzif8KCWH7VLRMZL$2^4XG3vfaC*|YRC}al zf;%!)Bb;nTw=k)p1n>)Yi}=?+ciPjmPVWtqTx{OPsgP!xNzE#6MF=ED--iG5!TS zp_)fpU=u?_kG~Si!hS{}h6w1_DMZ$JHbV~vkd}y842jCf%tb5}B$|tXQE?o|f5J|{ zId7eZj9D@UHjlwIApB62ETWX-AVl(7UZcmYem)p|(`SQ*Wr@&iR{+CfTUU)s>!ckohEK}uLSh39-@Rm}km~Nv$d%i5<;JB2WRTCIxUadkzirUJbB?%1B-J>xpOhjgKeE%VK_6KU%G*;_YJj?s|9; z2FKOy%g%b@mW`cIHTdOpT3Q4%dh%UP?7qYPad96K75!6nYHjS>b&Y7S)(LWctk=6w z@713@%=J3sIH8)=$3u7`E|D@qxGCflS$IdMX@@&UY0X=~qvfktmj94MtCzsXkr(ob z5)oOPooy(5)RZiUwevSR=hRzlr+2Jw&7k$tQZ}y5BUNo=m)i52Ua1Td&M1FKz4;V# zxVj{2PQAY5+^5$mn|LAZB%Imu-ujBW>O&TUms~8tnr33MM=$X5@?j?X-r})w10&|Y z{A4SSAJN$1FgS0&SPCNS}V^f>9nMQ>qEo$d>Wx5qNKCbKwk?G0V(SC0! z71e^BvQc|><XP&yz)<-VrG4fJ+uXZ7c0rYG z`|>Z7nkJ(iPBBkjPG&y6P~MeJ(IiRcA7fxWUg-9Qzzt5Wiw`(-KK=El;U*0QK(wH$ zZ?R8{K0(zkm@qD1%9L`!;7eVbxr;SjXegF@_i1sdAugh0LgM%}(gD^BQ)vX0>~TIb zWD8YFj5KR%%IEML#+)r}Zs%+uoHujS=E&|($ykZpy@RXT-V7Iek(af#_K&z9e827f zg_Zs7jG1og6z1k&DqW|B!=RsPZjM%$o~{xU7?aS!tQ239JEqJB=874+xKS5=O=fRw zDm%n@X=|n37)O47)qZ>W($%w&N*XF=|NAW*Yp;H`uf6so>E^BFE5ox!Kb|Tx(J3A@ zDQv5goZFg{D0uz*CH0wE{WeH$6e^|(18c4(4GdUId{tebG4DJzIBKU_PExSo+~pSs zPx2yn{c*$!v1cMGbmB@Tnp@W1ZF3ApMVb0l9G;E5)N|y`hO@QdJpnpx~wE|ViSXV%=`vAK=n0?18YEL;c zsdaGo(~7Wk{te}-jbvMBJDpi(m#Fxm2y|d3EKUNZ1PHx%6OVQv{627uNU*Dy{&+It?6ixj;^zL&liP-%P$p5(D1?Jhm->97M2lRS-~* zC=ksJ6v3EFz#d|+Xgfm^x+DvDRS1Ns8;FCY#LNsw57CB{jL+P>9j_l?3(#B~GtPbm z_)|~m1MjW|q&!lhCGFEQwi_@j)S~c$w07-cCquwYvxGlL!T~ELgC|jBATduX(k@X@ zNI?}aM8FKV((*qz0udp>MN4{?3y2^+06pWZEY^1NF62(ux`W!`{TJG?A$`=gAIvQn zj>q@hC%aCMoZH#}OfaQjE>tQS1(e5QKGJDZC03DU`F_o+#7EQX%KMu3pK1xKSia6O zJi6*BebQ_0fF?Wrrkg~f9Zk?X!J5DpFj82PPP8&hpkm?;(tg405Ljp70PhdsFj!Rg z6nSSw{%K_18Fx$ID|w2n1_~!e=a&0r zfueJ&nD*5ssQu$n`M*1&>$SCHL^SW~tP_g9U*G5eEH+YC)UMxz{W9N({q8P8&Ho{X zWC%m`3%@tyTOIgW`nV)GUJ0M-qLQGZLHmCDY6qgB1HM7;H1LKKpxb3L9&^=+lJIZV C6hV*x literal 0 HcmV?d00001 diff --git a/tests/mark/shape-transform/test.typ b/tests/mark/shape-transform/test.typ new file mode 100644 index 00000000..832ea405 --- /dev/null +++ b/tests/mark/shape-transform/test.typ @@ -0,0 +1,29 @@ +#import "/src/lib.typ": * +#import "/tests/helper.typ": * + +#test-case({ + import cetz.draw: * + + set-style(mark: (transform-shape: true)) + + scale(x: 3) + line((-1,-1), (1,1), mark: (start: "rect", end: "]")) +}) + +#test-case({ + import cetz.draw: * + + set-style(mark: (transform-shape: false)) + + scale(x: 3) + line((-1,-1), (1,1), mark: (start: "rect", end: ">")) +}) + +#test-case({ + import cetz.draw: * + + set-style(mark: (transform-shape: false)) + + rotate(45deg) + line((-1,-1), (1,-1), (1,1), mark: (start: "rect", end: "rect", scale: 3)) +}) diff --git a/tests/plot/annotation/ref/1.png b/tests/plot/annotation/ref/1.png index 6d7644278afd33ba7803bd671ffe322e5c81ecde..3ee1a19214a06a76fb4edb82dd03f5ae47e2263e 100644 GIT binary patch delta 14963 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 diff --git a/tests/plot/annotation/test.typ b/tests/plot/annotation/test.typ index 91da6529..215e7cff 100644 --- a/tests/plot/annotation/test.typ +++ b/tests/plot/annotation/test.typ @@ -16,5 +16,8 @@ line((calc.pi / 2, 1.1), (rel: (0, .2)), (rel: (2*calc.pi, 0)), (rel: (0, -.2))) content((calc.pi * 1.5, 1.5), $ lambda $) }) + plot.annotate(padding: .1, { + line((calc.pi / 2,-.1), (calc.pi / 2, .8), mark: (end: "stealth")) + }) }) }))