19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <jni.h> 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h" 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkShader.h" 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkGradientShader.h" 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkPorterDuff.h" 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkComposeShader.h" 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTemplates.h" 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkXfermode.h" 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy#include <SkiaShader.h> 12a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy#include <Caches.h> 1306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1406f96e2652e4855b6520ad9dd70583677605b79aRomain Guyusing namespace android::uirenderer; 1506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 167fac2e18339f765320d759e8d4c090f92431959eRomain Guystatic struct { 177fac2e18339f765320d759e8d4c090f92431959eRomain Guy jclass clazz; 1806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy jfieldID shader; 1906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} gShaderClassInfo; 207fac2e18339f765320d759e8d4c090f92431959eRomain Guy 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void ThrowIAE_IfNull(JNIEnv* env, void* ptr) { 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == ptr) { 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doThrowIAE(env); 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void Color_RGBToHSV(JNIEnv* env, jobject, int red, int green, int blue, jfloatArray hsvArray) 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar hsv[3]; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkRGBToHSV(red, green, blue, hsv); 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoHSV(env, hsvArray, 3); 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* values = autoHSV.ptr(); 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 3; i++) { 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[i] = SkScalarToFloat(hsv[i]); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 384cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArray) 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoHSV(env, hsvArray, 3); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float* values = autoHSV.ptr();; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar hsv[3]; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < 3; i++) { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hsv[i] = SkFloatToScalar(values[i]); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 484cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SkHSVToColor(alpha, hsv); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////// 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5406f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader) 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 566062c5912dc79704b489fc8c289b78a400ed05eeDerek Sollenberger SkSafeUnref(shader); 575c13d89c1332fcc499379b9064b891187b75ca32Chet Haase // skiaShader == NULL when not !USE_OPENGL_RENDERER, so no need to delete it outside the ifdef 58a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy#ifdef USE_OPENGL_RENDERER 59a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy if (android::uirenderer::Caches::hasInstance()) { 605c13d89c1332fcc499379b9064b891187b75ca32Chet Haase android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader); 61ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase } else { 62ad93c2bb63dfc813b2eefa1043aa63afbddce655Chet Haase delete skiaShader; 63a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy } 64a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy#endif 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6706f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic void Shader_setLocalMatrix(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader, 6806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const SkMatrix* matrix) 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 70a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed if (shader) { 71a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed if (NULL == matrix) { 72a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed shader->resetLocalMatrix(); 73a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed } 74a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed else { 75a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed shader->setLocalMatrix(*matrix); 76a04e555dc91b11ad833cb5db4a24e38082d1dc45Mike Reed } 77163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 7806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy skiaShader->setMatrix(const_cast<SkMatrix*>(matrix)); 79163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////// 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8506f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkShader* BitmapShader_constructor(JNIEnv* env, jobject o, const SkBitmap* bitmap, 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tileModeX, int tileModeY) 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* s = SkShader::CreateBitmapShader(*bitmap, 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkShader::TileMode)tileModeX, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (SkShader::TileMode)tileModeY); 9106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, s); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return s; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9606f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkiaShader* BitmapShader_postConstructor(JNIEnv* env, jobject o, SkShader* shader, 9706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkBitmap* bitmap, int tileModeX, int tileModeY) { 98163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 9906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader, 10006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY), 10106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 10206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return skiaShader; 103163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else 104163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return NULL; 105163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 1067fac2e18339f765320d759e8d4c090f92431959eRomain Guy} 1074cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 10806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy/////////////////////////////////////////////////////////////////////////////////////////////// 1097fac2e18339f765320d759e8d4c090f92431959eRomain Guy 1107fac2e18339f765320d759e8d4c090f92431959eRomain Guystatic SkShader* LinearGradient_create1(JNIEnv* env, jobject o, 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x0, float y0, float x1, float y1, 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jintArray colorArray, jfloatArray posArray, int tileMode) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint pts[2]; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0)); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1)); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy size_t count = env->GetArrayLength(colorArray); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0); 1227b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy SkScalar* pos = NULL; 1237fac2e18339f765320d759e8d4c090f92431959eRomain Guy 12406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (posArray) { 12506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy AutoJavaFloatArray autoPos(env, posArray, count); 12606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const float* posValues = autoPos.ptr(); 12706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy pos = (SkScalar*)storage.get(); 12806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy for (size_t i = 0; i < count; i++) { 12906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy pos[i] = SkFloatToScalar(posValues[i]); 13006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 13106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 1324cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 13306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader* shader = SkGradientShader::CreateLinear(pts, 13406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy reinterpret_cast<const SkColor*>(colorValues), 13506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy pos, count, 13606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy static_cast<SkShader::TileMode>(tileMode)); 13706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 13806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); 13906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy ThrowIAE_IfNull(env, shader); 14006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return shader; 14106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 14206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 14306f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader, 14406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float x0, float y0, float x1, float y1, jintArray colorArray, 14506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy jfloatArray posArray, int tileMode) { 146163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 14706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy size_t count = env->GetArrayLength(colorArray); 14806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 14906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 1507fac2e18339f765320d759e8d4c090f92431959eRomain Guy jfloat* storedBounds = new jfloat[4]; 1517fac2e18339f765320d759e8d4c090f92431959eRomain Guy storedBounds[0] = x0; storedBounds[1] = y0; 1527fac2e18339f765320d759e8d4c090f92431959eRomain Guy storedBounds[2] = x1; storedBounds[3] = y1; 15342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 15442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy bool missFirst = false; 15542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy bool missLast = false; 15642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy size_t stopCount = count; 1577fac2e18339f765320d759e8d4c090f92431959eRomain Guy 15842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy jfloat* storedPositions = NULL; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posArray) { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoPos(env, posArray, count); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* posValues = autoPos.ptr(); 16242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 16342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy missFirst = posValues[0] != 0.0f; 16442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy missLast = posValues[count - 1] != 1.0f; 16542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 16642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy stopCount += missFirst + missLast; 16742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions = new jfloat[stopCount]; 16842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 16942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy if (missFirst) { 17042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions[0] = 0.0f; 17142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 17242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 17342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy for (size_t i = missFirst; i < count + missFirst; i++) { 17442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions[i] = posValues[i - missFirst]; 17542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 17642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 17742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy if (missLast) { 17842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions[stopCount - 1] = 1.0f; 1797fac2e18339f765320d759e8d4c090f92431959eRomain Guy } 1807fac2e18339f765320d759e8d4c090f92431959eRomain Guy } else { 18142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions = new jfloat[count]; 1827fac2e18339f765320d759e8d4c090f92431959eRomain Guy storedPositions[0] = 0.0f; 1837b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy const jfloat step = 1.0f / (count - 1); 1847b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy for (size_t i = 1; i < count - 1; i++) { 1857b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[i] = step * i; 1867b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy } 1877b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[count - 1] = 1.0f; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 19042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy uint32_t* storedColors = new uint32_t[stopCount]; 19142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 19242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy if (missFirst) { 19342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedColors[0] = static_cast<uint32_t>(colorValues[0]); 19442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 19542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 19642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy for (size_t i = missFirst; i < count + missFirst; i++) { 19742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedColors[i] = static_cast<uint32_t>(colorValues[i - missFirst]); 19842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 19942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 20042e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy if (missLast) { 20142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedColors[stopCount - 1] = static_cast<uint32_t>(colorValues[count - 1]); 20242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy } 20342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 20406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors, 20542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy storedPositions, stopCount, shader, static_cast<SkShader::TileMode>(tileMode), NULL, 20606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 20706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 20806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); 20906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return skiaShader; 210163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else 211163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return NULL; 212163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 21306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 21406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 21506f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader, 21606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float x0, float y0, float x1, float y1, int color0, int color1, int tileMode) { 217163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 21806f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float* storedBounds = new float[4]; 21906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy storedBounds[0] = x0; storedBounds[1] = y0; 22006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy storedBounds[2] = x1; storedBounds[3] = y1; 22106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 22206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy float* storedPositions = new float[2]; 22306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy storedPositions[0] = 0.0f; 22406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy storedPositions[1] = 1.0f; 22506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 22606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy uint32_t* storedColors = new uint32_t[2]; 22761c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy storedColors[0] = static_cast<uint32_t>(color0); 22861c8c9c5b2006d18e9310b6521c65b36ffe75ce4Romain Guy storedColors[1] = static_cast<uint32_t>(color1); 22906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 23006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors, 23106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL, 23206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 23306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 23406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return skiaShader; 235163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else 236163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return NULL; 237163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2407fac2e18339f765320d759e8d4c090f92431959eRomain Guystatic SkShader* LinearGradient_create2(JNIEnv* env, jobject o, 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x0, float y0, float x1, float y1, 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int color0, int color1, int tileMode) 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint pts[2]; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0)); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1)); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkColor colors[2]; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[0] = color0; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[1] = color1; 2514cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode); 25306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, s); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return s; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////// 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 260ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guystatic SkShader* RadialGradient_create1(JNIEnv* env, jobject, float x, float y, float radius, 261ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy jintArray colorArray, jfloatArray posArray, int tileMode) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint center; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project center.set(SkFloatToScalar(x), SkFloatToScalar(y)); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t count = env->GetArrayLength(colorArray); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar* pos = NULL; 2704cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (posArray) { 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoPos(env, posArray, count); 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* posValues = autoPos.ptr(); 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos = (SkScalar*)storage.get(); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < count; i++) 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos[i] = SkFloatToScalar(posValues[i]); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* shader = SkGradientShader::CreateRadial(center, 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(radius), 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<const SkColor*>(colorValues), 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos, count, 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<SkShader::TileMode>(tileMode)); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNI_ABORT); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, shader); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return shader; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 291ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guystatic SkShader* RadialGradient_create2(JNIEnv* env, jobject, float x, float y, float radius, 292ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy int color0, int color1, int tileMode) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkPoint center; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project center.set(SkFloatToScalar(x), SkFloatToScalar(y)); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkColor colors[2]; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[0] = color0; 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[1] = color1; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* s = SkGradientShader::CreateRadial(center, SkFloatToScalar(radius), colors, NULL, 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2, (SkShader::TileMode)tileMode); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, s); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return s; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 306ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guystatic SkiaShader* RadialGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader, 307ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy float x, float y, float radius, jintArray colorArray, jfloatArray posArray, int tileMode) { 308ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#ifdef USE_OPENGL_RENDERER 309ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy size_t count = env->GetArrayLength(colorArray); 310ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 311ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 312ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy jfloat* storedPositions = new jfloat[count]; 313ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy uint32_t* storedColors = new uint32_t[count]; 314ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy for (size_t i = 0; i < count; i++) { 315ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedColors[i] = static_cast<uint32_t>(colorValues[i]); 316ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy } 317ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 318ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy if (posArray) { 319ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy AutoJavaFloatArray autoPos(env, posArray, count); 320ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy const float* posValues = autoPos.ptr(); 321ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy for (size_t i = 0; i < count; i++) { 322ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions[i] = posValues[i]; 323ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy } 324ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy } else { 325ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions[0] = 0.0f; 3267b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy const jfloat step = 1.0f / (count - 1); 3277b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy for (size_t i = 1; i < count - 1; i++) { 3287b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[i] = step * i; 3297b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy } 3307b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[count - 1] = 1.0f; 331ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy } 332ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 333ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors, 334ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions, count, shader, (SkShader::TileMode) tileMode, NULL, 335ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 336ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 337ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); 338ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy return skiaShader; 339ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#else 340ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy return NULL; 341ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#endif 342ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy} 343ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 344ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guystatic SkiaShader* RadialGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader, 345ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy float x, float y, float radius, int color0, int color1, int tileMode) { 346ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#ifdef USE_OPENGL_RENDERER 347ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy float* storedPositions = new float[2]; 348ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions[0] = 0.0f; 349ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions[1] = 1.0f; 350ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 351ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy uint32_t* storedColors = new uint32_t[2]; 352ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedColors[0] = static_cast<uint32_t>(color0); 353ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedColors[1] = static_cast<uint32_t>(color1); 354ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 355ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors, 356ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy storedPositions, 2, shader, (SkShader::TileMode) tileMode, NULL, 357ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 358ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 359ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy return skiaShader; 360ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#else 361ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy return NULL; 362ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy#endif 363ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy} 364ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkShader* SweepGradient_create1(JNIEnv* env, jobject, float x, float y, 368ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy jintArray jcolors, jfloatArray jpositions) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t count = env->GetArrayLength(jcolors); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const jint* colors = env->GetIntArrayElements(jcolors, NULL); 3714cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkAutoSTMalloc<8, SkScalar> storage(jpositions ? count : 0); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar* pos = NULL; 3744cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != jpositions) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaFloatArray autoPos(env, jpositions, count); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const float* posValues = autoPos.ptr(); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos = (SkScalar*)storage.get(); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < count; i++) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos[i] = SkFloatToScalar(posValues[i]); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* shader = SkGradientShader::CreateSweep(SkFloatToScalar(x), 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkFloatToScalar(y), 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<const SkColor*>(colors), 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pos, count); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors), 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNI_ABORT); 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, shader); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return shader; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y, 395ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy int color0, int color1) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkColor colors[2]; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[0] = color0; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors[1] = color1; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkShader* s = SkGradientShader::CreateSweep(SkFloatToScalar(x), SkFloatToScalar(y), 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project colors, NULL, 2); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ThrowIAE_IfNull(env, s); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return s; 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 405ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guystatic SkiaShader* SweepGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader, 406ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float x, float y, jintArray colorArray, jfloatArray posArray) { 407ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#ifdef USE_OPENGL_RENDERER 408ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy size_t count = env->GetArrayLength(colorArray); 409ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 410ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 411ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy jfloat* storedPositions = new jfloat[count]; 412ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy uint32_t* storedColors = new uint32_t[count]; 413ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy for (size_t i = 0; i < count; i++) { 414ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedColors[i] = static_cast<uint32_t>(colorValues[i]); 415ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 416ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 417ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy if (posArray) { 418ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy AutoJavaFloatArray autoPos(env, posArray, count); 419ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy const float* posValues = autoPos.ptr(); 420ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy for (size_t i = 0; i < count; i++) { 421ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedPositions[i] = posValues[i]; 422ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 423ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } else { 424ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedPositions[0] = 0.0f; 4257b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy const jfloat step = 1.0f / (count - 1); 4267b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy for (size_t i = 1; i < count - 1; i++) { 4277b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[i] = step * i; 4287b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy } 4297b5b6abf852c039983eded25ebe43a70fef5a4abRomain Guy storedPositions[count - 1] = 1.0f; 430ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy } 431ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 432ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, count, 433ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 434ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 435ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT); 436ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy return skiaShader; 437ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#else 438ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy return NULL; 439ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#endif 440ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 441ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 442ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guystatic SkiaShader* SweepGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader, 443ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float x, float y, int color0, int color1) { 444ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#ifdef USE_OPENGL_RENDERER 445ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy float* storedPositions = new float[2]; 446ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedPositions[0] = 0.0f; 447ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedPositions[1] = 1.0f; 448ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 449ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy uint32_t* storedColors = new uint32_t[2]; 450ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedColors[0] = static_cast<uint32_t>(color0); 451ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy storedColors[1] = static_cast<uint32_t>(color1); 452ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 453ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, 2, 454ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0); 455ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 456ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy return skiaShader; 457ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#else 458ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy return NULL; 459ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy#endif 460ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy} 461ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////// 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 46406f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkShader* ComposeShader_create1(JNIEnv* env, jobject o, 46506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader* shaderA, SkShader* shaderB, SkXfermode* mode) 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new SkComposeShader(shaderA, shaderB, mode); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47006f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkShader* ComposeShader_create2(JNIEnv* env, jobject o, 47106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode porterDuffMode) 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 47306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkAutoUnref au(SkPorterDuff::CreateXfermode(porterDuffMode)); 47406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkXfermode* mode = (SkXfermode*) au.get(); 47506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return new SkComposeShader(shaderA, shaderB, mode); 47606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 47706f96e2652e4855b6520ad9dd70583677605b79aRomain Guy 47806f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* shader, 47906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader* shaderA, SkiaShader* shaderB, SkPorterDuff::Mode porterDuffMode) { 480163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 48148daa54d31fc59ec969dcff65eb3cbb0ce879a8dRomain Guy SkXfermode::Mode mode = SkPorterDuff::ToXfermodeMode(porterDuffMode); 48248daa54d31fc59ec969dcff65eb3cbb0ce879a8dRomain Guy return new SkiaComposeShader(shaderA, shaderB, mode, shader); 483163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else 484163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return NULL; 485163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 48606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy} 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48806f96e2652e4855b6520ad9dd70583677605b79aRomain Guystatic SkiaShader* ComposeShader_postCreate1(JNIEnv* env, jobject o, SkShader* shader, 48906f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkiaShader* shaderA, SkiaShader* shaderB, SkXfermode* mode) { 490163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#ifdef USE_OPENGL_RENDERER 49106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy SkXfermode::Mode skiaMode; 49206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy if (!SkXfermode::IsMode(mode, &skiaMode)) { 49348daa54d31fc59ec969dcff65eb3cbb0ce879a8dRomain Guy // TODO: Support other modes 49406f96e2652e4855b6520ad9dd70583677605b79aRomain Guy skiaMode = SkXfermode::kSrcOver_Mode; 49506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy } 49606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy return new SkiaComposeShader(shaderA, shaderB, skiaMode, shader); 497163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#else 498163935113919a184122b8b3bd672ef08c8df65dcRomain Guy return NULL; 499163935113919a184122b8b3bd672ef08c8df65dcRomain Guy#endif 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////////////////////// 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gColorMethods[] = { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeRGBToHSV", "(III[F)V", (void*)Color_RGBToHSV }, 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeHSVToColor", "(I[F)I", (void*)Color_HSVToColor } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gShaderMethods[] = { 51006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativeDestructor", "(II)V", (void*)Shader_destructor }, 51106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativeSetLocalMatrix", "(III)V", (void*)Shader_setLocalMatrix } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gBitmapShaderMethods[] = { 51506f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativeCreate", "(III)I", (void*)BitmapShader_constructor }, 51606f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativePostCreate", "(IIII)I", (void*)BitmapShader_postConstructor } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gLinearGradientMethods[] = { 52006f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 }, 52106f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 }, 52206f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativePostCreate1", "(IFFFF[I[FI)I", (void*)LinearGradient_postCreate1 }, 52306f96e2652e4855b6520ad9dd70583677605b79aRomain Guy { "nativePostCreate2", "(IFFFFIII)I", (void*)LinearGradient_postCreate2 } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gRadialGradientMethods[] = { 527ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate1", "(FFF[I[FI)I", (void*)RadialGradient_create1 }, 528ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate2", "(FFFIII)I", (void*)RadialGradient_create2 }, 529ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativePostCreate1", "(IFFF[I[FI)I", (void*)RadialGradient_postCreate1 }, 530ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativePostCreate2", "(IFFFIII)I", (void*)RadialGradient_postCreate2 } 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gSweepGradientMethods[] = { 534ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate1", "(FF[I[F)I", (void*)SweepGradient_create1 }, 535ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate2", "(FFII)I", (void*)SweepGradient_create2 }, 536ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy { "nativePostCreate1", "(IFF[I[F)I", (void*)SweepGradient_postCreate1 }, 537ee916f14cbd1fe1422c063ce2ef7b185e2bc5c6fRomain Guy { "nativePostCreate2", "(IFFII)I", (void*)SweepGradient_postCreate2 } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gComposeShaderMethods[] = { 541ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate1", "(III)I", (void*)ComposeShader_create1 }, 542ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativeCreate2", "(III)I", (void*)ComposeShader_create2 }, 543ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativePostCreate1", "(IIII)I", (void*)ComposeShader_postCreate1 }, 544ddb80bebb0776e6d852aab6e8bba5d5591847a55Romain Guy { "nativePostCreate2", "(IIII)I", (void*)ComposeShader_postCreate2 } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REG(env, name, array) \ 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = android::AndroidRuntime::registerNativeMethods(env, name, array, SK_ARRAY_COUNT(array)); \ 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result < 0) return result 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Shader(JNIEnv* env) 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int result; 5564cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/Color", gColorMethods); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/Shader", gShaderMethods); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/BitmapShader", gBitmapShaderMethods); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/LinearGradient", gLinearGradientMethods); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/RadialGradient", gRadialGradientMethods); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/SweepGradient", gSweepGradientMethods); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project REG(env, "android/graphics/ComposeShader", gComposeShaderMethods); 5644cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 567