JDK-6599363 : Incorrect filling of GeneralPath under JDK 1.6
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-08-30
  • Updated: 2011-04-05
  • Resolved: 2011-04-05
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 JDK 7
6u10Fixed 7 b20Fixed
Description
The attached program correctly fills the intended area of the shape
under 1.5 but not 1.6

import java.awt.Graphics2D;
import java.awt.Font;
import java.awt.Shape;
import java.awt.Rectangle;
import java.awt.Color;
import java.awt.BasicStroke;
import java.awt.GradientPaint;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;


public class AffineGPTest

	public static void main(String[] args) {
		final int width = 200;
		final int height = 200;


		BufferedImage image;
		BufferedImage outimage = new BufferedImage(width*5, height*1, BufferedImage.TYPE_INT_RGB);

		/* the general path is a sine wave */
		GeneralPath oddShape = new GeneralPath();
		oddShape.moveTo(10,50);
		oddShape.curveTo(10,50,20,10,30,50);
		oddShape.moveTo(30,50);
		oddShape.curveTo(30,50,40,90,50,50);
		oddShape.moveTo(50,50);
		oddShape.curveTo(50,50,60,10,70,50);
		oddShape.moveTo(70,50);
		oddShape.curveTo(70,50,80,90,90,50);
		oddShape.closePath();

		Graphics2D g2;
		AffineTransform af;
		final Graphics2D outg2 = (Graphics2D)outimage.getGraphics();

		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D)image.getGraphics();
		g2.setColor(Color.GRAY);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.WHITE);
		af = new AffineTransform();
		af.translate(30,15);
		g2.setTransform(af);
		g2.fill(oddShape);

		outg2.drawImage(image,0,0,null);

		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D)image.getGraphics();
		g2.setColor(Color.BLACK);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.WHITE);
		af = new AffineTransform();
		af.rotate(Math.PI/2.0,85,100);
		g2.setTransform(af);
		g2.fill(oddShape);

		outg2.drawImage(image,width,0,null);

		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D)image.getGraphics();
		g2.setColor(Color.GRAY);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.WHITE);
		af = new AffineTransform();
		af.rotate(Math.PI,85,100);
		g2.setTransform(af);
		g2.fill(oddShape);

		outg2.drawImage(image,width*2,0,null);

		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D)image.getGraphics();
		g2.setColor(Color.BLACK);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.WHITE);
		af = new AffineTransform();
		af.rotate(-Math.PI/2.0,85,100);
		g2.setTransform(af);
		g2.fill(oddShape);

		outg2.drawImage(image,width*3,0,null);

		image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		g2 = (Graphics2D)image.getGraphics();
		g2.setColor(Color.GRAY);
		g2.fillRect(0,0,width,height);
		g2.setColor(Color.WHITE);
		af = new AffineTransform();
		af.rotate(10.0,85,100);
		af.scale(1.5,0.5);
		g2.setTransform(af);
		g2.fill(oddShape);

		outg2.drawImage(image,width*4,0,null);

		try {
			final String outname = "generalpath.png";
			System.out.println("Writing "+outname);
			final OutputStream os = new BufferedOutputStream(new FileOutputStream(outname));
			ImageIO.write(outimage,"png",os);
			os.flush();
			os.close();
		} catch (IOException e) {
			System.out.println("ouch io exception "+e);
		}
	}
}

Comments
SUGGESTED FIX http://sa.sfbay.sun.com/projects/java2d_data/7/6599363.0
04-09-2007

SUGGESTED FIX #sccs diffs src/share/native/sun/java2d/loops/ProcessPath.c ------- ProcessPath.c ------- 1526c1526 < ProcessLine(hnd, closeCoord, tCoords, --- > ProcessLine(hnd, tCoords, closeCoord, 1531,1532c1531,1532 < tCoords[0] = closeCoord[0]; < tCoords[1] = closeCoord[1]; --- > closeCoord[0] = tCoords[0]; > closeCoord[1] = tCoords[1];
31-08-2007

EVALUATION Invalid rendering happens because of incorrect tracking of current segment closing point in new ProcessPath pipeline. Please see suggested fix.
31-08-2007