Hello there,
It looks like there's something wrong with AndroidCanvas.fillRoundRect(). I am trying to fill some rectangles using a linear gradient. This is how it should like:
This is how it currently looks like in Android:
The problem is that the origin for the gradient fill is reset to the origin of each shape (see the rectangle in the bottom right).
This happens only for fillRoundRect; fillRect is not affected.
I have been looking into this and I think I know where the problem is. The current implementation of AndroidCanvas.fillRoundRect looks like this:
public Canvas fillRoundRect(float x, float y, float width, float height, float radius) {
this.canvas.translate(x, y);
rectf.set(0.0F, 0.0F, width, height);
this.canvas.drawRoundRect(rectf, radius, radius, this.currentState().prepareFill());
this.canvas.translate(-x, -y);
this.isDirty = true;
return this;
}
The problem is due to the canvas.translate calls.
This fixes the issue:
public Canvas fillRoundRect(float x, float y, float width, float height, float radius) {
rectf.set(x, y, x + width, y + height);
canvas.drawRoundRect(rectf, radius, radius, currentState().prepareFill());
dirty = true;
return this;
}
To me this seems more natural, so I was curious about why the translate calls were used in the first place. Going through the commit logs I found
this one:
===
From ab72fb60845312a2cb2815874f1ad995d89d90f0 Mon Sep 17 00:00:00 2001
Date: Wed, 16 May 2012 15:31:15 -0700
Subject: [PATCH] Work around odd Android Canvas drawRoundRect bug.
If the rect supplied to drawRoundRect has non-zero x or y, it causes the round
rectangle to be incorrectly rendered. So we simply translate the canvas, draw
using a rect at (0, 0) and then translate it back.
Surely someone would have discovered this bug already? Round rects are all the
rage in UIs.
[...]
===
The thing is that the original code (before this commit) looked like this:
rectf.set(x, y, width, height);
canvas.drawRoundRect(rectf, radius, radius, currentState().prepareFill());
but this was wrong -- rectf should be set to (x, y, x + width, y + height) (the last two parameters are not w/h, but the right and bottom coordinates). Probably this is why it was not working as expected if x or y were not 0.
So I am going to prepare a PR to "fix the fix".
Another option would be to use
the drawRoundRect method that takes (x, y, width, height) instead of a Rect, and avoid the creation of an intermediate Rect. However this was introduced in API level 21 which doesn't work if building PlayN using Maven (android.version is currently set to 4.1.1.4, which is the latest version available in Maven central).
PR will follow shortly.
Thank you,
Guillermo