/[classpath]/classpath/java/awt/geom/RoundRectangle2D.java
ViewVC logotype

Diff of /classpath/java/awt/geom/RoundRectangle2D.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by tromey, Fri Sep 26 15:12:28 2003 UTC revision 1.5 by smarothy, Sun Aug 1 22:27:36 2004 UTC
# Line 1  Line 1 
1  /* RoundRectangle2D.java -- represents a rectangle with rounded corners  /* RoundRectangle2D.java -- represents a rectangle with rounded corners
2     Copyright (C) 2000, 2002, 2003 Free Software Foundation     Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 39  package java.awt.geom; Line 39  package java.awt.geom;
39    
40  import java.util.NoSuchElementException;  import java.util.NoSuchElementException;
41    
42    
43  /** This class implements a rectangle with rounded corners.  /** This class implements a rectangle with rounded corners.
44   * @author Tom Tromey <tromey@cygnus.com>   * @author Tom Tromey <tromey@cygnus.com>
45   * @date December 3, 2000   * @date December 3, 2000
# Line 60  public abstract class RoundRectangle2D e Line 61  public abstract class RoundRectangle2D e
61     * @param arcHeight The arc height     * @param arcHeight The arc height
62     */     */
63    public abstract void setRoundRect(double x, double y, double w, double h,    public abstract void setRoundRect(double x, double y, double w, double h,
64                                       double arcWidth, double arcHeight);                                      double arcWidth, double arcHeight);
65    
66    /** Create a RoundRectangle2D.  This is protected because this class    /** Create a RoundRectangle2D.  This is protected because this class
67     * is abstract and cannot be instantiated.     * is abstract and cannot be instantiated.
68     */     */
69    protected  RoundRectangle2D()    protected RoundRectangle2D()
70    {    {
71    }    }
72    
# Line 87  public abstract class RoundRectangle2D e Line 88  public abstract class RoundRectangle2D e
88      // Now check to see if the point is in range of an arc.      // Now check to see if the point is in range of an arc.
89      double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y));      double dy = Math.min(Math.abs(my - y), Math.abs(my + mh - y));
90      double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x));      double dx = Math.min(Math.abs(mx - x), Math.abs(mx + mw - x));
91      double aw = getArcWidth();  
92      double ah = getArcHeight();      // The arc dimensions are that of the corresponding ellipse
93        // thus a 90 degree segment is half of that.
94        double aw = getArcWidth() / 2.0;
95        double ah = getArcHeight() / 2.0;
96      if (dx > aw || dy > ah)      if (dx > aw || dy > ah)
97        return true;        return true;
98    
# Line 112  public abstract class RoundRectangle2D e Line 116  public abstract class RoundRectangle2D e
116    {    {
117      // We have to check all four points here (for ordinary rectangles      // We have to check all four points here (for ordinary rectangles
118      // we can just check opposing corners).      // we can just check opposing corners).
119      return (contains(x, y) && contains(x + w, h)      return (contains(x, y) && contains(x, y + h) && contains(x + w, y + h)
120              && contains(x, y + h) && contains(x + w, y + h));             && contains(x + w, y));
121    }    }
122    
123    /** Return a new path iterator which iterates over this rectangle.    /** Return a new path iterator which iterates over this rectangle.
# Line 128  public abstract class RoundRectangle2D e Line 132  public abstract class RoundRectangle2D e
132      final double arcwidth = getArcWidth();      final double arcwidth = getArcWidth();
133      final double archeight = getArcHeight();      final double archeight = getArcHeight();
134      return new PathIterator()      return new PathIterator()
     {  
       /** We iterate clockwise around the rectangle, starting in the  
        * upper left.  This variable tracks our current point, which  
        * can be on either side of a given corner.  */  
       private int current = 0;  
   
       /** Child path iterator, used for corners.  */  
       private PathIterator corner;  
   
       /** This is used when rendering the corners.  We re-use the arc  
        * for each corner.  */  
       private Arc2D arc = new Arc2D.Double();  
   
       /** Temporary array used by getPoint.  */  
       private double[] temp = new double[2];  
   
       public int getWindingRule()  
       {  
         return WIND_NON_ZERO;  
       }  
   
       public boolean isDone()  
       {  
         return current > 9;  
       }  
   
       private void getPoint(int val)  
       {  
         switch (val)  
           {  
           case 0:  
           case 8:  
             temp[0] = minx;  
             temp[1] = miny + archeight;  
             break;  
           case 1:  
             temp[0] = minx + arcwidth;  
             temp[1] = miny;  
             break;  
           case 2:  
             temp[0] = maxx - arcwidth;  
             temp[1] = maxy;  
             break;  
           case 3:  
             temp[0] = maxx;  
             temp[1] = miny + archeight;  
             break;  
           case 4:  
             temp[0] = maxx;  
             temp[1] = maxy - archeight;  
             break;  
           case 5:  
             temp[0] = maxx - arcwidth;  
             temp[1] = maxy;  
             break;  
           case 6:  
             temp[0] = minx + arcwidth;  
             temp[1] = maxy;  
             break;  
           case 7:  
             temp[0] = minx;  
             temp[1] = maxy - archeight;  
             break;  
           }  
       }  
   
       public void next()  
       {  
         if (current >= 8)  
           ++current;  
         else if (corner != null)  
           {  
             // We're iterating through the corner.  Work on the child  
             // iterator; if it finishes, reset and move to the next  
             // point along the rectangle.  
             corner.next();  
             if (corner.isDone())  
               {  
                 corner = null;  
                 ++current;  
               }  
           }  
         else  
           {  
             // Make an arc between this point on the rectangle and  
             // the next one, and then iterate over this arc.  
             getPoint(current);  
             double x1 = temp[0];  
             double y1 = temp[1];  
             getPoint(current + 1);  
             arc.setFrameFromDiagonal(x1, y1, temp[0], temp[1]);  
             arc.setAngles(x1, y1, temp[0], temp[1]);  
             corner = arc.getPathIterator(at);  
           }  
       }  
   
       public int currentSegment(float[] coords)  
       {  
         if (corner != null)  
           {  
             int r = corner.currentSegment(coords);  
             if (r == SEG_MOVETO)  
               r = SEG_LINETO;  
             return r;  
           }  
   
         if (current < 9)  
           {  
             getPoint(current);  
             coords[0] = (float) temp[0];  
             coords[1] = (float) temp[1];  
           }  
         else if (current == 9)  
           return SEG_CLOSE;  
         else  
           throw new NoSuchElementException("rect iterator out of bounds");  
   
         if (at != null)  
           at.transform(coords, 0, coords, 0, 1);  
         return current == 0 ? SEG_MOVETO : SEG_LINETO;  
       }  
   
       public int currentSegment(double[] coords)  
