TransformedPaintTest.java revision 14851:980da45565c8
1/*
2 * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @key headful
27 * @bug 6689025 8023483
28 * @summary Tests that transformed Paints are rendered correctly
29 * @author Dmitri.Trembovetski@sun.com: area=Graphics
30 * @run main/othervm TransformedPaintTest
31 * @run main/othervm -Dsun.java2d.opengl=True TransformedPaintTest
32 */
33
34import java.awt.Color;
35import java.awt.Dimension;
36import java.awt.EventQueue;
37import java.awt.GradientPaint;
38import java.awt.Graphics;
39import java.awt.Graphics2D;
40import java.awt.GraphicsConfiguration;
41import java.awt.GraphicsEnvironment;
42import java.awt.LinearGradientPaint;
43import java.awt.MultipleGradientPaint.CycleMethod;
44import java.awt.Paint;
45import java.awt.RadialGradientPaint;
46import java.awt.TexturePaint;
47import java.awt.geom.Rectangle2D;
48import java.awt.image.BufferedImage;
49import java.awt.image.VolatileImage;
50import java.io.File;
51import java.io.IOException;
52import java.lang.reflect.InvocationTargetException;
53import javax.imageio.ImageIO;
54import javax.swing.JFrame;
55import javax.swing.JPanel;
56
57public class TransformedPaintTest {
58
59    private static enum PaintType {
60        COLOR,
61        GRADIENT,
62        LINEAR_GRADIENT,
63        RADIAL_GRADIENT,
64        TEXTURE
65    };
66
67    private static final int CELL_SIZE = 100;
68    private static final int R_WIDTH = 3 * CELL_SIZE;
69    private static final int R_HEIGHT = PaintType.values().length * CELL_SIZE;
70
71    private Paint createPaint(PaintType type, int startx, int starty,
72                              int w, int h)
73    {
74        // make sure that the blue color doesn't show up when filling a
75        // w by h rect
76        w++; h++;
77
78        int endx = startx + w;
79        int endy = starty + h;
80        Rectangle2D.Float r = new Rectangle2D.Float(startx, starty, w, h);
81        switch (type) {
82            case COLOR: return Color.red;
83            case GRADIENT: return
84                new GradientPaint(startx, starty, Color.red,
85                                  endx, endy, Color.green);
86            case LINEAR_GRADIENT: return
87                new LinearGradientPaint(startx, starty, endx, endy,
88                    new float[] { 0.0f, 0.999f, 1.0f },
89                    new Color[] { Color.red, Color.green, Color.blue });
90            case RADIAL_GRADIENT: return
91                new RadialGradientPaint(startx, starty,
92                    (float)Math.sqrt(w * w + h * h),
93                    new float[] { 0.0f, 0.999f, 1.0f },
94                    new Color[] { Color.red, Color.green, Color.blue },
95                    CycleMethod.NO_CYCLE);
96            case TEXTURE: {
97                BufferedImage bi =
98                    new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
99                Graphics2D g = (Graphics2D) bi.getGraphics();
100                g.setPaint(createPaint(PaintType.LINEAR_GRADIENT, 0, 0, w, h));
101                g.fillRect(0, 0, w, h);
102                return new TexturePaint(bi, r);
103            }
104        }
105        return Color.green;
106    }
107
108    private void renderLine(PaintType type, Graphics2D g,
109                            int startx, int starty, int w, int h)
110    {
111        Paint p = createPaint(type, startx, starty, w, h);
112        g.setPaint(p);
113
114        // first, no transform
115        g.fillRect(startx, starty, w, h);
116
117        // translation only
118        g.translate(w, 0);
119        g.fillRect(startx, starty, w, h);
120        g.translate(-w, 0);
121
122        // complex transform
123        g.translate(startx + w*2, starty);
124        g.rotate(Math.toRadians(90), w/2, h/2);
125        g.translate(-startx, -starty);
126        g.fillRect(startx, starty, w, h);
127    }
128
129    private void render(Graphics2D g, int w, int h) {
130        int paintTypes = PaintType.values().length;
131        int ystep = h / paintTypes;
132        int y = 0;
133
134        for (PaintType type : PaintType.values()) {
135            renderLine(type, (Graphics2D)g.create(),
136                       0, y, h / paintTypes, h / paintTypes);
137            y += ystep;
138        }
139    }
140
141    private void checkBI(BufferedImage bi) {
142        for (int y = 0; y < bi.getHeight(); y++) {
143            for (int x = 0; x < bi.getWidth(); x++) {
144                if (bi.getRGB(x, y) == Color.blue.getRGB()) {
145                    try {
146                        String fileName = "TransformedPaintTest_res.png";
147                        ImageIO.write(bi, "png", new File(fileName));
148                        System.err.println("Dumped image to: " + fileName);
149                    } catch (IOException ex) {}
150                    throw new RuntimeException("Test failed, blue color found");
151                }
152            }
153        }
154    }
155
156    private void runTest() {
157        GraphicsConfiguration gc = GraphicsEnvironment.
158            getLocalGraphicsEnvironment().getDefaultScreenDevice().
159                getDefaultConfiguration();
160
161        if (gc.getColorModel().getPixelSize() < 16) {
162            System.out.println("8-bit desktop depth found, test passed");
163            return;
164        }
165
166        VolatileImage vi = gc.createCompatibleVolatileImage(R_WIDTH, R_HEIGHT);
167        BufferedImage bi = null;
168        do {
169            vi.validate(gc);
170            Graphics2D g = vi.createGraphics();
171            render(g, vi.getWidth(), vi.getHeight());
172            bi = vi.getSnapshot();
173        } while (vi.contentsLost());
174
175        checkBI(bi);
176        System.out.println("Test PASSED.");
177    }
178
179    private static void showFrame(final TransformedPaintTest t) {
180        JFrame f = new JFrame("TransformedPaintTest");
181        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
182        final BufferedImage bi =
183            new BufferedImage(R_WIDTH, R_HEIGHT, BufferedImage.TYPE_INT_RGB);
184        JPanel p = new JPanel() {
185            @Override
186            protected void paintComponent(Graphics g) {
187                super.paintComponent(g);
188                Graphics2D g2d = (Graphics2D) g;
189                t.render(g2d, R_WIDTH, R_HEIGHT);
190                t.render(bi.createGraphics(), R_WIDTH, R_HEIGHT);
191                g2d.drawImage(bi, R_WIDTH + 5, 0, null);
192
193                g.setColor(Color.black);
194                g.drawString("Rendered to Back Buffer", 10, 20);
195                g.drawString("Rendered to BufferedImage", R_WIDTH + 15, 20);
196            }
197        };
198        p.setPreferredSize(new Dimension(2 * R_WIDTH + 5, R_HEIGHT));
199        f.add(p);
200        f.pack();
201        f.setVisible(true);
202    }
203
204    public static void main(String[] args) throws
205        InterruptedException, InvocationTargetException
206    {
207        boolean show = (args.length > 0 && "-show".equals(args[0]));
208
209        final TransformedPaintTest t = new TransformedPaintTest();
210        if (show) {
211            EventQueue.invokeAndWait(new Runnable() {
212                public void run() {
213                    showFrame(t);
214                }
215            });
216        } else {
217            t.runTest();
218        }
219    }
220}
221