1/*
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <math.h>
27#include <float.h>
28#include "jni_util.h"
29
30#include "GraphicsPrimitiveMgr.h"
31#include "LineUtils.h"
32#include "ProcessPath.h"
33#include "DrawPath.h"
34
35#include "sun_java2d_loops_FillPath.h"
36
37static void drawScanline(DrawHandler* hnd, jint x0, jint x1, jint y0) {
38 DHND(hnd)->pPrim->funcs.drawline(
39 DHND(hnd)->pRasInfo, x0, y0, DHND(hnd)->pixel, x1 - x0 + 1, 0,
40 BUMP_POS_PIXEL, 0, BUMP_NOOP, 0,
41 DHND(hnd)->pPrim, DHND(hnd)->pCompInfo);
42}
43
44/*
45 * Class: sun_java2d_loops_FillPath
46 * Method: FillPath
47 * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;IILjava/awt/geom/Path2D.Float;)V
48 */
49JNIEXPORT void JNICALL Java_sun_java2d_loops_FillPath_FillPath
50 (JNIEnv *env, jobject self,
51 jobject sg2d, jobject sData,
52 jint transX, jint transY, jobject p2df)
53{
54 jarray typesArray;
55 jarray coordsArray;
56 jint numTypes;
57 jint fillRule;
58 jboolean ok = JNI_TRUE;
59 jint pixel = GrPrim_Sg2dGetPixel(env, sg2d);
60 jint maxCoords;
61 jfloat *coords;
62 SurfaceDataOps *sdOps;
63 SurfaceDataRasInfo rasInfo;
64 CompositeInfo compInfo;
65 jint ret;
66 NativePrimitive *pPrim = GetNativePrim(env, self);
67 jint stroke;
68 jboolean throwExc = JNI_FALSE;
69
70 if (pPrim == NULL) {
71 return;
72 }
73 if (pPrim->pCompType->getCompInfo != NULL) {
74 GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);
75 }
76
77 stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
78
79 sdOps = SurfaceData_GetOps(env, sData);
80 if (sdOps == 0) {
81 return;
82 }
83
84 typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
85 coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
86 path2DFloatCoordsID);
87 if (coordsArray == NULL) {
88 JNU_ThrowNullPointerException(env, "coordinates array");
89 return;
90 }
91 numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
92 fillRule = (*env)->GetIntField(env, p2df, path2DWindingRuleID);
93 if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
94 JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
95 return;
96 }
97
98 GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
99
100 ret = sdOps->Lock(env, sdOps, &rasInfo, SD_LOCK_FASTEST | pPrim->dstflags);
101 if (ret == SD_FAILURE) {
102 return;
103 }
104
105 maxCoords = (*env)->GetArrayLength(env, coordsArray);
106 coords = (jfloat*)(*env)->GetPrimitiveArrayCritical(
107 env, coordsArray, NULL);
108 if (coords == NULL) {
109 SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
110 return;
111 }
112
113 if (ret == SD_SLOWLOCK) {
114 GrPrim_RefineBounds(&rasInfo.bounds, transX, transY,
115 coords, maxCoords);
116 ok = (rasInfo.bounds.x2 > rasInfo.bounds.x1 &&
117 rasInfo.bounds.y2 > rasInfo.bounds.y1);
118 }
119
120 if (ok) {
121 sdOps->GetRasInfo(env, sdOps, &rasInfo);
122 if (rasInfo.rasBase) {
123 if (rasInfo.bounds.x2 > rasInfo.bounds.x1 &&
124 rasInfo.bounds.y2 > rasInfo.bounds.y1)
125 {
126 DrawHandlerData dHData;
127 DrawHandler drawHandler = {
128 NULL,
129 NULL,
130 &drawScanline,
131 0, 0, 0, 0,
132 0, 0, 0, 0,
133 NULL
134 };
135
136 jbyte *types = (jbyte*)(*env)->GetPrimitiveArrayCritical(
137 env, typesArray, NULL);
138
139 /* Initialization of the following fields in the declaration of
140 * the dHData and drawHandler above causes warnings on sun
141 * studio compiler with
142 * -xc99=%none option applied (this option means compliance
143 * with C90 standard instead of C99)
144 */
145 dHData.pRasInfo = &rasInfo;
146 dHData.pixel = pixel;
147 dHData.pPrim = pPrim;
148 dHData.pCompInfo = &compInfo;
149
150 drawHandler.xMin = rasInfo.bounds.x1;
151 drawHandler.yMin = rasInfo.bounds.y1;
152 drawHandler.xMax = rasInfo.bounds.x2;
153 drawHandler.yMax = rasInfo.bounds.y2;
154 drawHandler.pData = &dHData;
155
156 if (types != NULL) {
157 if (!doFillPath(&drawHandler,
158 transX, transY, coords,
159 maxCoords, types, numTypes,
160 (stroke == sunHints_INTVAL_STROKE_PURE)?
161 PH_STROKE_PURE : PH_STROKE_DEFAULT,
162 fillRule))
163 {
164 throwExc = JNI_TRUE;
165 }
166
167 (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
168 JNI_ABORT);
169 }
170 }
171 }
172 SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
173 }
174 (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
175 JNI_ABORT);
176
177 if (throwExc) {
178 JNU_ThrowArrayIndexOutOfBoundsException(env,
179 "coords array");
180 }
181
182 SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
183}
184