1 /*
2 * Copyright (c) 2006, 2014, 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
207 this(s, null);
208 }
209
210 /**
211 * Constructs a new single precision {@code Path2D} object
212 * from an arbitrary {@link Shape} object, transformed by an
213 * {@link AffineTransform} object.
214 * All of the initial geometry and the winding rule for this path are
215 * taken from the specified {@code Shape} object and transformed
216 * by the specified {@code AffineTransform} object.
217 *
218 * @param s the specified {@code Shape} object
219 * @param at the specified {@code AffineTransform} object
220 * @since 1.6
221 */
222 public Float(Shape s, AffineTransform at) {
223 if (s instanceof Path2D) {
224 Path2D p2d = (Path2D) s;
225 setWindingRule(p2d.windingRule);
226 this.numTypes = p2d.numTypes;
227 this.pointTypes = Arrays.copyOf(p2d.pointTypes,
228 p2d.pointTypes.length);
229 this.numCoords = p2d.numCoords;
230 this.floatCoords = p2d.cloneCoordsFloat(at);
231 } else {
232 PathIterator pi = s.getPathIterator(at);
233 setWindingRule(pi.getWindingRule());
234 this.pointTypes = new byte[INIT_SIZE];
235 this.floatCoords = new float[INIT_SIZE * 2];
236 append(pi, false);
237 }
238 }
239
240 float[] cloneCoordsFloat(AffineTransform at) {
241 float ret[];
242 if (at == null) {
243 ret = Arrays.copyOf(this.floatCoords, this.floatCoords.length);
244 } else {
245 ret = new float[floatCoords.length];
246 at.transform(floatCoords, 0, ret, 0, numCoords / 2);
247 }
248 return ret;
249 }
250
251 double[] cloneCoordsDouble(AffineTransform at) {
252 double ret[] = new double[floatCoords.length];
253 if (at == null) {
254 for (int i = 0; i < numCoords; i++) {
255 ret[i] = floatCoords[i];
256 }
257 } else {
258 at.transform(floatCoords, 0, ret, 0, numCoords / 2);
259 }
260 return ret;
261 }
262
263 void append(float x, float y) {
264 floatCoords[numCoords++] = x;
265 floatCoords[numCoords++] = y;
266 }
267
268 void append(double x, double y) {
269 floatCoords[numCoords++] = (float) x;
270 floatCoords[numCoords++] = (float) y;
271 }
272
458 * @param x3 the X coordinate of the final end point
459 * @param y3 the Y coordinate of the final end point
460 * @see Path2D#curveTo
461 * @since 1.6
462 */
463 public final synchronized void curveTo(float x1, float y1,
464 float x2, float y2,
465 float x3, float y3)
466 {
467 needRoom(true, 6);
468 pointTypes[numTypes++] = SEG_CUBICTO;
469 floatCoords[numCoords++] = x1;
470 floatCoords[numCoords++] = y1;
471 floatCoords[numCoords++] = x2;
472 floatCoords[numCoords++] = y2;
473 floatCoords[numCoords++] = x3;
474 floatCoords[numCoords++] = y3;
475 }
476
477 int pointCrossings(double px, double py) {
478 double movx, movy, curx, cury, endx, endy;
479 float coords[] = floatCoords;
480 curx = movx = coords[0];
481 cury = movy = coords[1];
482 int crossings = 0;
483 int ci = 2;
484 for (int i = 1; i < numTypes; i++) {
485 switch (pointTypes[i]) {
486 case PathIterator.SEG_MOVETO:
487 if (cury != movy) {
488 crossings +=
489 Curve.pointCrossingsForLine(px, py,
490 curx, cury,
491 movx, movy);
492 }
493 movx = curx = coords[ci++];
494 movy = cury = coords[ci++];
495 break;
496 case PathIterator.SEG_LINETO:
497 crossings +=
535 curx, cury,
536 movx, movy);
537 }
538 curx = movx;
539 cury = movy;
540 break;
541 }
542 }
543 if (cury != movy) {
544 crossings +=
545 Curve.pointCrossingsForLine(px, py,
546 curx, cury,
547 movx, movy);
548 }
549 return crossings;
550 }
551
552 int rectCrossings(double rxmin, double rymin,
553 double rxmax, double rymax)
554 {
555 float coords[] = floatCoords;
556 double curx, cury, movx, movy, endx, endy;
557 curx = movx = coords[0];
558 cury = movy = coords[1];
559 int crossings = 0;
560 int ci = 2;
561 for (int i = 1;
562 crossings != Curve.RECT_INTERSECTS && i < numTypes;
563 i++)
564 {
565 switch (pointTypes[i]) {
566 case PathIterator.SEG_MOVETO:
567 if (curx != movx || cury != movy) {
568 crossings =
569 Curve.rectCrossingsForLine(crossings,
570 rxmin, rymin,
571 rxmax, rymax,
572 curx, cury,
573 movx, movy);
574 }
1044 this(s, null);
1045 }
1046
1047 /**
1048 * Constructs a new double precision {@code Path2D} object
1049 * from an arbitrary {@link Shape} object, transformed by an
1050 * {@link AffineTransform} object.
1051 * All of the initial geometry and the winding rule for this path are
1052 * taken from the specified {@code Shape} object and transformed
1053 * by the specified {@code AffineTransform} object.
1054 *
1055 * @param s the specified {@code Shape} object
1056 * @param at the specified {@code AffineTransform} object
1057 * @since 1.6
1058 */
1059 public Double(Shape s, AffineTransform at) {
1060 if (s instanceof Path2D) {
1061 Path2D p2d = (Path2D) s;
1062 setWindingRule(p2d.windingRule);
1063 this.numTypes = p2d.numTypes;
1064 this.pointTypes = Arrays.copyOf(p2d.pointTypes,
1065 p2d.pointTypes.length);
1066 this.numCoords = p2d.numCoords;
1067 this.doubleCoords = p2d.cloneCoordsDouble(at);
1068 } else {
1069 PathIterator pi = s.getPathIterator(at);
1070 setWindingRule(pi.getWindingRule());
1071 this.pointTypes = new byte[INIT_SIZE];
1072 this.doubleCoords = new double[INIT_SIZE * 2];
1073 append(pi, false);
1074 }
1075 }
1076
1077 float[] cloneCoordsFloat(AffineTransform at) {
1078 float ret[] = new float[doubleCoords.length];
1079 if (at == null) {
1080 for (int i = 0; i < numCoords; i++) {
1081 ret[i] = (float) doubleCoords[i];
1082 }
1083 } else {
1084 at.transform(doubleCoords, 0, ret, 0, numCoords / 2);
1085 }
1086 return ret;
1087 }
1088
1089 double[] cloneCoordsDouble(AffineTransform at) {
1090 double ret[];
1091 if (at == null) {
1092 ret = Arrays.copyOf(this.doubleCoords,
1093 this.doubleCoords.length);
1094 } else {
1095 ret = new double[doubleCoords.length];
1096 at.transform(doubleCoords, 0, ret, 0, numCoords / 2);
1097 }
1098 return ret;
1099 }
1100
1101 void append(float x, float y) {
1102 doubleCoords[numCoords++] = x;
1103 doubleCoords[numCoords++] = y;
1104 }
1105
1106 void append(double x, double y) {
1107 doubleCoords[numCoords++] = x;
1108 doubleCoords[numCoords++] = y;
1109 }
1110
1111 Point2D getPoint(int coordindex) {
1112 return new Point2D.Double(doubleCoords[coordindex],
1113 doubleCoords[coordindex+1]);
1114 }
1115
1185
1186 /**
1187 * {@inheritDoc}
1188 * @since 1.6
1189 */
1190 public final synchronized void curveTo(double x1, double y1,
1191 double x2, double y2,
1192 double x3, double y3)
1193 {
1194 needRoom(true, 6);
1195 pointTypes[numTypes++] = SEG_CUBICTO;
1196 doubleCoords[numCoords++] = x1;
1197 doubleCoords[numCoords++] = y1;
1198 doubleCoords[numCoords++] = x2;
1199 doubleCoords[numCoords++] = y2;
1200 doubleCoords[numCoords++] = x3;
1201 doubleCoords[numCoords++] = y3;
1202 }
1203
1204 int pointCrossings(double px, double py) {
1205 double movx, movy, curx, cury, endx, endy;
1206 double coords[] = doubleCoords;
1207 curx = movx = coords[0];
1208 cury = movy = coords[1];
1209 int crossings = 0;
1210 int ci = 2;
1211 for (int i = 1; i < numTypes; i++) {
1212 switch (pointTypes[i]) {
1213 case PathIterator.SEG_MOVETO:
1214 if (cury != movy) {
1215 crossings +=
1216 Curve.pointCrossingsForLine(px, py,
1217 curx, cury,
1218 movx, movy);
1219 }
1220 movx = curx = coords[ci++];
1221 movy = cury = coords[ci++];
1222 break;
1223 case PathIterator.SEG_LINETO:
1224 crossings +=
1262 curx, cury,
1263 movx, movy);
1264 }
1265 curx = movx;
1266 cury = movy;
1267 break;
1268 }
1269 }
1270 if (cury != movy) {
1271 crossings +=
1272 Curve.pointCrossingsForLine(px, py,
1273 curx, cury,
1274 movx, movy);
1275 }
1276 return crossings;
1277 }
1278
1279 int rectCrossings(double rxmin, double rymin,
1280 double rxmax, double rymax)
1281 {
1282 double coords[] = doubleCoords;
1283 double curx, cury, movx, movy, endx, endy;
1284 curx = movx = coords[0];
1285 cury = movy = coords[1];
1286 int crossings = 0;
1287 int ci = 2;
1288 for (int i = 1;
1289 crossings != Curve.RECT_INTERSECTS && i < numTypes;
1290 i++)
1291 {
1292 switch (pointTypes[i]) {
1293 case PathIterator.SEG_MOVETO:
1294 if (curx != movx || cury != movy) {
1295 crossings =
1296 Curve.rectCrossingsForLine(crossings,
1297 rxmin, rymin,
1298 rxmax, rymax,
1299 curx, cury,
1300 movx, movy);
1301 }
|
1 /*
2 * Copyright (c) 2006, 2015, 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
207 this(s, null);
208 }
209
210 /**
211 * Constructs a new single precision {@code Path2D} object
212 * from an arbitrary {@link Shape} object, transformed by an
213 * {@link AffineTransform} object.
214 * All of the initial geometry and the winding rule for this path are
215 * taken from the specified {@code Shape} object and transformed
216 * by the specified {@code AffineTransform} object.
217 *
218 * @param s the specified {@code Shape} object
219 * @param at the specified {@code AffineTransform} object
220 * @since 1.6
221 */
222 public Float(Shape s, AffineTransform at) {
223 if (s instanceof Path2D) {
224 Path2D p2d = (Path2D) s;
225 setWindingRule(p2d.windingRule);
226 this.numTypes = p2d.numTypes;
227 // trim arrays:
228 this.pointTypes = Arrays.copyOf(p2d.pointTypes, p2d.numTypes);
229 this.numCoords = p2d.numCoords;
230 this.floatCoords = p2d.cloneCoordsFloat(at);
231 } else {
232 PathIterator pi = s.getPathIterator(at);
233 setWindingRule(pi.getWindingRule());
234 this.pointTypes = new byte[INIT_SIZE];
235 this.floatCoords = new float[INIT_SIZE * 2];
236 append(pi, false);
237 }
238 }
239
240 @Override
241 float[] cloneCoordsFloat(AffineTransform at) {
242 // trim arrays:
243 float ret[];
244 if (at == null) {
245 ret = Arrays.copyOf(floatCoords, numCoords);
246 } else {
247 ret = new float[numCoords];
248 at.transform(floatCoords, 0, ret, 0, numCoords / 2);
249 }
250 return ret;
251 }
252
253 @Override
254 double[] cloneCoordsDouble(AffineTransform at) {
255 // trim arrays:
256 double ret[] = new double[numCoords];
257 if (at == null) {
258 for (int i = 0; i < numCoords; i++) {
259 ret[i] = floatCoords[i];
260 }
261 } else {
262 at.transform(floatCoords, 0, ret, 0, numCoords / 2);
263 }
264 return ret;
265 }
266
267 void append(float x, float y) {
268 floatCoords[numCoords++] = x;
269 floatCoords[numCoords++] = y;
270 }
271
272 void append(double x, double y) {
273 floatCoords[numCoords++] = (float) x;
274 floatCoords[numCoords++] = (float) y;
275 }
276
462 * @param x3 the X coordinate of the final end point
463 * @param y3 the Y coordinate of the final end point
464 * @see Path2D#curveTo
465 * @since 1.6
466 */
467 public final synchronized void curveTo(float x1, float y1,
468 float x2, float y2,
469 float x3, float y3)
470 {
471 needRoom(true, 6);
472 pointTypes[numTypes++] = SEG_CUBICTO;
473 floatCoords[numCoords++] = x1;
474 floatCoords[numCoords++] = y1;
475 floatCoords[numCoords++] = x2;
476 floatCoords[numCoords++] = y2;
477 floatCoords[numCoords++] = x3;
478 floatCoords[numCoords++] = y3;
479 }
480
481 int pointCrossings(double px, double py) {
482 if (numTypes == 0) {
483 return 0;
484 }
485 double movx, movy, curx, cury, endx, endy;
486 float coords[] = floatCoords;
487 curx = movx = coords[0];
488 cury = movy = coords[1];
489 int crossings = 0;
490 int ci = 2;
491 for (int i = 1; i < numTypes; i++) {
492 switch (pointTypes[i]) {
493 case PathIterator.SEG_MOVETO:
494 if (cury != movy) {
495 crossings +=
496 Curve.pointCrossingsForLine(px, py,
497 curx, cury,
498 movx, movy);
499 }
500 movx = curx = coords[ci++];
501 movy = cury = coords[ci++];
502 break;
503 case PathIterator.SEG_LINETO:
504 crossings +=
542 curx, cury,
543 movx, movy);
544 }
545 curx = movx;
546 cury = movy;
547 break;
548 }
549 }
550 if (cury != movy) {
551 crossings +=
552 Curve.pointCrossingsForLine(px, py,
553 curx, cury,
554 movx, movy);
555 }
556 return crossings;
557 }
558
559 int rectCrossings(double rxmin, double rymin,
560 double rxmax, double rymax)
561 {
562 if (numTypes == 0) {
563 return 0;
564 }
565 float coords[] = floatCoords;
566 double curx, cury, movx, movy, endx, endy;
567 curx = movx = coords[0];
568 cury = movy = coords[1];
569 int crossings = 0;
570 int ci = 2;
571 for (int i = 1;
572 crossings != Curve.RECT_INTERSECTS && i < numTypes;
573 i++)
574 {
575 switch (pointTypes[i]) {
576 case PathIterator.SEG_MOVETO:
577 if (curx != movx || cury != movy) {
578 crossings =
579 Curve.rectCrossingsForLine(crossings,
580 rxmin, rymin,
581 rxmax, rymax,
582 curx, cury,
583 movx, movy);
584 }
1054 this(s, null);
1055 }
1056
1057 /**
1058 * Constructs a new double precision {@code Path2D} object
1059 * from an arbitrary {@link Shape} object, transformed by an
1060 * {@link AffineTransform} object.
1061 * All of the initial geometry and the winding rule for this path are
1062 * taken from the specified {@code Shape} object and transformed
1063 * by the specified {@code AffineTransform} object.
1064 *
1065 * @param s the specified {@code Shape} object
1066 * @param at the specified {@code AffineTransform} object
1067 * @since 1.6
1068 */
1069 public Double(Shape s, AffineTransform at) {
1070 if (s instanceof Path2D) {
1071 Path2D p2d = (Path2D) s;
1072 setWindingRule(p2d.windingRule);
1073 this.numTypes = p2d.numTypes;
1074 // trim arrays:
1075 this.pointTypes = Arrays.copyOf(p2d.pointTypes, p2d.numTypes);
1076 this.numCoords = p2d.numCoords;
1077 this.doubleCoords = p2d.cloneCoordsDouble(at);
1078 } else {
1079 PathIterator pi = s.getPathIterator(at);
1080 setWindingRule(pi.getWindingRule());
1081 this.pointTypes = new byte[INIT_SIZE];
1082 this.doubleCoords = new double[INIT_SIZE * 2];
1083 append(pi, false);
1084 }
1085 }
1086
1087 @Override
1088 float[] cloneCoordsFloat(AffineTransform at) {
1089 // trim arrays:
1090 float ret[] = new float[numCoords];
1091 if (at == null) {
1092 for (int i = 0; i < numCoords; i++) {
1093 ret[i] = (float) doubleCoords[i];
1094 }
1095 } else {
1096 at.transform(doubleCoords, 0, ret, 0, numCoords / 2);
1097 }
1098 return ret;
1099 }
1100
1101 @Override
1102 double[] cloneCoordsDouble(AffineTransform at) {
1103 // trim arrays:
1104 double ret[];
1105 if (at == null) {
1106 ret = Arrays.copyOf(doubleCoords, numCoords);
1107 } else {
1108 ret = new double[numCoords];
1109 at.transform(doubleCoords, 0, ret, 0, numCoords / 2);
1110 }
1111 return ret;
1112 }
1113
1114 void append(float x, float y) {
1115 doubleCoords[numCoords++] = x;
1116 doubleCoords[numCoords++] = y;
1117 }
1118
1119 void append(double x, double y) {
1120 doubleCoords[numCoords++] = x;
1121 doubleCoords[numCoords++] = y;
1122 }
1123
1124 Point2D getPoint(int coordindex) {
1125 return new Point2D.Double(doubleCoords[coordindex],
1126 doubleCoords[coordindex+1]);
1127 }
1128
1198
1199 /**
1200 * {@inheritDoc}
1201 * @since 1.6
1202 */
1203 public final synchronized void curveTo(double x1, double y1,
1204 double x2, double y2,
1205 double x3, double y3)
1206 {
1207 needRoom(true, 6);
1208 pointTypes[numTypes++] = SEG_CUBICTO;
1209 doubleCoords[numCoords++] = x1;
1210 doubleCoords[numCoords++] = y1;
1211 doubleCoords[numCoords++] = x2;
1212 doubleCoords[numCoords++] = y2;
1213 doubleCoords[numCoords++] = x3;
1214 doubleCoords[numCoords++] = y3;
1215 }
1216
1217 int pointCrossings(double px, double py) {
1218 if (numTypes == 0) {
1219 return 0;
1220 }
1221 double movx, movy, curx, cury, endx, endy;
1222 double coords[] = doubleCoords;
1223 curx = movx = coords[0];
1224 cury = movy = coords[1];
1225 int crossings = 0;
1226 int ci = 2;
1227 for (int i = 1; i < numTypes; i++) {
1228 switch (pointTypes[i]) {
1229 case PathIterator.SEG_MOVETO:
1230 if (cury != movy) {
1231 crossings +=
1232 Curve.pointCrossingsForLine(px, py,
1233 curx, cury,
1234 movx, movy);
1235 }
1236 movx = curx = coords[ci++];
1237 movy = cury = coords[ci++];
1238 break;
1239 case PathIterator.SEG_LINETO:
1240 crossings +=
1278 curx, cury,
1279 movx, movy);
1280 }
1281 curx = movx;
1282 cury = movy;
1283 break;
1284 }
1285 }
1286 if (cury != movy) {
1287 crossings +=
1288 Curve.pointCrossingsForLine(px, py,
1289 curx, cury,
1290 movx, movy);
1291 }
1292 return crossings;
1293 }
1294
1295 int rectCrossings(double rxmin, double rymin,
1296 double rxmax, double rymax)
1297 {
1298 if (numTypes == 0) {
1299 return 0;
1300 }
1301 double coords[] = doubleCoords;
1302 double curx, cury, movx, movy, endx, endy;
1303 curx = movx = coords[0];
1304 cury = movy = coords[1];
1305 int crossings = 0;
1306 int ci = 2;
1307 for (int i = 1;
1308 crossings != Curve.RECT_INTERSECTS && i < numTypes;
1309 i++)
1310 {
1311 switch (pointTypes[i]) {
1312 case PathIterator.SEG_MOVETO:
1313 if (curx != movx || cury != movy) {
1314 crossings =
1315 Curve.rectCrossingsForLine(crossings,
1316 rxmin, rymin,
1317 rxmax, rymax,
1318 curx, cury,
1319 movx, movy);
1320 }
|