1 | /* |
2 | * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. Oracle designates this |
8 | * particular file as subject to the "Classpath" exception as provided |
9 | * by Oracle in the LICENSE file that accompanied this code. |
10 | * |
11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | * version 2 for more details (a copy is included in the LICENSE file that |
15 | * accompanied this code). |
16 | * |
17 | * You should have received a copy of the GNU General Public License version |
18 | * 2 along with this work; if not, write to the Free Software Foundation, |
19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | * |
21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 | * or visit www.oracle.com if you need additional information or have any |
23 | * questions. |
24 | */ |
25 | |
26 | #include "SurfaceData.h" |
27 | |
28 | #include "jni_util.h" |
29 | #include "Disposer.h" |
30 | |
31 | #include "stdlib.h" |
32 | #include "string.h" |
33 | |
34 | /** |
35 | * This include file contains information on how to use a SurfaceData |
36 | * object from native code. |
37 | */ |
38 | |
39 | static jclass pInvalidPipeClass; |
40 | static jclass pNullSurfaceDataClass; |
41 | static jfieldID pDataID; |
42 | static jfieldID allGrayID; |
43 | |
44 | jfieldID validID; |
45 | GeneralDisposeFunc SurfaceData_DisposeOps; |
46 | |
47 | #define InitClass(var, env, name) \ |
48 | do { \ |
49 | var = (*env)->FindClass(env, name); \ |
50 | if (var == NULL) { \ |
51 | return; \ |
52 | } \ |
53 | } while (0) |
54 | |
55 | #define InitField(var, env, jcl, name, type) \ |
56 | do { \ |
57 | var = (*env)->GetFieldID(env, jcl, name, type); \ |
58 | if (var == NULL) { \ |
59 | return; \ |
60 | } \ |
61 | } while (0) |
62 | |
63 | #define InitGlobalClassRef(var, env, name) \ |
64 | do { \ |
65 | jobject jtmp; \ |
66 | InitClass(jtmp, env, name); \ |
67 | var = (*env)->NewGlobalRef(env, jtmp); \ |
68 | if (var == NULL) { \ |
69 | return; \ |
70 | } \ |
71 | } while (0) |
72 | |
73 | /* |
74 | * Class: sun_java2d_SurfaceData |
75 | * Method: initIDs |
76 | * Signature: ()V |
77 | */ |
78 | JNIEXPORT void JNICALL |
79 | Java_sun_java2d_SurfaceData_initIDs(JNIEnv *env, jclass sd) |
80 | { |
81 | jclass pICMClass; |
82 | |
83 | InitGlobalClassRef(pInvalidPipeClass, env, |
84 | "sun/java2d/InvalidPipeException" ); |
85 | |
86 | InitGlobalClassRef(pNullSurfaceDataClass, env, |
87 | "sun/java2d/NullSurfaceData" ); |
88 | |
89 | InitField(pDataID, env, sd, "pData" , "J" ); |
90 | InitField(validID, env, sd, "valid" , "Z" ); |
91 | |
92 | InitClass(pICMClass, env, "java/awt/image/IndexColorModel" ); |
93 | InitField(allGrayID, env, pICMClass, "allgrayopaque" , "Z" ); |
94 | } |
95 | |
96 | /* |
97 | * Class: sun_java2d_SurfaceData |
98 | * Method: isOpaqueGray |
99 | * Signature: ()Z |
100 | */ |
101 | JNIEXPORT jboolean JNICALL |
102 | Java_sun_java2d_SurfaceData_isOpaqueGray(JNIEnv *env, jclass sdClass, |
103 | jobject icm) |
104 | { |
105 | if (icm == NULL) { |
106 | return JNI_FALSE; |
107 | } |
108 | return (*env)->GetBooleanField(env, icm, allGrayID); |
109 | } |
110 | |
111 | static SurfaceDataOps * |
112 | GetSDOps(JNIEnv *env, jobject sData, jboolean callSetup) |
113 | { |
114 | SurfaceDataOps *ops; |
115 | if (JNU_IsNull(env, sData)) { |
116 | JNU_ThrowNullPointerException(env, "surfaceData" ); |
117 | return NULL; |
118 | } |
119 | ops = (SurfaceDataOps *)JNU_GetLongFieldAsPtr(env, sData, pDataID); |
120 | if (ops == NULL) { |
121 | if (!(*env)->ExceptionOccurred(env) && |
122 | !(*env)->IsInstanceOf(env, sData, pNullSurfaceDataClass)) |
123 | { |
124 | if (!(*env)->GetBooleanField(env, sData, validID)) { |
125 | SurfaceData_ThrowInvalidPipeException(env, "invalid data" ); |
126 | } else { |
127 | JNU_ThrowNullPointerException(env, "native ops missing" ); |
128 | } |
129 | } |
130 | } else if (callSetup) { |
131 | SurfaceData_InvokeSetup(env, ops); |
132 | } |
133 | return ops; |
134 | } |
135 | |
136 | JNIEXPORT SurfaceDataOps * JNICALL |
137 | SurfaceData_GetOps(JNIEnv *env, jobject sData) |
138 | { |
139 | return GetSDOps(env, sData, JNI_TRUE); |
140 | } |
141 | |
142 | JNIEXPORT SurfaceDataOps * JNICALL |
143 | SurfaceData_GetOpsNoSetup(JNIEnv *env, jobject sData) |
144 | { |
145 | return GetSDOps(env, sData, JNI_FALSE); |
146 | } |
147 | |
148 | JNIEXPORT void JNICALL |
149 | SurfaceData_SetOps(JNIEnv *env, jobject sData, SurfaceDataOps *ops) |
150 | { |
151 | if (JNU_GetLongFieldAsPtr(env, sData, pDataID) == NULL) { |
152 | JNU_SetLongFieldFromPtr(env, sData, pDataID, ops); |
153 | /* Register the data for disposal */ |
154 | Disposer_AddRecord(env, sData, |
155 | SurfaceData_DisposeOps, |
156 | ptr_to_jlong(ops)); |
157 | } else { |
158 | JNU_ThrowInternalError(env, "Attempting to set SurfaceData ops twice" ); |
159 | } |
160 | } |
161 | |
162 | JNIEXPORT void JNICALL |
163 | SurfaceData_ThrowInvalidPipeException(JNIEnv *env, const char *msg) |
164 | { |
165 | (*env)->ThrowNew(env, pInvalidPipeClass, msg); |
166 | } |
167 | |
168 | #define GETMIN(v1, v2) (((v1) > (t=(v2))) && ((v1) = t)) |
169 | #define GETMAX(v1, v2) (((v1) < (t=(v2))) && ((v1) = t)) |
170 | |
171 | JNIEXPORT void JNICALL |
172 | SurfaceData_IntersectBounds(SurfaceDataBounds *dst, SurfaceDataBounds *src) |
173 | { |
174 | int t; |
175 | GETMAX(dst->x1, src->x1); |
176 | GETMAX(dst->y1, src->y1); |
177 | GETMIN(dst->x2, src->x2); |
178 | GETMIN(dst->y2, src->y2); |
179 | } |
180 | |
181 | JNIEXPORT void JNICALL |
182 | SurfaceData_IntersectBoundsXYXY(SurfaceDataBounds *bounds, |
183 | jint x1, jint y1, jint x2, jint y2) |
184 | { |
185 | int t; |
186 | GETMAX(bounds->x1, x1); |
187 | GETMAX(bounds->y1, y1); |
188 | GETMIN(bounds->x2, x2); |
189 | GETMIN(bounds->y2, y2); |
190 | } |
191 | |
192 | JNIEXPORT void JNICALL |
193 | SurfaceData_IntersectBoundsXYWH(SurfaceDataBounds *bounds, |
194 | jint x, jint y, jint w, jint h) |
195 | { |
196 | w = (w <= 0) ? x : x+w; |
197 | if (w < x) { |
198 | w = 0x7fffffff; |
199 | } |
200 | if (bounds->x1 < x) { |
201 | bounds->x1 = x; |
202 | } |
203 | if (bounds->x2 > w) { |
204 | bounds->x2 = w; |
205 | } |
206 | h = (h <= 0) ? y : y+h; |
207 | if (h < y) { |
208 | h = 0x7fffffff; |
209 | } |
210 | if (bounds->y1 < y) { |
211 | bounds->y1 = y; |
212 | } |
213 | if (bounds->y2 > h) { |
214 | bounds->y2 = h; |
215 | } |
216 | } |
217 | |
218 | JNIEXPORT void JNICALL |
219 | SurfaceData_IntersectBlitBounds(SurfaceDataBounds *src, |
220 | SurfaceDataBounds *dst, |
221 | jint dx, jint dy) |
222 | { |
223 | int t; |
224 | GETMAX(dst->x1, src->x1 + dx); |
225 | GETMAX(dst->y1, src->y1 + dy); |
226 | GETMIN(dst->x2, src->x2 + dx); |
227 | GETMIN(dst->y2, src->y2 + dy); |
228 | GETMAX(src->x1, dst->x1 - dx); |
229 | GETMAX(src->y1, dst->y1 - dy); |
230 | GETMIN(src->x2, dst->x2 - dx); |
231 | GETMIN(src->y2, dst->y2 - dy); |
232 | } |
233 | |
234 | JNIEXPORT SurfaceDataOps * JNICALL |
235 | SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize) |
236 | { |
237 | SurfaceDataOps *ops = malloc(opsSize); |
238 | SurfaceData_SetOps(env, sData, ops); |
239 | if (ops != NULL) { |
240 | memset(ops, 0, opsSize); |
241 | if (!(*env)->ExceptionCheck(env)) { |
242 | ops->sdObject = (*env)->NewWeakGlobalRef(env, sData); |
243 | } |
244 | } |
245 | return ops; |
246 | } |
247 | |
248 | void SurfaceData_DisposeOps(JNIEnv *env, jlong ops) |
249 | { |
250 | if (ops != 0) { |
251 | SurfaceDataOps *sdops = (SurfaceDataOps*)jlong_to_ptr(ops); |
252 | /* Invoke the ops-specific disposal function */ |
253 | SurfaceData_InvokeDispose(env, sdops); |
254 | (*env)->DeleteWeakGlobalRef(env, sdops->sdObject); |
255 | free(sdops); |
256 | } |
257 | } |
258 | |