-
-
Notifications
You must be signed in to change notification settings - Fork 64
Description
When cetz v0.4.2 calculates border anchors for cetz.draw.content, it changes text.bottom-edge and increases the effective line spacing, resulting in an additional bottom padding if the content is multi-line.
Lines 1143 to 1155 in 0459295
| // Compute the baseline offset | |
| let (_, line-baseline-height) = util.measure(ctx, text(top-edge: "cap-height", bottom-edge: "baseline", | |
| [ #show linebreak: [ ]; #body])) | |
| let (_, line-bounds-height) = util.measure(ctx, text(top-edge: "cap-height", bottom-edge: "bounds", | |
| [ #show linebreak: [ ]; #body])) | |
| let baseline-offset = line-bounds-height - line-baseline-height | |
| // Size of the bounding box | |
| let (content-width, content-height, ..) = if auto-size { | |
| util.measure(ctx, text(top-edge: "cap-height", bottom-edge: "baseline", body)) | |
| } else { | |
| vector.sub(b, a) | |
| } |
Minimal example
In the following example, the height of the green border line is expected to equal to the height of the aqua block, but it isn't.
#import "@preview/cetz:0.4.2"
#cetz.canvas({
import cetz.draw: *
content((0, 0), name: "a", block(
width: 6em,
fill: aqua.lighten(50%),
lorem(10),
))
line(
"a.north-west",
"a.north-east",
"a.south-east",
"a.south-west",
close: true,
stroke: green,
)
})Links and comparisons
#894 is a similar issue. #956 (first appeared in v0.4.2) has fixed that issue, but not this one.
The difference is that linebreaks in #894 are inserted manually, but here they're inserted automatically (by putting contents in a fixed-width block).
Therefore, the #show linebreak: [ ] hack used by #956 is not helpful.
In the minimal example above, changing a.south-{west,east} to a.base-{west,east} would draw the correct border line.
However, there exist certain cases that base-{west,east} are not applicable.
For instance, when drawing a chat bubble, you may want the lower-left corner of the whole group, including a triangle and a cetz.draw.content. This point locates at (x: group.triangle.west.x, y: group.content.base-west.y). If cetz had measured correctly, then this can be simplified as group.south-west.
Workaround
Set text.{top,bottom}-edge explicitly and control spacing on your own.
#import "@preview/cetz:0.4.2"
#cetz.canvas({
import cetz.draw: *
content((0, 0), name: "a", block(
width: 6em,
fill: aqua.lighten(50%),
{
// 👇 Edit here
set text(top-edge: "cap-height", bottom-edge: "baseline")
v(0.5em) // or use `block.inset`
lorem(10)
v(0.5em)
},
))
line(
"a.north-west",
"a.north-east",
"a.base-east",
"a.base-west",
close: true,
stroke: green,
)
})