0N/A/*
2362N/A * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#include <stdlib.h>
0N/A#include <jni.h>
0N/A#include <jlong.h>
0N/A#include "X11SurfaceData.h"
0N/A#include "Region.h"
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_x11_X11PMBlitLoops_nativeBlit
0N/A (JNIEnv *env, jobject joSelf,
0N/A jlong srcData, jlong dstData,
0N/A jlong gc, jobject clip,
0N/A jint srcx, jint srcy,
0N/A jint dstx, jint dsty,
0N/A jint width, jint height)
0N/A{
0N/A#ifndef HEADLESS
0N/A X11SDOps *srcXsdo, *dstXsdo;
0N/A SurfaceDataBounds span, srcBounds;
0N/A RegionData clipInfo;
0N/A GC xgc;
0N/A
0N/A if (width <= 0 || height <= 0) {
0N/A return;
0N/A }
0N/A
0N/A srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
0N/A if (srcXsdo == NULL) {
0N/A return;
0N/A }
0N/A dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
0N/A if (dstXsdo == NULL) {
0N/A return;
0N/A }
0N/A if (Region_GetInfo(env, clip, &clipInfo)) {
0N/A return;
0N/A }
0N/A
0N/A xgc = (GC)gc;
0N/A if (xgc == NULL) {
0N/A return;
0N/A }
0N/A
0N/A#ifdef MITSHM
0N/A if (srcXsdo->isPixmap) {
0N/A X11SD_UnPuntPixmap(srcXsdo);
0N/A }
0N/A#endif /* MITSHM */
0N/A
0N/A /* clip the source rect to the source pixmap's dimensions */
0N/A srcBounds.x1 = srcx;
0N/A srcBounds.y1 = srcy;
0N/A srcBounds.x2 = srcx + width;
0N/A srcBounds.y2 = srcy + height;
0N/A SurfaceData_IntersectBoundsXYXY(&srcBounds,
0N/A 0, 0, srcXsdo->pmWidth, srcXsdo->pmHeight);
0N/A span.x1 = dstx;
0N/A span.y1 = dsty;
0N/A span.x2 = dstx + width;
0N/A span.y2 = dsty + height;
0N/A
0N/A /* intersect the source and dest rects */
0N/A SurfaceData_IntersectBlitBounds(&srcBounds, &span,
0N/A dstx - srcx, dsty - srcy);
0N/A srcx = srcBounds.x1;
0N/A srcy = srcBounds.y1;
0N/A dstx = span.x1;
0N/A dsty = span.y1;
0N/A
0N/A if (srcXsdo->bitmask != 0) {
0N/A XSetClipOrigin(awt_display, xgc, dstx - srcx, dsty - srcy);
0N/A XSetClipMask(awt_display, xgc, srcXsdo->bitmask);
0N/A }
0N/A
0N/A Region_IntersectBounds(&clipInfo, &span);
0N/A if (!Region_IsEmpty(&clipInfo)) {
0N/A Region_StartIteration(env, &clipInfo);
0N/A srcx -= dstx;
0N/A srcy -= dsty;
0N/A while (Region_NextIteration(&clipInfo, &span)) {
0N/A XCopyArea(awt_display, srcXsdo->drawable, dstXsdo->drawable, xgc,
0N/A srcx + span.x1, srcy + span.y1,
0N/A span.x2 - span.x1, span.y2 - span.y1,
0N/A span.x1, span.y1);
0N/A }
0N/A Region_EndIteration(env, &clipInfo);
0N/A }
0N/A
0N/A if (srcXsdo->bitmask != 0) {
0N/A XSetClipMask(awt_display, xgc, None);
0N/A }
0N/A
0N/A#ifdef MITSHM
0N/A if (srcXsdo->shmPMData.usingShmPixmap) {
0N/A srcXsdo->shmPMData.xRequestSent = JNI_TRUE;
0N/A }
0N/A#endif /* MITSHM */
0N/A X11SD_DirectRenderNotify(env, dstXsdo);
0N/A#endif /* !HEADLESS */
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_x11_X11PMBlitBgLoops_nativeBlitBg
0N/A (JNIEnv *env, jobject joSelf,
0N/A jlong srcData, jlong dstData,
0N/A jlong xgc, jint pixel,
0N/A jint srcx, jint srcy,
0N/A jint dstx, jint dsty,
0N/A jint width, jint height)
0N/A{
0N/A#ifndef HEADLESS
0N/A X11SDOps *srcXsdo, *dstXsdo;
0N/A GC dstGC;
0N/A SurfaceDataBounds dstBounds, srcBounds;
0N/A Drawable srcDrawable;
0N/A
0N/A if (width <= 0 || height <= 0) {
0N/A return;
0N/A }
0N/A
0N/A srcXsdo = (X11SDOps *)jlong_to_ptr(srcData);
0N/A if (srcXsdo == NULL) {
0N/A return;
0N/A }
0N/A dstXsdo = (X11SDOps *)jlong_to_ptr(dstData);
0N/A if (dstXsdo == NULL) {
0N/A return;
0N/A }
0N/A
0N/A dstGC = (GC)xgc;
0N/A if (dstGC == NULL) {
0N/A return;
0N/A }
0N/A
0N/A#ifdef MITSHM
0N/A if (srcXsdo->isPixmap) {
0N/A X11SD_UnPuntPixmap(srcXsdo);
0N/A }
0N/A#endif /* MITSHM */
0N/A
0N/A srcDrawable = srcXsdo->GetPixmapWithBg(env, srcXsdo, pixel);
0N/A if (srcDrawable == 0) {
0N/A return;
0N/A }
0N/A
0N/A /* clip the source rect to the source pixmap's dimensions */
0N/A srcBounds.x1 = srcx;
0N/A srcBounds.y1 = srcy;
0N/A srcBounds.x2 = srcx + width;
0N/A srcBounds.y2 = srcy + height;
0N/A SurfaceData_IntersectBoundsXYXY(&srcBounds,
0N/A 0, 0, srcXsdo->pmWidth, srcXsdo->pmHeight);
0N/A dstBounds.x1 = dstx;
0N/A dstBounds.y1 = dsty;
0N/A dstBounds.x2 = dstx + width;
0N/A dstBounds.y2 = dsty + height;
0N/A
0N/A /* intersect the source and dest rects */
0N/A SurfaceData_IntersectBlitBounds(&srcBounds, &dstBounds,
0N/A dstx - srcx, dsty - srcy);
0N/A srcx = srcBounds.x1;
0N/A srcy = srcBounds.y1;
0N/A dstx = dstBounds.x1;
0N/A dsty = dstBounds.y1;
0N/A width = srcBounds.x2 - srcBounds.x1;
0N/A height = srcBounds.y2 - srcBounds.y1;
0N/A
0N/A /* do an unmasked copy as we've already filled transparent
0N/A pixels of the source image with the desired color */
0N/A XCopyArea(awt_display, srcDrawable, dstXsdo->drawable, dstGC,
0N/A srcx, srcy, width, height, dstx, dsty);
0N/A
0N/A srcXsdo->ReleasePixmapWithBg(env, srcXsdo);
0N/A X11SD_DirectRenderNotify(env, dstXsdo);
0N/A#endif /* !HEADLESS */
0N/A}
0N/A
0N/A/*
0N/A * Class: sun_java2d_x11_X11PMBlitLoops
0N/A * Method: updateBitmask
0N/A * Signature: (Lsun/java2d/SurfaceData;Lsun/java2d/SurfaceData;)V
0N/A */
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_x11_X11PMBlitLoops_updateBitmask
0N/A (JNIEnv *env, jclass xpmbl, jobject srcsd, jobject dstsd, jboolean isICM)
0N/A{
0N/A#ifndef HEADLESS
0N/A SurfaceDataOps *srcOps = SurfaceData_GetOps(env, srcsd);
0N/A X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, dstsd);
0N/A SurfaceDataRasInfo srcInfo;
0N/A
0N/A int flags;
0N/A int screen;
0N/A int width;
0N/A int height;
0N/A jint srcScan, dstScan;
0N/A int rowCount;
0N/A unsigned char *pDst;
0N/A XImage *image;
0N/A GC xgc;
0N/A
0N/A if (srcOps == NULL || xsdo == NULL) {
0N/A JNU_ThrowNullPointerException(env, "Null BISD in updateMaskRegion");
0N/A return;
0N/A }
0N/A
0N/A AWT_LOCK();
0N/A
0N/A screen = xsdo->configData->awt_visInfo.screen;
0N/A width = xsdo->pmWidth;
0N/A height = xsdo->pmHeight;
0N/A
0N/A if (xsdo->bitmask == 0) {
0N/A /* create the bitmask if it is not yet created */
0N/A xsdo->bitmask = XCreatePixmap(awt_display,
0N/A RootWindow(awt_display, screen),
0N/A width, height, 1);
0N/A if (xsdo->bitmask == 0) {
0N/A AWT_UNLOCK();
0N/A JNU_ThrowOutOfMemoryError(env,
0N/A "Cannot create bitmask for "
0N/A "offscreen surface");
0N/A return;
0N/A }
0N/A }
0N/A
0N/A /* Create a bitmask image and then blit it to the pixmap. */
0N/A image = XCreateImage(awt_display, DefaultVisual(awt_display, screen),
0N/A 1, XYBitmap, 0, NULL, width, height, 32, 0);
0N/A if (image == NULL) {
0N/A AWT_UNLOCK();
0N/A JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
0N/A return;
0N/A }
0N/A dstScan = image->bytes_per_line;
0N/A image->data = malloc(dstScan * height);
0N/A if (image->data == NULL) {
0N/A XFree(image);
0N/A AWT_UNLOCK();
0N/A JNU_ThrowOutOfMemoryError(env, "Cannot allocate bitmask for mask");
0N/A return;
0N/A }
0N/A pDst = (unsigned char *)image->data;
0N/A
0N/A srcInfo.bounds.x1 = 0;
0N/A srcInfo.bounds.y1 = 0;
0N/A srcInfo.bounds.x2 = width;
0N/A srcInfo.bounds.y2 = height;
0N/A
0N/A flags = (isICM ? (SD_LOCK_LUT | SD_LOCK_READ) : SD_LOCK_READ);
0N/A if (srcOps->Lock(env, srcOps, &srcInfo, flags) != SD_SUCCESS) {
0N/A XDestroyImage(image);
0N/A AWT_UNLOCK();
0N/A return;
0N/A }
0N/A srcOps->GetRasInfo(env, srcOps, &srcInfo);
0N/A
0N/A rowCount = height;
0N/A if (isICM) {
0N/A unsigned char *pSrc;
0N/A jint *srcLut;
0N/A
0N/A srcScan = srcInfo.scanStride;
0N/A srcLut = srcInfo.lutBase;
0N/A pSrc = (unsigned char *)srcInfo.rasBase;
0N/A
0N/A if (image->bitmap_bit_order == MSBFirst) {
0N/A do {
0N/A int x = 0, bx = 0;
0N/A unsigned int pix = 0;
0N/A unsigned int bit = 0x80;
0N/A unsigned char *srcPixel = pSrc;
0N/A do {
0N/A if (bit == 0) {
0N/A pDst[bx++] = (unsigned char)pix;
0N/A pix = 0;
0N/A bit = 0x80;
0N/A }
0N/A pix |= bit & (srcLut[*srcPixel++] >> 31);
0N/A bit >>= 1;
0N/A } while (++x < width);
0N/A pDst[bx] = (unsigned char)pix;
0N/A pDst += dstScan;
0N/A pSrc = (unsigned char *) (((intptr_t)pSrc) + srcScan);
0N/A } while (--rowCount > 0);
0N/A } else {
0N/A do {
0N/A int x = 0, bx = 0;
0N/A unsigned int pix = 0;
0N/A unsigned int bit = 1;
0N/A unsigned char *srcPixel = pSrc;
0N/A do {
0N/A if ((bit >> 8) != 0) {
0N/A pDst[bx++] = (unsigned char) pix;
0N/A pix = 0;
0N/A bit = 1;
0N/A }
0N/A pix |= bit & (srcLut[*srcPixel++] >> 31);
0N/A bit <<= 1;
0N/A } while (++x < width);
0N/A pDst[bx] = (unsigned char) pix;
0N/A pDst += dstScan;
0N/A pSrc = (unsigned char *) (((intptr_t)pSrc) + srcScan);
0N/A } while (--rowCount > 0);
0N/A }
0N/A } else /*DCM with ARGB*/ {
0N/A unsigned int *pSrc;
0N/A
0N/A /* this is a number of pixels in a row, not number of bytes */
0N/A srcScan = srcInfo.scanStride;
0N/A pSrc = (unsigned int *)srcInfo.rasBase;
0N/A
0N/A if (image->bitmap_bit_order == MSBFirst) {
0N/A do {
0N/A int x = 0, bx = 0;
0N/A unsigned int pix = 0;
0N/A unsigned int bit = 0x80;
0N/A int *srcPixel = (int *) pSrc;
0N/A do {
0N/A if (bit == 0) {
0N/A /* next word */
0N/A pDst[bx++] = (unsigned char)pix;
0N/A pix = 0;
0N/A bit = 0x80;
0N/A }
0N/A if (*srcPixel++ & 0xff000000) {
0N/A /* if src pixel is opaque, set the bit in the bitmap */
0N/A pix |= bit;
0N/A }
0N/A bit >>= 1;
0N/A } while (++x < width);
0N/A /* last pixels in a row */
0N/A pDst[bx] = (unsigned char)pix;
0N/A
0N/A pDst += dstScan;
0N/A pSrc = (unsigned int *) (((intptr_t)pSrc) + srcScan);
0N/A } while (--rowCount > 0);
0N/A } else {
0N/A do {
0N/A int x = 0, bx = 0;
0N/A unsigned int pix = 0;
0N/A unsigned int bit = 1;
0N/A int *srcPixel = (int *) pSrc;
0N/A do {
0N/A if ((bit >> 8) != 0) {
0N/A pDst[bx++] = (unsigned char)pix;
0N/A pix = 0;
0N/A bit = 1;
0N/A }
0N/A if (*srcPixel++ & 0xff000000) {
0N/A /* if src pixel is opaque, set the bit in the bitmap */
0N/A pix |= bit;
0N/A }
0N/A bit <<= 1;
0N/A } while (++x < width);
0N/A pDst[bx] = (unsigned char)pix;
0N/A pDst += dstScan;
0N/A pSrc = (unsigned int *) (((intptr_t)pSrc) + srcScan);
0N/A } while (--rowCount > 0);
0N/A }
0N/A }
0N/A SurfaceData_InvokeRelease(env, srcOps, &srcInfo);
0N/A SurfaceData_InvokeUnlock(env, srcOps, &srcInfo);
0N/A
0N/A xgc = XCreateGC(awt_display, xsdo->bitmask, 0L, NULL);
0N/A XSetForeground(awt_display, xgc, 1);
0N/A XSetBackground(awt_display, xgc, 0);
0N/A XPutImage(awt_display, xsdo->bitmask, xgc,
0N/A image, 0, 0, 0, 0, width, height);
0N/A
0N/A XFreeGC(awt_display, xgc);
0N/A XDestroyImage(image);
0N/A
0N/A AWT_UNLOCK();
0N/A#endif /* !HEADLESS */
0N/A}