Shader.cpp revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
1#include <jni.h> 2#include "GraphicsJNI.h" 3 4#include "SkShader.h" 5#include "SkGradientShader.h" 6#include "SkPorterDuff.h" 7#include "SkShaderExtras.h" 8#include "SkTemplates.h" 9#include "SkXfermode.h" 10 11static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) { 12 if (NULL == ptr) { 13 doThrowIAE(env); 14 } 15} 16 17static void Color_RGBToHSV(JNIEnv* env, jobject, int red, int green, int blue, jfloatArray hsvArray) 18{ 19 SkScalar hsv[3]; 20 SkRGBToHSV(red, green, blue, hsv); 21 22 AutoJavaFloatArray autoHSV(env, hsvArray, 3); 23 float* values = autoHSV.ptr(); 24 for (int i = 0; i < 3; i++) { 25 values[i] = SkScalarToFloat(hsv[i]); 26 } 27} 28 29static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArray) 30{ 31 AutoJavaFloatArray autoHSV(env, hsvArray, 3); 32 float* values = autoHSV.ptr();; 33 SkScalar hsv[3]; 34 35 for (int i = 0; i < 3; i++) { 36 hsv[i] = SkFloatToScalar(values[i]); 37 } 38 39 return SkHSVToColor(alpha, hsv); 40} 41 42/////////////////////////////////////////////////////////////////////////////////////////////// 43 44static void Shader_destructor(JNIEnv* env, jobject, SkShader* shader) 45{ 46 SkASSERT(shader != NULL); 47 shader->unref(); 48} 49 50static bool Shader_getLocalMatrix(JNIEnv* env, jobject, const SkShader* shader, SkMatrix* matrix) 51{ 52 SkASSERT(shader != NULL); 53 return shader->getLocalMatrix(matrix); 54} 55 56static void Shader_setLocalMatrix(JNIEnv* env, jobject, SkShader* shader, const SkMatrix* matrix) 57{ 58 SkASSERT(shader != NULL); 59 60 if (NULL == matrix) { 61 shader->resetLocalMatrix(); 62 } 63 else { 64 shader->setLocalMatrix(*matrix); 65 } 66} 67 68/////////////////////////////////////////////////////////////////////////////////////////////// 69 70static SkShader* BitmapShader_constructor(JNIEnv* env, jobject, const SkBitmap* bitmap, 71 int tileModeX, int tileModeY) 72{ 73 SkShader* s = SkShader::CreateBitmapShader(*bitmap, 74 (SkShader::TileMode)tileModeX, 75 (SkShader::TileMode)tileModeY); 76 ThrowIAE_IfNull(env, s); 77 return s; 78} 79 80/////////////////////////////////////////////////////////////////////////////////////////////// 81 82static SkShader* LinearGradient_create1(JNIEnv* env, jobject, 83 float x0, float y0, float x1, float y1, 84 jintArray colorArray, jfloatArray posArray, int tileMode) 85{ 86 SkPoint pts[2]; 87 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0)); 88 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1)); 89 90 size_t count = env->GetArrayLength(colorArray); 91 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 92 93 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0); 94 SkScalar* pos = NULL; 95 96 if (posArray) { 97 AutoJavaFloatArray autoPos(env, posArray, count); 98 const float* posValues = autoPos.ptr(); 99 pos = (SkScalar*)storage.get(); 100 for (size_t i = 0; i < count; i++) 101 pos[i] = SkFloatToScalar(posValues[i]); 102 } 103 104 SkShader* shader = SkGradientShader::CreateLinear(pts, 105 reinterpret_cast<const SkColor*>(colorValues), 106 pos, count, 107 static_cast<SkShader::TileMode>(tileMode)); 108 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), 109 JNI_ABORT); 110 ThrowIAE_IfNull(env, shader); 111 return shader; 112} 113 114static SkShader* LinearGradient_create2(JNIEnv* env, jobject, 115 float x0, float y0, float x1, float y1, 116 int color0, int color1, int tileMode) 117{ 118 SkPoint pts[2]; 119 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0)); 120 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1)); 121 122 SkColor colors[2]; 123 colors[0] = color0; 124 colors[1] = color1; 125 126 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode); 127 ThrowIAE_IfNull(env, s); 128 return s; 129} 130 131/////////////////////////////////////////////////////////////////////////////////////////////// 132 133static SkShader* RadialGradient_create1(JNIEnv* env, jobject, 134 float x, float y, float radius, 135 jintArray colorArray, jfloatArray posArray, int tileMode) 136{ 137 SkPoint center; 138 center.set(SkFloatToScalar(x), SkFloatToScalar(y)); 139 140 size_t count = env->GetArrayLength(colorArray); 141 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL); 142 143 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0); 144 SkScalar* pos = NULL; 145 146 if (posArray) { 147 AutoJavaFloatArray autoPos(env, posArray, count); 148 const float* posValues = autoPos.ptr(); 149 pos = (SkScalar*)storage.get(); 150 for (size_t i = 0; i < count; i++) 151 pos[i] = SkFloatToScalar(posValues[i]); 152 } 153 154 SkShader* shader = SkGradientShader::CreateRadial(center, 155 SkFloatToScalar(radius), 156 reinterpret_cast<const SkColor*>(colorValues), 157 pos, count, 158 static_cast<SkShader::TileMode>(tileMode)); 159 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), 160 JNI_ABORT); 161 162 ThrowIAE_IfNull(env, shader); 163 return shader; 164} 165 166static SkShader* RadialGradient_create2(JNIEnv* env, jobject, 167 float x, float y, float radius, 168 int color0, int color1, int tileMode) 169{ 170 SkPoint center; 171 center.set(SkFloatToScalar(x), SkFloatToScalar(y)); 172 173 SkColor colors[2]; 174 colors[0] = color0; 175 colors[1] = color1; 176 177 SkShader* s = SkGradientShader::CreateRadial(center, SkFloatToScalar(radius), colors, NULL, 178 2, (SkShader::TileMode)tileMode); 179 ThrowIAE_IfNull(env, s); 180 return s; 181} 182 183/////////////////////////////////////////////////////////////////////////////// 184 185static SkShader* SweepGradient_create1(JNIEnv* env, jobject, float x, float y, 186 jintArray jcolors, jfloatArray jpositions) 187{ 188 size_t count = env->GetArrayLength(jcolors); 189 const jint* colors = env->GetIntArrayElements(jcolors, NULL); 190 191 SkAutoSTMalloc<8, SkScalar> storage(jpositions ? count : 0); 192 SkScalar* pos = NULL; 193 194 if (NULL != jpositions) { 195 AutoJavaFloatArray autoPos(env, jpositions, count); 196 const float* posValues = autoPos.ptr(); 197 pos = (SkScalar*)storage.get(); 198 for (size_t i = 0; i < count; i++) { 199 pos[i] = SkFloatToScalar(posValues[i]); 200 } 201 } 202 203 SkShader* shader = SkGradientShader::CreateSweep(SkFloatToScalar(x), 204 SkFloatToScalar(y), 205 reinterpret_cast<const SkColor*>(colors), 206 pos, count); 207 env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors), 208 JNI_ABORT); 209 ThrowIAE_IfNull(env, shader); 210 return shader; 211} 212 213static SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y, 214 int color0, int color1) 215{ 216 SkColor colors[2]; 217 colors[0] = color0; 218 colors[1] = color1; 219 SkShader* s = SkGradientShader::CreateSweep(SkFloatToScalar(x), SkFloatToScalar(y), 220 colors, NULL, 2); 221 ThrowIAE_IfNull(env, s); 222 return s; 223} 224 225/////////////////////////////////////////////////////////////////////////////////////////////// 226 227static SkShader* ComposeShader_create1(JNIEnv* env, jobject, 228 SkShader* shaderA, SkShader* shaderB, SkXfermode* mode) 229{ 230 return new SkComposeShader(shaderA, shaderB, mode); 231} 232 233static SkShader* ComposeShader_create2(JNIEnv* env, jobject, 234 SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode mode) 235{ 236 SkAutoUnref au(SkPorterDuff::CreateXfermode(mode)); 237 238 return new SkComposeShader(shaderA, shaderB, (SkXfermode*)au.get()); 239} 240 241/////////////////////////////////////////////////////////////////////////////////////////////// 242 243static JNINativeMethod gColorMethods[] = { 244 { "nativeRGBToHSV", "(III[F)V", (void*)Color_RGBToHSV }, 245 { "nativeHSVToColor", "(I[F)I", (void*)Color_HSVToColor } 246}; 247 248static JNINativeMethod gShaderMethods[] = { 249 { "nativeDestructor", "(I)V", (void*)Shader_destructor }, 250 { "nativeGetLocalMatrix", "(II)Z", (void*)Shader_getLocalMatrix }, 251 { "nativeSetLocalMatrix", "(II)V", (void*)Shader_setLocalMatrix } 252}; 253 254static JNINativeMethod gBitmapShaderMethods[] = { 255 { "nativeCreate", "(III)I", (void*)BitmapShader_constructor } 256}; 257 258static JNINativeMethod gLinearGradientMethods[] = { 259 { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 }, 260 { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 } 261}; 262 263static JNINativeMethod gRadialGradientMethods[] = { 264 {"nativeCreate1", "(FFF[I[FI)I", (void*)RadialGradient_create1 }, 265 {"nativeCreate2", "(FFFIII)I", (void*)RadialGradient_create2 } 266}; 267 268static JNINativeMethod gSweepGradientMethods[] = { 269 {"nativeCreate1", "(FF[I[F)I", (void*)SweepGradient_create1 }, 270 {"nativeCreate2", "(FFII)I", (void*)SweepGradient_create2 } 271}; 272 273static JNINativeMethod gComposeShaderMethods[] = { 274 {"nativeCreate1", "(III)I", (void*)ComposeShader_create1 }, 275 {"nativeCreate2", "(III)I", (void*)ComposeShader_create2 } 276}; 277 278#include <android_runtime/AndroidRuntime.h> 279 280#define REG(env, name, array) \ 281 result = android::AndroidRuntime::registerNativeMethods(env, name, array, SK_ARRAY_COUNT(array)); \ 282 if (result < 0) return result 283 284int register_android_graphics_Shader(JNIEnv* env); 285int register_android_graphics_Shader(JNIEnv* env) 286{ 287 int result; 288 289 REG(env, "android/graphics/Color", gColorMethods); 290 REG(env, "android/graphics/Shader", gShaderMethods); 291 REG(env, "android/graphics/BitmapShader", gBitmapShaderMethods); 292 REG(env, "android/graphics/LinearGradient", gLinearGradientMethods); 293 REG(env, "android/graphics/RadialGradient", gRadialGradientMethods); 294 REG(env, "android/graphics/SweepGradient", gSweepGradientMethods); 295 REG(env, "android/graphics/ComposeShader", gComposeShaderMethods); 296 297 return result; 298} 299 300