Path: blob/master/src/java.desktop/share/native/libawt/java2d/pipe/SpanClipRenderer.c
41159 views
/*1* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <stdlib.h>26#include <string.h>27#include <math.h>2829#include "jni.h"30#include "jni_util.h"3132#include "sun_java2d_pipe_SpanClipRenderer.h"3334jfieldID pBandsArrayID;35jfieldID pEndIndexID;36jfieldID pRegionID;37jfieldID pCurIndexID;38jfieldID pNumXbandsID;3940JNIEXPORT void JNICALL41Java_sun_java2d_pipe_SpanClipRenderer_initIDs42(JNIEnv *env, jclass src, jclass rc, jclass ric)43{44/* Region fields */45pBandsArrayID = (*env)->GetFieldID(env, rc, "bands", "[I");46if (pBandsArrayID == NULL) {47return;48}49pEndIndexID = (*env)->GetFieldID(env, rc, "endIndex", "I");50if (pEndIndexID == NULL) {51return;52}5354/* RegionIterator fields */55pRegionID = (*env)->GetFieldID(env, ric, "region",56"Lsun/java2d/pipe/Region;");57if (pRegionID == NULL) {58return;59}60pCurIndexID = (*env)->GetFieldID(env, ric, "curIndex", "I");61if (pCurIndexID == NULL) {62return;63}64pNumXbandsID = (*env)->GetFieldID(env, ric, "numXbands", "I");65if (pNumXbandsID == NULL) {66return;67}68}6970static void71fill(jbyte *alpha, jint offset, jint tsize,72jint x, jint y, jint w, jint h, jbyte value)73{74alpha += offset + y * tsize + x;75tsize -= w;76while (--h >= 0) {77for (x = 0; x < w; x++) {78*alpha++ = value;79}80alpha += tsize;81}82}8384static jboolean85nextYRange(jint *box, jint *bands, jint endIndex,86jint *pCurIndex, jint *pNumXbands)87{88jint curIndex = *pCurIndex;89jint numXbands = *pNumXbands;90jboolean ret;9192curIndex += numXbands * 2;93ret = (curIndex + 3 < endIndex);94if (ret) {95box[1] = bands[curIndex++];96box[3] = bands[curIndex++];97numXbands = bands[curIndex++];98} else {99numXbands = 0;100}101*pCurIndex = curIndex;102*pNumXbands = numXbands;103return ret;104}105106static jboolean107nextXBand(jint *box, jint *bands, jint endIndex,108jint *pCurIndex, jint *pNumXbands)109{110jint curIndex = *pCurIndex;111jint numXbands = *pNumXbands;112113if (numXbands <= 0 || curIndex + 2 > endIndex) {114return JNI_FALSE;115}116numXbands--;117box[0] = bands[curIndex++];118box[2] = bands[curIndex++];119120*pCurIndex = curIndex;121*pNumXbands = numXbands;122return JNI_TRUE;123}124125JNIEXPORT void JNICALL126Java_sun_java2d_pipe_SpanClipRenderer_fillTile127(JNIEnv *env, jobject sr, jobject ri,128jbyteArray alphaTile, jint offset, jint tsize, jintArray boxArray)129{130jbyte *alpha;131jint *box;132jint w, h;133jsize alphalen;134135if ((*env)->GetArrayLength(env, boxArray) < 4) {136JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");137return;138}139alphalen = (*env)->GetArrayLength(env, alphaTile);140141box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);142if (box == NULL) {143return;144}145146w = box[2] - box[0];147h = box[3] - box[1];148149if (alphalen < offset || (alphalen - offset) / tsize < h) {150(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);151JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");152return;153}154155alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);156if (alpha == NULL) {157(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);158return;159}160161fill(alpha, offset, tsize, 0, 0, w, h, (jbyte) 0xff);162163(*env)->ReleasePrimitiveArrayCritical(env, alphaTile, alpha, 0);164(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);165166Java_sun_java2d_pipe_SpanClipRenderer_eraseTile(env, sr, ri,167alphaTile, offset, tsize,168boxArray);169}170171JNIEXPORT void JNICALL172Java_sun_java2d_pipe_SpanClipRenderer_eraseTile173(JNIEnv *env, jobject sr, jobject ri,174jbyteArray alphaTile, jint offset, jint tsize, jintArray boxArray)175{176jobject region;177jintArray bandsArray;178jint *bands;179jbyte *alpha;180jint *box;181jint endIndex;182jint curIndex;183jint saveCurIndex;184jint numXbands;185jint saveNumXbands;186jint lox;187jint loy;188jint hix;189jint hiy;190jint firstx;191jint firsty;192jint lastx;193jint lasty;194jint curx;195jsize alphalen;196197if ((*env)->GetArrayLength(env, boxArray) < 4) {198JNU_ThrowArrayIndexOutOfBoundsException(env, "band array");199return;200}201alphalen = (*env)->GetArrayLength(env, alphaTile);202203saveCurIndex = (*env)->GetIntField(env, ri, pCurIndexID);204saveNumXbands = (*env)->GetIntField(env, ri, pNumXbandsID);205region = (*env)->GetObjectField(env, ri, pRegionID);206bandsArray = (*env)->GetObjectField(env, region, pBandsArrayID);207endIndex = (*env)->GetIntField(env, region, pEndIndexID);208209if (endIndex > (*env)->GetArrayLength(env, bandsArray)) {210endIndex = (*env)->GetArrayLength(env, bandsArray);211}212213box = (*env)->GetPrimitiveArrayCritical(env, boxArray, 0);214if (box == NULL) {215return;216}217218lox = box[0];219loy = box[1];220hix = box[2];221hiy = box[3];222223if (alphalen < offset ||224alphalen < offset + (hix-lox) ||225(alphalen - offset - (hix-lox)) / tsize < (hiy - loy - 1)) {226(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);227JNU_ThrowArrayIndexOutOfBoundsException(env, "alpha tile array");228return;229}230231bands = (*env)->GetPrimitiveArrayCritical(env, bandsArray, 0);232if (bands == NULL) {233(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);234return;235}236alpha = (*env)->GetPrimitiveArrayCritical(env, alphaTile, 0);237if (alpha == NULL) {238(*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0);239(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);240return;241}242243curIndex = saveCurIndex;244numXbands = saveNumXbands;245firsty = hiy;246lasty = hiy;247firstx = hix;248lastx = lox;249250while (nextYRange(box, bands, endIndex, &curIndex, &numXbands)) {251if (box[3] <= loy) {252saveNumXbands = numXbands;253saveCurIndex = curIndex;254continue;255}256if (box[1] >= hiy) {257break;258}259if (box[1] < loy) {260box[1] = loy;261}262if (box[3] > hiy) {263box[3] = hiy;264}265curx = lox;266while (nextXBand(box, bands, endIndex, &curIndex, &numXbands)) {267if (box[2] <= lox) {268continue;269}270if (box[0] >= hix) {271break;272}273if (box[0] < lox) {274box[0] = lox;275}276if (lasty < box[1]) {277fill(alpha, offset, tsize,2780, lasty - loy,279hix - lox, box[1] - lasty, 0);280}281lasty = box[3];282if (firstx > box[0]) {283firstx = box[0];284}285if (curx < box[0]) {286fill(alpha, offset, tsize,287curx - lox, box[1] - loy,288box[0] - curx, box[3] - box[1], 0);289}290curx = box[2];291if (curx >= hix) {292curx = hix;293break;294}295}296if (curx > lox) {297if (curx < hix) {298fill(alpha, offset, tsize,299curx - lox, box[1] - loy,300hix - curx, box[3] - box[1], 0);301}302if (firsty > box[1]) {303firsty = box[1];304}305}306if (lastx < curx) {307lastx = curx;308}309}310311box[0] = firstx;312box[1] = firsty;313box[2] = lastx;314box[3] = lasty;315316(*env)->ReleasePrimitiveArrayCritical(env, alphaTile, alpha, 0);317(*env)->ReleasePrimitiveArrayCritical(env, bandsArray, bands, 0);318(*env)->ReleasePrimitiveArrayCritical(env, boxArray, box, 0);319320(*env)->SetIntField(env, ri, pCurIndexID, saveCurIndex);321(*env)->SetIntField(env, ri, pNumXbandsID, saveNumXbands);322}323324325