greywolf82
greywolf82

Reputation: 22173

Canvas drawtext multiline centered

I need to draw text in a bitmap centered horizontally and vertically, adjusting the text size in order to cover all the space. The problem is that the text is multi-line with \n. This is my current code:

private int determineMaxTextSize(String str, float maxWidth) {
        int size = 0;
        if (TextUtils.isEmpty(str))
            return 0;
        Paint paint = new Paint();
        do {
            paint.setTextSize(++size);
        } while (paint.measureText(str) < maxWidth);
        return size > 0 ? size - 1 : 0;
    }

private void drawText(String text, int textColor, int bckColor) {
    TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    int max = Integer.MAX_VALUE;
    String[] tokens = text.split("\n");
    for (String s : tokens) {
        int m = determineMaxTextSize(s, params.width);
        if (m > 0 && m < max)
            max = m;
    }
    paint.setTextSize(max);
    paint.setColor(textColor);
    paint.setTextAlign(Paint.Align.CENTER);
    Bitmap b = Bitmap.createBitmap(params.width + 1, params.height + 1, Bitmap.Config.ARGB_8888);
    b.eraseColor(bckColor);
    Canvas canvas = new Canvas(b);
    Rect r = new Rect();
    int xPos = canvas.getWidth() / 2;
    int yPos = (canvas.getHeight() / 2);
    for (String s : tokens) {
        if (s.equals("\n"))
            s = " ";
        paint.getTextBounds(s, 0, s.length(), r);
        canvas.drawText(s, xPos, yPos, paint);
        yPos += Math.abs(r.height());
    }
    setImageBitmap(b);
}

This code nearly works but the text starts from the center.

Upvotes: 1

Views: 1319

Answers (1)

MichaelStoddart
MichaelStoddart

Reputation: 5639

This is a late answer so I apologise if it is no longer needed but after looking for an answer I decided to employ some maths to solve this issue.

In order to center my multiline text, I take the width of the canvas, subtract the width of the text, and then divide by 2. This number is then used as the x offset of the drawText method.

Here is my full example:

public static Bitmap textAsBitmap(String text, float textSize, int textColor, Context mContext) {
    Paint paint = new Paint(ANTI_ALIAS_FLAG);
    int pixel = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, textSize, mContext.getResources().getDisplayMetrics());

    String[] str = text.split(",");

    paint.setTextSize(pixel);
    paint.setTypeface(FontUtils.getRalewayExtraBold(mContext));
    paint.setColor(textColor);
    paint.setTextAlign(Paint.Align.LEFT);
    float baseline = -paint.ascent(); // ascent() is negative
    int width = (int) (paint.measureText(text) + 0.0f); // round

    int height = (int) (baseline + paint.descent() + 0.0f);
    Bitmap image = Bitmap.createBitmap((width/str.length)+10, (height*str.length), Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(image);

    for (int i = 0; i < str.length; i++){
        //Center text here
        float textOffset = (canvas.getWidth()-paint.measureText((str[i])))/2;
        canvas.drawText(str[i], textOffset, ((i+1)*baseline), paint);
    }

    return image;
}

Upvotes: 2

Related Questions