0N/A/*
2362N/A * Copyright (c) 1998, 2000, 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 <string.h>
0N/A#include <math.h>
0N/A
0N/A#include "jni.h"
0N/A#include "jni_util.h"
0N/A
0N/A#include "sun_java2d_pipe_SpanClipRenderer.h"
0N/A#include "sun_java2d_pipe_RegionIterator.h"
0N/A
0N/AjfieldID pBandsArrayID;
0N/AjfieldID pEndIndexID;
0N/AjfieldID pRegionID;
0N/AjfieldID pCurIndexID;
0N/AjfieldID pNumXbandsID;
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_pipe_SpanClipRenderer_initIDs
0N/A (JNIEnv *env, jclass src, jclass rc, jclass ric)
0N/A{
0N/A /* Region fields */
0N/A pBandsArrayID = (*env)->GetFieldID(env, rc, "bands", "[I");
0N/A pEndIndexID = (*env)->GetFieldID(env, rc, "endIndex", "I");
0N/A
0N/A /* RegionIterator fields */
0N/A pRegionID = (*env)->GetFieldID(env, ric, "region",
0N/A "Lsun/java2d/pipe/Region;");
0N/A pCurIndexID = (*env)->GetFieldID(env, ric, "curIndex", "I");
0N/A pNumXbandsID = (*env)->GetFieldID(env, ric, "numXbands", "I");
0N/A
0N/A if((pBandsArrayID == NULL)
0N/A || (pEndIndexID == NULL)
0N/A || (pRegionID == NULL)
0N/A || (pCurIndexID == NULL)
0N/A || (pNumXbandsID == NULL))
0N/A {
0N/A JNU_ThrowInternalError(env, "NULL field ID");
0N/A }
0N/A}
0N/A
0N/Astatic void
0N/Afill(jbyte *alpha, jint offset, jint tsize,
0N/A jint x, jint y, jint w, jint h, jbyte value)
0N/A{
0N/A alpha += offset + y * tsize + x;
0N/A tsize -= w;
0N/A while (--h >= 0) {
0N/A for (x = 0; x < w; x++) {
0N/A *alpha++ = value;
0N/A }
0N/A alpha += tsize;
0N/A }
0N/A}
0N/A
0N/Astatic jboolean
0N/AnextYRange(jint *box, jint *bands, jint endIndex,
0N/A jint *pCurIndex, jint *pNumXbands)
0N/A{
0N/A jint curIndex = *pCurIndex;
0N/A jint numXbands = *pNumXbands;
0N/A jboolean ret;
0N/A
0N/A curIndex += numXbands * 2;
0N/A ret = (curIndex + 3 < endIndex);
0N/A if (ret) {
0N/A box[1] = bands[curIndex++];
0N/A box[3] = bands[curIndex++];
0N/A numXbands = bands[curIndex++];
0N/A } else {
0N/A numXbands = 0;
0N/A }
0N/A *pCurIndex = curIndex;
0N/A *pNumXbands = numXbands;
0N/A return ret;
0N/A}
0N/A
0N/Astatic jboolean
0N/AnextXBand(jint *box, jint *bands, jint endIndex,
0N/A jint *pCurIndex, jint *pNumXbands)
0N/A{
0N/A jint curIndex = *pCurIndex;
0N/A jint numXbands = *pNumXbands;
0N/A
0N/A if (numXbands <= 0 || curIndex + 2 > endIndex) {
0N/A return JNI_FALSE;
0N/A }
0N/A numXbands--;
0N/A box[0] = bands[curIndex++];
0N/A box[2] = bands[curIndex++];
0N/A
0N/A *pCurIndex = curIndex;
0N/A *pNumXbands = numXbands;
0N/A return JNI_TRUE;
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_pipe_SpanClipRenderer_fillTile
0N/A (JNIEnv *env, jobject sr, jobject ri,
0N/A jbyteArray alphaTile, jint offset, jint tsize, jintArray boxArray)
0N/A{
0N/A jbyte *alpha;
0N/A jint *box;
0N/A jint w, h;
0N/A jsize alphalen;
0N/A
0N/A if ((*env)->GetArrayLength(env, boxArray) < 4) {
0N/A JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");
0N/A }
0N/A alphalen = (*env)->GetArrayLength(env, alphaTile);
0N/A
0N/A box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);
0N/A
0N/A w = box[2] - box[0];
0N/A h = box[3] - box[1];
0N/A
0N/A if (alphalen < offset || (alphalen - offset) / tsize < h) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
0N/A JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");
0N/A }
0N/A
0N/A alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);
0N/A
0N/A fill(alpha, offset, tsize, 0, 0, w, h, (jbyte) 0xff);
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, alphaTile, alpha, 0);
0N/A (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
0N/A
0N/A Java_sun_java2d_pipe_SpanClipRenderer_eraseTile(env, sr, ri,
0N/A alphaTile, offset, tsize,
0N/A boxArray);
0N/A}
0N/A
0N/AJNIEXPORT void JNICALL
0N/AJava_sun_java2d_pipe_SpanClipRenderer_eraseTile
0N/A (JNIEnv *env, jobject sr, jobject ri,
0N/A jbyteArray alphaTile, jint offset, jint tsize, jintArray boxArray)
0N/A{
0N/A jobject region;
0N/A jintArray bandsArray;
0N/A jint *bands;
0N/A jbyte *alpha;
0N/A jint *box;
0N/A jint endIndex;
0N/A jint curIndex;
0N/A jint saveCurIndex;
0N/A jint numXbands;
0N/A jint saveNumXbands;
0N/A jint lox;
0N/A jint loy;
0N/A jint hix;
0N/A jint hiy;
0N/A jint firstx;
0N/A jint firsty;
0N/A jint lastx;
0N/A jint lasty;
0N/A jint curx;
0N/A jsize alphalen;
0N/A
0N/A if ((*env)->GetArrayLength(env, boxArray) < 4) {
0N/A JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");
0N/A }
0N/A alphalen = (*env)->GetArrayLength(env, alphaTile);
0N/A
0N/A saveCurIndex = (*env)->GetIntField(env, ri, pCurIndexID);
0N/A saveNumXbands = (*env)->GetIntField(env, ri, pNumXbandsID);
0N/A region = (*env)->GetObjectField(env, ri, pRegionID);
0N/A bandsArray = (*env)->GetObjectField(env, region, pBandsArrayID);
0N/A endIndex = (*env)->GetIntField(env, region, pEndIndexID);
0N/A
0N/A if (endIndex > (*env)->GetArrayLength(env, bandsArray)) {
0N/A endIndex = (*env)->GetArrayLength(env, bandsArray);
0N/A }
0N/A
0N/A box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);
0N/A
0N/A lox = box[0];
0N/A loy = box[1];
0N/A hix = box[2];
0N/A hiy = box[3];
0N/A
0N/A if (alphalen < offset ||
0N/A alphalen < offset + (hix-lox) ||
0N/A (alphalen - offset - (hix-lox)) / tsize < (hiy - loy - 1)) {
0N/A (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
0N/A JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");
0N/A }
0N/A
0N/A bands = (*env)->GetPrimitiveArrayCritical(env, bandsArray, 0);
0N/A alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);
0N/A
0N/A curIndex = saveCurIndex;
0N/A numXbands = saveNumXbands;
0N/A firsty = hiy;
0N/A lasty = hiy;
0N/A firstx = hix;
0N/A lastx = lox;
0N/A
0N/A while (nextYRange(box, bands, endIndex, &curIndex, &numXbands)) {
0N/A if (box[3] <= loy) {
0N/A saveNumXbands = numXbands;
0N/A saveCurIndex = curIndex;
0N/A continue;
0N/A }
0N/A if (box[1] >= hiy) {
0N/A break;
0N/A }
0N/A if (box[1] < loy) {
0N/A box[1] = loy;
0N/A }
0N/A if (box[3] > hiy) {
0N/A box[3] = hiy;
0N/A }
0N/A curx = lox;
0N/A while (nextXBand(box, bands, endIndex, &curIndex, &numXbands)) {
0N/A if (box[2] <= lox) {
0N/A continue;
0N/A }
0N/A if (box[0] >= hix) {
0N/A break;
0N/A }
0N/A if (box[0] < lox) {
0N/A box[0] = lox;
0N/A }
0N/A if (lasty < box[1]) {
0N/A fill(alpha, offset, tsize,
0N/A 0, lasty - loy,
0N/A hix - lox, box[1] - lasty, 0);
0N/A }
0N/A lasty = box[3];
0N/A if (firstx > box[0]) {
0N/A firstx = box[0];
0N/A }
0N/A if (curx < box[0]) {
0N/A fill(alpha, offset, tsize,
0N/A curx - lox, box[1] - loy,
0N/A box[0] - curx, box[3] - box[1], 0);
0N/A }
0N/A curx = box[2];
0N/A if (curx >= hix) {
0N/A curx = hix;
0N/A break;
0N/A }
0N/A }
0N/A if (curx > lox) {
0N/A if (curx < hix) {
0N/A fill(alpha, offset, tsize,
0N/A curx - lox, box[1] - loy,
0N/A hix - curx, box[3] - box[1], 0);
0N/A }
0N/A if (firsty > box[1]) {
0N/A firsty = box[1];
0N/A }
0N/A }
0N/A if (lastx < curx) {
0N/A lastx = curx;
0N/A }
0N/A }
0N/A
0N/A box[0] = firstx;
0N/A box[1] = firsty;
0N/A box[2] = lastx;
0N/A box[3] = lasty;
0N/A
0N/A (*env)->ReleasePrimitiveArrayCritical(env, alphaTile, alpha, 0);
0N/A (*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0);
0N/A (*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);
0N/A
0N/A (*env)->SetIntField(env, ri, pCurIndexID, saveCurIndex);
0N/A (*env)->SetIntField(env, ri, pNumXbandsID, saveNumXbands);
0N/A}