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