Question

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...

Was it helpful?

Solution

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.

OTHER TIPS

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);
        }
    }

This is a bug in Android and while it's already submitted to the bug tracker you might want to +1 it there to get some attention: Issue 39755

Use this function to draw correctly with word wrap, new line break and text alignment features -

static void drawTextWithStaticLayout(Canvas canvas, float x, float y, String text, int wrapWidth, TextPaint paint,Layout.Alignment alignment) {
    if (android.os.Build.VERSION.SDK_INT <= 15) {
        StaticLayout sl = new StaticLayout(text,paint, wrapWidth, alignment,1.0f,0.0f,false);
        sl.draw(canvas);
    }
    else {
        float originalTextSize = paint.getTextSize();
        final float magnifier = 1000f;
        canvas.save();
            canvas.translate(x,y);
            canvas.scale(1f / magnifier, 1f / magnifier);
            paint.setTextSize(originalTextSize * magnifier);
            StaticLayout sl = new StaticLayout(text,paint, (int)magnifier*wrapWidth, alignment,1.0f,0.0f,false);
            sl.draw(canvas);
        canvas.restore();
        paint.setTextSize(originalTextSize);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top