Hi, > On 23 Nov 2015, at 19:40, Branden Visser <[email protected]> wrote: > > 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 > } > That's correct.
> [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 You're trying to transform glyphHeight (a dimension) using a method for transforming points. That won't work. > val scalingFactorY = tp.getTextMatrix.getScalingFactorY > val heightUserScaled = heightUser * scalingFactorY The matrix transforms are 2D, you can't extract just a single scale and use it to transform a point (even if that point is non-zero in only one dimension, because the resulting matrix-transformed point may be non-zero for *both* dimensions, x and y). I'd recommend creating an AffineTransform from the Matrix, and then call transformShape to transform the glyph's bounding rectangle. Make sure you do all transforms using matrices, don't try to extract the various scaling factors because they can't be applied in isolation. -- John > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]

