1 /*
   2  * Copyright (c) 1996, 2017, 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 package java.awt;
  27 
  28 import java.awt.geom.AffineTransform;
  29 import java.awt.geom.PathIterator;
  30 import java.awt.geom.Point2D;
  31 import java.awt.geom.Rectangle2D;
  32 
  33 /**
  34  * The {@code Shape} interface provides definitions for objects
  35  * that represent some form of geometric shape.  The {@code Shape}
  36  * is described by a {@link PathIterator} object, which can express the
  37  * outline of the {@code Shape} as well as a rule for determining
  38  * how the outline divides the 2D plane into interior and exterior
  39  * points.  Each {@code Shape} object provides callbacks to get the
  40  * bounding box of the geometry, determine whether points or
  41  * rectangles lie partly or entirely within the interior
  42  * of the {@code Shape}, and retrieve a {@code PathIterator}
  43  * object that describes the trajectory path of the {@code Shape}
  44  * outline.
  45  * <p>
  46  * <a id="def_insideness"><b>Definition of insideness:</b></a>
  47  * A point is considered to lie inside a
  48  * {@code Shape} if and only if:
  49  * <ul>
  50  * <li> it lies completely
  51  * inside the {@code Shape} boundary <i>or</i>
  52  * <li>
  53  * it lies exactly on the {@code Shape} boundary <i>and</i> the
  54  * space immediately adjacent to the
  55  * point in the increasing {@code X} direction is
  56  * entirely inside the boundary <i>or</i>
  57  * <li>
  58  * it lies exactly on a horizontal boundary segment <b>and</b> the
  59  * space immediately adjacent to the point in the
  60  * increasing {@code Y} direction is inside the boundary.
  61  * </ul>
  62  * <p>The {@code contains} and {@code intersects} methods
  63  * consider the interior of a {@code Shape} to be the area it
  64  * encloses as if it were filled.  This means that these methods
  65  * consider
  66  * unclosed shapes to be implicitly closed for the purpose of
  67  * determining if a shape contains or intersects a rectangle or if a
  68  * shape contains a point.
  69  *
  70  * @see java.awt.geom.PathIterator
  71  * @see java.awt.geom.AffineTransform
  72  * @see java.awt.geom.FlatteningPathIterator
  73  * @see java.awt.geom.GeneralPath
  74  *
  75  * @author Jim Graham
  76  * @since 1.2
  77  */
  78 public interface Shape {
  79     /**
  80      * Returns an integer {@link Rectangle} that completely encloses the
  81      * {@code Shape}.  Note that there is no guarantee that the
  82      * returned {@code Rectangle} is the smallest bounding box that
  83      * encloses the {@code Shape}, only that the {@code Shape}
  84      * lies entirely within the indicated  {@code Rectangle}.  The
  85      * returned {@code Rectangle} might also fail to completely
  86      * enclose the {@code Shape} if the {@code Shape} overflows
  87      * the limited range of the integer data type.  The
  88      * {@code getBounds2D} method generally returns a
  89      * tighter bounding box due to its greater flexibility in
  90      * representation.
  91      *
  92      * <p>
  93      * Note that the
  94      * <a href="{@docRoot}/java.desktop/java/awt/Shape.html#def_insideness">
  95      * definition of insideness</a> can lead to situations where points
  96      * on the defining outline of the {@code shape} may not be considered
  97      * contained in the returned {@code bounds} object, but only in cases
  98      * where those points are also not considered contained in the original
  99      * {@code shape}.
 100      * </p>
 101      * <p>
 102      * If a {@code point} is inside the {@code shape} according to the
 103      * {@link #contains(double x, double y) contains(point)} method, then
 104      * it must be inside the returned {@code Rectangle} bounds object
 105      * according to the {@link #contains(double x, double y) contains(point)}
 106      * method of the {@code bounds}. Specifically:
 107      * </p>
 108      * <p>
 109      *  {@code shape.contains(x,y)} requires {@code bounds.contains(x,y)}
 110      * </p>
 111      * <p>
 112      * If a {@code point} is not inside the {@code shape}, then it might
 113      * still be contained in the {@code bounds} object:
 114      * </p>
 115      * <p>
 116      *  {@code bounds.contains(x,y)} does not imply {@code shape.contains(x,y)}
 117      * </p>
 118      * @return an integer {@code Rectangle} that completely encloses
 119      *                 the {@code Shape}.
 120      * @see #getBounds2D
 121      * @since 1.2
 122      */
 123     public Rectangle getBounds();
 124 
 125     /**
 126      * Returns a high precision and more accurate bounding box of
 127      * the {@code Shape} than the {@code getBounds} method.
 128      * Note that there is no guarantee that the returned
 129      * {@link Rectangle2D} is the smallest bounding box that encloses
 130      * the {@code Shape}, only that the {@code Shape} lies
 131      * entirely within the indicated {@code Rectangle2D}.  The
 132      * bounding box returned by this method is usually tighter than that
 133      * returned by the {@code getBounds} method and never fails due
 134      * to overflow problems since the return value can be an instance of
 135      * the {@code Rectangle2D} that uses double precision values to
 136      * store the dimensions.
 137      *
 138      * <p>
 139      * Note that the
 140      * <a href="{@docRoot}/java.desktop/java/awt/Shape.html#def_insideness">
 141      * definition of insideness</a> can lead to situations where points
 142      * on the defining outline of the {@code shape} may not be considered
 143      * contained in the returned {@code bounds} object, but only in cases
 144      * where those points are also not considered contained in the original
 145      * {@code shape}.
 146      * </p>
 147      * <p>
 148      * If a {@code point} is inside the {@code shape} according to the
 149      * {@link #contains(Point2D p) contains(point)} method, then it must
 150      * be inside the returned {@code Rectangle2D} bounds object according
 151      * to the {@link #contains(Point2D p) contains(point)} method of the
 152      * {@code bounds}. Specifically:
 153      * </p>
 154      * <p>
 155      *  {@code shape.contains(p)} requires {@code bounds.contains(p)}
 156      * </p>
 157      * <p>
 158      * If a {@code point} is not inside the {@code shape}, then it might
 159      * still be contained in the {@code bounds} object:
 160      * </p>
 161      * <p>
 162      *  {@code bounds.contains(p)} does not imply {@code shape.contains(p)}
 163      * </p>
 164      * @return an instance of {@code Rectangle2D} that is a
 165      *                 high-precision bounding box of the {@code Shape}.
 166      * @see #getBounds
 167      * @since 1.2
 168      */
 169     public Rectangle2D getBounds2D();
 170 
 171     /**
 172      * Tests if the specified coordinates are inside the boundary of the
 173      * {@code Shape}, as described by the
 174      * <a href="{@docRoot}/java.desktop/java/awt/Shape.html#def_insideness">
 175      * definition of insideness</a>.
 176      * @param x the specified X coordinate to be tested
 177      * @param y the specified Y coordinate to be tested
 178      * @return {@code true} if the specified coordinates are inside
 179      *         the {@code Shape} boundary; {@code false}
 180      *         otherwise.
 181      * @since 1.2
 182      */
 183     public boolean contains(double x, double y);
 184 
 185     /**
 186      * Tests if a specified {@link Point2D} is inside the boundary
 187      * of the {@code Shape}, as described by the
 188      * <a href="{@docRoot}/java.desktop/java/awt/Shape.html#def_insideness">
 189      * definition of insideness</a>.
 190      * @param p the specified {@code Point2D} to be tested
 191      * @return {@code true} if the specified {@code Point2D} is
 192      *          inside the boundary of the {@code Shape};
 193      *          {@code false} otherwise.
 194      * @since 1.2
 195      */
 196     public boolean contains(Point2D p);
 197 
 198     /**
 199      * Tests if the interior of the {@code Shape} intersects the
 200      * interior of a specified rectangular area.
 201      * The rectangular area is considered to intersect the {@code Shape}
 202      * if any point is contained in both the interior of the
 203      * {@code Shape} and the specified rectangular area.
 204      * <p>
 205      * The {@code Shape.intersects()} method allows a {@code Shape}
 206      * implementation to conservatively return {@code true} when:
 207      * <ul>
 208      * <li>
 209      * there is a high probability that the rectangular area and the
 210      * {@code Shape} intersect, but
 211      * <li>
 212      * the calculations to accurately determine this intersection
 213      * are prohibitively expensive.
 214      * </ul>
 215      * This means that for some {@code Shapes} this method might
 216      * return {@code true} even though the rectangular area does not
 217      * intersect the {@code Shape}.
 218      * The {@link java.awt.geom.Area Area} class performs
 219      * more accurate computations of geometric intersection than most
 220      * {@code Shape} objects and therefore can be used if a more precise
 221      * answer is required.
 222      *
 223      * @param x the X coordinate of the upper-left corner
 224      *          of the specified rectangular area
 225      * @param y the Y coordinate of the upper-left corner
 226      *          of the specified rectangular area
 227      * @param w the width of the specified rectangular area
 228      * @param h the height of the specified rectangular area
 229      * @return {@code true} if the interior of the {@code Shape} and
 230      *          the interior of the rectangular area intersect, or are
 231      *          both highly likely to intersect and intersection calculations
 232      *          would be too expensive to perform; {@code false} otherwise.
 233      * @see java.awt.geom.Area
 234      * @since 1.2
 235      */
 236     public boolean intersects(double x, double y, double w, double h);
 237 
 238     /**
 239      * Tests if the interior of the {@code Shape} intersects the
 240      * interior of a specified {@code Rectangle2D}.
 241      * The {@code Shape.intersects()} method allows a {@code Shape}
 242      * implementation to conservatively return {@code true} when:
 243      * <ul>
 244      * <li>
 245      * there is a high probability that the {@code Rectangle2D} and the
 246      * {@code Shape} intersect, but
 247      * <li>
 248      * the calculations to accurately determine this intersection
 249      * are prohibitively expensive.
 250      * </ul>
 251      * This means that for some {@code Shapes} this method might
 252      * return {@code true} even though the {@code Rectangle2D} does not
 253      * intersect the {@code Shape}.
 254      * The {@link java.awt.geom.Area Area} class performs
 255      * more accurate computations of geometric intersection than most
 256      * {@code Shape} objects and therefore can be used if a more precise
 257      * answer is required.
 258      *
 259      * @param r the specified {@code Rectangle2D}
 260      * @return {@code true} if the interior of the {@code Shape} and
 261      *          the interior of the specified {@code Rectangle2D}
 262      *          intersect, or are both highly likely to intersect and intersection
 263      *          calculations would be too expensive to perform; {@code false}
 264      *          otherwise.
 265      * @see #intersects(double, double, double, double)
 266      * @since 1.2
 267      */
 268     public boolean intersects(Rectangle2D r);
 269 
 270     /**
 271      * Tests if the interior of the {@code Shape} entirely contains
 272      * the specified rectangular area.  All coordinates that lie inside
 273      * the rectangular area must lie within the {@code Shape} for the
 274      * entire rectangular area to be considered contained within the
 275      * {@code Shape}.
 276      * <p>
 277      * The {@code Shape.contains()} method allows a {@code Shape}
 278      * implementation to conservatively return {@code false} when:
 279      * <ul>
 280      * <li>
 281      * the {@code intersect} method returns {@code true} and
 282      * <li>
 283      * the calculations to determine whether or not the
 284      * {@code Shape} entirely contains the rectangular area are
 285      * prohibitively expensive.
 286      * </ul>
 287      * This means that for some {@code Shapes} this method might
 288      * return {@code false} even though the {@code Shape} contains
 289      * the rectangular area.
 290      * The {@link java.awt.geom.Area Area} class performs
 291      * more accurate geometric computations than most
 292      * {@code Shape} objects and therefore can be used if a more precise
 293      * answer is required.
 294      *
 295      * @param x the X coordinate of the upper-left corner
 296      *          of the specified rectangular area
 297      * @param y the Y coordinate of the upper-left corner
 298      *          of the specified rectangular area
 299      * @param w the width of the specified rectangular area
 300      * @param h the height of the specified rectangular area
 301      * @return {@code true} if the interior of the {@code Shape}
 302      *          entirely contains the specified rectangular area;
 303      *          {@code false} otherwise or, if the {@code Shape}
 304      *          contains the rectangular area and the
 305      *          {@code intersects} method returns {@code true}
 306      *          and the containment calculations would be too expensive to
 307      *          perform.
 308      * @see java.awt.geom.Area
 309      * @see #intersects
 310      * @since 1.2
 311      */
 312     public boolean contains(double x, double y, double w, double h);
 313 
 314     /**
 315      * Tests if the interior of the {@code Shape} entirely contains the
 316      * specified {@code Rectangle2D}.
 317      * The {@code Shape.contains()} method allows a {@code Shape}
 318      * implementation to conservatively return {@code false} when:
 319      * <ul>
 320      * <li>
 321      * the {@code intersect} method returns {@code true} and
 322      * <li>
 323      * the calculations to determine whether or not the
 324      * {@code Shape} entirely contains the {@code Rectangle2D}
 325      * are prohibitively expensive.
 326      * </ul>
 327      * This means that for some {@code Shapes} this method might
 328      * return {@code false} even though the {@code Shape} contains
 329      * the {@code Rectangle2D}.
 330      * The {@link java.awt.geom.Area Area} class performs
 331      * more accurate geometric computations than most
 332      * {@code Shape} objects and therefore can be used if a more precise
 333      * answer is required.
 334      *
 335      * @param r The specified {@code Rectangle2D}
 336      * @return {@code true} if the interior of the {@code Shape}
 337      *          entirely contains the {@code Rectangle2D};
 338      *          {@code false} otherwise or, if the {@code Shape}
 339      *          contains the {@code Rectangle2D} and the
 340      *          {@code intersects} method returns {@code true}
 341      *          and the containment calculations would be too expensive to
 342      *          perform.
 343      * @see #contains(double, double, double, double)
 344      * @since 1.2
 345      */
 346     public boolean contains(Rectangle2D r);
 347 
 348     /**
 349      * Returns an iterator object that iterates along the
 350      * {@code Shape} boundary and provides access to the geometry of the
 351      * {@code Shape} outline.  If an optional {@link AffineTransform}
 352      * is specified, the coordinates returned in the iteration are
 353      * transformed accordingly.
 354      * <p>
 355      * Each call to this method returns a fresh {@code PathIterator}
 356      * object that traverses the geometry of the {@code Shape} object
 357      * independently from any other {@code PathIterator} objects in use
 358      * at the same time.
 359      * <p>
 360      * It is recommended, but not guaranteed, that objects
 361      * implementing the {@code Shape} interface isolate iterations
 362      * that are in process from any changes that might occur to the original
 363      * object's geometry during such iterations.
 364      *
 365      * @param at an optional {@code AffineTransform} to be applied to the
 366      *          coordinates as they are returned in the iteration, or
 367      *          {@code null} if untransformed coordinates are desired
 368      * @return a new {@code PathIterator} object, which independently
 369      *          traverses the geometry of the {@code Shape}.
 370      * @since 1.2
 371      */
 372     public PathIterator getPathIterator(AffineTransform at);
 373 
 374     /**
 375      * Returns an iterator object that iterates along the {@code Shape}
 376      * boundary and provides access to a flattened view of the
 377      * {@code Shape} outline geometry.
 378      * <p>
 379      * Only SEG_MOVETO, SEG_LINETO, and SEG_CLOSE point types are
 380      * returned by the iterator.
 381      * <p>
 382      * If an optional {@code AffineTransform} is specified,
 383      * the coordinates returned in the iteration are transformed
 384      * accordingly.
 385      * <p>
 386      * The amount of subdivision of the curved segments is controlled
 387      * by the {@code flatness} parameter, which specifies the
 388      * maximum distance that any point on the unflattened transformed
 389      * curve can deviate from the returned flattened path segments.
 390      * Note that a limit on the accuracy of the flattened path might be
 391      * silently imposed, causing very small flattening parameters to be
 392      * treated as larger values.  This limit, if there is one, is
 393      * defined by the particular implementation that is used.
 394      * <p>
 395      * Each call to this method returns a fresh {@code PathIterator}
 396      * object that traverses the {@code Shape} object geometry
 397      * independently from any other {@code PathIterator} objects in use at
 398      * the same time.
 399      * <p>
 400      * It is recommended, but not guaranteed, that objects
 401      * implementing the {@code Shape} interface isolate iterations
 402      * that are in process from any changes that might occur to the original
 403      * object's geometry during such iterations.
 404      *
 405      * @param at an optional {@code AffineTransform} to be applied to the
 406      *          coordinates as they are returned in the iteration, or
 407      *          {@code null} if untransformed coordinates are desired
 408      * @param flatness the maximum distance that the line segments used to
 409      *          approximate the curved segments are allowed to deviate
 410      *          from any point on the original curve
 411      * @return a new {@code PathIterator} that independently traverses
 412      *         a flattened view of the geometry of the  {@code Shape}.
 413      * @since 1.2
 414      */
 415     public PathIterator getPathIterator(AffineTransform at, double flatness);
 416 }