Ad

Paint Attributes Are Not Working On Canvas

I am trying to create the white impact font with black outline (aka "The Meme Font"). I applied the logic for both texts that are drawn on Canvas but it works only for one of them. Here is a result to show what I'm talking about:

enter image description here

Here is my code:

        Canvas canvas = new Canvas(mutableBitmap);

        TextPaint topFillPaint = new TextPaint();
        TextPaint bottomFillPaint = new TextPaint();

        TextPaint topStrokePaint = new TextPaint();
        TextPaint bottomStrokePaint = new TextPaint();

        Typeface typeface = getResources().getFont(R.font.impact);

        topFillPaint.setColor(Color.WHITE);
        topFillPaint.setTextSize(topTextView.getTextSize());
        topFillPaint.setTypeface(typeface);

        topStrokePaint.setStyle(Paint.Style.STROKE);
        topStrokePaint.setStrokeWidth(8);
        topStrokePaint.setColor(Color.BLACK);
        topStrokePaint.setTextSize(topTextView.getTextSize());
        topStrokePaint.setTypeface(typeface);

        bottomFillPaint.setColor(Color.WHITE);
        bottomFillPaint.setTextSize(bottomTextView.getTextSize());
        bottomFillPaint.setTypeface(typeface);

        bottomStrokePaint.setStyle(Paint.Style.STROKE);
        bottomStrokePaint.setStrokeWidth(8);
        bottomStrokePaint.setColor(Color.BLACK);
        bottomStrokePaint.setTextSize(bottomTextView.getTextSize());
        bottomStrokePaint.setTypeface(typeface);

        float topTextMeasurement = topFillPaint.measureText(topText);
        float bottomTextMeasurement = bottomFillPaint.measureText(bottomText);

        StaticLayout topFillLayout = new StaticLayout(topText, topFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                1.0f, 0.0f, false);
        StaticLayout topStrokeLayout = new StaticLayout(topText, topStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                1.0f, 0.0f, false);


        StaticLayout bottomFillLayout = new StaticLayout(bottomText, bottomFillPaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                1.0f, 0.0f, false);
        StaticLayout bottomStrokeLayout = new StaticLayout(bottomText, bottomStrokePaint, canvas.getWidth(), Layout.Alignment.ALIGN_CENTER,
                1.0f, 0.0f, false);

        canvas.translate(0,0);
        topFillLayout.draw(canvas);

        canvas.translate(0,0);
        topStrokeLayout.draw(canvas);

        canvas.translate(0, canvas.getHeight() - 210);
        bottomFillLayout.draw(canvas);

        canvas.translate(0, canvas.getHeight() - 210);
        bottomStrokeLayout.draw(canvas);

UPDATE

I've commented out

canvas.translate(0, canvas.getHeight() - 210); and bottomFillLayout.draw(canvas); and the black border was drawn. So either the fill text covers the outline or the outline doesn't exist when fill text is drawn.

Ad

Answer

To get the behavior you want, you'd just remove the second canvas.translate(0, canvas.getHeight() - 210);.

The canvas.translate calls adjust the current translation of the Canvas (it adds to the translation, it doesn't reset it absolutely). This means that canvas.translate(0, 0); is actually a no-op because it doesn't change the translation at all (these lines can just be removed). The translation does not reset after draw calls so this means that your second canvas.translate(0, canvas.getHeight() - 210); call is translating off of the screen (unless your screen height is less than 210 * 2).

See the android.graphics.Canvas documentation of the translate method for more information.

Ad
source: stackoverflow.com
Ad