JDK-4147957 : setClip with invalid rect changes rect to valid
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.8,1.2.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,solaris_2.6,windows_95
  • CPU: generic,x86
  • Submitted: 1998-06-11
  • Updated: 2013-07-03
  • Resolved: 1999-01-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.2.2 1.2.2Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description

Name: rm29839			Date: 06/11/98


When constructing clip rectangles for graphics
operations it is desireable to be able to 
intersect two rectangles and pass the result to
setClip.

If the two rectangles are disjoint
(no intersection) then intersect returns a rect
with a negitive width or height.  If you pass 
such a rectangle to setClip, getClipBounds will
return the same rectangle with the absolute value
of all points in the rectangle that was passed to
setClip.

That can really mess up GUI code.
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;


public class MMM extends Frame{
  public static void main (String [] args){
    new MMM();
  }
  public MMM(){
    setSize(200,200);
    show();
    validate();
  }
  
    public void paint(Graphics g){
      Rectangle r1 = new Rectangle(0,0,100,100);
      Rectangle r2 = new Rectangle(200,200,20,20);
      Rectangle r3 = r1.intersection(r2);
      System.out.println("intersect    :(" + (int)r3.getX() + "," + (int)r3.getY() + "," + (int)r3.getWidth() + "," + (int)r3.getHeight() + ")" );g.setClip(r3);
      Rectangle r4 = g.getClipBounds();
      System.out.println("getClipBounds:(" + (int)r4.getX() + "," + (int)r4.getY() + "," + (int)r4.getWidth() + "," + (int)r4.getHeight() + ")"  );
      
    }
  
}
(Review ID: 33441)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.2.2 FIXED IN: 1.2.2 INTEGRATED IN: 1.2.2
14-06-2004

WORK AROUND Name: rm29839 Date: 06/11/98 Check for negative values for width and height and bypass code that would have used that intersection as a clip. ======================================================================
11-06-2004

SUGGESTED FIX alan.bateman@ireland 1998-08-17 If the decision is that intersection() should return a zero rectangle instead of a negative rectangle then the following is a suggested solution (it requires a modification to both an AWT and a 2D class). (1) In src/share/classes/java/awt/Rectangle.java :- public Rectangle intersection(Rectangle r) { int x1 = Math.max(x, r.x); int x2 = Math.min(x + width, r.x + r.width); int y1 = Math.max(y, r.y); int y2 = Math.min(y + height, r.y + r.height); if (x2 < x1) x2 = x1; // new if (y2 < y1) y2 = y1; // new return new Rectangle(x1, y1, x2 - x1, y2 - y1); } (2) In src/share/classes/sun/java2d/SunGraphics2D.java :- Shape intersectRectShape(Rectangle2D r, Shape s, boolean keep1, boolean keep2) { if (s instanceof Rectangle2D) { Rectangle2D r2 = (Rectangle2D) s; Rectangle2D outrect; if (!keep1) { outrect = r; } else if (!keep2) { outrect = r2; } else { outrect = new Rectangle2D.Float(); } // begin changes double x1 = Math.max(r.getX(), r2.getX()); double x2 = Math.min(r.getX() + r.getWidth(), r2.getX() + r2.getWidth()); double y1 = Math.max(r.getY(), r2.getY()); double y2 = Math.min(r.getY() + r.getHeight(), r2.getY() + r2.getHeight()); if (x2 < x1) x2 = x1; if (y2 < y1) y2 = y1; outrect.setFrame(x1, y1, x2 - x1, y2 - y1); return outrect; // end changes } if (r.contains(s.getBounds2D())) { if (keep2) { s = cloneShape(s); } return s; } return intersectByArea(r, s, keep1, keep2); }
11-06-2004

EVALUATION Name: ksT78225 Date: 09/10/98 ###@###.###\11 Sep '98 The given code(MMM.java) cannot be run under jdk1.1.7 since the class Rectangle doesn't have getX,getY....methods. In Win32,this bug is reproducible with jdk1.2beta3, 1.2beta4 and 1.2fcs-I. Before setClip(), the rectangle's height and width are displayed as negative numbers, after setClip(), the getClipBounds() returns rectangle with a different x,y positions and height and width as absolute values. In Solaris the bug is NOT reproducible ,this code displays the same points before and after setClip(), tested with 1.2fcs-I(PC-5.5) and with 1.2fcs-F(Sparc-5.6). The setClip()shouldn't accept rectangle with negative height and width. ====================================================================== Modified Rectangle:intersection and SunGraphics2D:intersectRectShape to return (0,0,0,0) if width or height is negative when there is no intersection. src/share/classes/sun/java2d/SunGraphics2D.java src/share/classes/java/awt/Rectangle.java ------- Rectangle.java ------- *** /tmp/d2oA0M_ Thu Dec 24 14:40:20 1998 --- Rectangle.java Mon Dec 21 18:06:59 1998 *************** *** 529,534 **** --- 529,538 ---- int x2 = Math.min(x + width, r.x + r.width); int y1 = Math.max(y, r.y); int y2 = Math.min(y + height, r.y + r.height); + if (((x2 - x1) < 0) || ((y2 - y1) < 0)) + // Width or height is negative. No intersection. + return new Rectangle(0,0,0,0); + else return new Rectangle(x1, y1, x2 - x1, y2 - y1); } ------- SunGraphics2D.java ------- *** /tmp/dEXHlV_ Wed Dec 23 14:05:46 1998 --- SunGraphics2D.java Mon Dec 21 19:03:04 1998 *************** *** 369,387 **** } else { outrect = new Rectangle2D.Float(); } ! double x1 = r.getX(); ! double y1 = r.getY(); ! double x2 = r2.getX(); ! double y2 = r2.getY(); ! double x = Math.max(x1, x2); ! double y = Math.max(y1, y2); ! x1 += r.getWidth(); ! y1 += r.getHeight(); ! x2 += r2.getWidth(); ! y2 += r2.getHeight(); ! outrect.setFrameFromDiagonal(x, y, ! Math.min(x1, x2), ! Math.min(y1, y2)); return outrect; } if (r.contains(s.getBounds2D())) { --- 369,386 ---- } else { outrect = new Rectangle2D.Float(); } ! double x1 = Math.max(r.getX(), r2.getX()); ! double x2 = Math.min(r.getX() + r.getWidth(), ! r2.getX() + r2.getWidth()); ! double y1 = Math.max(r.getY(), r2.getY()); ! double y2 = Math.min(r.getY() + r.getHeight(), ! r2.getY() + r2.getHeight()); ! ! if (((x2 - x1) < 0) || ((y2 - y1) < 0)) ! // Width or height is negative. No intersection. ! outrect.setFrameFromDiagonal(0, 0, 0, 0); ! else ! outrect.setFrameFromDiagonal(x1, y1, x2, y2); return outrect; } if (r.contains(s.getBounds2D())) { mike.bronson@eng 1998-12-24
24-12-1998