Question

I'm using a Canvas to create a Drawable with some background and some text. The drawable is used as a compound drawable inside an EditText.

The text is drawn via drawText() on the canvas, but I do have an issue with the y-position of the drawn text in some cases. In those cases parts of some characters are cut off (see image links).

Characters without positioning issue:

http://i50.tinypic.com/zkpu1l.jpg

Characters with positioning issue, text contains 'g', 'j', 'q', etc.:

http://i45.tinypic.com/vrqxja.jpg

You can find a code snippet to reproduce the issue below.

Does any expert know how to determine the proper offset for the y position?

public void writeTestBitmap(String text, String fileName) {
   // font size
   float fontSize = new EditText(this.getContext()).getTextSize();
   fontSize+=fontSize*0.2f;
   // paint to write text with
   Paint paint = new Paint(); 
   paint.setStyle(Style.FILL);  
   paint.setColor(Color.DKGRAY);
   paint.setAntiAlias(true);
   paint.setTypeface(Typeface.SERIF);
   paint.setTextSize((int)fontSize);
   // min. rect of text
   Rect textBounds = new Rect();
   paint.getTextBounds(text, 0, text.length(), textBounds);
   // create bitmap for text
   Bitmap bm = Bitmap.createBitmap(textBounds.width(), textBounds.height(), Bitmap.Config.ARGB_8888);
   // canvas
   Canvas canvas = new Canvas(bm);
   canvas.drawARGB(255, 0, 255, 0);// for visualization
   // y = ?
   canvas.drawText(text, 0, textBounds.height(), paint);

   try {
      FileOutputStream out = new FileOutputStream(fileName);
      bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
   } catch (Exception e) {
      e.printStackTrace();
   }
}
Was it helpful?

Solution

I think it's probably a mistake to assume that textBounds.bottom = 0. For those descending characters, the bottom parts of those characters are probably below 0 (which means textBounds.bottom > 0). You probably want something like:

canvas.drawText(text, 0, textBounds.top, paint); //instead of textBounds.height()

If your textBounds is from +5 to -5, and you draw text at y=height (10), then you'll only see the top half of the text.

OTHER TIPS

I believe that if you want to draw text near the upper left corner you should do this:

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

And you can move around the text by summing the desired amount of displacement to the two coordinates:

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

The reason why this works (at least for me) is that getTextBounds() tells you where drawText() would draw the text in the event that x=0 and y=0. So you have to counteract this behavior by subtracting the displacement (textBounds.left and textBounds.top) introduced by the way text is handled in Android.

In this answer I elaborate a little more on this topic.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top