2

I have made several tests to position text on a given location on the canvas and come to the conclusion that drawText() does not work correctly. (My sample code and screenshot will show.) If possible, please give me an advice how this can be overcome.

In case of any text (in my example just "123") I can get the size of the text correctly. However, the positioning (mainly horizontally) is not accurate. To make it worse, this phenomena is not identical with all characters. E.g. in case the text starts with an "A", it works as expected.

I have attached two areas from my screenshots. The one with "123" shows how the text is offset to the right. The one with "A12" shows how it looks when the positioning is correct. My code draws a grey control rectangle with the dimensions given for the text. One should expect that the text appears exactly in this frame. But it does not. Having this problem, it is impossible to accurately set any text in a drawing.

package com.pm.pmcentertest;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;

public class Draw extends View {

public Paint myPaint;

public Draw(Context context) {
    super(context);
    myPaint = new Paint();
 }

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.CYAN);

    // The text shall appear in the lower left corner
    int x = 0;
    int y = canvas.getHeight();

    // We use a large text size for demonstration
    String Text = "123";
    myPaint.setTextSize(400);

    // We get the dimensions of the text
    Rect bounds = new Rect();
    myPaint.getTextBounds(Text, 0, Text.length(), bounds);

    // Now we draw a rectangle for the area in which the text should appear
    // using the TextBounds values
    myPaint.setColor(Color.parseColor("GREY"));
    canvas.drawRect(x, y - bounds.height(), x + bounds.width(), y, myPaint);

    // Now we draw the text to the same position
    myPaint.setColor(Color.parseColor("WHITE"));
    canvas.drawText(Text, x, y, myPaint);

  }
}

Negative example with offset

Positive example when start with A

Peter Mattheisen
  • 117
  • 2
  • 13

1 Answers1

0

The problem is in the Rect object. You have to change your code:

canvas.drawRect(x, y - bounds.height(), x + bounds.width(), y, myPaint);

To the bounds.width() -> bounds.right

canvas.drawRect(x, y - bounds.height(), x + bounds.right, y, myPaint);

Method width() returns the rectangle's width. This does not check for a valid rectangle (i.e. left <= right) so the result may be negative.

Volodymyr
  • 6,393
  • 4
  • 53
  • 84
  • Dear Volodymyr, bounds.width() is actually representing the true length of the text. However, thanks to your answer I realized that the bounds rect often does not start with 0 as its left most point. (This is strange and I do not understand the sense of it.) Nevertheless what I found out now is that the bounds.left value represents the offset in display from which I suffered. So the solution to the problem is a change in the text positioning line to: canvas.drawText(Text, x - bounds.left, y - bounds.bottom, myPaint); Thanks for giving me this valuable hint. Peter – Peter Mattheisen Sep 09 '16 at 14:16
  • @PeterMattheisen Yes, I agree with you that is not so obvious. – Volodymyr Sep 09 '16 at 14:18