Path: blob/master/src/java.desktop/share/native/libawt/java2d/loops/DrawPolygons.c
41159 views
/*1* Copyright (c) 2000, 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 "jni_util.h"2627#include "GraphicsPrimitiveMgr.h"28#include "LineUtils.h"2930#include "sun_java2d_loops_DrawPolygons.h"3132static void33RefineBounds(SurfaceDataBounds *bounds, jint transX, jint transY,34jint *xPointsPtr, jint *yPointsPtr, jint pointsNeeded)35{36jint xmin, ymin, xmax, ymax;37if (pointsNeeded > 0) {38xmin = xmax = transX + *xPointsPtr++;39ymin = ymax = transY + *yPointsPtr++;40while (--pointsNeeded > 0) {41jint x = transX + *xPointsPtr++;42jint y = transY + *yPointsPtr++;43if (xmin > x) xmin = x;44if (ymin > y) ymin = y;45if (xmax < x) xmax = x;46if (ymax < y) ymax = y;47}48if (++xmax < xmin) xmax--;49if (++ymax < ymin) ymax--;50if (bounds->x1 < xmin) bounds->x1 = xmin;51if (bounds->y1 < ymin) bounds->y1 = ymin;52if (bounds->x2 > xmax) bounds->x2 = xmax;53if (bounds->y2 > ymax) bounds->y2 = ymax;54} else {55bounds->x2 = bounds->x1;56bounds->y2 = bounds->y1;57}58}5960static void61ProcessPoly(SurfaceDataRasInfo *pRasInfo,62DrawLineFunc *pLine,63NativePrimitive *pPrim,64CompositeInfo *pCompInfo,65jint pixel, jint transX, jint transY,66jint *xPointsPtr, jint *yPointsPtr,67jint *nPointsPtr, jint numPolys,68jboolean close)69{70int i;71for (i = 0; i < numPolys; i++) {72jint numPts = nPointsPtr[i];73if (numPts > 1) {74jint x0, y0, x1, y1;75jboolean empty = JNI_TRUE;76x0 = x1 = transX + *xPointsPtr++;77y0 = y1 = transY + *yPointsPtr++;78while (--numPts > 0) {79jint x2 = transX + *xPointsPtr++;80jint y2 = transY + *yPointsPtr++;81empty = (empty && x1 == x2 && y1 == y2);82LineUtils_ProcessLine(pRasInfo, pixel, pLine,83pPrim, pCompInfo,84x1, y1, x2, y2,85(numPts > 1 || close));86x1 = x2;87y1 = y2;88}89if (close && (empty || x1 != x0 || y1 != y0)) {90LineUtils_ProcessLine(pRasInfo, pixel, pLine,91pPrim, pCompInfo,92x1, y1, x0, y0, !empty);93}94} else if (numPts == 1) {95xPointsPtr++;96yPointsPtr++;97}98}99}100101/*102* Class: sun_java2d_loops_DrawPolygons103* Method: DrawPolygons104* Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;[I[I[IIIIZ)V105*/106JNIEXPORT void JNICALL107Java_sun_java2d_loops_DrawPolygons_DrawPolygons108(JNIEnv *env, jobject self,109jobject sg2d, jobject sData,110jintArray xPointsArray, jintArray yPointsArray,111jintArray nPointsArray, jint numPolys,112jint transX, jint transY, jboolean close)113{114SurfaceDataOps *sdOps;115SurfaceDataRasInfo rasInfo;116NativePrimitive *pPrim;117CompositeInfo compInfo;118jsize nPointsLen, xPointsLen, yPointsLen;119jint *nPointsPtr = NULL;120jint *xPointsPtr = NULL;121jint *yPointsPtr = NULL;122jint pointsNeeded;123jint i, ret;124jboolean ok = JNI_TRUE;125jint pixel = GrPrim_Sg2dGetPixel(env, sg2d);126127if (JNU_IsNull(env, xPointsArray) || JNU_IsNull(env, yPointsArray)) {128JNU_ThrowNullPointerException(env, "coordinate array");129return;130}131if (JNU_IsNull(env, nPointsArray)) {132JNU_ThrowNullPointerException(env, "polygon length array");133return;134}135136nPointsLen = (*env)->GetArrayLength(env, nPointsArray);137xPointsLen = (*env)->GetArrayLength(env, xPointsArray);138yPointsLen = (*env)->GetArrayLength(env, yPointsArray);139if (nPointsLen < numPolys) {140JNU_ThrowArrayIndexOutOfBoundsException(env,141"polygon length array size");142return;143}144145pPrim = GetNativePrim(env, self);146if (pPrim == NULL) {147return;148}149if (pPrim->pCompType->getCompInfo != NULL) {150GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);151}152153sdOps = SurfaceData_GetOps(env, sData);154if (sdOps == 0) {155return;156}157158GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);159160ret = sdOps->Lock(env, sdOps, &rasInfo, SD_LOCK_FASTEST | pPrim->dstflags);161if (ret == SD_FAILURE) {162return;163}164165nPointsPtr = (*env)->GetPrimitiveArrayCritical(env, nPointsArray, NULL);166if (!nPointsPtr) {167ok = JNI_FALSE;168}169170if (ok) {171pointsNeeded = 0;172for (i = 0; i < numPolys; i++) {173if (nPointsPtr[i] > 0) {174pointsNeeded += nPointsPtr[i];175}176}177178if (yPointsLen < pointsNeeded || xPointsLen < pointsNeeded) {179(*env)->ReleasePrimitiveArrayCritical(env, nPointsArray,180nPointsPtr, JNI_ABORT);181SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);182JNU_ThrowArrayIndexOutOfBoundsException(env,183"coordinate array length");184return;185}186187xPointsPtr = (*env)->GetPrimitiveArrayCritical(env, xPointsArray, NULL);188if (!xPointsPtr) {189ok = JNI_FALSE;190}191if (ok) {192yPointsPtr = (*env)->GetPrimitiveArrayCritical(env, yPointsArray, NULL);193if (!yPointsPtr) {194ok = JNI_FALSE;195}196}197}198199if (ok) {200if (ret == SD_SLOWLOCK) {201RefineBounds(&rasInfo.bounds, transX, transY,202xPointsPtr, yPointsPtr, pointsNeeded);203ok = (rasInfo.bounds.x2 > rasInfo.bounds.x1 &&204rasInfo.bounds.y2 > rasInfo.bounds.y1);205}206}207208if (ok) {209sdOps->GetRasInfo(env, sdOps, &rasInfo);210if (rasInfo.rasBase &&211rasInfo.bounds.x2 > rasInfo.bounds.x1 &&212rasInfo.bounds.y2 > rasInfo.bounds.y1)213{214ProcessPoly(&rasInfo, pPrim->funcs.drawline, pPrim, &compInfo,215pixel, transX, transY,216xPointsPtr, yPointsPtr,217nPointsPtr, numPolys,218close);219}220SurfaceData_InvokeRelease(env, sdOps, &rasInfo);221}222223if (nPointsPtr) {224(*env)->ReleasePrimitiveArrayCritical(env, nPointsArray,225nPointsPtr, JNI_ABORT);226}227if (xPointsPtr) {228(*env)->ReleasePrimitiveArrayCritical(env, xPointsArray,229xPointsPtr, JNI_ABORT);230}231if (yPointsPtr) {232(*env)->ReleasePrimitiveArrayCritical(env, yPointsArray,233yPointsPtr, JNI_ABORT);234}235SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);236}237238239