Will accurate character bounding boxes be implemented?

My question is concerning the bounding box of characters in typst. Currently, the bounding box of small letter characters have the same height as those of capital letter characters; when we reveal the bounding boxes of ‘x’ and ‘X’ by

#box([x], stroke: black)#box([X], stroke: black)

we see that these have the same height:

image

The small letter x has some additional white space at the top. My question is the following

Question
Will accurate bounding boxes be implemented in the future?

And perhaps: would there be a rough or very rough estimate of when? I didn’t see it on the roadmap, but I might have overlooked it.

Context
The reason I’m interested in this is the following, it might be of interest to others too. Currently when putting a label in a CeTZ picture, the vertical positioning of the actual character / text of the label looks sometimes slightly off because for some characters the bounding box is too tall, which offsets the center of the character. Just as one example, a situation where it matters is when labeling axes in a plot.

When you want to create a plot (I’m using the CeTZ-plot library for this) and position each axis label such that the north-east of its bounding box is put at the tip of the axis arrow:

 set-style(axes: (label: (anchor: "north-east")))

The plot would look like this

The x-label is fine, the right border of the x coincides with the tip of the arrow. The y-label though looks off as it seems shifted down a little bit. This is of course because its bounding box includes some white space at its top.

For completeness, here is the code of the plot:

#cetz.canvas({
  import cetz.draw: *
  import cetz-plot: *

  set-style(
    axes: (label: (anchor: "north-east")),
  )
  
  plot.plot(
    axis-style: "school-book",
    x-tick-step: none, y-tick-step: none,
    x-label: $x$, y-label: $y$,
    {
      plot.add(
        domain: (-1.6, 1.6),
        t => calc.sin(t)
      )
    }
  )
})

You can get accurate bounding boxes with text(top-edge: "bounds", bottom-edge: "bounds", [x]).

With your example, this gives:

3 Likes

Amazing! Thank you Johannes :smiley: