How to accurately measure the pixel size of text drawn on a canvas by drawTextOnPath().
I’m using drawTextOnPath() to display some text on Canvas and I need to know the dimensions of the text drawn. I know this is not feasible for a path consisting of multiple segments, curves, etc., but my path is a completely horizontal segment. I’m using Paint.getTextBounds() to get the Rect with the dimensions of the text I want to draw.
When I draw text
anywhere, I use this rectangle to draw a bounding box around the text.
Here’s some simplified code to reflect what I’m currently doing:
// to keep this example simple, always at origin (0,0)
public drawBoundedText(Canvas canvas, String text, Paint paint) {
Rect textDims = new Rect();
paint.getTextBounds(text,0, text.length(), textDims);
float hOffset = 0;
float vOffset = paint.getFontMetrics().descent; vertically centers text
float startX = textDims.left; / 0
float startY = textDims.bottom;
float endX = textDims.right;
float endY = textDims.bottom;
path.moveTo(startX, startY);
path.lineTo(endX, endY);
path.close();
draw the text
canvas.drawTextOnPath(text, path, 0, vOffset, paint);
draw bounding box
canvas.drawRect(textDims, paint);
}
The result – close – but not perfect. If I replace the penultimate line with:
canvas.drawText(text, startX, startY - vOffset, paint);
Then it just worked perfectly. There is usually a gap of 1-3 pixels on the right and bottom edges. The error also seems to vary with font size. Any ideas? It’s possible that I did everything correctly, the problem is drawTextOnPath(); Text quality degrades significantly when drawing along a path, even if the path is horizontal, probably because of the interpolation algorithm or whatever it uses behind the scenes. I wouldn’t be surprised to find that size jitter is also coming from there.
Solution
I found a solution that worked for my specific situation, although it didn’t really solve the original problem.
Since my particular use case only draws text along a single, straight line path, I was able to get rid of all paths and use Canvas.drawText() along with Canvas.translate() and canvas.rotate(). This also eliminates the text size randomness and ugliness I see when drawing along the path.