135        {        {
136          if (corner != null)          /** We iterate counterclockwise around the rectangle, starting in the
137            {           * upper right.  This variable tracks our current point, which
138              int r = corner.currentSegment(coords);           * can be on either side of a given corner.  */
139              if (r == SEG_MOVETO)          private int current = 0;
140                r = SEG_LINETO;  
141              return r;          /** Child path iterator, used for corners.  */
142            }          private PathIterator corner;
143    
144          if (current < 9)          /** This is used when rendering the corners.  We re-use the arc
145            {           * for each corner.  */
146              getPoint(current);          private Arc2D arc = new Arc2D.Double();
147              coords[0] = temp[0];  
148              coords[1] = temp[1];          /** Temporary array used by getPoint.  */
149            }          private double[] temp = new double[2];
150          else if (current == 9)  
151            return SEG_CLOSE;          public int getWindingRule()
152          else          {
153            throw new NoSuchElementException("rect iterator out of bounds");            return WIND_NON_ZERO;
154            }
155          if (at != null)  
156            at.transform(coords, 0, coords, 0, 1);          public boolean isDone()
157          return current == 0 ? SEG_MOVETO : SEG_LINETO;          {
158        }            return current > 9;
159      };          }
160    
161            private void getPoint(int val)
162            {
163              switch (val)
164                {
165                case 0:
166                case 8:
167                  temp[0] = maxx;
168                  temp[1] = miny + archeight;
169                  break;
170                case 7:
171                  temp[0] = maxx;
172                  temp[1] = maxy - archeight;
173                  break;
174                case 6:
175                  temp[0] = maxx - arcwidth;
176                  temp[1] = maxy;
177                  break;
178                case 5:
179                  temp[0] = minx + arcwidth;
180                  temp[1] = maxy;
181                  break;
182                case 4:
183                  temp[0] = minx;
184                  temp[1] = maxy - archeight;
185                  break;
186                case 3:
187                  temp[0] = minx;
188                  temp[1] = miny + archeight;
189                  break;
190                case 2:
191                  temp[0] = minx + arcwidth;
192                  temp[1] = miny;
193                  break;
194                case 1:
195                  temp[0] = maxx - arcwidth;
196                  temp[1] = miny;
197                  break;
198                }
199            }
200    
201            public void next()
202            {
203              if (current >= 8)
204                ++current;
205              else if (corner != null)
206                {
207                  // We're iterating through the corner.  Work on the child
208                  // iterator; if it finishes, reset and move to the next
209                  // point along the rectangle.
210                  corner.next();
211                  if (corner.isDone())
212                    {
213                      corner = null;
214                      ++current;
215                    }
216                }
217              else
218                {
219                  // Make an arc between this point on the rectangle and
220                  // the next one, and then iterate over this arc.
221                  getPoint(current);
222                  double x1 = temp[0];
223                  double y1 = temp[1];
224                  getPoint(current + 1);
225                  Rectangle2D.Double r = new Rectangle2D.Double(Math.min(x1,
226                                                                         temp[0]),
227                                                                Math.min(y1,
228                                                                         temp[1]),
229                                                                Math.abs(x1
230                                                                         - temp[0]),
231                                                                Math.abs(y1
232                                                                         - temp[1]));
233                  arc.setArc(r, (current >> 1) * 90.0, 90.0, Arc2D.OPEN);
234                  corner = arc.getPathIterator(at);
235                }
236            }
237    
238            public int currentSegment(float[] coords)
239            {
240              if (corner != null)
241                {
242                  int r = corner.currentSegment(coords);
243                  if (r == SEG_MOVETO)
244                    r = SEG_LINETO;
245                  return r;
246                }
247    
248              if (current < 9)
249                {
250                  getPoint(current);
251                  coords[0] = (float) temp[0];
252                  coords[1] = (float) temp[1];
253                }
254              else if (current == 9)
255                return SEG_CLOSE;
256              else
257                throw new NoSuchElementException("rect iterator out of bounds");
258    
259              if (at != null)
260                at.transform(coords, 0, coords, 0, 1);
261              return current == 0 ? SEG_MOVETO : SEG_LINETO;
262            }
263    
264            public int currentSegment(double[] coords)
265            {
266              if (corner != null)
267                {
268                  int r = corner.currentSegment(coords);
269                  if (r == SEG_MOVETO)
270                    r = SEG_LINETO;
271                  return r;
272                }
273    
274              if (current < 9)
275                {
276                  getPoint(current);
277                  coords[0] = temp[0];
278                  coords[1] = temp[1];
279                }
280              else if (current == 9)
281                return SEG_CLOSE;
282              else
283                throw new NoSuchElementException("rect iterator out of bounds");
284    
285              if (at != null)
286                at.transform(coords, 0, coords, 0, 1);
287              return current == 0 ? SEG_MOVETO : SEG_LINETO;
288            }
289          };
290    }    }
291    
292    /** Return true if the given rectangle intersects this shape.    /** Return true if the given rectangle intersects this shape.
# Line 286  public abstract class RoundRectangle2D e Line 297  public abstract class RoundRectangle2D e
297     */     */
298    public boolean intersects(double x, double y, double w, double h)    public boolean intersects(double x, double y, double w, double h)
299    {    {
300      // Here we can use the same code we use for an ordinary rectangle.      // Check if any corner is within the rectangle
301      double mx = getX();      return (contains(x, y) || contains(x, y + h) || contains(x + w, y + h)
302      double mw = getWidth();             || contains(x + w, y));
     if (x < mx || x >= mx + mw || x + w < mx || x + w >= mx + mw)  
       return false;  
     double my = getY();  
     double mh = getHeight();  
     return y >= my && y < my + mh && y + h >= my && y + h < my + mh;  
303    }    }
304    
305    /** Set the boundary of this round rectangle.    /** Set the boundary of this round rectangle.
# Line 315  public abstract class RoundRectangle2D e Line 321  public abstract class RoundRectangle2D e
321    public void setRoundRect(RoundRectangle2D rr)    public void setRoundRect(RoundRectangle2D rr)
322    {    {
323      setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(),      setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(),
324                    rr.getArcWidth(), rr.getArcHeight());                   rr.getArcWidth(), rr.getArcHeight());
325    }    }
326    
327    /** A subclass of RoundRectangle which keeps its parameters as    /** A subclass of RoundRectangle which keeps its parameters as
# Line 353  public abstract class RoundRectangle2D e Line 359  public abstract class RoundRectangle2D e
359       * @param arcWidth The arc width       * @param arcWidth The arc width
360       * @param arcHeight The arc height       * @param arcHeight The arc height
361       */       */
362      public Double(double x, double y, double w, double h,      public Double(double x, double y, double w, double h, double arcWidth,
363                     double arcWidth, double arcHeight)                    double arcHeight)
364      {      {
365        this.x = x;        this.x = x;
366        this.y = y;        this.y = y;
# Line 405  public abstract class RoundRectangle2D e Line 411  public abstract class RoundRectangle2D e
411      }      }
412    
413      public void setRoundRect(double x, double y, double w, double h,      public void setRoundRect(double x, double y, double w, double h,
414                                double arcWidth, double arcHeight)                               double arcWidth, double arcHeight)
415      {      {
416        this.x = x;        this.x = x;
417        this.y = y;        this.y = y;
# Line 451  public abstract class RoundRectangle2D e Line 457  public abstract class RoundRectangle2D e
457       * @param arcWidth The arc width       * @param arcWidth The arc width
458       * @param arcHeight The arc height       * @param arcHeight The arc height
459       */       */
460      public Float(float x, float y, float w, float h,      public Float(float x, float y, float w, float h, float arcWidth,
461                    float arcWidth, float arcHeight)                   float arcHeight)
462      {      {
463        this.x = x;        this.x = x;
464        this.y = y;        this.y = y;
# Line 503  public abstract class RoundRectangle2D e Line 509  public abstract class RoundRectangle2D e
509      }      }
510    
511      public void setRoundRect(float x, float y, float w, float h,      public void setRoundRect(float x, float y, float w, float h,
512                                float arcWidth, float arcHeight)                               float arcWidth, float arcHeight)
513      {      {
514        this.x = x;        this.x = x;
515        this.y = y;        this.y = y;
# Line 514  public abstract class RoundRectangle2D e Line 520  public abstract class RoundRectangle2D e
520      }      }
521    
522      public void setRoundRect(double x, double y, double w, double h,      public void setRoundRect(double x, double y, double w, double h,
523                                double arcWidth, double arcHeight)                               double arcWidth, double arcHeight)
524      {      {
525        this.x = (float) x;        this.x = (float) x;
526        this.y = (float) y;        this.y = (float) y;

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26