Added support for focal points in RadialGradient
Updated RadialGradient API to accept optional starting
(focal) point parameters. Internally create a two point
conical shader if focal points are provided.
Fixes: 167695230
Test: Added CTS test to verify focal points on RadialGradient
Change-Id: I18baba3d0a7285c3f787af8f441c797414bae2cf
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index e36e355..45795ff 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -133,11 +133,25 @@
///////////////////////////////////////////////////////////////////////////////////////////////
-static jlong RadialGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
- jfloat radius, jlongArray colorArray, jfloatArray posArray, jint tileMode,
+static jlong RadialGradient_create(JNIEnv* env,
+ jobject,
+ jlong matrixPtr,
+ jfloat startX,
+ jfloat startY,
+ jfloat startRadius,
+ jfloat endX,
+ jfloat endY,
+ jfloat endRadius,
+ jlongArray colorArray,
+ jfloatArray posArray,
+ jint tileMode,
jlong colorSpaceHandle) {
- SkPoint center;
- center.set(x, y);
+
+ SkPoint start;
+ start.set(startX, startY);
+
+ SkPoint end;
+ end.set(endX, endY);
std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);
@@ -148,11 +162,17 @@
#error Need to convert float array to SkScalar array before calling the following function.
#endif
- sk_sp<SkShader> shader = SkGradientShader::MakeRadial(center, radius, &colors[0],
- GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
- static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr);
+ auto colorSpace = GraphicsJNI::getNativeColorSpace(colorSpaceHandle);
+ auto skTileMode = static_cast<SkTileMode>(tileMode);
+ sk_sp<SkShader> shader = SkGradientShader::MakeTwoPointConical(start, startRadius, end,
+ endRadius, &colors[0], std::move(colorSpace), pos, colors.size(), skTileMode,
+ sGradientShaderFlags, nullptr);
ThrowIAE_IfNull(env, shader);
+ // Explicitly create a new shader with the specified matrix to match existing behavior.
+ // Passing in the matrix in the instantiation above can throw exceptions for non-invertible
+ // matrices. However, makeWithLocalMatrix will still allow for the shader to be created
+ // and skia handles null-shaders internally (i.e. is ignored)
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
if (matrix) {
shader = shader->makeWithLocalMatrix(*matrix);
@@ -279,7 +299,7 @@
};
static const JNINativeMethod gRadialGradientMethods[] = {
- { "nativeCreate", "(JFFF[J[FIJ)J", (void*)RadialGradient_create },
+ { "nativeCreate", "(JFFFFFF[J[FIJ)J", (void*)RadialGradient_create },
};
static const JNINativeMethod gSweepGradientMethods[] = {