1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "SkRegion.h"
18*d57664e9SAndroid Build Coastguard Worker #include "SkPath.h"
19*d57664e9SAndroid Build Coastguard Worker #include "GraphicsJNI.h"
20*d57664e9SAndroid Build Coastguard Worker
21*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ // Layoutlib does not support parcel
22*d57664e9SAndroid Build Coastguard Worker #include <android/binder_parcel.h>
23*d57664e9SAndroid Build Coastguard Worker #include <android/binder_parcel_jni.h>
24*d57664e9SAndroid Build Coastguard Worker #include <android/binder_parcel_utils.h>
25*d57664e9SAndroid Build Coastguard Worker #endif
26*d57664e9SAndroid Build Coastguard Worker
27*d57664e9SAndroid Build Coastguard Worker namespace android {
28*d57664e9SAndroid Build Coastguard Worker
29*d57664e9SAndroid Build Coastguard Worker static jfieldID gRegion_nativeInstanceFieldID;
30*d57664e9SAndroid Build Coastguard Worker
boolTojboolean(bool value)31*d57664e9SAndroid Build Coastguard Worker static inline jboolean boolTojboolean(bool value) {
32*d57664e9SAndroid Build Coastguard Worker return value ? JNI_TRUE : JNI_FALSE;
33*d57664e9SAndroid Build Coastguard Worker }
34*d57664e9SAndroid Build Coastguard Worker
GetSkRegion(JNIEnv * env,jobject regionObject)35*d57664e9SAndroid Build Coastguard Worker static inline SkRegion* GetSkRegion(JNIEnv* env, jobject regionObject) {
36*d57664e9SAndroid Build Coastguard Worker jlong regionHandle = env->GetLongField(regionObject, gRegion_nativeInstanceFieldID);
37*d57664e9SAndroid Build Coastguard Worker SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
38*d57664e9SAndroid Build Coastguard Worker SkASSERT(region != NULL);
39*d57664e9SAndroid Build Coastguard Worker return region;
40*d57664e9SAndroid Build Coastguard Worker }
41*d57664e9SAndroid Build Coastguard Worker
Region_constructor(JNIEnv * env,jobject)42*d57664e9SAndroid Build Coastguard Worker static jlong Region_constructor(JNIEnv* env, jobject) {
43*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<jlong>(new SkRegion);
44*d57664e9SAndroid Build Coastguard Worker }
45*d57664e9SAndroid Build Coastguard Worker
Region_destructor(JNIEnv * env,jobject,jlong regionHandle)46*d57664e9SAndroid Build Coastguard Worker static void Region_destructor(JNIEnv* env, jobject, jlong regionHandle) {
47*d57664e9SAndroid Build Coastguard Worker SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
48*d57664e9SAndroid Build Coastguard Worker SkASSERT(region);
49*d57664e9SAndroid Build Coastguard Worker delete region;
50*d57664e9SAndroid Build Coastguard Worker }
51*d57664e9SAndroid Build Coastguard Worker
Region_setRegion(JNIEnv * env,jobject,jlong dstHandle,jlong srcHandle)52*d57664e9SAndroid Build Coastguard Worker static void Region_setRegion(JNIEnv* env, jobject, jlong dstHandle, jlong srcHandle) {
53*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
54*d57664e9SAndroid Build Coastguard Worker const SkRegion* src = reinterpret_cast<SkRegion*>(srcHandle);
55*d57664e9SAndroid Build Coastguard Worker SkASSERT(dst && src);
56*d57664e9SAndroid Build Coastguard Worker *dst = *src;
57*d57664e9SAndroid Build Coastguard Worker }
58*d57664e9SAndroid Build Coastguard Worker
Region_setRect(JNIEnv * env,jobject,jlong dstHandle,jint left,jint top,jint right,jint bottom)59*d57664e9SAndroid Build Coastguard Worker static jboolean Region_setRect(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom) {
60*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
61*d57664e9SAndroid Build Coastguard Worker bool result = dst->setRect({left, top, right, bottom});
62*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
63*d57664e9SAndroid Build Coastguard Worker }
64*d57664e9SAndroid Build Coastguard Worker
Region_setPath(JNIEnv * env,jobject,jlong dstHandle,jlong pathHandle,jlong clipHandle)65*d57664e9SAndroid Build Coastguard Worker static jboolean Region_setPath(JNIEnv* env, jobject, jlong dstHandle,
66*d57664e9SAndroid Build Coastguard Worker jlong pathHandle, jlong clipHandle) {
67*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
68*d57664e9SAndroid Build Coastguard Worker const SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
69*d57664e9SAndroid Build Coastguard Worker const SkRegion* clip = reinterpret_cast<SkRegion*>(clipHandle);
70*d57664e9SAndroid Build Coastguard Worker SkASSERT(dst && path && clip);
71*d57664e9SAndroid Build Coastguard Worker bool result = dst->setPath(*path, *clip);
72*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
73*d57664e9SAndroid Build Coastguard Worker
74*d57664e9SAndroid Build Coastguard Worker }
75*d57664e9SAndroid Build Coastguard Worker
Region_getBounds(JNIEnv * env,jobject,jlong regionHandle,jobject rectBounds)76*d57664e9SAndroid Build Coastguard Worker static jboolean Region_getBounds(JNIEnv* env, jobject, jlong regionHandle, jobject rectBounds) {
77*d57664e9SAndroid Build Coastguard Worker SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
78*d57664e9SAndroid Build Coastguard Worker GraphicsJNI::irect_to_jrect(region->getBounds(), env, rectBounds);
79*d57664e9SAndroid Build Coastguard Worker bool result = !region->isEmpty();
80*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
81*d57664e9SAndroid Build Coastguard Worker }
82*d57664e9SAndroid Build Coastguard Worker
Region_getBoundaryPath(JNIEnv * env,jobject,jlong regionHandle,jlong pathHandle)83*d57664e9SAndroid Build Coastguard Worker static jboolean Region_getBoundaryPath(JNIEnv* env, jobject, jlong regionHandle, jlong pathHandle) {
84*d57664e9SAndroid Build Coastguard Worker const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
85*d57664e9SAndroid Build Coastguard Worker SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
86*d57664e9SAndroid Build Coastguard Worker bool result = region->getBoundaryPath(path);
87*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
88*d57664e9SAndroid Build Coastguard Worker }
89*d57664e9SAndroid Build Coastguard Worker
Region_op0(JNIEnv * env,jobject,jlong dstHandle,jint left,jint top,jint right,jint bottom,jint op)90*d57664e9SAndroid Build Coastguard Worker static jboolean Region_op0(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom, jint op) {
91*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
92*d57664e9SAndroid Build Coastguard Worker bool result = dst->op({left, top, right, bottom}, (SkRegion::Op)op);
93*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
94*d57664e9SAndroid Build Coastguard Worker }
95*d57664e9SAndroid Build Coastguard Worker
Region_op1(JNIEnv * env,jobject,jlong dstHandle,jobject rectObject,jlong regionHandle,jint op)96*d57664e9SAndroid Build Coastguard Worker static jboolean Region_op1(JNIEnv* env, jobject, jlong dstHandle, jobject rectObject, jlong regionHandle, jint op) {
97*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
98*d57664e9SAndroid Build Coastguard Worker const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
99*d57664e9SAndroid Build Coastguard Worker SkIRect ir;
100*d57664e9SAndroid Build Coastguard Worker GraphicsJNI::jrect_to_irect(env, rectObject, &ir);
101*d57664e9SAndroid Build Coastguard Worker bool result = dst->op(ir, *region, (SkRegion::Op)op);
102*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
103*d57664e9SAndroid Build Coastguard Worker }
104*d57664e9SAndroid Build Coastguard Worker
Region_op2(JNIEnv * env,jobject,jlong dstHandle,jlong region1Handle,jlong region2Handle,jint op)105*d57664e9SAndroid Build Coastguard Worker static jboolean Region_op2(JNIEnv* env, jobject, jlong dstHandle, jlong region1Handle, jlong region2Handle, jint op) {
106*d57664e9SAndroid Build Coastguard Worker SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
107*d57664e9SAndroid Build Coastguard Worker const SkRegion* region1 = reinterpret_cast<SkRegion*>(region1Handle);
108*d57664e9SAndroid Build Coastguard Worker const SkRegion* region2 = reinterpret_cast<SkRegion*>(region2Handle);
109*d57664e9SAndroid Build Coastguard Worker bool result = dst->op(*region1, *region2, (SkRegion::Op)op);
110*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
111*d57664e9SAndroid Build Coastguard Worker }
112*d57664e9SAndroid Build Coastguard Worker
113*d57664e9SAndroid Build Coastguard Worker //////////////////////////////////// These are methods, not static
114*d57664e9SAndroid Build Coastguard Worker
Region_isEmpty(JNIEnv * env,jobject region)115*d57664e9SAndroid Build Coastguard Worker static jboolean Region_isEmpty(JNIEnv* env, jobject region) {
116*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->isEmpty();
117*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
118*d57664e9SAndroid Build Coastguard Worker }
119*d57664e9SAndroid Build Coastguard Worker
Region_isRect(JNIEnv * env,jobject region)120*d57664e9SAndroid Build Coastguard Worker static jboolean Region_isRect(JNIEnv* env, jobject region) {
121*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->isRect();
122*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
123*d57664e9SAndroid Build Coastguard Worker }
124*d57664e9SAndroid Build Coastguard Worker
Region_isComplex(JNIEnv * env,jobject region)125*d57664e9SAndroid Build Coastguard Worker static jboolean Region_isComplex(JNIEnv* env, jobject region) {
126*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->isComplex();
127*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
128*d57664e9SAndroid Build Coastguard Worker }
129*d57664e9SAndroid Build Coastguard Worker
Region_contains(JNIEnv * env,jobject region,jint x,jint y)130*d57664e9SAndroid Build Coastguard Worker static jboolean Region_contains(JNIEnv* env, jobject region, jint x, jint y) {
131*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->contains(x, y);
132*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
133*d57664e9SAndroid Build Coastguard Worker }
134*d57664e9SAndroid Build Coastguard Worker
Region_quickContains(JNIEnv * env,jobject region,jint left,jint top,jint right,jint bottom)135*d57664e9SAndroid Build Coastguard Worker static jboolean Region_quickContains(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
136*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->quickContains({left, top, right, bottom});
137*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
138*d57664e9SAndroid Build Coastguard Worker }
139*d57664e9SAndroid Build Coastguard Worker
Region_quickRejectIIII(JNIEnv * env,jobject region,jint left,jint top,jint right,jint bottom)140*d57664e9SAndroid Build Coastguard Worker static jboolean Region_quickRejectIIII(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
141*d57664e9SAndroid Build Coastguard Worker SkIRect ir;
142*d57664e9SAndroid Build Coastguard Worker ir.setLTRB(left, top, right, bottom);
143*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->quickReject(ir);
144*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
145*d57664e9SAndroid Build Coastguard Worker }
146*d57664e9SAndroid Build Coastguard Worker
Region_quickRejectRgn(JNIEnv * env,jobject region,jobject other)147*d57664e9SAndroid Build Coastguard Worker static jboolean Region_quickRejectRgn(JNIEnv* env, jobject region, jobject other) {
148*d57664e9SAndroid Build Coastguard Worker bool result = GetSkRegion(env, region)->quickReject(*GetSkRegion(env, other));
149*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(result);
150*d57664e9SAndroid Build Coastguard Worker }
151*d57664e9SAndroid Build Coastguard Worker
Region_translate(JNIEnv * env,jobject region,jint x,jint y,jobject dst)152*d57664e9SAndroid Build Coastguard Worker static void Region_translate(JNIEnv* env, jobject region, jint x, jint y, jobject dst) {
153*d57664e9SAndroid Build Coastguard Worker SkRegion* rgn = GetSkRegion(env, region);
154*d57664e9SAndroid Build Coastguard Worker if (dst)
155*d57664e9SAndroid Build Coastguard Worker rgn->translate(x, y, GetSkRegion(env, dst));
156*d57664e9SAndroid Build Coastguard Worker else
157*d57664e9SAndroid Build Coastguard Worker rgn->translate(x, y);
158*d57664e9SAndroid Build Coastguard Worker }
159*d57664e9SAndroid Build Coastguard Worker
160*d57664e9SAndroid Build Coastguard Worker // Scale the rectangle by given scale and set the reuslt to the dst.
scale_rect(SkIRect * dst,const SkIRect & src,float scale)161*d57664e9SAndroid Build Coastguard Worker static void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
162*d57664e9SAndroid Build Coastguard Worker dst->fLeft = (int)::roundf(src.fLeft * scale);
163*d57664e9SAndroid Build Coastguard Worker dst->fTop = (int)::roundf(src.fTop * scale);
164*d57664e9SAndroid Build Coastguard Worker dst->fRight = (int)::roundf(src.fRight * scale);
165*d57664e9SAndroid Build Coastguard Worker dst->fBottom = (int)::roundf(src.fBottom * scale);
166*d57664e9SAndroid Build Coastguard Worker }
167*d57664e9SAndroid Build Coastguard Worker
168*d57664e9SAndroid Build Coastguard Worker // Scale the region by given scale and set the reuslt to the dst.
169*d57664e9SAndroid Build Coastguard Worker // dest and src can be the same region instance.
scale_rgn(SkRegion * dst,const SkRegion & src,float scale)170*d57664e9SAndroid Build Coastguard Worker static void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
171*d57664e9SAndroid Build Coastguard Worker SkRegion tmp;
172*d57664e9SAndroid Build Coastguard Worker SkRegion::Iterator iter(src);
173*d57664e9SAndroid Build Coastguard Worker
174*d57664e9SAndroid Build Coastguard Worker for (; !iter.done(); iter.next()) {
175*d57664e9SAndroid Build Coastguard Worker SkIRect r;
176*d57664e9SAndroid Build Coastguard Worker scale_rect(&r, iter.rect(), scale);
177*d57664e9SAndroid Build Coastguard Worker tmp.op(r, SkRegion::kUnion_Op);
178*d57664e9SAndroid Build Coastguard Worker }
179*d57664e9SAndroid Build Coastguard Worker dst->swap(tmp);
180*d57664e9SAndroid Build Coastguard Worker }
181*d57664e9SAndroid Build Coastguard Worker
Region_scale(JNIEnv * env,jobject region,jfloat scale,jobject dst)182*d57664e9SAndroid Build Coastguard Worker static void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst) {
183*d57664e9SAndroid Build Coastguard Worker SkRegion* rgn = GetSkRegion(env, region);
184*d57664e9SAndroid Build Coastguard Worker if (dst)
185*d57664e9SAndroid Build Coastguard Worker scale_rgn(GetSkRegion(env, dst), *rgn, scale);
186*d57664e9SAndroid Build Coastguard Worker else
187*d57664e9SAndroid Build Coastguard Worker scale_rgn(rgn, *rgn, scale);
188*d57664e9SAndroid Build Coastguard Worker }
189*d57664e9SAndroid Build Coastguard Worker
Region_toString(JNIEnv * env,jobject clazz,jlong regionHandle)190*d57664e9SAndroid Build Coastguard Worker static jstring Region_toString(JNIEnv* env, jobject clazz, jlong regionHandle) {
191*d57664e9SAndroid Build Coastguard Worker SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
192*d57664e9SAndroid Build Coastguard Worker char* str = region->toString();
193*d57664e9SAndroid Build Coastguard Worker if (str == NULL) {
194*d57664e9SAndroid Build Coastguard Worker return NULL;
195*d57664e9SAndroid Build Coastguard Worker }
196*d57664e9SAndroid Build Coastguard Worker jstring result = env->NewStringUTF(str);
197*d57664e9SAndroid Build Coastguard Worker free(str);
198*d57664e9SAndroid Build Coastguard Worker return result;
199*d57664e9SAndroid Build Coastguard Worker }
200*d57664e9SAndroid Build Coastguard Worker
201*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////
202*d57664e9SAndroid Build Coastguard Worker
Region_createFromParcel(JNIEnv * env,jobject clazz,jobject parcel)203*d57664e9SAndroid Build Coastguard Worker static jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
204*d57664e9SAndroid Build Coastguard Worker {
205*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ // Layoutlib does not support parcel
206*d57664e9SAndroid Build Coastguard Worker if (parcel == nullptr) {
207*d57664e9SAndroid Build Coastguard Worker return 0;
208*d57664e9SAndroid Build Coastguard Worker }
209*d57664e9SAndroid Build Coastguard Worker
210*d57664e9SAndroid Build Coastguard Worker std::vector<int32_t> rects;
211*d57664e9SAndroid Build Coastguard Worker
212*d57664e9SAndroid Build Coastguard Worker AParcel* p = AParcel_fromJavaParcel(env, parcel);
213*d57664e9SAndroid Build Coastguard Worker ndk::AParcel_readVector(p, &rects);
214*d57664e9SAndroid Build Coastguard Worker AParcel_delete(p);
215*d57664e9SAndroid Build Coastguard Worker
216*d57664e9SAndroid Build Coastguard Worker if ((rects.size() % 4) != 0) {
217*d57664e9SAndroid Build Coastguard Worker return 0;
218*d57664e9SAndroid Build Coastguard Worker }
219*d57664e9SAndroid Build Coastguard Worker
220*d57664e9SAndroid Build Coastguard Worker SkRegion* region = new SkRegion;
221*d57664e9SAndroid Build Coastguard Worker for (size_t x = 0; x + 4 <= rects.size(); x += 4) {
222*d57664e9SAndroid Build Coastguard Worker region->op({rects[x], rects[x+1], rects[x+2], rects[x+3]}, SkRegion::kUnion_Op);
223*d57664e9SAndroid Build Coastguard Worker }
224*d57664e9SAndroid Build Coastguard Worker
225*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<jlong>(region);
226*d57664e9SAndroid Build Coastguard Worker #else
227*d57664e9SAndroid Build Coastguard Worker return 0;
228*d57664e9SAndroid Build Coastguard Worker #endif
229*d57664e9SAndroid Build Coastguard Worker }
230*d57664e9SAndroid Build Coastguard Worker
Region_writeToParcel(JNIEnv * env,jobject clazz,jlong regionHandle,jobject parcel)231*d57664e9SAndroid Build Coastguard Worker static jboolean Region_writeToParcel(JNIEnv* env, jobject clazz, jlong regionHandle, jobject parcel)
232*d57664e9SAndroid Build Coastguard Worker {
233*d57664e9SAndroid Build Coastguard Worker #ifdef __ANDROID__ // Layoutlib does not support parcel
234*d57664e9SAndroid Build Coastguard Worker const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
235*d57664e9SAndroid Build Coastguard Worker if (parcel == nullptr) {
236*d57664e9SAndroid Build Coastguard Worker return JNI_FALSE;
237*d57664e9SAndroid Build Coastguard Worker }
238*d57664e9SAndroid Build Coastguard Worker
239*d57664e9SAndroid Build Coastguard Worker std::vector<int32_t> rects;
240*d57664e9SAndroid Build Coastguard Worker SkRegion::Iterator it(*region);
241*d57664e9SAndroid Build Coastguard Worker while (!it.done()) {
242*d57664e9SAndroid Build Coastguard Worker const SkIRect& r = it.rect();
243*d57664e9SAndroid Build Coastguard Worker rects.push_back(r.fLeft);
244*d57664e9SAndroid Build Coastguard Worker rects.push_back(r.fTop);
245*d57664e9SAndroid Build Coastguard Worker rects.push_back(r.fRight);
246*d57664e9SAndroid Build Coastguard Worker rects.push_back(r.fBottom);
247*d57664e9SAndroid Build Coastguard Worker it.next();
248*d57664e9SAndroid Build Coastguard Worker }
249*d57664e9SAndroid Build Coastguard Worker
250*d57664e9SAndroid Build Coastguard Worker AParcel* p = AParcel_fromJavaParcel(env, parcel);
251*d57664e9SAndroid Build Coastguard Worker ndk::AParcel_writeVector(p, rects);
252*d57664e9SAndroid Build Coastguard Worker AParcel_delete(p);
253*d57664e9SAndroid Build Coastguard Worker
254*d57664e9SAndroid Build Coastguard Worker return JNI_TRUE;
255*d57664e9SAndroid Build Coastguard Worker #else
256*d57664e9SAndroid Build Coastguard Worker return JNI_FALSE;
257*d57664e9SAndroid Build Coastguard Worker #endif
258*d57664e9SAndroid Build Coastguard Worker }
259*d57664e9SAndroid Build Coastguard Worker
260*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////
261*d57664e9SAndroid Build Coastguard Worker
Region_equals(JNIEnv * env,jobject clazz,jlong r1Handle,jlong r2Handle)262*d57664e9SAndroid Build Coastguard Worker static jboolean Region_equals(JNIEnv* env, jobject clazz, jlong r1Handle, jlong r2Handle)
263*d57664e9SAndroid Build Coastguard Worker {
264*d57664e9SAndroid Build Coastguard Worker const SkRegion *r1 = reinterpret_cast<SkRegion*>(r1Handle);
265*d57664e9SAndroid Build Coastguard Worker const SkRegion *r2 = reinterpret_cast<SkRegion*>(r2Handle);
266*d57664e9SAndroid Build Coastguard Worker return boolTojboolean(*r1 == *r2);
267*d57664e9SAndroid Build Coastguard Worker }
268*d57664e9SAndroid Build Coastguard Worker
269*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////
270*d57664e9SAndroid Build Coastguard Worker
271*d57664e9SAndroid Build Coastguard Worker struct RgnIterPair {
272*d57664e9SAndroid Build Coastguard Worker SkRegion fRgn; // a copy of the caller's region
273*d57664e9SAndroid Build Coastguard Worker SkRegion::Iterator fIter; // an iterator acting upon the copy (fRgn)
274*d57664e9SAndroid Build Coastguard Worker
RgnIterPairandroid::RgnIterPair275*d57664e9SAndroid Build Coastguard Worker explicit RgnIterPair(const SkRegion& rgn) : fRgn(rgn) {
276*d57664e9SAndroid Build Coastguard Worker // have our iterator reference our copy (fRgn), so we know it will be
277*d57664e9SAndroid Build Coastguard Worker // unchanged for the lifetime of the iterator
278*d57664e9SAndroid Build Coastguard Worker fIter.reset(fRgn);
279*d57664e9SAndroid Build Coastguard Worker }
280*d57664e9SAndroid Build Coastguard Worker };
281*d57664e9SAndroid Build Coastguard Worker
RegionIter_constructor(JNIEnv * env,jobject,jlong regionHandle)282*d57664e9SAndroid Build Coastguard Worker static jlong RegionIter_constructor(JNIEnv* env, jobject, jlong regionHandle)
283*d57664e9SAndroid Build Coastguard Worker {
284*d57664e9SAndroid Build Coastguard Worker const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
285*d57664e9SAndroid Build Coastguard Worker SkASSERT(region);
286*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<jlong>(new RgnIterPair(*region));
287*d57664e9SAndroid Build Coastguard Worker }
288*d57664e9SAndroid Build Coastguard Worker
RegionIter_destructor(JNIEnv * env,jobject,jlong pairHandle)289*d57664e9SAndroid Build Coastguard Worker static void RegionIter_destructor(JNIEnv* env, jobject, jlong pairHandle)
290*d57664e9SAndroid Build Coastguard Worker {
291*d57664e9SAndroid Build Coastguard Worker RgnIterPair* pair = reinterpret_cast<RgnIterPair*>(pairHandle);
292*d57664e9SAndroid Build Coastguard Worker SkASSERT(pair);
293*d57664e9SAndroid Build Coastguard Worker delete pair;
294*d57664e9SAndroid Build Coastguard Worker }
295*d57664e9SAndroid Build Coastguard Worker
RegionIter_next(JNIEnv * env,jobject,jlong pairHandle,jobject rectObject)296*d57664e9SAndroid Build Coastguard Worker static jboolean RegionIter_next(JNIEnv* env, jobject, jlong pairHandle, jobject rectObject)
297*d57664e9SAndroid Build Coastguard Worker {
298*d57664e9SAndroid Build Coastguard Worker RgnIterPair* pair = reinterpret_cast<RgnIterPair*>(pairHandle);
299*d57664e9SAndroid Build Coastguard Worker // the caller has checked that rectObject is not nul
300*d57664e9SAndroid Build Coastguard Worker SkASSERT(pair);
301*d57664e9SAndroid Build Coastguard Worker SkASSERT(rectObject);
302*d57664e9SAndroid Build Coastguard Worker
303*d57664e9SAndroid Build Coastguard Worker if (!pair->fIter.done()) {
304*d57664e9SAndroid Build Coastguard Worker GraphicsJNI::irect_to_jrect(pair->fIter.rect(), env, rectObject);
305*d57664e9SAndroid Build Coastguard Worker pair->fIter.next();
306*d57664e9SAndroid Build Coastguard Worker return JNI_TRUE;
307*d57664e9SAndroid Build Coastguard Worker }
308*d57664e9SAndroid Build Coastguard Worker return JNI_FALSE;
309*d57664e9SAndroid Build Coastguard Worker }
310*d57664e9SAndroid Build Coastguard Worker
311*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////////////////////////////////
312*d57664e9SAndroid Build Coastguard Worker
313*d57664e9SAndroid Build Coastguard Worker static const JNINativeMethod gRegionIterMethods[] = {
314*d57664e9SAndroid Build Coastguard Worker { "nativeConstructor", "(J)J", (void*)RegionIter_constructor },
315*d57664e9SAndroid Build Coastguard Worker { "nativeDestructor", "(J)V", (void*)RegionIter_destructor },
316*d57664e9SAndroid Build Coastguard Worker { "nativeNext", "(JLandroid/graphics/Rect;)Z", (void*)RegionIter_next }
317*d57664e9SAndroid Build Coastguard Worker };
318*d57664e9SAndroid Build Coastguard Worker
319*d57664e9SAndroid Build Coastguard Worker static const JNINativeMethod gRegionMethods[] = {
320*d57664e9SAndroid Build Coastguard Worker // these are static methods
321*d57664e9SAndroid Build Coastguard Worker { "nativeConstructor", "()J", (void*)Region_constructor },
322*d57664e9SAndroid Build Coastguard Worker { "nativeDestructor", "(J)V", (void*)Region_destructor },
323*d57664e9SAndroid Build Coastguard Worker { "nativeSetRegion", "(JJ)V", (void*)Region_setRegion },
324*d57664e9SAndroid Build Coastguard Worker { "nativeSetRect", "(JIIII)Z", (void*)Region_setRect },
325*d57664e9SAndroid Build Coastguard Worker { "nativeSetPath", "(JJJ)Z", (void*)Region_setPath },
326*d57664e9SAndroid Build Coastguard Worker { "nativeGetBounds", "(JLandroid/graphics/Rect;)Z", (void*)Region_getBounds },
327*d57664e9SAndroid Build Coastguard Worker { "nativeGetBoundaryPath", "(JJ)Z", (void*)Region_getBoundaryPath },
328*d57664e9SAndroid Build Coastguard Worker { "nativeOp", "(JIIIII)Z", (void*)Region_op0 },
329*d57664e9SAndroid Build Coastguard Worker { "nativeOp", "(JLandroid/graphics/Rect;JI)Z", (void*)Region_op1 },
330*d57664e9SAndroid Build Coastguard Worker { "nativeOp", "(JJJI)Z", (void*)Region_op2 },
331*d57664e9SAndroid Build Coastguard Worker // these are methods that take the java region object
332*d57664e9SAndroid Build Coastguard Worker { "isEmpty", "()Z", (void*)Region_isEmpty },
333*d57664e9SAndroid Build Coastguard Worker { "isRect", "()Z", (void*)Region_isRect },
334*d57664e9SAndroid Build Coastguard Worker { "isComplex", "()Z", (void*)Region_isComplex },
335*d57664e9SAndroid Build Coastguard Worker { "contains", "(II)Z", (void*)Region_contains },
336*d57664e9SAndroid Build Coastguard Worker { "quickContains", "(IIII)Z", (void*)Region_quickContains },
337*d57664e9SAndroid Build Coastguard Worker { "quickReject", "(IIII)Z", (void*)Region_quickRejectIIII },
338*d57664e9SAndroid Build Coastguard Worker { "quickReject", "(Landroid/graphics/Region;)Z", (void*)Region_quickRejectRgn },
339*d57664e9SAndroid Build Coastguard Worker { "scale", "(FLandroid/graphics/Region;)V", (void*)Region_scale },
340*d57664e9SAndroid Build Coastguard Worker { "translate", "(IILandroid/graphics/Region;)V", (void*)Region_translate },
341*d57664e9SAndroid Build Coastguard Worker { "nativeToString", "(J)Ljava/lang/String;", (void*)Region_toString },
342*d57664e9SAndroid Build Coastguard Worker // parceling methods
343*d57664e9SAndroid Build Coastguard Worker { "nativeCreateFromParcel", "(Landroid/os/Parcel;)J", (void*)Region_createFromParcel },
344*d57664e9SAndroid Build Coastguard Worker { "nativeWriteToParcel", "(JLandroid/os/Parcel;)Z", (void*)Region_writeToParcel },
345*d57664e9SAndroid Build Coastguard Worker { "nativeEquals", "(JJ)Z", (void*)Region_equals },
346*d57664e9SAndroid Build Coastguard Worker };
347*d57664e9SAndroid Build Coastguard Worker
register_android_graphics_Region(JNIEnv * env)348*d57664e9SAndroid Build Coastguard Worker int register_android_graphics_Region(JNIEnv* env)
349*d57664e9SAndroid Build Coastguard Worker {
350*d57664e9SAndroid Build Coastguard Worker jclass clazz = FindClassOrDie(env, "android/graphics/Region");
351*d57664e9SAndroid Build Coastguard Worker
352*d57664e9SAndroid Build Coastguard Worker gRegion_nativeInstanceFieldID = GetFieldIDOrDie(env, clazz, "mNativeRegion", "J");
353*d57664e9SAndroid Build Coastguard Worker
354*d57664e9SAndroid Build Coastguard Worker RegisterMethodsOrDie(env, "android/graphics/Region", gRegionMethods, NELEM(gRegionMethods));
355*d57664e9SAndroid Build Coastguard Worker return RegisterMethodsOrDie(env, "android/graphics/RegionIterator", gRegionIterMethods,
356*d57664e9SAndroid Build Coastguard Worker NELEM(gRegionIterMethods));
357*d57664e9SAndroid Build Coastguard Worker }
358*d57664e9SAndroid Build Coastguard Worker
359*d57664e9SAndroid Build Coastguard Worker } // namespace android
360