Java – How to accurately measure the pixel size of text drawn on a canvas by drawTextOnPath().

How to accurately measure the pixel size of text drawn on a canvas by drawTextOnPath()…. here is a solution to the problem.

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.

Related Problems and Solutions