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