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_DrawPath.h"
36
37static void processLine(DrawHandler* hnd,
38 jint x0, jint y0, jint x1, jint y1)
39{
40 LineUtils_ProcessLine(DHND(hnd)->pRasInfo,
41 DHND(hnd)->pixel,
42 DHND(hnd)->pPrim->funcs.drawline,
43 DHND(hnd)->pPrim,
44 DHND(hnd)->pCompInfo,
45 x0, y0, x1, y1, 0);
46}
47
48static void processPoint(DrawHandler* hnd, jint x0, jint y0)
49{
50 DHND(hnd)->pPrim->funcs.drawline(
51 DHND(hnd)->pRasInfo, x0, y0, DHND(hnd)->pixel, 1, 0,
52 BUMP_POS_PIXEL, 0, BUMP_NOOP, 0,
53 DHND(hnd)->pPrim, DHND(hnd)->pCompInfo);
54}
55
56 /*
57 * Class: sun_java2d_loops_DrawPath
58 * Method: DrawPath
59 * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;IILjava/awt/geom/Path2D.Float;)V
60 */
61JNIEXPORT void JNICALL Java_sun_java2d_loops_DrawPath_DrawPath
62 (JNIEnv *env, jobject self,
63 jobject sg2d, jobject sData,
64 jint transX, jint transY, jobject p2df)
65{
66 jarray typesArray;
67 jarray coordsArray;
68 jint numTypes;
69 jboolean ok = JNI_TRUE;
70 jint pixel = GrPrim_Sg2dGetPixel(env, sg2d);
71 jint maxCoords;
72 jfloat *coords;
73 SurfaceDataOps *sdOps;
74 SurfaceDataRasInfo rasInfo;
75 CompositeInfo compInfo;
76 jint ret;
77 NativePrimitive *pPrim = GetNativePrim(env, self);
78 jint stroke;
79 jboolean throwExc = JNI_FALSE;
80
81 if (pPrim == NULL) {
82 return;
83 }
84 if (pPrim->pCompType->getCompInfo != NULL) {
85 GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);
86 }
87
88 stroke = (*env)->GetIntField(env, sg2d, sg2dStrokeHintID);
89
90 sdOps = SurfaceData_GetOps(env, sData);
91 if (sdOps == 0) {
92 return;
93 }
94
95 typesArray = (jarray)(*env)->GetObjectField(env, p2df, path2DTypesID);
96 coordsArray = (jarray)(*env)->GetObjectField(env, p2df,
97 path2DFloatCoordsID);
98 if (coordsArray == NULL) {
99 JNU_ThrowNullPointerException(env, "coordinates array");
100 return;
101 }
102 numTypes = (*env)->GetIntField(env, p2df, path2DNumTypesID);
103 if ((*env)->GetArrayLength(env, typesArray) < numTypes) {
104 JNU_ThrowArrayIndexOutOfBoundsException(env, "types array");
105 return;
106 }
107
108 GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
109
110 ret = sdOps->Lock(env, sdOps, &rasInfo, SD_LOCK_FASTEST | pPrim->dstflags);
111 if (ret == SD_FAILURE) {
112 return;
113 }
114
115 maxCoords = (*env)->GetArrayLength(env, coordsArray);
116 coords = (jfloat*)(*env)->GetPrimitiveArrayCritical(
117 env, coordsArray, NULL);
118 if (coords == NULL) {
119 SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
120 return;
121 }
122
123 if (ret == SD_SLOWLOCK) {
124 GrPrim_RefineBounds(&rasInfo.bounds, transX, transY,
125 coords, maxCoords);
126 ok = (rasInfo.bounds.x2 > rasInfo.bounds.x1 &&
127 rasInfo.bounds.y2 > rasInfo.bounds.y1);
128 }
129
130 if (ok) {
131 sdOps->GetRasInfo(env, sdOps, &rasInfo);
132 if (rasInfo.rasBase) {
133 if (rasInfo.bounds.x2 > rasInfo.bounds.x1 &&
134 rasInfo.bounds.y2 > rasInfo.bounds.y1)
135 {
136 DrawHandlerData dHData;
137 DrawHandler drawHandler =
138 {
139 &processLine,
140 &processPoint,
141 NULL,
142 0, 0, 0, 0,
143 0, 0, 0, 0,
144 NULL
145 };
146
147 jbyte *types = (jbyte*)(*env)->GetPrimitiveArrayCritical(
148 env, typesArray, NULL);
149
150 /* Initialization of the following fields in the declaration of
151 * the dHData and drawHandler above causes warnings on sun
152 * studio compiler with
153 * -xc99=%none option applied (this option means compliance
154 * with C90 standard instead of C99)
155 */
156 dHData.pRasInfo = &rasInfo;
157 dHData.pixel = pixel;
158 dHData.pPrim = pPrim;
159 dHData.pCompInfo = &compInfo;
160
161 drawHandler.xMin = rasInfo.bounds.x1;
162 drawHandler.yMin = rasInfo.bounds.y1;
163 drawHandler.xMax = rasInfo.bounds.x2;
164 drawHandler.yMax = rasInfo.bounds.y2;
165 drawHandler.pData = &dHData;
166
167 if (types != NULL) {
168 if (!doDrawPath(&drawHandler, NULL, transX, transY,
169 coords, maxCoords, types, numTypes,
170 (stroke == sunHints_INTVAL_STROKE_PURE)?
171 PH_STROKE_PURE : PH_STROKE_DEFAULT))
172 {
173 throwExc = JNI_TRUE;
174 }
175
176 (*env)->ReleasePrimitiveArrayCritical(env, typesArray, types,
177 JNI_ABORT);
178 }
179 }
180 }
181 SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
182 }
183 (*env)->ReleasePrimitiveArrayCritical(env, coordsArray, coords,
184 JNI_ABORT);
185
186 if (throwExc) {
187 JNU_ThrowArrayIndexOutOfBoundsException(env,
188 "coords array");
189 }
190
191 SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
192}
193