JDK-4151279 : Curves are not as pleasing as JDK 1.1 (affects ovals, arcs and roundrects)
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.2.0,1.2.1,1.3.0,1.4.0,5.0,6
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS:
    generic,linux,solaris_2.5,solaris_2.6,windows_98,windows_nt,windows_2000,windows_xp generic,linux,solaris_2.5,solaris_2.6,windows_98,windows_nt,windows_2000,windows_xp
  • CPU: generic,x86,sparc
  • Submitted: 1998-06-22
  • Updated: 2005-09-19
  • Resolved: 2005-09-19
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.
JDK 6
6 b53Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Description
Run the following program against 1.2beta4-J and you will see rows
of circles painted with fillOval to an offscreen image.  However,
the circles will have several flat edges which make them look 
more like polygons than circles.  This doesn't happen under 1.1.6,
nor does it happen when painting directly to a component.

import java.awt.*;
import java.awt.event.*;

public class CircleBug extends Panel {
    
    public CircleBug() {
	super(null);
	
	setSize(400, 400);
	buffer = null;
    }

    public void paint(Graphics g) {
	if (buffer == null) {
	    Dimension size = getSize();
	    Graphics bg;
	    int x, y;
	    
	    buffer = createImage(size.width, size.height);
	    if (buffer != null) {
		bg = buffer.getGraphics();
		
		bg.setColor(Color.black);
		bg.fillRect(0, 0, size.width, size.height);
		bg.setColor(Color.white);
	
		x = 0;
		y = 0;
		while (y < size.height) {
		    while (x < size.width) {
			bg.fillOval(x, y, 36, 36);
			x += 40;
		    }
		    x = 0;
		    y += 40;
		}
	    }
	}
	
	if (buffer != null) {
	    g.drawImage(buffer, 0, 0, this);
	}
    }

    public static void main(String args[]) {
	Frame frame = new Frame("2D Circle bug");
	
	frame.addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent e) {
		System.exit(0);
	    }
	});
	frame.setLayout(new BorderLayout());
	frame.add("Center", new CircleBug());
	frame.pack();
	frame.setVisible(true);
    }

    protected Image buffer;
}


Name: rlT66838			Date: 06/11/99


c:\users\default>java -version
java version "1.2.1"
HotSpot VM (1.0fcs, mixed mode, build E)

c:\users\default>java -fullversion
java full version "JDK-1.2.1-A"

Please find code below.  

g2.draw(new Ellipse2D.Double(40.0, 100.0, 20.0, 20.0)); produced a much poorer circle both on screen and printer then its g.drawOval... counterpart.

I thought it was supposed to be the other way around???
________________________________
package printing;

import java.awt.*;
import java.awt.event.*;
import java.awt.print.*;
import java.awt.geom.*;
import javax.swing.*;

public class FramePrint extends JFrame {

    public FramePrint() {

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu menuFile = new JMenu("File");
        menuBar.add(menuFile);

        JMenuItem itemPrint = new JMenuItem("Print");
        menuFile.add(itemPrint);
            itemPrint.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    print();
                }
            }
                                        );

        setSize(100,200);
        setVisible(true);
    }

    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2 = (Graphics2D)g;

        g2.draw(new Ellipse2D.Double(40.0, 100.0, 20.0, 20.0));

        g.drawOval(70, 100, 20, 20);
    }

    public void print() {
        //NOTE how can a PrinterJob be related to a PrintJob?????
//        PrinterJob.getPrinterJob().pageDialog(new PageFormat());
        PrintJob printJob = Toolkit.getDefaultToolkit().getPrintJob(this, "blah", null);
        Graphics g = printJob.getGraphics();
        this.paint(g);
//        printAll(g);this will print all GUI components, but not the custom graphics
        g.dispose();
        printJob.end();
    }

    public static void main(String[] args) {
        new FramePrint();
    }
}
(Review ID: 84211)
======================================================================

Name: gm110360			Date: 04/12/2002


FULL PRODUCT VERSION :
java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
Java HotSpot(TM) Client VM (build 1.4.0-rc-b91, mixed mode)

FULL OPERATING SYSTEM VERSION :
Windows 2000 SP2

A DESCRIPTION OF THE PROBLEM :
This is not a duplicate of the related 4151279. In 4151279,
it is pointed out that offscreen rendering of circles does
not work quite right and does not produce circles. While
4151279 is not closed, the last Sun comment is from
1998-08-13 and it does not appear that this bug is truely
open (you have released 1.2, 1.3 and 1.4 since then).

In light of this, the API specifications should be changed
(or at least the documentation). It presently reads, "Draws
the outline of an oval." But does nothing of the sort, As i
mentioned in 4151279, i made a 8.5 pixel diamater circle and
got something back with two edges that were 8 pixels long.

I would suggest a change to "draws a shape that fits within
a rectangle of dimensions... that, at times, resembles an oval."

here is the web link to you documentation
http://java.sun.com/j2se/1.4/docs/api/java/awt/Graphics.html#drawOval(int,%20int,%20int,%20int)

