Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 4.2.1 wrong character kerning (spacing)

When using Canvas and drawText() method I see a different rendering on Android 4.2.1.

Below 4.2:

enter image description here

For Android 4.2.1 (Nexux 7) I get:

enter image description here

As you can see the text Consumption is very tight. Seems to be a kerning problem introduced in 4.2.1. The Paint used to draw text is nothing special:

titlePaint = new Paint();
titlePaint.setAntiAlias(true);
titlePaint.setColor(0xffffffff);
titlePaint.setTextSize(0.125f);
titlePaint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
titlePaint.setTextAlign(Align.CENTER);
titlePaint.setLinearText(true);

If I don't use titlePaint.setLinearText(true) I get a strange result on 4.2.1 as you can see there:

Android 4.2 on Nexus 7: canvas.drawText() not working correctly

EDIT:

This strange behaviour has been reported to the Android team: http://code.google.com/p/android/issues/detail?id=39755 but it's still not a "official" issue.

EDIT (2):

Some rumors claim that the problem is a textSize < 1.0f...

like image 663
Seraphim's Avatar asked Dec 20 '12 14:12

Seraphim's


2 Answers

I answer my own question after accepting the only response that proposed a workaround for my specific issue. That could be a "nice" and "definitive" solution:

public static void drawTextOnCanvasWithMagnifier(Canvas canvas, String text, float x, float y, Paint paint) {
        if (android.os.Build.VERSION.SDK_INT <= 15) {
            //draw normally
            canvas.drawText(text, x, y, paint);
        }
        else {
            //workaround
            float originalTextSize = paint.getTextSize();
            final float magnifier = 1000f;
            canvas.save();
            canvas.scale(1f / magnifier, 1f / magnifier);
            paint.setTextSize(originalTextSize * magnifier);
            canvas.drawText(text, x * magnifier, y * magnifier, paint);
            canvas.restore();
            paint.setTextSize(originalTextSize);
        }
    }
like image 156
Seraphim's Avatar answered Sep 21 '22 22:09

Seraphim's


Workaround, that I'm currently using:

scalePaint.setTextSize(1.5f);

then, in onDraw method:

canvas.save();
canvas.scale(0.01f, 0.01f);
canvas.drawText(""+i, 0.5f*100, 0.8f*100, scalePaint);                  
canvas.restore();

As you can see, I'm rescaling back the position of the text, so it's where it's supposed to be.

like image 21
scana Avatar answered Sep 22 '22 22:09

scana