jdk/src/share/native/sun/java2d/SurfaceData.c
changeset 2 90ce3da70b43
child 5506 202f599c92aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/java2d/SurfaceData.c	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,254 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+#include "SurfaceData.h"
+
+#include "jni_util.h"
+#include "Disposer.h"
+
+#include "malloc.h"
+#include "string.h"
+
+/**
+ * This include file contains information on how to use a SurfaceData
+ * object from native code.
+ */
+
+static jclass pInvalidPipeClass;
+static jclass pNullSurfaceDataClass;
+static jfieldID pDataID;
+static jfieldID allGrayID;
+
+jfieldID validID;
+GeneralDisposeFunc SurfaceData_DisposeOps;
+
+#define InitClass(var, env, name) \
+do { \
+    var = (*env)->FindClass(env, name); \
+    if (var == NULL) { \
+        return; \
+    } \
+} while (0)
+
+#define InitField(var, env, jcl, name, type) \
+do { \
+    var = (*env)->GetFieldID(env, jcl, name, type); \
+    if (var == NULL) { \
+        return; \
+    } \
+} while (0)
+
+#define InitGlobalClassRef(var, env, name) \
+do { \
+    jobject jtmp; \
+    InitClass(jtmp, env, name); \
+    var = (*env)->NewGlobalRef(env, jtmp); \
+    if (var == NULL) { \
+        return; \
+    } \
+} while (0)
+
+/*
+ * Class:     sun_java2d_SurfaceData
+ * Method:    initIDs
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_SurfaceData_initIDs(JNIEnv *env, jclass sd)
+{
+    jclass pICMClass;
+
+    InitGlobalClassRef(pInvalidPipeClass, env,
+                       "sun/java2d/InvalidPipeException");
+
+    InitGlobalClassRef(pNullSurfaceDataClass, env,
+                       "sun/java2d/NullSurfaceData");
+
+    InitField(pDataID, env, sd, "pData", "J");
+    InitField(validID, env, sd, "valid", "Z");
+
+    InitClass(pICMClass, env, "java/awt/image/IndexColorModel");
+    InitField(allGrayID, env, pICMClass, "allgrayopaque", "Z");
+}
+
+/*
+ * Class:     sun_java2d_SurfaceData
+ * Method:    isOpaqueGray
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_java2d_SurfaceData_isOpaqueGray(JNIEnv *env, jclass sdClass,
+                                         jobject icm)
+{
+    if (icm == NULL) {
+        return JNI_FALSE;
+    }
+    return (*env)->GetBooleanField(env, icm, allGrayID);
+}
+
+static SurfaceDataOps *
+GetSDOps(JNIEnv *env, jobject sData, jboolean callSetup)
+{
+    SurfaceDataOps *ops;
+    if (JNU_IsNull(env, sData)) {
+        JNU_ThrowNullPointerException(env, "surfaceData");
+        return NULL;
+    }
+    ops = (SurfaceDataOps *)JNU_GetLongFieldAsPtr(env, sData, pDataID);
+    if (ops == NULL) {
+        if (!(*env)->ExceptionOccurred(env) &&
+            !(*env)->IsInstanceOf(env, sData, pNullSurfaceDataClass))
+        {
+            if (!(*env)->GetBooleanField(env, sData, validID)) {
+                SurfaceData_ThrowInvalidPipeException(env, "invalid data");
+            } else {
+                JNU_ThrowNullPointerException(env, "native ops missing");
+            }
+        }
+    } else if (callSetup) {
+        SurfaceData_InvokeSetup(env, ops);
+    }
+    return ops;
+}
+
+JNIEXPORT SurfaceDataOps * JNICALL
+SurfaceData_GetOps(JNIEnv *env, jobject sData)
+{
+    return GetSDOps(env, sData, JNI_TRUE);
+}
+
+JNIEXPORT SurfaceDataOps * JNICALL
+SurfaceData_GetOpsNoSetup(JNIEnv *env, jobject sData)
+{
+    return GetSDOps(env, sData, JNI_FALSE);
+}
+
+JNIEXPORT void JNICALL
+SurfaceData_SetOps(JNIEnv *env, jobject sData, SurfaceDataOps *ops)
+{
+    if (JNU_GetLongFieldAsPtr(env, sData, pDataID) == NULL) {
+        JNU_SetLongFieldFromPtr(env, sData, pDataID, ops);
+        /* Register the data for disposal */
+        Disposer_AddRecord(env, sData,
+                           SurfaceData_DisposeOps,
+                           ptr_to_jlong(ops));
+    } else {
+        JNU_ThrowInternalError(env, "Attempting to set SurfaceData ops twice");
+    }
+}
+
+JNIEXPORT void JNICALL
+SurfaceData_ThrowInvalidPipeException(JNIEnv *env, const char *msg)
+{
+    (*env)->ThrowNew(env, pInvalidPipeClass, msg);
+}
+
+#define GETMIN(v1, v2)          (((v1) > (t=(v2))) && ((v1) = t))
+#define GETMAX(v1, v2)          (((v1) < (t=(v2))) && ((v1) = t))
+
+JNIEXPORT void JNICALL
+SurfaceData_IntersectBounds(SurfaceDataBounds *dst, SurfaceDataBounds *src)
+{
+    int t;
+    GETMAX(dst->x1, src->x1);
+    GETMAX(dst->y1, src->y1);
+    GETMIN(dst->x2, src->x2);
+    GETMIN(dst->y2, src->y2);
+}
+
+JNIEXPORT void JNICALL
+SurfaceData_IntersectBoundsXYXY(SurfaceDataBounds *bounds,
+                                jint x1, jint y1, jint x2, jint y2)
+{
+    int t;
+    GETMAX(bounds->x1, x1);
+    GETMAX(bounds->y1, y1);
+    GETMIN(bounds->x2, x2);
+    GETMIN(bounds->y2, y2);
+}
+
+JNIEXPORT void JNICALL
+SurfaceData_IntersectBoundsXYWH(SurfaceDataBounds *bounds,
+                                jint x, jint y, jint w, jint h)
+{
+    w = (w <= 0) ? x : x+w;
+    if (w < x) {
+        w = 0x7fffffff;
+    }
+    if (bounds->x1 < x) {
+        bounds->x1 = x;
+    }
+    if (bounds->x2 > w) {
+        bounds->x2 = w;
+    }
+    h = (h <= 0) ? y : y+h;
+    if (h < y) {
+        h = 0x7fffffff;
+    }
+    if (bounds->y1 < y) {
+        bounds->y1 = y;
+    }
+    if (bounds->y2 > h) {
+        bounds->y2 = h;
+    }
+}
+
+JNIEXPORT void JNICALL
+SurfaceData_IntersectBlitBounds(SurfaceDataBounds *src,
+                                SurfaceDataBounds *dst,
+                                jint dx, jint dy)
+{
+    int t;
+    GETMAX(dst->x1, src->x1 + dx);
+    GETMAX(dst->y1, src->y1 + dy);
+    GETMIN(dst->x2, src->x2 + dx);
+    GETMIN(dst->y2, src->y2 + dy);
+    GETMAX(src->x1, dst->x1 - dx);
+    GETMAX(src->y1, dst->y1 - dy);
+    GETMIN(src->x2, dst->x2 - dx);
+    GETMIN(src->y2, dst->y2 - dy);
+}
+
+SurfaceDataOps *SurfaceData_InitOps(JNIEnv *env, jobject sData, int opsSize)
+{
+    SurfaceDataOps *ops = malloc(opsSize);
+    SurfaceData_SetOps(env, sData, ops);
+    if (ops != NULL) {
+        memset(ops, 0, opsSize);
+        ops->sdObject = (*env)->NewWeakGlobalRef(env, sData);
+    }
+    return ops;
+}
+
+void SurfaceData_DisposeOps(JNIEnv *env, jlong ops)
+{
+    if (ops != 0) {
+        SurfaceDataOps *sdops = (SurfaceDataOps*)jlong_to_ptr(ops);
+        /* Invoke the ops-specific disposal function */
+        SurfaceData_InvokeDispose(env, sdops);
+        (*env)->DeleteWeakGlobalRef(env, sdops->sdObject);
+        free(sdops);
+    }
+}