--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11PMBlitLoops.c Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,400 @@
+/*
+ * Copyright 2000-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 <stdlib.h>
+#include <jni.h>
+#include <jlong.h>
+#include "X11SurfaceData.h"
+#include "Region.h"
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11PMBlitLoops_nativeBlit
+ (JNIEnv *env, jobject joSelf,
+ jlong srcData, jlong dstData,
+ jlong gc, jobject clip,
+ jint srcx, jint srcy,
+ jint dstx, jint dsty,
+ jint width, jint height)
+{
+#ifndef HEADLESS
+ X11SDOps *srcXsdo, *dstXsdo;
+ SurfaceDataBounds span, srcBounds;
+ RegionData clipInfo;
+ GC xgc;
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
+ if (srcXsdo == NULL) {
+ return;
+ }
+ dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+ if (dstXsdo == NULL) {
+ return;
+ }
+ if (Region_GetInfo(env, clip, &clipInfo)) {
+ return;
+ }
+
+ xgc = (GC)gc;
+ if (xgc == NULL) {
+ return;
+ }
+
+#ifdef MITSHM
+ if (srcXsdo->isPixmap) {
+ X11SD_UnPuntPixmap(srcXsdo);
+ }
+#endif /* MITSHM */
+
+ /* clip the source rect to the source pixmap's dimensions */
+ srcBounds.x1 = srcx;
+ srcBounds.y1 = srcy;
+ srcBounds.x2 = srcx + width;
+ srcBounds.y2 = srcy + height;
+ SurfaceData_IntersectBoundsXYXY(&srcBounds,
+ 0, 0, srcXsdo->pmWidth, srcXsdo->pmHeight);
+ span.x1 = dstx;
+ span.y1 = dsty;
+ span.x2 = dstx + width;
+ span.y2 = dsty + height;
+
+ /* intersect the source and dest rects */
+ SurfaceData_IntersectBlitBounds(&srcBounds, &span,
+ dstx - srcx, dsty - srcy);
+ srcx = srcBounds.x1;
+ srcy = srcBounds.y1;
+ dstx = span.x1;
+ dsty = span.y1;
+
+ if (srcXsdo->bitmask != 0) {
+ XSetClipOrigin(awt_display, xgc, dstx - srcx, dsty - srcy);
+ XSetClipMask(awt_display, xgc, srcXsdo->bitmask);
+ }
+
+ Region_IntersectBounds(&clipInfo, &span);
+ if (!Region_IsEmpty(&clipInfo)) {
+ Region_StartIteration(env, &clipInfo);
+ srcx -= dstx;
+ srcy -= dsty;
+ while (Region_NextIteration(&clipInfo, &span)) {
+ XCopyArea(awt_display, srcXsdo->drawable, dstXsdo->drawable, xgc,
+ srcx + span.x1, srcy + span.y1,
+ span.x2 - span.x1, span.y2 - span.y1,
+ span.x1, span.y1);
+ }
+ Region_EndIteration(env, &clipInfo);
+ }
+
+ if (srcXsdo->bitmask != 0) {
+ XSetClipMask(awt_display, xgc, None);
+ }
+
+#ifdef MITSHM
+ if (srcXsdo->shmPMData.usingShmPixmap) {
+ srcXsdo->shmPMData.xRequestSent = JNI_TRUE;
+ }
+#endif /* MITSHM */
+ X11SD_DirectRenderNotify(env, dstXsdo);
+#endif /* !HEADLESS */
+}
+
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11PMBlitBgLoops_nativeBlitBg
+ (JNIEnv *env, jobject joSelf,
+ jlong srcData, jlong dstData,
+ jlong xgc, jint pixel,
+ jint srcx, jint srcy,
+ jint dstx, jint dsty,
+ jint width, jint height)
+{
+#ifndef HEADLESS
+ X11SDOps *srcXsdo, *dstXsdo;
+ GC dstGC;
+ SurfaceDataBounds dstBounds, srcBounds;
+ Drawable srcDrawable;
+
+ if (width <= 0 || height <= 0) {
+ return;
+ }
+
+ srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
+ if (srcXsdo == NULL) {
+ return;
+ }
+ dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
+ if (dstXsdo == NULL) {
+ return;
+ }
+
+ dstGC = (GC)xgc;
+ if (dstGC == NULL) {
+ return;
+ }
+
+#ifdef MITSHM
+ if (srcXsdo->isPixmap) {
+ X11SD_UnPuntPixmap(srcXsdo);
+ }
+#endif /* MITSHM */
+
+ srcDrawable = srcXsdo->GetPixmapWithBg(env, srcXsdo, pixel);
+ if (srcDrawable == 0) {
+ return;
+ }
+
+ /* clip the source rect to the source pixmap's dimensions */
+ srcBounds.x1 = srcx;
+ srcBounds.y1 = srcy;
+ srcBounds.x2 = srcx + width;
+ srcBounds.y2 = srcy + height;
+ SurfaceData_IntersectBoundsXYXY(&srcBounds,
+ 0, 0, srcXsdo->pmWidth, srcXsdo->pmHeight);
+ dstBounds.x1 = dstx;
+ dstBounds.y1 = dsty;
+ dstBounds.x2 = dstx + width;
+ dstBounds.y2 = dsty + height;
+
+ /* intersect the source and dest rects */
+ SurfaceData_IntersectBlitBounds(&srcBounds, &dstBounds,
+ dstx - srcx, dsty - srcy);
+ srcx = srcBounds.x1;
+ srcy = srcBounds.y1;
+ dstx = dstBounds.x1;
+ dsty = dstBounds.y1;
+ width = srcBounds.x2 - srcBounds.x1;
+ height = srcBounds.y2 - srcBounds.y1;
+
+ /* do an unmasked copy as we've already filled transparent
+ pixels of the source image with the desired color */
+ XCopyArea(awt_display, srcDrawable, dstXsdo->drawable, dstGC,
+ srcx, srcy, width, height, dstx, dsty);
+
+ srcXsdo->ReleasePixmapWithBg(env, srcXsdo);
+ X11SD_DirectRenderNotify(env, dstXsdo);
+#endif /* !HEADLESS */
+}
+
+/*
+ * Class: sun_java2d_x11_X11PMBlitLoops
+ * Method: updateBitmask
+ * Signature: (Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_java2d_x11_X11PMBlitLoops_updateBitmask
+ (JNIEnv *env, jclass xpmbl, jobject srcsd, jobject dstsd, jboolean isICM)
+{
+#ifndef HEADLESS
+ SurfaceDataOps *srcOps = SurfaceData_GetOps(env, srcsd);
+ X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, dstsd);
+ SurfaceDataRasInfo srcInfo;
+
+ int flags;
+ int screen;
+ int width;
+ int height;
+ jint srcScan, dstScan;
+ int rowCount;
+ unsigned char *pDst;
+ XImage *image;
+ GC xgc;
+
+ if (srcOps == NULL || xsdo == NULL) {
+ JNU_ThrowNullPointerException(env, "Null BISD in updateMaskRegion");
+ return;
+ }
+
+ AWT_LOCK();
+
+ screen = xsdo->configData->awt_visInfo.screen;
+ width = xsdo->pmWidth;
+ height = xsdo->pmHeight;
+
+ if (xsdo->bitmask == 0) {
+ /* create the bitmask if it is not yet created */
+ xsdo->bitmask = XCreatePixmap(awt_display,
+ RootWindow(awt_display, screen),
+ width, height, 1);
+ if (xsdo->bitmask == 0) {
+ AWT_UNLOCK();
+ JNU_ThrowOutOfMemoryError(env,
+ "Cannot create bitmask for "
+ "offscreen surface");
+ return;
+ }
+ }
+
+ /* Create a bitmask image and then blit it to the pixmap. */
+ image = XCreateImage(awt_display, DefaultVisual(awt_display, screen),
+ 1, XYBitmap, 0, NULL, width, height, 32, 0);
+ if (image == NULL) {
+ AWT_UNLOCK();
+ JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
+ return;
+ }
+ dstScan = image->bytes_per_line;
+ image->data = malloc(dstScan * height);
+ if (image->data == NULL) {
+ XFree(image);
+ AWT_UNLOCK();
+ JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
+ return;
+ }
+ pDst = (unsigned char *)image->data;
+
+ srcInfo.bounds.x1 = 0;
+ srcInfo.bounds.y1 = 0;
+ srcInfo.bounds.x2 = width;
+ srcInfo.bounds.y2 = height;
+
+ flags = (isICM ? (SD_LOCK_LUT | SD_LOCK_READ) : SD_LOCK_READ);
+ if (srcOps->Lock(env, srcOps, &srcInfo, flags) != SD_SUCCESS) {
+ XDestroyImage(image);
+ AWT_UNLOCK();
+ return;
+ }
+ srcOps->GetRasInfo(env, srcOps, &srcInfo);
+
+ rowCount = height;
+ if (isICM) {
+ unsigned char *pSrc;
+ jint *srcLut;
+
+ srcScan = srcInfo.scanStride;
+ srcLut = srcInfo.lutBase;
+ pSrc = (unsigned char *)srcInfo.rasBase;
+
+ if (image->bitmap_bit_order == MSBFirst) {
+ do {
+ int x = 0, bx = 0;
+ unsigned int pix = 0;
+ unsigned int bit = 0x80;
+ unsigned char *srcPixel = pSrc;
+ do {
+ if (bit == 0) {
+ pDst[bx++] = (unsigned char)pix;
+ pix = 0;
+ bit = 0x80;
+ }
+ pix |= bit & (srcLut[*srcPixel++] >> 31);
+ bit >>= 1;
+ } while (++x < width);
+ pDst[bx] = (unsigned char)pix;
+ pDst += dstScan;
+ pSrc = (unsigned char *) (((intptr_t)pSrc) + srcScan);
+ } while (--rowCount > 0);
+ } else {
+ do {
+ int x = 0, bx = 0;
+ unsigned int pix = 0;
+ unsigned int bit = 1;
+ unsigned char *srcPixel = pSrc;
+ do {
+ if ((bit >> 8) != 0) {
+ pDst[bx++] = (unsigned char) pix;
+ pix = 0;
+ bit = 1;
+ }
+ pix |= bit & (srcLut[*srcPixel++] >> 31);
+ bit <<= 1;
+ } while (++x < width);
+ pDst[bx] = (unsigned char) pix;
+ pDst += dstScan;
+ pSrc = (unsigned char *) (((intptr_t)pSrc) + srcScan);
+ } while (--rowCount > 0);
+ }
+ } else /*DCM with ARGB*/ {
+ unsigned int *pSrc;
+
+ /* this is a number of pixels in a row, not number of bytes */
+ srcScan = srcInfo.scanStride;
+ pSrc = (unsigned int *)srcInfo.rasBase;
+
+ if (image->bitmap_bit_order == MSBFirst) {
+ do {
+ int x = 0, bx = 0;
+ unsigned int pix = 0;
+ unsigned int bit = 0x80;
+ int *srcPixel = (int *) pSrc;
+ do {
+ if (bit == 0) {
+ /* next word */
+ pDst[bx++] = (unsigned char)pix;
+ pix = 0;
+ bit = 0x80;
+ }
+ if (*srcPixel++ & 0xff000000) {
+ /* if src pixel is opaque, set the bit in the bitmap */
+ pix |= bit;
+ }
+ bit >>= 1;
+ } while (++x < width);
+ /* last pixels in a row */
+ pDst[bx] = (unsigned char)pix;
+
+ pDst += dstScan;
+ pSrc = (unsigned int *) (((intptr_t)pSrc) + srcScan);
+ } while (--rowCount > 0);
+ } else {
+ do {
+ int x = 0, bx = 0;
+ unsigned int pix = 0;
+ unsigned int bit = 1;
+ int *srcPixel = (int *) pSrc;
+ do {
+ if ((bit >> 8) != 0) {
+ pDst[bx++] = (unsigned char)pix;
+ pix = 0;
+ bit = 1;
+ }
+ if (*srcPixel++ & 0xff000000) {
+ /* if src pixel is opaque, set the bit in the bitmap */
+ pix |= bit;
+ }
+ bit <<= 1;
+ } while (++x < width);
+ pDst[bx] = (unsigned char)pix;
+ pDst += dstScan;
+ pSrc = (unsigned int *) (((intptr_t)pSrc) + srcScan);
+ } while (--rowCount > 0);
+ }
+ }
+ SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
+ SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
+
+ xgc = XCreateGC(awt_display, xsdo->bitmask, 0L, NULL);
+ XSetForeground(awt_display, xgc, 1);
+ XSetBackground(awt_display, xgc, 0);
+ XPutImage(awt_display, xsdo->bitmask, xgc,
+ image, 0, 0, 0, 0, width, height);
+
+ XFreeGC(awt_display, xgc);
+ XDestroyImage(image);
+
+ AWT_UNLOCK();
+#endif /* !HEADLESS */
+}