Skip to content

Tight bounding box around text in graphics?

5 messages · Paul Murrell, Duncan Murdoch

#
I've mentioned in previous messages that I'm trying to redo rgl text.

Part of what I need is to measure the size of strings in pixels when 
they are drawn by base graphics.

It appears that

   strwidth(texts, "user", cex = cex, font = font, family = family)

gives accurate measurements of the width in user coordinates.  I've got 
those set up to match pixels, so I'm fine here.

However, the equivalent call for strheight() only measures height above 
the baseline according to the docs, and indeed the number is smaller 
than the size of what's displayed.  Descenders (e.g. the tail of "y") 
aren't counted.

Is there a way to measure how far a character might descend?  Is it 
valid to assume it won't descend more than a line height below the top 
of the char?

I have a partial solution -- textshaping::shape_text gives a "height" 
value that includes lots of space below the character, and a 
"top_border" value that measures from the top of the textbox to the 
baseline.  So I think `height - top_border` would give me what I'm 
asking for.  But this only works with graphics devices in the ragg 
package.  Is there a general solution?

Duncan Murdoch
#
Hi

strheight(), which is based GEStrHeight(), is pretty crude, not only 
ignoring descenders, but also only considering the ascent of the overall 
font (capital "M").

There is a GEStrMetric(), which returns character-specific ascent and 
descent, but that is only currently exposed via grid::stringAscent() and 
grid::stringDescent().  There is also grid::stringHeight(), which is as 
unsubtle as strheight().

For example, these are all the same (just font ascent) ...

 > strheight("y", "in")
[1] 0.1248031
 > strheight("x", "in")
[1] 0.1248031
 > strheight("M", "in")
[1] 0.1248031

... and these are all the same ...

 > convertHeight(stringHeight("y"), "in")
[1] 0.124803149606299inches
 > convertHeight(stringHeight("x"), "in")
[1] 0.124803149606299inches
 > convertHeight(stringAscent("M"), "in")
[1] 0.124803149606299inches

... but these have more detail ...

 > convertHeight(stringAscent("y"), "in")
[1] 0.0936023622047244inches
 > convertHeight(stringDescent("y"), "in")
[1] 0.0416010498687664inches
 > convertHeight(stringAscent("x"), "in")
[1] 0.0936023622047244inches
 > convertHeight(stringDescent("x"), "in")
[1] 0inches
 > convertHeight(stringHeight("M"), "in")
[1] 0.124803149606299inches
 > convertHeight(stringDescent("M"), "in")
[1] 0inches

In theory, it should not be difficult to add a graphics::strascent() and 
graphics::strdescent() if that would help.

Paul
On 26/09/23 08:06, Duncan Murdoch wrote:

  
    
#
Thanks!  I said "base graphics" in my question, but I really have no 
objection to using grid graphics, so I'll explore those grid functions.

Duncan Murdoch
On 25/09/2023 3:53 p.m., Paul Murrell wrote:
#
I've done some exploring, and things aren't working out as I would have 
expected.  Here's an example:

   library(grid)
   library(ragg)

   agg_png("test.png")
   pushViewport(viewport(gp = gpar(cex = 5)))
   y <-  c(0.2, 0.4, 0.6)

   texts <- c("??", "Tokyo", "Tokyo ??")

   convertHeight(stringDescent(texts), "npc")

   grid.text(texts,
             x = 0, y = y, just = c(0,0))
   grid.segments(x0 = 0, x1 = 1, y0 = y, y1 = y)

   popViewport()
   dev.off()

(In case it doesn't make it through in email, the texts are Tokyo 
written in kanji, then in roman letters, then in both.)

What I see is that the kanji string is being reported as having zero 
descent, but in the resulting test.png file, it's clear that it does 
descend below the baseline.

I can think of lots of reasons for this discrepancy; can you suggest 
which is likeliest?

  - I have some misconception about how this is supposed to work
  - The Kanji font on my system misreports some measurements
  - The ragg::agg_png() device misreports measurements
  - Some other bug somewhere.

Duncan
On 26/09/2023 5:57 a.m., Duncan Murdoch wrote:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.png
Type: image/png
Size: 11907 bytes
Desc: not available
URL: <https://stat.ethz.ch/pipermail/r-devel/attachments/20230926/854399a2/attachment.png>