NOTE: comments and opinions of the author are independant of
those of EML, DOE, and the US government.


REGRESSION.  Last worked in version 1.1.8

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.see 4151279, there is code there.
2.also look at the user who claims that drawOval(a,b,c,d)
followed by drawOval(a,b,c,d) does not produce the same output!
3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
I expect the Documentation to document what the JMV does. It
does not.

For 4151279 the expected result is a circle (even when the
oval is drawn off screen) and the results are a football/oval.

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
public class Class extends Frame{
  public static void main(String[] args) {
    Class c = new Class();
    c.setSize(100,100);
    c.setVisible(true);
    c.repaint();
  }
  //note that just double buffering doesn't make it very bad
  //calling another method with an image to draw on
  //is what makes it _very_ bad
  public void paint(Graphics g) {
    Image i = this.createImage(this.getWidth(),this.getHeight());
    drawOnIt(i);
    drawOnIt(i.getGraphics());
    g.drawImage(i,0,0,this);
  }
  //draws "ovals"
  public void drawOnIt(Image i) {
    Graphics g = i.getGraphics();
    g.setColor(Color.black);
    for(int h=0;h<=15;h++)
      g.drawOval(30+(h*35),30,h+1,h+1);
    for(int h=0;h<=15;h++)
      g.drawOval(30+(h*35),70,16+h,16+h);
  }

  //draws "ovals", just as bad
  public void drawOnIt(Graphics g) {
    g.setColor(Color.black);
    for(int h=0;h<=15;h++)
      g.drawOval(30+(h*35),110,h+1,h+1);
    for(int h=0;h<=15;h++)
      g.drawOval(30+(h*35),150,16+h,16+h);
  }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
do all you rendering on screen (not really a work around).
(Review ID: 139638)
======================================================================

Name: gm110360			Date: 04/17/2002


FULL PRODUCT VERSION :
Java 2 SDK Standard Edition v1.3

FULL OPERATING SYSTEM VERSION :
Intel & Windows 98

ADDITIONAL OPERATING SYSTEMS :
Macintosh 8.6


A DESCRIPTION OF THE PROBLEM :
Hello,
   I have used Java since 1998, because it looks like C and
it is platform-independent.
   But I have one problem: filloval function does not work
correctly, especially small ones.

Please look at my homepage
http://homepage3.nifty.com/Aim/oval
On Macintosh system, all three rows of circles are seen the
same except their colors, but on Windows system the three
sets of
circles are seen differently. Some are not true circles, one
of them looks like a silhouette of a dome.

Please improve the quality of this.
Thank you,
T

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. use update(Graphics g)
2. offG.fillOval(25, 20, 3, 3);
3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
true circles

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Nothing

This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/*
 * circles.java	01/06/2001
 */

import java.awt.*;


public class circles extends java.applet.Applet {
	Image 	offscr;
	Graphics 	offG;
    

    public void init() {
    }
    
    public void paint(Graphics g) {
    	Image pict;
    	
    	update(g);
		
    	g.setColor(Color.red);
		for(int i = 0; i < 20; i++){
			g.fillOval(i*25, 40, i, i);
		}
    }

    public void update(Graphics g) {
		offscr = createImage(500, 60);
		offG = offscr.getGraphics();
	
		offG.setColor(Color.white);		//make background
		offG.fillRect(0, 0, 500, 60);
		offG.setColor(Color.green);
		for(int i = 0; i < 20; i++){
			offG.fillOval(i*25, 20, i, i);
		}
		g.drawImage(offscr, 0, 0, this);
		offG.dispose();

    }
}




---------- END SOURCE ----------
(Review ID: 145281)
======================================================================

Comments
EVALUATION We currently use an algorithm that does the following to render the circles and ovals: convert to Bezier approximation (less than 1% error) flatten to floating point polygons (less than 1 pixel error) round polygon vertices to integers (? error) fill integer polygon I believe that most of the error and visible artifacts come from the 3rd stage that rounds polygons to integers before scan converting them. We plan to implement subpixel precision scan conversion for FCS which I believe will fix most of the problem. If there is still a significant problem and/or there is time for FCS, we will investigate direct scan conversion of the Bezier segments, but that should not be necessary since there are plenty of commercial rendering packages that get decent results for circles from rendering flattened Bezier approximations. jim.graham@Eng 1998-07-27 I fixed the filler to maintain sub-pixel precision in filling the flattened cubics and the circles are now much better, though not yet perfect. I am downgrading this bug to a P4. If we have time to write a Bezier tracer for FCS then we will, otherwise I think circles look good enough for the first release. jim.graham@Eng 1998-08-13 We are currently working on separate pipeline for drawing cubic and quad Bezier curves. We are using adaptive forward differencing. This approach according to our preliminary results could noticeably increase quality and speed up drawing of the Bezier curves. ###@###.### 2005-2-18 14:21:49 GMT
18-02-2005