# HG changeset patch # User ceisserer # Date 1475261130 25200 # Node ID d9b9053b5c5d65d82b3ee109f6b62398492e60de # Parent 0d3b7bc68b7d2c65e9fef7facfac02b05912d516 8162591: All existing gradient paint implementations have issues with coordinates/sizes larger than Short.MAX_VALUE (exactly) on any Linux systems Reviewed-by: flar, serb, prr diff -r 0d3b7bc68b7d -r d9b9053b5c5d jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java --- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java Fri Sep 30 09:28:18 2016 -0700 +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPaints.java Fri Sep 30 11:45:30 2016 -0700 @@ -95,15 +95,15 @@ private XRGradient() { } - /** - * There are no restrictions for accelerating GradientPaint, so this - * method always returns true. - */ @Override boolean isPaintValid(SunGraphics2D sg2d) { - return true; + GradientPaint paint = (GradientPaint) sg2d.paint; + + return XRUtils.isPointCoordInShortRange(paint.getPoint1()) + && XRUtils.isPointCoordInShortRange(paint.getPoint2()); } + @Override void setXRPaint(SunGraphics2D sg2d, Paint pt) { GradientPaint paint = (GradientPaint) pt; @@ -130,24 +130,27 @@ @Override boolean isPaintValid(SunGraphics2D sg2d) { - return ((LinearGradientPaint) sg2d.getPaint()).getColorSpace() == ColorSpaceType.SRGB; + LinearGradientPaint paint = (LinearGradientPaint) sg2d.getPaint(); + + return paint.getColorSpace() == ColorSpaceType.SRGB + && XRUtils.isPointCoordInShortRange(paint.getStartPoint()) + && XRUtils.isPointCoordInShortRange(paint.getEndPoint()) + && paint.getTransform().getDeterminant() != 0.0; } @Override void setXRPaint(SunGraphics2D sg2d, Paint pt) { LinearGradientPaint paint = (LinearGradientPaint) pt; - Color[] colors = paint.getColors(); Point2D pt1 = paint.getStartPoint(); Point2D pt2 = paint.getEndPoint(); - int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); float[] fractions = paint.getFractions(); int[] pixels = convertToIntArgbPixels(colors); + AffineTransform at = paint.getTransform(); - AffineTransform at = paint.getTransform(); try { - at.invert(); + at.invert(); } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); } @@ -165,8 +168,12 @@ @Override boolean isPaintValid(SunGraphics2D sg2d) { RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint; - return grad.getFocusPoint().equals(grad.getCenterPoint()) - && grad.getColorSpace() == ColorSpaceType.SRGB; + + return grad.getColorSpace() == ColorSpaceType.SRGB + && grad.getFocusPoint().equals(grad.getCenterPoint()) + && XRUtils.isPointCoordInShortRange(grad.getCenterPoint()) + && grad.getRadius() <= Short.MAX_VALUE + && grad.getTransform().getDeterminant() != 0.0; } @Override @@ -174,18 +181,17 @@ RadialGradientPaint paint = (RadialGradientPaint) pt; Color[] colors = paint.getColors(); Point2D center = paint.getCenterPoint(); + float cx = (float) center.getX(); + float cy = (float) center.getY(); + AffineTransform at = paint.getTransform(); int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); float[] fractions = paint.getFractions(); int[] pixels = convertToIntArgbPixels(colors); float radius = paint.getRadius(); - float cx = (float) center.getX(); - float cy = (float) center.getY(); - - AffineTransform at = paint.getTransform(); try { - at.invert(); + at.invert(); } catch (NoninvertibleTransformException ex) { ex.printStackTrace(); } diff -r 0d3b7bc68b7d -r d9b9053b5c5d jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java --- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java Fri Sep 30 09:28:18 2016 -0700 +++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRUtils.java Fri Sep 30 11:45:30 2016 -0700 @@ -26,6 +26,7 @@ package sun.java2d.xr; import java.awt.*; +import java.awt.geom.Point2D; import java.awt.MultipleGradientPaint.*; import java.awt.geom.AffineTransform; import java.awt.image.*; @@ -260,6 +261,15 @@ return (x > 65535 ? 65535 : (x < 0) ? 0 : x); } + public static boolean isDoubleInShortRange(double dbl) { + return dbl <= Short.MAX_VALUE && dbl >= Short.MIN_VALUE; + } + + public static boolean isPointCoordInShortRange(Point2D p) { + return isDoubleInShortRange(p.getX()) && isDoubleInShortRange(p.getY()); + } + + public static boolean isTransformQuadrantRotated(AffineTransform tr) { return ((tr.getType() & (AffineTransform.TYPE_GENERAL_ROTATION | AffineTransform.TYPE_GENERAL_TRANSFORM)) == 0); diff -r 0d3b7bc68b7d -r d9b9053b5c5d jdk/test/sun/java2d/xrender/HugeGradientTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/java2d/xrender/HugeGradientTest.java Fri Sep 30 11:45:30 2016 -0700 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.awt.*; +import java.awt.image.*; +import javax.swing.*; + +/** + * @test + * @bug 8162591 + * @summary tests gradients with start/endpoints exceeding Short.MAX coordinates + * @author ceisserer + */ +public class HugeGradientTest extends Frame { + public static volatile boolean success = false; + + public HugeGradientTest() { + Image dstImg = getGraphicsConfiguration() + .createCompatibleVolatileImage(30, 30); + Graphics2D g = (Graphics2D) dstImg.getGraphics(); + + g.setPaint(new LinearGradientPaint(0f, Short.MAX_VALUE, 0f, Short.MAX_VALUE +31, + new float[]{0f, 1f}, new Color[]{Color.BLACK, Color.RED})); + g.translate(0, -Short.MAX_VALUE); + g.fillRect (0, 0, Short.MAX_VALUE*2 , Short.MAX_VALUE*2); + + BufferedImage readBackImg = new BufferedImage(dstImg.getWidth(null), + dstImg.getHeight(null), BufferedImage.TYPE_INT_RGB); + readBackImg.getGraphics().drawImage(dstImg, 0, 0, null); + + for (int x = 0; x < readBackImg.getWidth(); x++) { + for (int y = 0; y < readBackImg.getHeight(); y++) { + int redVal = (readBackImg.getRGB(x, y) & 0x00FF0000) >> 16; + + if (redVal > 127) { + return; + } + } + } + + throw new RuntimeException("Test Failed"); + } + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new HugeGradientTest(); + } + }); + } +}