Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gettextbounds in android

Tags:

android

We used to find the rectangle which fits the given text, for example if give "TESTING" in gettextbounds api it will give a rectangle that fits the given string "TESTING", but could any plz clarify on which basis the rectangle length is calculated, whether the font size will be considered if so is it possible for me to check like this ?

1) Way i tried CharSequence text = getText(); canvas.drawText(text, 0, text.length(), mTextX, mTextY, getPaint());

    Paint pt = new Paint ( );
    pt.setTextSize(10);

    TextPaint tp = getPaint();
    String string = "haa";
    Rect currentBounds = new Rect ( );
    //this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);

    tp.getTextBounds((String) text, 0, text.length(), currentBounds );

    Log.e ( " ", "Desired Text " +text);
    Log.e ( " ", "first Ondraw Left " +currentBounds.left);
    Log.e ( " ", "Ondraw Top" +currentBounds.top);
    Log.e ( " ", "Ondraw right " +currentBounds.right);
    Log.e ( " ", "Ondraw bottom " +currentBounds.bottom);

    pt.setTextSize(20);


    tp.getTextBounds((String) text, 0, text.length(), currentBounds );

    Log.e ( "", "Desired Text " +text);
    Log.e ( " ", "Second Ondraw Left " +currentBounds.left);
    Log.e ( " ", "Ondraw Top" +currentBounds.top);
    Log.e ( " ", "Ondraw right " +currentBounds.right);
    Log.e ( "Nrace ", "Ondraw bottom " +currentBounds.bottom);

2) Second way i tried

    TextPaint tp = getPaint();
    String string = "haa";
    Rect currentBounds = new Rect ( );
    this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 32);               

    tp.getTextBounds(string, 0, string.length(), currentBounds );

    Log.e ( " ", "first Left " +currentBounds.left);
    Log.e ( " ", "Top" +currentBounds.top);
    Log.e ( " ", "right " +currentBounds.right);
    Log.e ( " ", "bottom " +currentBounds.bottom);

    this.setTextSize(/* TypedValue.COMPLEX_UNIT_PX */ 10, /* fontPixelSize*Home.fltFontRatio */ 10);

    tp.getTextBounds(string, 0, string.length(), currentBounds );

    Log.e ( " ", "Sefond Left " +currentBounds.left);
    Log.e ( " ", "Top" +currentBounds.top);
    Log.e ( " ", "right " +currentBounds.right);
    Log.e ( "", "bottom " +currentBounds.bottom);

In the above two methods am trying to find out the various rectangle size for the given text size. if this is not a good way plz advise me by posting some sample codes. Simply to say i have to find the various rectangle which fits the text "TESTING" for various font size.

Thanks in advance.

like image 579
Prasath Avatar asked Apr 19 '11 09:04

Prasath


People also ask

What is Paint in android?

TextPaint is an extension of Paint that leaves room for some extra data used during text measuring and drawing. The Paint class holds the style and color information about how to draw geometries, text and bitmaps.

What is static layout in Android?

StaticLayout is a Layout for text that will not be edited after it is laid out. Use DynamicLayout for text that may change. This is used by widgets to control text layout.

What is Android canvas?

The Canvas class holds the "draw" calls. To draw something, you need 4 basic components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint (to describe the colors and styles for the drawing).


2 Answers

I find this part of the API quite confusing, however I think I almost understood how it works. A call to getTextBounds() returns the smallest rectangle that would enclose all the characters drawn by a subsequent call to drawText() with x=0 and y=0. This is stated in slightly different words on the API reference. Everything that is in Paint and could affect the appearance of the text is taken into account. Here's an example:

Rect bounds = new Rect();

Paint paint = new Paint();
paint.setTextAlign(Align.LEFT);
paint.setTypeface(typeface);
paint.setTextSize(textSize);
paint.getTextBounds(text, 0, text.length(), bounds);

The reason why the rectangle has such exotic coordinates is because when you draw text with drawText(), the origin to which x and y are relative depends on the typographical properties of the Paint that you selected. For instance y is relative to the baseline, which is neither above nor below the font, but usually strikes it somewhere across the middle. For this reason the bounds rectangle will have (usually) a negative top and a positive bottom. The negative top means that the top of the text is above the baseline (y decreases going up), while the positive bottom means that the bottom of the text is below the baseline (y increases going down). It is interesting to note that when you measure a string such as "Hi" the bottom is likely to be 0, because those characters do not have a below the baseline part. On the contrary, when you measure a string like "Hg" you are likely to get a positive bottom, because the story of the g is below the baseline. I'm not sure how the horizontal position is estimated, though.

With this said, to draw the text of which you have computed the bounds you can do:

canvas.drawText(text, -bounds.left, -bounds.top, paint);

This will draw the text near to the upper left corner of the canvas. The coordinates of the upper left corner are (0, 0) so to move the text around you only have to add your desired amount of displacement:

canvas.drawText(text, -bounds.left + yourX, -bounds.top + yourY, paint);

Another example: if you want to create a bitmap that contains text, and you want to fit exactly the available space, you can do:

Bitmap bitmap = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left, -bounds.top, paint);

If you want to leave a few pixels to the left, right, top and bottom, let's say 2, you can do:

Bitmap bitmap = Bitmap.createBitmap(bounds.width() + 4, bounds.height() + 4, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText(text, -bounds.left + 2, -bounds.top + 2, paint);
like image 51
damix911 Avatar answered Oct 19 '22 02:10

damix911


There are some nuances, so it is better once to see... Red rectangle shows text bounds, x,y - any coordinates (of left lower point of the text bounds)

Rect textBounds = new Rect();
Paint textPaint = new Paint();
Paint rectPaint = new Paint();
String text = "java m";

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    textPaint.setTextSize(100);
    textPaint.getTextBounds(text, 0, text.length(), textBounds);

    canvas.drawText(text, x, y, textPaint);

    rectPaint.setColor(Color.RED);
    rectPaint.setStyle(Paint.Style.STROKE);

    canvas.drawRect(
            x,                       // left
            y - textBounds.height(), // top
            x + textBounds.width(),  // right
            y,                       // bottom
            rectPaint);
}

text = "Hello Worlds"

enter image description here

text = "java m"

enter image description here

like image 38
Andrew Avatar answered Oct 19 '22 01:10

Andrew