Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4489667

Graphics draw() and fill() don't always line up polygons

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P3 P3
    • 1.4.0
    • 1.4.0
    • client-libs
    • 2d
    • x86
    • windows_2000



      Name: nt126004 Date: 08/08/2001


      java version "1.4.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b65)
      Java HotSpot(TM) Client VM (build 1.4.0-beta-b65, mixed mode)


      It seems there are some cases where Graphics draw() and fill() don't always
      line up correctly. In particular, I know that if a draw(myPolygon) and fill
      (myPolygon) are done on the graphics object of a BufferedImage, this outline
      drawn with draw(myPolygon) will not correctly outline the filled polygon drawn
      with fill(myPolygon). However, if these same operations are performed directly
      on a graphics object of a JComponent in jdk1.4-beta, this problem does not
      occur.

      I have created a program to demonstrate this. On the left will be the polygon
      drawn directly to the JPanel, and on the right the polygon drawn in a
      BufferedImage, where the BufferedImage is drawn on the panel. Note that when
      looking at the polygon on the right, white pixels are escaping the black
      border, and red pixels are somehow staying inside. These white pixels always
      escape up and left by one pixel. Because of this, the bottom right pixels of
      the polygon that should be white end up being red. I suspect somehow something
      is off by one pixel in the second case. Maybe has to do with aliasing (as
      antialiasing might not show the problem)?

      I have a screenshot showing the program running from jdk1.3.1 and jdk1.4-beta
      and how they differ. To sum it up, in 1.4-beta, left looks good, right looks
      bad. In 1.3.1, both look bad. I will send this screenshot upon request.

      *NOTE ABOUT TEST PROGRAM* The way the cursor-like polygons are created is not
      obvious. It should be noted that the way the polygon is made does not matter,
      as long as the polygon is made (just added Points to a Polygon). I kept this
      cursor-like polygon because I thought it showed the problem well. Also note
      that uncommenting the while loop in main() can make the polygons spin, showing
      the problem at different angles. As they spin you'll note that white pixels
      only escape the black border up and left 1 pixel.

      I am running a completely up-to-date Windows 2000 Professional box. My video
      card is a 3dfx Voodoo 3 3000. My driver has the following info:

      Driver Provider: 3dfx Interactive, Inc.
      Driver Date: 11/2/2000
      Driver Version: 5.0.2195.232
      Digital Signer: Microsoft Windows Hardware Compatibility Publisher

      Here is driver files info:
      --File-- --Version--
      C:\WINNT\System32\3dfxOGL.dll 1.0.0.0734 ICD
      C:\WINNT\System32\3dfxSpl2.dll 1.00.00.0004
      C:\WINNT\System32\3dfxSpl3.dll 1.00.00.0004
      C:\WINNT\System32\3dfxvs.dll 5.00.2195.0232
      C:\WINNT\System32\DRIVERS\3dfxvsm.sys 5.00.2195.0232
      C:\WINNT\System32\glide2x.dll 2.61.00.0658
      C:\WINNT\System32\glide3x.dll 3.10.00.0658



      =-=-=-=-=-=-=-=-= TestFill.java =-=-=-=-=-=-=-=-=
      import javax.swing.*;
      import java.awt.*;
      import java.awt.geom.*;
      import java.awt.image.*;

      public class TestFill extends JPanel
      {
          // the angle the polygon is facing
          private static double angle = .75;
          // the buffered image which polygon will be drawn (badly) on
          private BufferedImage image;
          // the seven points of the polygon
          private Point p1;
          private Point p2;
          private Point p3;
          private Point p4;
          private Point p5;
          private Point p6;
          private Point p7;

          public static void main(String[] argv)
          {
              JFrame f = new JFrame();
              f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              f.getContentPane().add(new TestFill());
              f.setSize(100,80);
              f.show();
      // uncomment this to see the polygons at different angles
      /* while (true)
              {
                  // change this amount to make the rotation faster/slower
                  angle += 0.000002;
                  f.repaint();
              }*/
          }

          public void paintComponent(Graphics g)
          {
              setBackground(Color.red);
              super.paintComponent(g);
              // length of both sides of buffered image
              int size = 32;
              // x and y coordinates of center of image
              int x = size / 2;
              int y = x;
              // make the new buffered image to draw stuff to
              image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
              // graphics 2d object of the buffered image, shown on right
              Graphics2D rightGraphics = image.createGraphics();
              // graphics 2d object for the polygon drawn directly to the JPanel
              Graphics2D leftGraphics = (Graphics2D) g;
              // ensure antialiasing is OFF (or problem will be blurred out)
              leftGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                            RenderingHints.VALUE_ANTIALIAS_OFF);
              // make the points of the polygon (depending on current angle)
              // note that it doesn't really matter what these points are, they are
              // merely points added to a polygon (which happen to make a familiar
              // cursor picture)
              p1 = makePoint(0, 15);
              p2 = makePoint(-105.9, 7.28);
              p3 = makePoint(-90, 1+.5);
              p4 = makePoint(-174.3+2, 10.05+.5);
              p5 = makePoint(174.3-2, 10.05+.5);
              p6 = makePoint(90, 1+.5);
              p7 = makePoint(105.9, 7.28);
              // put the points in the polygon
              Polygon p = new Polygon();
              p.addPoint(x + p1.x, y - p1.y);
              p.addPoint(x + p2.x, y - p2.y);
              p.addPoint(x + p3.x, y - p3.y);
              p.addPoint(x + p4.x, y - p4.y);
              p.addPoint(x + p5.x, y - p5.y);
              p.addPoint(x + p6.x, y - p6.y);
              p.addPoint(x + p7.x, y - p7.y);
              
              // here's the meat of the test.. do same calls to leftGraphics and
              // rightGraphics, and note that they do not look identical...
              
              // fill with white background of polygon (for left and right)
              leftGraphics.setColor(Color.white);
              leftGraphics.fill(p);
              rightGraphics.setColor(Color.white);
              rightGraphics.fill(p);
              // outline polygon with black (for left and right)
              leftGraphics.setColor(Color.black);
              leftGraphics.draw(p);
              rightGraphics.setColor(Color.black);
              rightGraphics.draw(p);
              // draw this buffered image on the right (which shows the problem)
              g.drawImage(image, 50, 0, this);
          }

          // create point from angle and distance from center (all that matters is
          // this returns a point to be put in the polygon (i.e. not worth debugging))
          private Point makePoint(double angleOffset, double dist)
          {
              return new Point((int)(dist * Math.cos(angle +
                                                     Math.toRadians(angleOffset))),
                               (int)(dist * Math.sin(angle +
                                                     Math.toRadians(angleOffset))));
          }
      }
      =-=-=-=-=-=-=-=-= END TestFill.java =-=-=-=-=-=-=-=-=
      (Review ID: 129586)
      ======================================================================

            flar Jim Graham
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: