Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canvas.drawTextOnPath(...) not working on Lollipop

canvas.DrawTextOnPath does not seem to work on a Lollipop device. See the difference here. (The Nexus 10 image is correct but Lollipop does not display correctly)

Image

The code is a simple path draw.

// Path for the inner circle
unitPath = new Path();
unitPath.addArc(unitRect, 180.0f, 180.0f);

// Draw the text and the path
canvas.drawTextOnPath("Inner Circle", unitPath, 0.0f, 0.0f, unitPaint);
canvas.drawPath(unitPath,unitPaint);

The Android Studio test project illustrating this issue can be seen here for anyone who wants to see it. https://dl.dropboxusercontent.com/u/6768304/WebLinks/TestApp.rar

Is there something "different" I need to do on this device?

like image 533
Kuffs Avatar asked Nov 04 '14 15:11

Kuffs


People also ask

How to draw bitmap on canvas in android?

Draw the specified bitmap, with its top/left corner at (x,y), using the specified paint, transformed by the current matrix. Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle. Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle.

What is the canvas in android?

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


1 Answers

OK so it seems that DrawTextOnPath is a little broken now with font sizes below 1.0f

The solution is to scale everything up, draw the text then shrink it back down.

The drawTitle method in the demo project would change from this:

private void drawTitle(Canvas canvas) {
    canvas.drawTextOnPath(upperTitle, upperTitlePath, 0.0f, 0.02f, unitPaint);
    canvas.drawTextOnPath(lowerTitle, lowerTitlePath, 0.0f, 0.0f, unitPaint);
    canvas.drawTextOnPath(unitTitle, unitPath, 0.0f, 0.0f, unitPaint);
    canvas.drawPath(unitPath,unitPaint);
}

to this:

private void drawTitle(Canvas canvas) {
    //Save original font size
    float originalTextSize = unitPaint.getTextSize();

    // set a magnification factor
    final float magnifier = 100f;

    // Scale the canvas
    canvas.save();
    canvas.scale(1f / magnifier, 1f / magnifier);

    // create new rects and paths based on the new scale
    unitRect = new RectF();
    unitRect.set((faceRect.left + unitPosition) * magnifier, (faceRect.top + unitPosition) * magnifier, (faceRect.right - unitPosition) * magnifier, (faceRect.bottom - unitPosition) * magnifier);
    unitPath = new Path();
    unitPath.addArc(unitRect, 180.0f, 180.0f);

    titleRect = new RectF();
    titleRect.set((faceRect.left + titlePosition) * magnifier, (faceRect.top + titlePosition) * magnifier, (faceRect.right - titlePosition) * magnifier, (faceRect.bottom - titlePosition) * magnifier);
    upperTitlePath = new Path();
    upperTitlePath.addArc(titleRect, 180.0f, 180.0f);

    titleRect = new RectF();
    titleRect.set((faceRect.left + titlePosition) * magnifier, (faceRect.top + titlePosition) * magnifier, (faceRect.right - titlePosition) * magnifier, (faceRect.bottom - titlePosition) * magnifier);
    lowerTitlePath = new Path();
    lowerTitlePath.addArc(titleRect, -180.0f, -180.0f);

    // increase the font size
    unitPaint.setTextSize(originalTextSize * magnifier);

    // do the drawing of the text
    canvas.drawTextOnPath(unitTitle, unitPath, 0.0f, 0.0f, unitPaint);
    canvas.drawTextOnPath(upperTitle, upperTitlePath, 0.0f, 0.02f, unitPaint);
    canvas.drawTextOnPath(lowerTitle, lowerTitlePath, 0.0f, 0.0f, unitPaint);

    // bring everything back to normal
    canvas.restore();
    unitPaint.setTextSize(originalTextSize);

    canvas.drawPath(unitPath, unitPaint);
}
like image 122
Kuffs Avatar answered Nov 09 '22 05:11

Kuffs