bug4337267.java revision 9330:8b1f1c2a400f
13125Sdg/* 23125Sdg * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. 33125Sdg * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43125Sdg * 53125Sdg * This code is free software; you can redistribute it and/or modify it 63125Sdg * under the terms of the GNU General Public License version 2 only, as 73125Sdg * published by the Free Software Foundation. 83125Sdg * 93125Sdg * This code is distributed in the hope that it will be useful, but WITHOUT 103125Sdg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 113125Sdg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 123125Sdg * version 2 for more details (a copy is included in the LICENSE file that 133125Sdg * accompanied this code). 143125Sdg * 153125Sdg * You should have received a copy of the GNU General Public License version 163125Sdg * 2 along with this work; if not, write to the Free Software Foundation, 173125Sdg * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 183125Sdg * 193125Sdg * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 203125Sdg * or visit www.oracle.com if you need additional information or have any 213125Sdg * questions. 223125Sdg */ 233125Sdg 243125Sdg/* 253125Sdg * @test 263125Sdg * @bug 4337267 273125Sdg * @summary test that numeric shaping works in Swing components 283125Sdg * @author Sergey Groznyh 293125Sdg * @run main bug4337267 3050479Speter */ 313125Sdg 323125Sdgimport java.awt.Component; 333125Sdgimport java.awt.Dimension; 343125Sdgimport java.awt.Graphics; 353125Sdgimport java.awt.font.NumericShaper; 363125Sdgimport java.awt.font.TextAttribute; 373125Sdgimport java.awt.image.BufferedImage; 383125Sdgimport javax.swing.BoxLayout; 393125Sdgimport javax.swing.JComponent; 403125Sdgimport javax.swing.JFrame; 413125Sdgimport javax.swing.JLabel; 423125Sdgimport javax.swing.JPanel; 433125Sdgimport javax.swing.JTextArea; 443125Sdgimport javax.swing.SwingUtilities; 453125Sdg 463125Sdgpublic class bug4337267 { 473125Sdg TestJPanel p1, p2; 483125Sdg TestBufferedImage i1, i2; 493125Sdg JComponent[] printq; 503125Sdg JFrame window; 513125Sdg static boolean testFailed = false; 523125Sdg static boolean done = false; 533125Sdg 543125Sdg String shaped = 553125Sdg "000 (E) 111 (A) \u0641\u0642\u0643 \u0662\u0662\u0662 (E) 333"; 563125Sdg String text = "000 (E) 111 (A) \u0641\u0642\u0643 222 (E) 333"; 573125Sdg 583125Sdg void run() { 593125Sdg initUI(); 603125Sdg testTextComponent(); 613125Sdg testNonTextComponentHTML(); 623125Sdg testNonTextComponentPlain(); 6399829Salfred 643125Sdg doneTask(); 653125Sdg } 6699829Salfred 6799829Salfred void initUI() { 6899829Salfred window = new JFrame("bug4337267"); 6999829Salfred window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 7099829Salfred window.setSize(800, 600); 713125Sdg Component content = createContentPane(); 723125Sdg window.add(content); 7399829Salfred window.setVisible(true); 7499829Salfred } 7599829Salfred 7699829Salfred Runnable printComponents = new Runnable() { 7799829Salfred public void run() { 783125Sdg printComponent(printq[0], i1); 793125Sdg printComponent(printq[1], i2); 803125Sdg } 813125Sdg }; 823125Sdg 8399829Salfred Runnable compareRasters = new Runnable() { 843125Sdg public void run() { 853125Sdg assertEquals(p1.image, p2.image); 863125Sdg assertEquals(i1, i2); 873125Sdg } 883125Sdg }; 893125Sdg 903125Sdg void doneTask() { 913125Sdg final Object monitor = this; 923125Sdg SwingUtilities.invokeLater(new Runnable() { 933125Sdg public void run() { 943125Sdg done = true; 953125Sdg synchronized(monitor) { 963125Sdg monitor.notify(); 973125Sdg } 98 } 99 }); 100 } 101 102 103 void fail(String message) { 104 testFailed = true; 105 throw new RuntimeException(message); 106 } 107 108 void assertEquals(Object o1, Object o2) { 109 if ((o1 == null) && (o2 != null)) { 110 fail("Expected null, got " + o2); 111 } else if ((o1 != null) && (o2 == null)) { 112 fail("Expected " + o1 + ", got null"); 113 } else if (!o1.equals(o2)) { 114 fail("Expected " + o1 + ", got " + o2); 115 } 116 } 117 118 void testTextComponent() { 119 System.out.println("testTextComponent:"); 120 JTextArea area1 = new JTextArea(); 121 injectComponent(p1, area1, false); 122 area1.setText(shaped); 123 JTextArea area2 = new JTextArea(); 124 injectComponent(p2, area2, true); 125 area2.setText(text); 126 window.repaint(); 127 printq = new JComponent[] { area1, area2 }; 128 SwingUtilities.invokeLater(printComponents); 129 SwingUtilities.invokeLater(compareRasters); 130 } 131 132 void testNonTextComponentHTML() { 133 System.out.println("testNonTextComponentHTML:"); 134 JLabel label1 = new JLabel(); 135 injectComponent(p1, label1, false); 136 label1.setText("<html>" + shaped); 137 JLabel label2 = new JLabel(); 138 injectComponent(p2, label2, true); 139 label2.setText("<html>" + text); 140 window.repaint(); 141 printq = new JComponent[] { label1, label2 }; 142 SwingUtilities.invokeLater(printComponents); 143 SwingUtilities.invokeLater(compareRasters); 144 } 145 146 void testNonTextComponentPlain() { 147 System.out.println("testNonTextComponentHTML:"); 148 JLabel label1 = new JLabel(); 149 injectComponent(p1, label1, false); 150 label1.setText(shaped); 151 JLabel label2 = new JLabel(); 152 injectComponent(p2, label2, true); 153 label2.setText(text); 154 window.repaint(); 155 printq = new JComponent[] { label1, label2 }; 156 SwingUtilities.invokeLater(printComponents); 157 SwingUtilities.invokeLater(compareRasters); 158 } 159 160 void setShaping(JComponent c) { 161 c.putClientProperty(TextAttribute.NUMERIC_SHAPING, 162 NumericShaper.getContextualShaper(NumericShaper.ARABIC)); 163 } 164 165 void injectComponent(JComponent p, JComponent c, boolean shape) { 166 if (shape) { 167 setShaping(c); 168 } 169 p.removeAll(); 170 p.add(c); 171 } 172 173 void printComponent(JComponent c, TestBufferedImage i) { 174 Graphics g = i.getGraphics(); 175 g.setColor(c.getBackground()); 176 g.fillRect(0, 0, i.getWidth(), i.getHeight()); 177 c.print(g); 178 } 179 180 Component createContentPane() { 181 Dimension size = new Dimension(500, 100); 182 i1 = new TestBufferedImage(size.width, size.height, 183 BufferedImage.TYPE_INT_ARGB); 184 i2 = new TestBufferedImage(size.width, size.height, 185 BufferedImage.TYPE_INT_ARGB); 186 p1 = new TestJPanel(); 187 p1.setPreferredSize(size); 188 p2 = new TestJPanel(); 189 p2.setPreferredSize(size); 190 JPanel panel = new JPanel(); 191 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 192 panel.add(p1); 193 panel.add(p2); 194 195 return panel; 196 } 197 198 static class TestBufferedImage extends BufferedImage { 199 int MAX_GLITCHES = 0; 200 201 TestBufferedImage(int width, int height, int imageType) { 202 super(width, height, imageType); 203 } 204 205 @Override 206 public boolean equals(Object other) { 207 if (! (other instanceof TestBufferedImage)) { 208 return false; 209 } 210 TestBufferedImage image2 = (TestBufferedImage) other; 211 int width = getWidth(); 212 int height = getHeight(); 213 if ((image2.getWidth() != width) || (image2.getHeight() != height)) { 214 return false; 215 } 216 int glitches = 0; 217 for (int x = 0; x < width; x++) { 218 for (int y = 0; y < height; y++) { 219 int rgb1 = getRGB(x, y); 220 int rgb2 = image2.getRGB(x, y); 221 if (rgb1 != rgb2) { 222 //System.out.println(x+" "+y+" "+rgb1+" "+rgb2); 223 glitches++; 224 } 225 } 226 } 227 return glitches <= MAX_GLITCHES; 228 } 229 } 230 231 static class TestJPanel extends JPanel { 232 TestBufferedImage image = createImage(new Dimension(1, 1)); 233 234 TestBufferedImage createImage(Dimension d) { 235 return new TestBufferedImage(d.width, d.height, 236 BufferedImage.TYPE_INT_ARGB); 237 } 238 239 public void setPreferredSize(Dimension size) { 240 super.setPreferredSize(size); 241 image = createImage(size); 242 } 243 244 public void paint(Graphics g) { 245 Graphics g0 = image.getGraphics(); 246 super.paint(g0); 247 g.drawImage(image, 0, 0, this); 248 } 249 } 250 251 252 253 public static void main(String[] args) throws Throwable { 254 final bug4337267 test = new bug4337267(); 255 SwingUtilities.invokeLater(new Runnable() { 256 public void run() { 257 test.run(); 258 } 259 }); 260 261 synchronized(test) { 262 while (!done) { 263 try { 264 test.wait(); 265 } catch (InterruptedException ex) { 266 // do nothing 267 } 268 } 269 } 270 271 if (testFailed) { 272 throw new RuntimeException("FAIL"); 273 } 274 275 System.out.println("OK"); 276 } 277} 278