src/share/classes/java/awt/geom/Path2D.java

Print this page


   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                     }