sunil sunny sunil sunny - 11 months ago 60
Android Question

How to draw a line to perfectly align top of a text?

I am able to align the baseline perfectly. The

will give a baseline that is perfectly aligned with text (lineBottom - descent).
I am using
as the topline which will give a line with padding on top see the screenshot.

enter image description here

The main issue is I have different fonts.And this code works perfectly on some fonts.

This is the code

int baseline = getLineBounds(i, rect);
int topLine =;

canvas.drawLine(rect.left - padding, baseline, rect.right + padding,
baseline, paint);

canvas.drawLine(rect.left - padding, topLine, rect.right + padding, topLine,

canvas.drawLine(rect.left - padding, (baseline + topLine) / 2, rect.right
+ padding, (baseline + topLine) / 2, paint1);

This is what I have tried.

1) Used a "StaticLayout" to get the top line but didn't make any difference.

2) Used paint to get the height of font and add it with baseline

paint.getTextBounds(getText().toString(), 0, getText().length(), r);
int height = r.height();
int topLine = baseline + height;

3) Tried with FontPadding =false

So my question is how to get the the topline like the baseline.
Any help with this is greatly appreciated.

Answer Source

Try paint.getTextBounds(...) again, but use, (or actually instead of r.height:

paint.getTextBounds(getText().toString(), 0, getText().length(), r);
int ascent =;
int topLine = baseline + ascent;

r.height gives the distance from the very bottom of the character to the very top, whereas should give the negative of the distance from the baseline to the very top.

If this doesn't work either, you might just need to draw the text to a temporary canvas in memory and run through the pixels row by row until you find a black one to measure the ascent yourself.

In either case, make sure you use a text that has capital letters in it. If you use a text with only lower case, it will likely give you the coordinates of the orange dashed line instead.

Note that both methods will give you the coordinate of a pixel at the very top edge of the font, not in the center of the stroke. Also, some letters in some fonts might overshoot the coordinate you really want to draw by quite a bit. Your safest bet is probably to pick a standard-string for measuring, like a capital O for the blue line and a lower-case o for the orange line (if it's not a script-font that has a little squiggle in the top right corner of the O that goes above the top of the circle...) and then store some small offset for each font that tells you how thick the line-width of the stroke is, so your lines go through the top of the letter rather than above it.