Fix ReactNativeART arc drawing on Android
Summary: **Motivation**: Arc drawing has been broken on Android for some time. dgladkov submitted a PR, which ended up having a bug and was never merged. This PR should fix that bug as well as provide screenshots to prove it works. **Reproducing the Bug:** dgladkov made a simple test app which helps to illustrate the bug. The repo can be found [here](https://github.com/dgladkov/RNArtArcDrawingBug). The demo app illustrates that on iOS, wedges are drawn correctly, but Android only draws full circles. [Direct Link to iOS Before](https://github.com/dgladkov/RNArtArcDrawingBug/blob/master/images/ios.png). [Direct Link to Android Before](https://github.com/dgladkov/RNArtArcDrawingBug/blob/master/images/android.png). **Proof The Bug is Fixed:** [Here is a direct link to Android After pic.](http://i.imgur.com/9dTU2Xn.png) You can see the wedges match the iOS Before screenshot. **What went wrong:** dgladkov's solution relied on Java's modulus, which in fact, implements modulus in a non-standard way. Modulus should a Closes https://github.com/facebook/react-native/pull/7049 Differential Revision: D3234404 Pulled By: spicyj fb-gh-sync-id: 4974b818dc49d9d16f2483c49b462c459a8bb479 fbshipit-source-id: 4974b818dc49d9d16f2483c49b462c459a8bb479
This commit is contained in:
parent
d363b1f2e2
commit
1af47603cf
|
@ -191,6 +191,20 @@ public class ARTShapeShadowNode extends ARTVirtualNode {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floor modulus of the float arguments. Java modulus will return a negative remainder
|
||||||
|
* when the divisor is negative. Modulus should always be positive. This mimics the behavior of
|
||||||
|
* Math.floorMod, introduced in Java 8.
|
||||||
|
*/
|
||||||
|
private float modulus(float x, float y) {
|
||||||
|
float remainder = x % y;
|
||||||
|
float modulus = remainder;
|
||||||
|
if (remainder < 0) {
|
||||||
|
modulus += y;
|
||||||
|
}
|
||||||
|
return modulus;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a {@link Path} from an array of instructions constructed by JS
|
* Creates a {@link Path} from an array of instructions constructed by JS
|
||||||
* (see ARTSerializablePath.js). Each instruction starts with a type (see PATH_TYPE_*) followed
|
* (see ARTSerializablePath.js). Each instruction starts with a type (see PATH_TYPE_*) followed
|
||||||
|
@ -232,11 +246,18 @@ public class ARTShapeShadowNode extends ARTVirtualNode {
|
||||||
float r = data[i++] * mScale;
|
float r = data[i++] * mScale;
|
||||||
float start = (float) Math.toDegrees(data[i++]);
|
float start = (float) Math.toDegrees(data[i++]);
|
||||||
float end = (float) Math.toDegrees(data[i++]);
|
float end = (float) Math.toDegrees(data[i++]);
|
||||||
boolean clockwise = data[i++] == 0f;
|
boolean clockwise = data[i++] == 1f;
|
||||||
if (!clockwise) {
|
float sweep = end - start;
|
||||||
end = 360 - end;
|
if (Math.abs(sweep) > 360) {
|
||||||
|
sweep = 360;
|
||||||
|
} else {
|
||||||
|
sweep = modulus(sweep, 360);
|
||||||
}
|
}
|
||||||
float sweep = start - end;
|
if (!clockwise && sweep < 360) {
|
||||||
|
start = end;
|
||||||
|
sweep = 360 - sweep;
|
||||||
|
}
|
||||||
|
|
||||||
RectF oval = new RectF(x - r, y - r, x + r, y + r);
|
RectF oval = new RectF(x - r, y - r, x + r, y + r);
|
||||||
path.addArc(oval, start, sweep);
|
path.addArc(oval, start, sweep);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue