pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Branden Visser <mrvis...@gmail.com>
Subject Getting visual height of a glyph
Date Tue, 24 Nov 2015 03:40:44 GMT
Hello!

I've seen lots of discussion about getting the height of a glyph,
those of which are saying that using the path accessor of the font
should result in getting an accurate visual height of a glyph, while
close, it has not been my experience.

I've attached a PDF with 7 different TrueType fonts, and I have a
(Scala) program [1] [2] that uses the font path to try and get the
bounding boxes of the characters, and then draws a copy of the PDF
with the boxes drawn around the characters.

You'll see that most boxes are double the height of the glyph.
However, for many other documents I've tried, the path is very
accurate (generally PDType1Font, I think).

I've seen discussion that says that the font size is the height of the
glyph, but that appears to be ~1.5x the height of the capital A's in
the attached document. Same with the CapHeight which IIUC should be
the height of those capital A's, but it seems to be around the same
height as the font size. I've also seen crazy documents where the font
size is 1.0 for all characters, and the size is controlled by the
Y-scale, so I'm not sure using font size for height is a great
alternative.

Presumably, if these letter A's can be displayed to me at this height,
there must be something that would indicate the height of the
characters, but I can't pinpoint what it is. I looked at the
PathIterator instructions, and indeed the upper-most point that is
drawn is one that appears to be exactly double the height of the
glyph.

So, is there a way to get the visual height of a given character? Is
there an element to the height that I'm missing?

Thanks,
Branden

[1] Function to get the height from a character code

private[this] def getCharacterHeightFromPath(font: PDFont, code: Int): Float = {
  val path = font match {
    case f: PDType1CFont => f.getPath(f.getEncoding.getName(code))
    case f: PDType1Font => f.getPath(f.getEncoding.getName(code))
    case f: PDType0Font => f.getPath(code)
    case f: PDType3Font => f.getPath(f.getEncoding.getName(code))
    case f: PDTrueTypeFont => f.getPath(f.getEncoding.getName(code))
  }

  path.getBounds2D.getHeight.toFloat
}

[2] Translate to user space, where `tp` is a TextPosition given by the
PDFTextStripper

val f = tp.getFont
val glyphHeight = getCharacterHeightFromPath(f, tp.getCharacterCodes.head)
val heightUser = f.getFontMatrix.transformPoint(0, glyphHeight).y

val scalingFactorY = tp.getTextMatrix.getScalingFactorY
val heightUserScaled = heightUser * scalingFactorY


Mime
View raw message