Displacement by one pixel if using setStroke

View: New views
3 Messages — Rating Filter:   Alert me  

Displacement by one pixel if using setStroke

by Dr. Christoph Gille :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

When using setStroke, the pixel is displaced by one position
I guess that it is a numeric rounding error in 2d.
The following program demonstrates the error and shows my workaround:
g.translate(0.001,0.001);




import java.awt.*;
import javax.swing.*;

/**
   You should see a dashed black-red rectangle.

   Without calling translate however, the dashed rectangle is displaced by one
   pixel.

   Starting
   java test.Topenjdk

   java -version
   java version "1.6.0_0"
   OpenJDK  Runtime Environment (build 1.6.0_0-b11)
   OpenJDK Client VM (build 1.6.0_0-b11, mixed mode, sharing)
*/
public final class Topenjdk extends JComponent {
    boolean bugfixed;
    public static void main(String argv[]) throws Exception {
        for(boolean withWorkaround : new boolean[]{true,false}) {
            final JFrame f=new JFrame(withWorkaround ? "With workaround" : "Bug: rectangles do not coincide ");
            final Topenjdk component=new Topenjdk();
            component.bugfixed=withWorkaround;
            f.getContentPane().add(component);
            f.setLocation(withWorkaround ? 20:0, withWorkaround ? 20:0);
            f.setSize(300,300);
            f.show();
        }
    }
    public void paintComponent(Graphics graphics) {
        final Graphics2D g=(Graphics2D)graphics;
        if (bugfixed) g.translate(0.001,0.001);
        g.setColor(Color.WHITE);
        g.fillRect(0,0,999,999);
        g.setColor(Color.BLACK);
        g.drawRect(10,10,100,100);
        g.setStroke(new BasicStroke(1f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,1f,new float[]{12/3f, 12-12/3f},3));
        g.setColor(Color.RED);
        g.drawRect(10,10,100,100);
        if (bugfixed)  g.translate(-0.001,-0.001);
    }
}



Re: Displacement by one pixel if using setStroke

by Roman Kennke-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Christoph,

> When using setStroke, the pixel is displaced by one position
> I guess that it is a numeric rounding error in 2d.

Do you see that problem in OpenJDK6 or7 or both?

I will file a bug report ASAP and work on fixing the problem.

Thanks, Roman




Re: Displacement by one pixel if using setStroke

by Roman Kennke-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Christoph,

I have filed bug #6889147, it should appear shortly on bugs.sun.com.
This seems to be another problem in the Pisces renderer. It seems to be
valid both for OpenJDK6 and 7. I try to have a look as soon as I find
time.

Thanks, Roman



Am Dienstag, den 06.10.2009, 12:31 +0200 schrieb Dr. Christoph Gille:

> When using setStroke, the pixel is displaced by one position
> I guess that it is a numeric rounding error in 2d.
> The following program demonstrates the error and shows my workaround:
> g.translate(0.001,0.001);
>
>
>
>
> import java.awt.*;
> import javax.swing.*;
>
> /**
>    You should see a dashed black-red rectangle.
>
>    Without calling translate however, the dashed rectangle is displaced by one
>    pixel.
>
>    Starting
>    java test.Topenjdk
>
>    java -version
>    java version "1.6.0_0"
>    OpenJDK  Runtime Environment (build 1.6.0_0-b11)
>    OpenJDK Client VM (build 1.6.0_0-b11, mixed mode, sharing)
> */
> public final class Topenjdk extends JComponent {
>     boolean bugfixed;
>     public static void main(String argv[]) throws Exception {
>         for(boolean withWorkaround : new boolean[]{true,false}) {
>             final JFrame f=new JFrame(withWorkaround ? "With workaround" : "Bug: rectangles do not coincide ");
>             final Topenjdk component=new Topenjdk();
>             component.bugfixed=withWorkaround;
>             f.getContentPane().add(component);
>             f.setLocation(withWorkaround ? 20:0, withWorkaround ? 20:0);
>             f.setSize(300,300);
>             f.show();
>         }
>     }
>     public void paintComponent(Graphics graphics) {
>         final Graphics2D g=(Graphics2D)graphics;
>         if (bugfixed) g.translate(0.001,0.001);
>         g.setColor(Color.WHITE);
>         g.fillRect(0,0,999,999);
>         g.setColor(Color.BLACK);
>         g.drawRect(10,10,100,100);
>         g.setStroke(new BasicStroke(1f,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,1f,new float[]{12/3f, 12-12/3f},3));
>         g.setColor(Color.RED);
>         g.drawRect(10,10,100,100);
>         if (bugfixed)  g.translate(-0.001,-0.001);
>     }
> }
>
>