blob: 4be1321043e9cd29125d40209d2f00d3f9516f76 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#include <jni.h>
2#include "GraphicsJNI.h"
3
4#include "SkShader.h"
5#include "SkGradientShader.h"
6#include "SkPorterDuff.h"
7#include "SkComposeShader.h"
8#include "SkTemplates.h"
9#include "SkXfermode.h"
10
Romain Guy06f96e22010-07-30 19:18:16 -070011#include <SkiaShader.h>
Romain Guya2341a92010-09-08 18:04:33 -070012#include <Caches.h>
Romain Guy06f96e22010-07-30 19:18:16 -070013
14using namespace android::uirenderer;
15
Romain Guy7fac2e12010-07-16 17:10:13 -070016static struct {
17 jclass clazz;
Romain Guy06f96e22010-07-30 19:18:16 -070018 jfieldID shader;
19} gShaderClassInfo;
Romain Guy7fac2e12010-07-16 17:10:13 -070020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
22 if (NULL == ptr) {
23 doThrowIAE(env);
24 }
25}
26
27static void Color_RGBToHSV(JNIEnv* env, jobject, int red, int green, int blue, jfloatArray hsvArray)
28{
29 SkScalar hsv[3];
30 SkRGBToHSV(red, green, blue, hsv);
31
32 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
33 float* values = autoHSV.ptr();
34 for (int i = 0; i < 3; i++) {
35 values[i] = SkScalarToFloat(hsv[i]);
36 }
37}
38
39static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArray)
40{
41 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
42 float* values = autoHSV.ptr();;
43 SkScalar hsv[3];
44
45 for (int i = 0; i < 3; i++) {
46 hsv[i] = SkFloatToScalar(values[i]);
47 }
48
49 return SkHSVToColor(alpha, hsv);
50}
51
52///////////////////////////////////////////////////////////////////////////////////////////////
53
Romain Guy06f96e22010-07-30 19:18:16 -070054static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055{
Chet Haase5c13d892010-10-08 08:37:55 -070056 shader->safeUnref();
57 // skiaShader == NULL when not !USE_OPENGL_RENDERER, so no need to delete it outside the ifdef
Romain Guya2341a92010-09-08 18:04:33 -070058#ifdef USE_OPENGL_RENDERER
59 if (android::uirenderer::Caches::hasInstance()) {
Chet Haase5c13d892010-10-08 08:37:55 -070060 android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader);
Chet Haasead93c2b2010-10-22 16:17:12 -070061 } else {
62 delete skiaShader;
Romain Guya2341a92010-09-08 18:04:33 -070063 }
64#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065}
66
67static bool Shader_getLocalMatrix(JNIEnv* env, jobject, const SkShader* shader, SkMatrix* matrix)
68{
Mike Reeda04e5552009-07-30 11:05:57 -040069 return shader ? shader->getLocalMatrix(matrix) : false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070}
71
Romain Guy06f96e22010-07-30 19:18:16 -070072static void Shader_setLocalMatrix(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader,
73 const SkMatrix* matrix)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074{
Mike Reeda04e5552009-07-30 11:05:57 -040075 if (shader) {
76 if (NULL == matrix) {
77 shader->resetLocalMatrix();
78 }
79 else {
80 shader->setLocalMatrix(*matrix);
81 }
Romain Guy16393512010-08-08 00:14:31 -070082#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -070083 skiaShader->setMatrix(const_cast<SkMatrix*>(matrix));
Romain Guy16393512010-08-08 00:14:31 -070084#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 }
86}
87
88///////////////////////////////////////////////////////////////////////////////////////////////
89
Romain Guy06f96e22010-07-30 19:18:16 -070090static SkShader* BitmapShader_constructor(JNIEnv* env, jobject o, const SkBitmap* bitmap,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 int tileModeX, int tileModeY)
92{
93 SkShader* s = SkShader::CreateBitmapShader(*bitmap,
94 (SkShader::TileMode)tileModeX,
95 (SkShader::TileMode)tileModeY);
Romain Guy06f96e22010-07-30 19:18:16 -070096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 ThrowIAE_IfNull(env, s);
98 return s;
99}
Romain Guy06f96e22010-07-30 19:18:16 -0700100
101static SkiaShader* BitmapShader_postConstructor(JNIEnv* env, jobject o, SkShader* shader,
102 SkBitmap* bitmap, int tileModeX, int tileModeY) {
Romain Guy16393512010-08-08 00:14:31 -0700103#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700104 SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader,
105 static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY),
106 NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
107 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700108#else
109 return NULL;
110#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700111}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
113///////////////////////////////////////////////////////////////////////////////////////////////
114
Romain Guy7fac2e12010-07-16 17:10:13 -0700115static SkShader* LinearGradient_create1(JNIEnv* env, jobject o,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 float x0, float y0, float x1, float y1,
117 jintArray colorArray, jfloatArray posArray, int tileMode)
118{
119 SkPoint pts[2];
120 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0));
121 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1));
122
Romain Guy06f96e22010-07-30 19:18:16 -0700123 size_t count = env->GetArrayLength(colorArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
125
126 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
127 SkScalar* pos = NULL;
Romain Guy7fac2e12010-07-16 17:10:13 -0700128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 if (posArray) {
130 AutoJavaFloatArray autoPos(env, posArray, count);
131 const float* posValues = autoPos.ptr();
132 pos = (SkScalar*)storage.get();
Romain Guy7fac2e12010-07-16 17:10:13 -0700133 for (size_t i = 0; i < count; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 pos[i] = SkFloatToScalar(posValues[i]);
Romain Guy06f96e22010-07-30 19:18:16 -0700135 }
136 }
137
138 SkShader* shader = SkGradientShader::CreateLinear(pts,
139 reinterpret_cast<const SkColor*>(colorValues),
140 pos, count,
141 static_cast<SkShader::TileMode>(tileMode));
142
143 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
144 ThrowIAE_IfNull(env, shader);
145 return shader;
146}
147
148static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
149 float x0, float y0, float x1, float y1, jintArray colorArray,
150 jfloatArray posArray, int tileMode) {
Romain Guy16393512010-08-08 00:14:31 -0700151#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700152 size_t count = env->GetArrayLength(colorArray);
153 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
154
155 jfloat* storedBounds = new jfloat[4];
156 storedBounds[0] = x0; storedBounds[1] = y0;
157 storedBounds[2] = x1; storedBounds[3] = y1;
158 jfloat* storedPositions = new jfloat[count];
159 uint32_t* storedColors = new uint32_t[count];
Romain Guy61c8c9c2010-08-09 20:48:09 -0700160 for (size_t i = 0; i < count; i++) {
161 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
162 }
Romain Guy06f96e22010-07-30 19:18:16 -0700163
164 if (posArray) {
165 AutoJavaFloatArray autoPos(env, posArray, count);
166 const float* posValues = autoPos.ptr();
167 for (size_t i = 0; i < count; i++) {
Romain Guy7fac2e12010-07-16 17:10:13 -0700168 storedPositions[i] = posValues[i];
169 }
170 } else {
171 storedPositions[0] = 0.0f;
172 storedPositions[1] = 1.0f;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 }
Romain Guy06f96e22010-07-30 19:18:16 -0700174
175 SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
176 storedPositions, count, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
177 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
178
179 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
180 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700181#else
182 return NULL;
183#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700184}
185
186static SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
187 float x0, float y0, float x1, float y1, int color0, int color1, int tileMode) {
Romain Guy16393512010-08-08 00:14:31 -0700188#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700189 float* storedBounds = new float[4];
190 storedBounds[0] = x0; storedBounds[1] = y0;
191 storedBounds[2] = x1; storedBounds[3] = y1;
192
193 float* storedPositions = new float[2];
194 storedPositions[0] = 0.0f;
195 storedPositions[1] = 1.0f;
196
197 uint32_t* storedColors = new uint32_t[2];
Romain Guy61c8c9c2010-08-09 20:48:09 -0700198 storedColors[0] = static_cast<uint32_t>(color0);
199 storedColors[1] = static_cast<uint32_t>(color1);
Romain Guy06f96e22010-07-30 19:18:16 -0700200
201 SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
202 storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
203 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
204
205 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700206#else
207 return NULL;
208#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209}
210
Romain Guy7fac2e12010-07-16 17:10:13 -0700211static SkShader* LinearGradient_create2(JNIEnv* env, jobject o,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 float x0, float y0, float x1, float y1,
213 int color0, int color1, int tileMode)
214{
215 SkPoint pts[2];
216 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0));
217 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1));
218
219 SkColor colors[2];
220 colors[0] = color0;
221 colors[1] = color1;
Romain Guy7fac2e12010-07-16 17:10:13 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode);
Romain Guy06f96e22010-07-30 19:18:16 -0700224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 ThrowIAE_IfNull(env, s);
226 return s;
227}
228
229///////////////////////////////////////////////////////////////////////////////////////////////
230
Romain Guyddb80be2010-09-20 19:04:33 -0700231static SkShader* RadialGradient_create1(JNIEnv* env, jobject, float x, float y, float radius,
232 jintArray colorArray, jfloatArray posArray, int tileMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 SkPoint center;
234 center.set(SkFloatToScalar(x), SkFloatToScalar(y));
235
236 size_t count = env->GetArrayLength(colorArray);
237 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
238
239 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
240 SkScalar* pos = NULL;
241
242 if (posArray) {
243 AutoJavaFloatArray autoPos(env, posArray, count);
244 const float* posValues = autoPos.ptr();
245 pos = (SkScalar*)storage.get();
246 for (size_t i = 0; i < count; i++)
247 pos[i] = SkFloatToScalar(posValues[i]);
248 }
249
250 SkShader* shader = SkGradientShader::CreateRadial(center,
251 SkFloatToScalar(radius),
252 reinterpret_cast<const SkColor*>(colorValues),
253 pos, count,
254 static_cast<SkShader::TileMode>(tileMode));
255 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
256 JNI_ABORT);
257
258 ThrowIAE_IfNull(env, shader);
259 return shader;
260}
261
Romain Guyddb80be2010-09-20 19:04:33 -0700262static SkShader* RadialGradient_create2(JNIEnv* env, jobject, float x, float y, float radius,
263 int color0, int color1, int tileMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 SkPoint center;
265 center.set(SkFloatToScalar(x), SkFloatToScalar(y));
266
267 SkColor colors[2];
268 colors[0] = color0;
269 colors[1] = color1;
270
271 SkShader* s = SkGradientShader::CreateRadial(center, SkFloatToScalar(radius), colors, NULL,
272 2, (SkShader::TileMode)tileMode);
273 ThrowIAE_IfNull(env, s);
274 return s;
275}
276
Romain Guyddb80be2010-09-20 19:04:33 -0700277static SkiaShader* RadialGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
278 float x, float y, float radius, jintArray colorArray, jfloatArray posArray, int tileMode) {
279#ifdef USE_OPENGL_RENDERER
280 size_t count = env->GetArrayLength(colorArray);
281 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
282
283 jfloat* storedPositions = new jfloat[count];
284 uint32_t* storedColors = new uint32_t[count];
285 for (size_t i = 0; i < count; i++) {
286 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
287 }
288
289 if (posArray) {
290 AutoJavaFloatArray autoPos(env, posArray, count);
291 const float* posValues = autoPos.ptr();
292 for (size_t i = 0; i < count; i++) {
293 storedPositions[i] = posValues[i];
294 }
295 } else {
296 storedPositions[0] = 0.0f;
297 storedPositions[1] = 1.0f;
298 }
299
300 SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors,
301 storedPositions, count, shader, (SkShader::TileMode) tileMode, NULL,
302 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
303
304 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
305 return skiaShader;
306#else
307 return NULL;
308#endif
309}
310
311static SkiaShader* RadialGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
312 float x, float y, float radius, int color0, int color1, int tileMode) {
313#ifdef USE_OPENGL_RENDERER
314 float* storedPositions = new float[2];
315 storedPositions[0] = 0.0f;
316 storedPositions[1] = 1.0f;
317
318 uint32_t* storedColors = new uint32_t[2];
319 storedColors[0] = static_cast<uint32_t>(color0);
320 storedColors[1] = static_cast<uint32_t>(color1);
321
322 SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors,
323 storedPositions, 2, shader, (SkShader::TileMode) tileMode, NULL,
324 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
325
326 return skiaShader;
327#else
328 return NULL;
329#endif
330}
331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332///////////////////////////////////////////////////////////////////////////////
333
334static SkShader* SweepGradient_create1(JNIEnv* env, jobject, float x, float y,
Romain Guyddb80be2010-09-20 19:04:33 -0700335 jintArray jcolors, jfloatArray jpositions) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 size_t count = env->GetArrayLength(jcolors);
337 const jint* colors = env->GetIntArrayElements(jcolors, NULL);
338
339 SkAutoSTMalloc<8, SkScalar> storage(jpositions ? count : 0);
340 SkScalar* pos = NULL;
341
342 if (NULL != jpositions) {
343 AutoJavaFloatArray autoPos(env, jpositions, count);
344 const float* posValues = autoPos.ptr();
345 pos = (SkScalar*)storage.get();
346 for (size_t i = 0; i < count; i++) {
347 pos[i] = SkFloatToScalar(posValues[i]);
348 }
349 }
350
351 SkShader* shader = SkGradientShader::CreateSweep(SkFloatToScalar(x),
352 SkFloatToScalar(y),
353 reinterpret_cast<const SkColor*>(colors),
354 pos, count);
355 env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
356 JNI_ABORT);
357 ThrowIAE_IfNull(env, shader);
358 return shader;
359}
360
361static SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y,
Romain Guyddb80be2010-09-20 19:04:33 -0700362 int color0, int color1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 SkColor colors[2];
364 colors[0] = color0;
365 colors[1] = color1;
366 SkShader* s = SkGradientShader::CreateSweep(SkFloatToScalar(x), SkFloatToScalar(y),
367 colors, NULL, 2);
368 ThrowIAE_IfNull(env, s);
369 return s;
370}
371
Romain Guyee916f12010-09-20 17:53:08 -0700372static SkiaShader* SweepGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
373 float x, float y, jintArray colorArray, jfloatArray posArray) {
374#ifdef USE_OPENGL_RENDERER
375 size_t count = env->GetArrayLength(colorArray);
376 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
377
378 jfloat* storedPositions = new jfloat[count];
379 uint32_t* storedColors = new uint32_t[count];
380 for (size_t i = 0; i < count; i++) {
381 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
382 }
383
384 if (posArray) {
385 AutoJavaFloatArray autoPos(env, posArray, count);
386 const float* posValues = autoPos.ptr();
387 for (size_t i = 0; i < count; i++) {
388 storedPositions[i] = posValues[i];
389 }
390 } else {
391 storedPositions[0] = 0.0f;
392 storedPositions[1] = 1.0f;
393 }
394
395 SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, count,
396 shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
397
398 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
399 return skiaShader;
400#else
401 return NULL;
402#endif
403}
404
405static SkiaShader* SweepGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
406 float x, float y, int color0, int color1) {
407#ifdef USE_OPENGL_RENDERER
408 float* storedPositions = new float[2];
409 storedPositions[0] = 0.0f;
410 storedPositions[1] = 1.0f;
411
412 uint32_t* storedColors = new uint32_t[2];
413 storedColors[0] = static_cast<uint32_t>(color0);
414 storedColors[1] = static_cast<uint32_t>(color1);
415
416 SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, 2,
417 shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
418
419 return skiaShader;
420#else
421 return NULL;
422#endif
423}
424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425///////////////////////////////////////////////////////////////////////////////////////////////
426
Romain Guy06f96e22010-07-30 19:18:16 -0700427static SkShader* ComposeShader_create1(JNIEnv* env, jobject o,
428 SkShader* shaderA, SkShader* shaderB, SkXfermode* mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429{
430 return new SkComposeShader(shaderA, shaderB, mode);
431}
432
Romain Guy06f96e22010-07-30 19:18:16 -0700433static SkShader* ComposeShader_create2(JNIEnv* env, jobject o,
434 SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode porterDuffMode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435{
Romain Guy06f96e22010-07-30 19:18:16 -0700436 SkAutoUnref au(SkPorterDuff::CreateXfermode(porterDuffMode));
437 SkXfermode* mode = (SkXfermode*) au.get();
438 return new SkComposeShader(shaderA, shaderB, mode);
439}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440
Romain Guy06f96e22010-07-30 19:18:16 -0700441static SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
442 SkiaShader* shaderA, SkiaShader* shaderB, SkPorterDuff::Mode porterDuffMode) {
Romain Guy16393512010-08-08 00:14:31 -0700443#ifdef USE_OPENGL_RENDERER
Romain Guy48daa542010-08-10 19:21:34 -0700444 SkXfermode::Mode mode = SkPorterDuff::ToXfermodeMode(porterDuffMode);
445 return new SkiaComposeShader(shaderA, shaderB, mode, shader);
Romain Guy16393512010-08-08 00:14:31 -0700446#else
447 return NULL;
448#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700449}
450
451static SkiaShader* ComposeShader_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
452 SkiaShader* shaderA, SkiaShader* shaderB, SkXfermode* mode) {
Romain Guy16393512010-08-08 00:14:31 -0700453#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700454 SkXfermode::Mode skiaMode;
455 if (!SkXfermode::IsMode(mode, &skiaMode)) {
Romain Guy48daa542010-08-10 19:21:34 -0700456 // TODO: Support other modes
Romain Guy06f96e22010-07-30 19:18:16 -0700457 skiaMode = SkXfermode::kSrcOver_Mode;
458 }
459 return new SkiaComposeShader(shaderA, shaderB, skiaMode, shader);
Romain Guy16393512010-08-08 00:14:31 -0700460#else
461 return NULL;
462#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463}
464
465///////////////////////////////////////////////////////////////////////////////////////////////
466
467static JNINativeMethod gColorMethods[] = {
468 { "nativeRGBToHSV", "(III[F)V", (void*)Color_RGBToHSV },
469 { "nativeHSVToColor", "(I[F)I", (void*)Color_HSVToColor }
470};
471
472static JNINativeMethod gShaderMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700473 { "nativeDestructor", "(II)V", (void*)Shader_destructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 { "nativeGetLocalMatrix", "(II)Z", (void*)Shader_getLocalMatrix },
Romain Guy06f96e22010-07-30 19:18:16 -0700475 { "nativeSetLocalMatrix", "(III)V", (void*)Shader_setLocalMatrix }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476};
477
478static JNINativeMethod gBitmapShaderMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700479 { "nativeCreate", "(III)I", (void*)BitmapShader_constructor },
480 { "nativePostCreate", "(IIII)I", (void*)BitmapShader_postConstructor }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481};
482
483static JNINativeMethod gLinearGradientMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700484 { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
485 { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 },
486 { "nativePostCreate1", "(IFFFF[I[FI)I", (void*)LinearGradient_postCreate1 },
487 { "nativePostCreate2", "(IFFFFIII)I", (void*)LinearGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488};
489
490static JNINativeMethod gRadialGradientMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700491 { "nativeCreate1", "(FFF[I[FI)I", (void*)RadialGradient_create1 },
492 { "nativeCreate2", "(FFFIII)I", (void*)RadialGradient_create2 },
493 { "nativePostCreate1", "(IFFF[I[FI)I", (void*)RadialGradient_postCreate1 },
494 { "nativePostCreate2", "(IFFFIII)I", (void*)RadialGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495};
496
497static JNINativeMethod gSweepGradientMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700498 { "nativeCreate1", "(FF[I[F)I", (void*)SweepGradient_create1 },
499 { "nativeCreate2", "(FFII)I", (void*)SweepGradient_create2 },
Romain Guyee916f12010-09-20 17:53:08 -0700500 { "nativePostCreate1", "(IFF[I[F)I", (void*)SweepGradient_postCreate1 },
501 { "nativePostCreate2", "(IFFII)I", (void*)SweepGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502};
503
504static JNINativeMethod gComposeShaderMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700505 { "nativeCreate1", "(III)I", (void*)ComposeShader_create1 },
506 { "nativeCreate2", "(III)I", (void*)ComposeShader_create2 },
507 { "nativePostCreate1", "(IIII)I", (void*)ComposeShader_postCreate1 },
508 { "nativePostCreate2", "(IIII)I", (void*)ComposeShader_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509};
510
511#include <android_runtime/AndroidRuntime.h>
512
513#define REG(env, name, array) \
514 result = android::AndroidRuntime::registerNativeMethods(env, name, array, SK_ARRAY_COUNT(array)); \
515 if (result < 0) return result
516
517int register_android_graphics_Shader(JNIEnv* env);
518int register_android_graphics_Shader(JNIEnv* env)
519{
520 int result;
521
522 REG(env, "android/graphics/Color", gColorMethods);
523 REG(env, "android/graphics/Shader", gShaderMethods);
524 REG(env, "android/graphics/BitmapShader", gBitmapShaderMethods);
525 REG(env, "android/graphics/LinearGradient", gLinearGradientMethods);
526 REG(env, "android/graphics/RadialGradient", gRadialGradientMethods);
527 REG(env, "android/graphics/SweepGradient", gSweepGradientMethods);
528 REG(env, "android/graphics/ComposeShader", gComposeShaderMethods);
529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 return result;
531}
532