Mercurial > hg > release > icedtea7-forest-2.4 > jdk
changeset 4361:f290441b0cb7
7043054: REGRESSION: JDK 7 b126 : Wrong userBounds in Paint.createContext()
Reviewed-by: prr
author | flar |
---|---|
date | Wed, 11 May 2011 16:12:01 -0700 |
parents | 85f53467c30c |
children | 43e54e60d261 |
files | src/share/classes/sun/java2d/opengl/OGLRenderer.java src/share/classes/sun/java2d/pipe/AAShapePipe.java src/share/classes/sun/java2d/pipe/AlphaColorPipe.java src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java src/share/classes/sun/java2d/pipe/LoopPipe.java src/share/classes/sun/java2d/pipe/ParallelogramPipe.java src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java src/windows/classes/sun/java2d/d3d/D3DRenderer.java test/java/awt/Paint/PgramUserBoundsTest.java |
diffstat | 9 files changed, 226 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/sun/java2d/opengl/OGLRenderer.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/opengl/OGLRenderer.java Wed May 11 16:12:01 2011 -0700 @@ -102,15 +102,20 @@ final ParallelogramPipe realpipe = oglr.getAAParallelogramPipe(); return new ParallelogramPipe() { public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) { GraphicsPrimitive.tracePrimitive("OGLFillAAParallelogram"); realpipe.fillParallelogram(sg2d, + ux1, uy1, ux2, uy2, x, y, dx1, dy1, dx2, dy2); } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, @@ -118,6 +123,7 @@ { GraphicsPrimitive.tracePrimitive("OGLDrawAAParallelogram"); realpipe.drawParallelogram(sg2d, + ux1, uy1, ux2, uy2, x, y, dx1, dy1, dx2, dy2, lw1, lw2); } @@ -166,21 +172,29 @@ oglr.fillSpans(sg2d, si, transx, transy); } public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) { GraphicsPrimitive.tracePrimitive("OGLFillParallelogram"); - oglr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2); + oglr.fillParallelogram(sg2d, + ux1, uy1, ux2, uy2, + x, y, dx1, dy1, dx2, dy2); } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, double lw1, double lw2) { GraphicsPrimitive.tracePrimitive("OGLDrawParallelogram"); - oglr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2); + oglr.drawParallelogram(sg2d, + ux1, uy1, ux2, uy2, + x, y, dx1, dy1, dx2, dy2, lw1, lw2); } public void copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)
--- a/src/share/classes/sun/java2d/pipe/AAShapePipe.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/AAShapePipe.java Wed May 11 16:12:01 2011 -0700 @@ -68,21 +68,23 @@ renderPath(sg, s, null); } - private static Rectangle2D computeBBox(double x, double y, - double dx1, double dy1, - double dx2, double dy2) + private static Rectangle2D computeBBox(double ux1, double uy1, + double ux2, double uy2) { - double lox, loy, hix, hiy; - lox = hix = x; - loy = hiy = y; - if (dx1 < 0) { lox += dx1; } else { hix += dx1; } - if (dy1 < 0) { loy += dy1; } else { hiy += dy1; } - if (dx2 < 0) { lox += dx2; } else { hix += dx2; } - if (dy2 < 0) { loy += dy2; } else { hiy += dy2; } - return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy); + if ((ux2 -= ux1) < 0) { + ux1 += ux2; + ux2 = -ux2; + } + if ((uy2 -= uy1) < 0) { + uy1 += uy2; + uy2 = -uy2; + } + return new Rectangle2D.Double(ux1, uy1, ux2, uy2); } public void fillParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) @@ -97,10 +99,12 @@ return; } - renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); + renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox); } public void drawParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, @@ -118,7 +122,7 @@ // Note that bbox is of the original shape, not the wide path. // This is appropriate for handing to Paint methods... - renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); + renderTiles(sg, computeBBox(ux1, uy1, ux2, uy2), aatg, abox); } private static byte[] theTile;
--- a/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/AlphaColorPipe.java Wed May 11 16:12:01 2011 -0700 @@ -66,6 +66,8 @@ } public void fillParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) @@ -75,6 +77,8 @@ } public void drawParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2,
--- a/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/BufferedRenderPipe.java Wed May 11 16:12:01 2011 -0700 @@ -408,6 +408,8 @@ } public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) @@ -429,6 +431,8 @@ } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, @@ -454,6 +458,8 @@ private class AAParallelogramPipe implements ParallelogramPipe { public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) @@ -475,6 +481,8 @@ } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2,
--- a/src/share/classes/sun/java2d/pipe/LoopPipe.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/LoopPipe.java Wed May 11 16:12:01 2011 -0700 @@ -352,6 +352,8 @@ } public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) @@ -362,6 +364,8 @@ } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2,
--- a/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/ParallelogramPipe.java Wed May 11 16:12:01 2011 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2011 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,9 +40,17 @@ * => (x+dx2, y+dy2) * => origin * </pre> + * The four u[xy][12] parameters are the unsorted extreme coordinates + * of the primitive in user space. They may have been generated by a + * line or a rectangle so they could have u[xy]2 < u[xy]1 in some cases. + * They should be sorted before calculating the bounds of the original + * primitive (such as for calculating the user space bounds for the + * Paint.createContext() method). */ public interface ParallelogramPipe { public void fillParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2); @@ -59,6 +67,8 @@ * difference between the outer and inner parallelograms. */ public void drawParallelogram(SunGraphics2D sg, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2,
--- a/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java Tue May 10 15:59:01 2011 -0700 +++ b/src/share/classes/sun/java2d/pipe/PixelToParallelogramConverter.java Wed May 11 16:12:01 2011 -0700 @@ -175,8 +175,8 @@ } public boolean drawGeneralLine(SunGraphics2D sg2d, - double x1, double y1, - double x2, double y2) + double ux1, double uy1, + double ux2, double uy2) { if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM || sg2d.strokeState == SunGraphics2D.STROKE_THINDASHED) @@ -194,13 +194,14 @@ double lw = bs.getLineWidth(); // Save the original dx, dy in case we need it to transform // the linewidth as a perpendicular vector below - double dx = x2 - x1; - double dy = y2 - y1; + double dx = ux2 - ux1; + double dy = uy2 - uy1; + double x1, y1, x2, y2; switch (sg2d.transformState) { case SunGraphics2D.TRANSFORM_GENERIC: case SunGraphics2D.TRANSFORM_TRANSLATESCALE: { - double coords[] = {x1, y1, x2, y2}; + double coords[] = {ux1, uy1, ux2, uy2}; sg2d.transform.transform(coords, 0, coords, 0, 2); x1 = coords[0]; y1 = coords[1]; @@ -213,13 +214,17 @@ { double tx = sg2d.transform.getTranslateX(); double ty = sg2d.transform.getTranslateY(); - x1 += tx; - y1 += ty; - x2 += tx; - y2 += ty; + x1 = ux1 + tx; + y1 = uy1 + ty; + x2 = ux2 + tx; + y2 = uy2 + ty; } break; case SunGraphics2D.TRANSFORM_ISIDENT: + x1 = ux1; + y1 = uy1; + x2 = ux2; + y2 = uy2; break; default: throw new InternalError("unknown TRANSFORM state..."); @@ -279,7 +284,8 @@ dx += udx; dy += udy; } - outrenderer.fillParallelogram(sg2d, px, py, -udy, udx, dx, dy); + outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2, + px, py, -udy, udx, dx, dy); return true; } @@ -313,7 +319,8 @@ px = newx; py = newy; } - outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2); + outrenderer.fillParallelogram(sg2d, rx, ry, rx+rw, ry+rh, + px, py, dx1, dy1, dx2, dy2); } public void drawRectangle(SunGraphics2D sg2d, @@ -360,10 +367,12 @@ // entire hole in the middle of the parallelogram // so we can just fill the outer parallelogram. fillOuterParallelogram(sg2d, + rx, ry, rx+rw, ry+rh, px, py, dx1, dy1, dx2, dy2, len1, len2, lw1, lw2); } else { outrenderer.drawParallelogram(sg2d, + rx, ry, rx+rw, ry+rh, px, py, dx1, dy1, dx2, dy2, lw1 / len1, lw2 / len2); } @@ -377,6 +386,8 @@ * and issues a single fillParallelogram request to fill it. */ public void fillOuterParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double px, double py, double dx1, double dy1, double dx2, double dy2, @@ -412,6 +423,7 @@ dx2 += udx2; dy2 += udy2; - outrenderer.fillParallelogram(sg2d, px, py, dx1, dy1, dx2, dy2); + outrenderer.fillParallelogram(sg2d, ux1, uy1, ux2, uy2, + px, py, dx1, dy1, dx2, dy2); } }
--- a/src/windows/classes/sun/java2d/d3d/D3DRenderer.java Tue May 10 15:59:01 2011 -0700 +++ b/src/windows/classes/sun/java2d/d3d/D3DRenderer.java Wed May 11 16:12:01 2011 -0700 @@ -102,15 +102,20 @@ final ParallelogramPipe realpipe = d3dr.getAAParallelogramPipe(); return new ParallelogramPipe() { public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) { GraphicsPrimitive.tracePrimitive("D3DFillAAParallelogram"); realpipe.fillParallelogram(sg2d, + ux1, uy1, ux2, uy2, x, y, dx1, dy1, dx2, dy2); } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, @@ -118,6 +123,7 @@ { GraphicsPrimitive.tracePrimitive("D3DDrawAAParallelogram"); realpipe.drawParallelogram(sg2d, + ux1, uy1, ux2, uy2, x, y, dx1, dy1, dx2, dy2, lw1, lw2); } @@ -167,21 +173,29 @@ d3dr.fillSpans(sg2d, si, transx, transy); } public void fillParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2) { GraphicsPrimitive.tracePrimitive("D3DFillParallelogram"); - d3dr.fillParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2); + d3dr.fillParallelogram(sg2d, + ux1, uy1, ux2, uy2, + x, y, dx1, dy1, dx2, dy2); } public void drawParallelogram(SunGraphics2D sg2d, + double ux1, double uy1, + double ux2, double uy2, double x, double y, double dx1, double dy1, double dx2, double dy2, double lw1, double lw2) { GraphicsPrimitive.tracePrimitive("D3DDrawParallelogram"); - d3dr.drawParallelogram(sg2d, x, y, dx1, dy1, dx2, dy2, lw1, lw2); + d3dr.drawParallelogram(sg2d, + ux1, uy1, ux2, uy2, + x, y, dx1, dy1, dx2, dy2, lw1, lw2); } public void copyArea(SunGraphics2D sg2d, int x, int y, int w, int h, int dx, int dy)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/awt/Paint/PgramUserBoundsTest.java Wed May 11 16:12:01 2011 -0700 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 7043054 + * @summary Verifies that Paint objects receive the appropriate user space + * bounds in their createContext() method + * @run main PgramUserBoundsTest + */ + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.PaintContext; +import java.awt.RenderingHints; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; + +public class PgramUserBoundsTest { + static final int MinX = 10; + static final int MinY = 20; + static final int MaxX = 30; + static final int MaxY = 50; + static AffineTransform identity = new AffineTransform(); + + public static void main(String argv[]) { + BufferedImage bimg = + new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = bimg.createGraphics(); + g2d.setPaint(new BoundsCheckerPaint(MinX, MinY, MaxX, MaxY)); + testAll(g2d); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + testAll(g2d); + } + + static void testAll(Graphics2D g2d) { + g2d.setTransform(identity); + g2d.translate(100, 100); + testPrimitives(g2d); + + g2d.setTransform(identity); + g2d.scale(10, 10); + testPrimitives(g2d); + + g2d.setTransform(identity); + g2d.rotate(Math.PI/6); + testPrimitives(g2d); + } + + static void testPrimitives(Graphics2D g2d) { + testLine(g2d); + testRect(g2d); + } + + static void testLine(Graphics2D g2d) { + testLine(g2d, MinX, MinY, MaxX, MaxY); + testLine(g2d, MaxX, MinY, MinX, MaxY); + testLine(g2d, MinX, MaxY, MaxX, MinY); + testLine(g2d, MaxX, MaxY, MinX, MinY); + } + + static void testRect(Graphics2D g2d) { + g2d.fillRect(MinX, MinY, MaxX - MinX, MaxY - MinY); + g2d.fill(new Rectangle(MinX, MinY, MaxX - MinX, MaxY - MinY)); + } + + static void testLine(Graphics2D g2d, int x1, int y1, int x2, int y2) { + g2d.drawLine(x1, y1, x2, y2); + g2d.draw(new Line2D.Double(x1, y1, x2, y2)); + } + + static class BoundsCheckerPaint implements Paint { + private Color c = Color.WHITE; + private Rectangle2D expectedBounds; + + public BoundsCheckerPaint(double x1, double y1, + double x2, double y2) + { + expectedBounds = new Rectangle2D.Double(); + expectedBounds.setFrameFromDiagonal(x1, y1, x2, y2); + } + + public int getTransparency() { + return c.getTransparency(); + } + + public PaintContext createContext(ColorModel cm, + Rectangle deviceBounds, + Rectangle2D userBounds, + AffineTransform xform, + RenderingHints hints) + { + System.out.println("user bounds = "+userBounds); + if (!userBounds.equals(expectedBounds)) { + throw new RuntimeException("bounds fail to match"); + } + return c.createContext(cm, deviceBounds, userBounds, xform, hints); + } + } +}