1fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown/*
2fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Copyright (C) 2011 The Android Open Source Project
3fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown *
4fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * you may not use this file except in compliance with the License.
6fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * You may obtain a copy of the License at
7fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown *
8fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown *
10fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * Unless required by applicable law or agreed to in writing, software
11fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * See the License for the specific language governing permissions and
14fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown * limitations under the License.
15fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown */
16fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkRegion.h"
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkPath.h"
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h"
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown#include <binder/Parcel.h>
22d84e1ce0b535128f03416145554fb405f9fade3eJeff Sharkey#include "android_os_Parcel.h"
23fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown#include "android_util_Binder.h"
24fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <jni.h>
26ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe#include <core_jni_helpers.h>
27fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
28fbf097732137a32930d151f7ba6816a5b870c32aJeff Brownnamespace android {
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRegion_nativeInstanceFieldID;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
32a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic inline jboolean boolTojboolean(bool value) {
33a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return value ? JNI_TRUE : JNI_FALSE;
34a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat}
35a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline SkRegion* GetSkRegion(JNIEnv* env, jobject regionObject) {
37a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    jlong regionHandle = env->GetLongField(regionObject, gRegion_nativeInstanceFieldID);
38a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
39a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkASSERT(region != NULL);
40a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return region;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
43a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jlong Region_constructor(JNIEnv* env, jobject) {
44a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return reinterpret_cast<jlong>(new SkRegion);
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic void Region_destructor(JNIEnv* env, jobject, jlong regionHandle) {
48a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(region);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete region;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
53a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic void Region_setRegion(JNIEnv* env, jobject, jlong dstHandle, jlong srcHandle) {
54a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
55a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* src = reinterpret_cast<SkRegion*>(srcHandle);
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(dst && src);
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *dst = *src;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_setRect(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom) {
61a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
62a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = dst->setRect(left, top, right, bottom);
63a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
66a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_setPath(JNIEnv* env, jobject, jlong dstHandle,
67a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat                               jlong pathHandle, jlong clipHandle) {
68a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion*       dst  = reinterpret_cast<SkRegion*>(dstHandle);
69a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkPath*   path = reinterpret_cast<SkPath*>(pathHandle);
70a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* clip = reinterpret_cast<SkRegion*>(clipHandle);
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(dst && path && clip);
72a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = dst->setPath(*path, *clip);
73a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
74a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
77a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_getBounds(JNIEnv* env, jobject, jlong regionHandle, jobject rectBounds) {
78a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GraphicsJNI::irect_to_jrect(region->getBounds(), env, rectBounds);
80a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = !region->isEmpty();
81a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
84a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_getBoundaryPath(JNIEnv* env, jobject, jlong regionHandle, jlong pathHandle) {
85a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
86a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkPath*   path = reinterpret_cast<SkPath*>(pathHandle);
87a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = region->getBoundaryPath(path);
88a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
91a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_op0(JNIEnv* env, jobject, jlong dstHandle, jint left, jint top, jint right, jint bottom, jint op) {
92a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkIRect ir;
944cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ir.set(left, top, right, bottom);
96a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = dst->op(ir, (SkRegion::Op)op);
97a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
100a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_op1(JNIEnv* env, jobject, jlong dstHandle, jobject rectObject, jlong regionHandle, jint op) {
101a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
102a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkIRect    ir;
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GraphicsJNI::jrect_to_irect(env, rectObject, &ir);
105a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = dst->op(ir, *region, (SkRegion::Op)op);
106a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
109a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_op2(JNIEnv* env, jobject, jlong dstHandle, jlong region1Handle, jlong region2Handle, jint op) {
110a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* dst = reinterpret_cast<SkRegion*>(dstHandle);
111a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region1 = reinterpret_cast<SkRegion*>(region1Handle);
112a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region2 = reinterpret_cast<SkRegion*>(region2Handle);
113a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = dst->op(*region1, *region2, (SkRegion::Op)op);
114a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1174cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes////////////////////////////////////  These are methods, not static
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean Region_isEmpty(JNIEnv* env, jobject region) {
120a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->isEmpty();
121a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1234cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean Region_isRect(JNIEnv* env, jobject region) {
125a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->isRect();
126a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1284cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean Region_isComplex(JNIEnv* env, jobject region) {
130a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->isComplex();
131a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
134a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_contains(JNIEnv* env, jobject region, jint x, jint y) {
135a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->contains(x, y);
136a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1384cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
139a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_quickContains(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
140a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->quickContains(left, top, right, bottom);
141a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1434cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
144a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_quickRejectIIII(JNIEnv* env, jobject region, jint left, jint top, jint right, jint bottom) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkIRect ir;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ir.set(left, top, right, bottom);
147a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->quickReject(ir);
148a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1504cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean Region_quickRejectRgn(JNIEnv* env, jobject region, jobject other) {
152a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    bool result = GetSkRegion(env, region)->quickReject(*GetSkRegion(env, other));
153a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(result);
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1554cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
156a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic void Region_translate(JNIEnv* env, jobject region, jint x, jint y, jobject dst) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkRegion* rgn = GetSkRegion(env, region);
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dst)
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rgn->translate(x, y, GetSkRegion(env, dst));
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rgn->translate(x, y);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
164b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima// Scale the rectangle by given scale and set the reuslt to the dst.
165b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshimastatic void scale_rect(SkIRect* dst, const SkIRect& src, float scale) {
166b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   dst->fLeft = (int)::roundf(src.fLeft * scale);
167b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   dst->fTop = (int)::roundf(src.fTop * scale);
168b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   dst->fRight = (int)::roundf(src.fRight * scale);
169b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   dst->fBottom = (int)::roundf(src.fBottom * scale);
170b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima}
171b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
172b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima// Scale the region by given scale and set the reuslt to the dst.
173b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima// dest and src can be the same region instance.
174b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshimastatic void scale_rgn(SkRegion* dst, const SkRegion& src, float scale) {
175b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   SkRegion tmp;
176b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   SkRegion::Iterator iter(src);
177b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
178b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   for (; !iter.done(); iter.next()) {
179b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima       SkIRect r;
180b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima       scale_rect(&r, iter.rect(), scale);
181b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima       tmp.op(r, SkRegion::kUnion_Op);
182b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   }
183b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima   dst->swap(tmp);
184b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima}
185b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
186b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshimastatic void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst) {
187b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima    SkRegion* rgn = GetSkRegion(env, region);
188b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima    if (dst)
189b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima        scale_rgn(GetSkRegion(env, dst), *rgn, scale);
190b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima    else
191b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima        scale_rgn(rgn, *rgn, scale);
192b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima}
193b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
194a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jstring Region_toString(JNIEnv* env, jobject clazz, jlong regionHandle) {
195a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
196120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    char* str = region->toString();
197120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    if (str == NULL) {
198120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato        return NULL;
199120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    }
200120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    jstring result = env->NewStringUTF(str);
201120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    free(str);
202120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato    return result;
203120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato}
204120856c50a56595c0954ae1bf6f05888386937b9Joe Onorato
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////////
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
207a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jlong Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2093082fe440f90b7a3e6e031b6641f4a71b907dd4fDerek Sollenberger    if (parcel == nullptr) {
2103082fe440f90b7a3e6e031b6641f4a71b907dd4fDerek Sollenberger        return 0;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2124cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    android::Parcel* p = android::parcelForJavaObject(env, parcel);
2144cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
215fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    std::vector<int32_t> rects;
216fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    p->readInt32Vector(&rects);
217fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger
218fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    if ((rects.size() % 4) != 0) {
219cdadfc211ddd232fde9f63d9aa3ae26af8b8f583Derek Sollenberger        return 0;
220cdadfc211ddd232fde9f63d9aa3ae26af8b8f583Derek Sollenberger    }
2213082fe440f90b7a3e6e031b6641f4a71b907dd4fDerek Sollenberger
222cdadfc211ddd232fde9f63d9aa3ae26af8b8f583Derek Sollenberger    SkRegion* region = new SkRegion;
223fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    for (size_t x = 0; x + 4 <= rects.size(); x += 4) {
224fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        region->op(rects[x], rects[x+1], rects[x+2], rects[x+3], SkRegion::kUnion_Op);
2253082fe440f90b7a3e6e031b6641f4a71b907dd4fDerek Sollenberger    }
2264cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
227a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return reinterpret_cast<jlong>(region);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
230a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_writeToParcel(JNIEnv* env, jobject clazz, jlong regionHandle, jobject parcel)
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
232a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
2332a6d6e504712dcddd030a6007d9dfbb089258619Leon Scroggins III    if (parcel == nullptr) {
234a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat        return JNI_FALSE;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2364cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    android::Parcel* p = android::parcelForJavaObject(env, parcel);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    std::vector<int32_t> rects;
240fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    SkRegion::Iterator it(*region);
241fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    while (!it.done()) {
242fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        const SkIRect& r = it.rect();
243fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        rects.push_back(r.fLeft);
244fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        rects.push_back(r.fTop);
245fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        rects.push_back(r.fRight);
246fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        rects.push_back(r.fBottom);
247fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger        it.next();
2482a6d6e504712dcddd030a6007d9dfbb089258619Leon Scroggins III    }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
250fd00820ca3db46eafda00b66e73bbfc2d9e37eaeDerek Sollenberger    p->writeInt32Vector(rects);
251a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return JNI_TRUE;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////////
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
256a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean Region_equals(JNIEnv* env, jobject clazz, jlong r1Handle, jlong r2Handle)
257b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima{
258a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion *r1 = reinterpret_cast<SkRegion*>(r1Handle);
259a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion *r2 = reinterpret_cast<SkRegion*>(r2Handle);
260a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return boolTojboolean(*r1 == *r2);
261b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima}
262b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
263b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima////////////////////////////////////////////////////////////////////////////////////////////////////////////
264b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct RgnIterPair {
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkRegion            fRgn;   // a copy of the caller's region
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkRegion::Iterator  fIter;  // an iterator acting upon the copy (fRgn)
2684cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
269c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh    explicit RgnIterPair(const SkRegion& rgn) : fRgn(rgn) {
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // have our iterator reference our copy (fRgn), so we know it will be
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // unchanged for the lifetime of the iterator
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fIter.reset(fRgn);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
276a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jlong RegionIter_constructor(JNIEnv* env, jobject, jlong regionHandle)
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
278a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
2794cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes    SkASSERT(region);
280a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return reinterpret_cast<jlong>(new RgnIterPair(*region));
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
283a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic void RegionIter_destructor(JNIEnv* env, jobject, jlong pairHandle)
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
285a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    RgnIterPair* pair = reinterpret_cast<RgnIterPair*>(pairHandle);
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(pair);
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    delete pair;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
290a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhatstatic jboolean RegionIter_next(JNIEnv* env, jobject, jlong pairHandle, jobject rectObject)
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
292a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    RgnIterPair* pair = reinterpret_cast<RgnIterPair*>(pairHandle);
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // the caller has checked that rectObject is not nul
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(pair);
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(rectObject);
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (!pair->fIter.done()) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        GraphicsJNI::irect_to_jrect(pair->fIter.rect(), env, rectObject);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pair->fIter.next();
300a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat        return JNI_TRUE;
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
302a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    return JNI_FALSE;
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////////////////////
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
30776f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gRegionIterMethods[] = {
308a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeConstructor",  "(J)J",                         (void*)RegionIter_constructor   },
309a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeDestructor",   "(J)V",                         (void*)RegionIter_destructor    },
310a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeNext",         "(JLandroid/graphics/Rect;)Z",  (void*)RegionIter_next          }
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
31376f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gRegionMethods[] = {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // these are static methods
315a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeConstructor",      "()J",                              (void*)Region_constructor       },
316a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeDestructor",       "(J)V",                             (void*)Region_destructor        },
317a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeSetRegion",        "(JJ)V",                            (void*)Region_setRegion         },
318a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeSetRect",          "(JIIII)Z",                         (void*)Region_setRect           },
319a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeSetPath",          "(JJJ)Z",                           (void*)Region_setPath           },
320a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeGetBounds",        "(JLandroid/graphics/Rect;)Z",      (void*)Region_getBounds         },
321a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeGetBoundaryPath",  "(JJ)Z",                            (void*)Region_getBoundaryPath   },
322a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeOp",               "(JIIIII)Z",                        (void*)Region_op0               },
323a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeOp",               "(JLandroid/graphics/Rect;JI)Z",    (void*)Region_op1               },
324a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeOp",               "(JJJI)Z",                          (void*)Region_op2               },
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // these are methods that take the java region object
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "isEmpty",                "()Z",                              (void*)Region_isEmpty           },
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "isRect",                 "()Z",                              (void*)Region_isRect            },
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "isComplex",              "()Z",                              (void*)Region_isComplex         },
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "contains",               "(II)Z",                            (void*)Region_contains          },
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "quickContains",          "(IIII)Z",                          (void*)Region_quickContains     },
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "quickReject",            "(IIII)Z",                          (void*)Region_quickRejectIIII   },
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "quickReject",            "(Landroid/graphics/Region;)Z",     (void*)Region_quickRejectRgn    },
333b10f138e125b5656e810901d14c5f956ff5d9b64Mitsuru Oshima    { "scale",                  "(FLandroid/graphics/Region;)V",    (void*)Region_scale             },
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    { "translate",              "(IILandroid/graphics/Region;)V",   (void*)Region_translate         },
335a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeToString",         "(J)Ljava/lang/String;",            (void*)Region_toString          },
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // parceling methods
337a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeCreateFromParcel", "(Landroid/os/Parcel;)J",           (void*)Region_createFromParcel  },
338a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeWriteToParcel",    "(JLandroid/os/Parcel;)Z",          (void*)Region_writeToParcel     },
339a0398430fcf365fba6e42ad0bdca2fbf45ed6fe0Ashok Bhat    { "nativeEquals",           "(JJ)Z",                            (void*)Region_equals            },
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Region(JNIEnv* env)
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
344ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    jclass clazz = FindClassOrDie(env, "android/graphics/Region");
3454cb1753ec6e90d7e747880c599dc1c164a568cf3Elliott Hughes
346ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    gRegion_nativeInstanceFieldID = GetFieldIDOrDie(env, clazz, "mNativeRegion", "J");
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
348ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    RegisterMethodsOrDie(env, "android/graphics/Region", gRegionMethods, NELEM(gRegionMethods));
349ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe    return RegisterMethodsOrDie(env, "android/graphics/RegionIterator", gRegionIterMethods,
350ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe                                NELEM(gRegionIterMethods));
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
352fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
353fbf097732137a32930d151f7ba6816a5b870c32aJeff BrownSkRegion* android_graphics_Region_getSkRegion(JNIEnv* env, jobject regionObj) {
354fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown    return GetSkRegion(env, regionObj);
355fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown}
356fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
357fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown} // namespace android
358