How to draw a decorative frame (rect with concave corners) around text?

#let frame-shape(width: 10cm, height: 5cm, radius: 15pt, a: 0pt, ..args) = {
  set curve.quad(relative: true)
  set curve.line(relative: true)
  curve(
    ..args,
    curve.move((0pt, radius)),
    curve.line((0pt, height - radius * 2)), // Left
    curve.quad((-a + radius, a), (radius, radius)), // Bottom-left
    curve.line((width - radius * 2, 0pt)), // Bottom
    curve.quad((a, a - radius), (radius, 0pt - radius)), // Bottom-right
    curve.line((0pt, -height + radius * 2)), // Right
    curve.quad((a - radius, -a), (-radius, -radius)), // Top-right
    curve.line((-width + radius * 2, 0pt)), // Top edge
    curve.quad((-a, -a + radius), (-radius, radius)), // Top-left
  )
}

#let frame(
  width: 100%,
  height: auto,
  radius: 15pt,
  inner: 2pt,
  stroke: 1pt,
  inner-stroke: 0.5pt,
  body,
) = {
  layout(size => {
    let body-block = block.with(width: width, inset: radius + inner)
    let (height, body) = if height != auto {
      (height, body-block(height: height, body))
    } else {
      let body = body-block(body)
      (measure(body, ..size).height, body)
    }
    place(frame-shape(
      width: width,
      height: height,
      radius: radius,
      stroke: stroke,
    ))
    place(dx: inner, dy: inner, frame-shape(
      width: width - inner * 2,
      height: height - inner * 2,
      radius: radius,
      stroke: inner-stroke,
      a: inner / 2,
    ))
    body
  })
}

#set par(justify: true)

#place(rect(width: 100%, height: 100%))
#frame(lorem(50))
#lorem(50)

1 Like