1 /* 2 * Copyright (c) 2006, 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 /** 26 * @test 27 * @key headful 28 * @bug 6216010 29 * @summary check to see that underline thickness scales. 30 * @run main UnderlineTest 31 */ 32 33 import java.awt.Color; 34 import java.awt.Container; 35 import java.awt.Dimension; 36 import java.awt.Font; 37 import java.awt.Graphics; 38 import java.awt.Graphics2D; 39 import java.awt.GridLayout; 40 import java.awt.font.FontRenderContext; 41 import java.awt.font.LineMetrics; 42 import java.awt.font.TextAttribute; 43 import java.awt.font.TextLayout; 44 import java.awt.geom.AffineTransform; 45 import java.util.HashMap; 46 import javax.swing.JComponent; 47 import javax.swing.JFrame; 48 import javax.swing.JScrollPane; 49 50 public class UnderlineTest { 51 static class FontsPanel extends Container { FontsPanel(Font[] fonts)52 FontsPanel(Font[] fonts) { 53 setLayout(new GridLayout(0, 1)); 54 for (int i = 0; i < fonts.length; ++i) { 55 add(new FontPanel(fonts[i])); 56 } 57 } 58 } 59 60 static String fps = "Stellar glyphs"; 61 static Dimension fpd = new Dimension(600, 120); 62 static class FontPanel extends JComponent { 63 Font f; FontPanel(Font f)64 FontPanel(Font f) { 65 this.f = f; 66 setPreferredSize(fpd); 67 setMinimumSize(fpd); 68 setMaximumSize(fpd); 69 setSize(fpd); 70 } 71 paintComponent(Graphics g)72 public void paintComponent(Graphics g) { 73 g.setColor(Color.WHITE); 74 g.fillRect(0, 0, fpd.width, fpd.height); 75 76 g.setColor(Color.RED); 77 FontRenderContext frc = ((Graphics2D)g).getFontRenderContext(); 78 LineMetrics lm = f.getLineMetrics(fps, frc); 79 int h = (int)(fpd.height - 20 - lm.getAscent()); 80 g.drawLine(20, h, fpd.width - 20, h); 81 h = fpd.height - 20; 82 g.drawLine(20, h, fpd.width - 20, h); 83 h = (int)(fpd.height - 20 + lm.getDescent()); 84 g.drawLine(20, h, fpd.width - 20, h); 85 86 g.setColor(Color.BLACK); 87 g.setFont(f); 88 g.drawString(fps, 50, fpd.height - 20); 89 } 90 } 91 main(String args[])92 public static void main(String args[]) { 93 String fontName = Font.DIALOG; 94 if (args.length > 0) { 95 fontName = args[0]; 96 } 97 FontRenderContext frc = new FontRenderContext(null, false, false); 98 FontRenderContext frc2 = new FontRenderContext(AffineTransform.getScaleInstance(1.5, 1.5), false, false); 99 100 Font font0 = new Font(fontName, 0, 20); 101 HashMap map = new HashMap(); 102 map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); 103 map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON); 104 Font font = font0.deriveFont(map); 105 106 System.out.println("Using font: " + font); 107 108 double rot = -Math.PI/4; 109 AffineTransform scrtx = AffineTransform.getRotateInstance(rot); 110 scrtx.scale(1, 2); 111 112 Font[] fonts = { 113 font.deriveFont(1f), 114 font.deriveFont(20f), 115 font.deriveFont(40f), 116 font.deriveFont(80f), 117 font.deriveFont(AffineTransform.getRotateInstance(rot)), 118 font.deriveFont(AffineTransform.getScaleInstance(1, 2)), 119 font.deriveFont(AffineTransform.getScaleInstance(2, 4)), 120 font.deriveFont(scrtx), 121 }; 122 123 LineMetrics[] metrics = new LineMetrics[fonts.length * 2]; 124 for (int i = 0; i < metrics.length; ++i) { 125 Font f = fonts[i % fonts.length]; 126 FontRenderContext frcx = i < fonts.length ? frc : frc2; 127 metrics[i] = f.getLineMetrics("X", frcx); 128 // dumpMetrics("Metrics for " + f.getSize2D() + " pt. font,\n tx: " + 129 // f.getTransform() + ",\n frctx: " + frcx.getTransform(), metrics[i]); 130 } 131 132 // test for linear scale 133 // this seems to work, might need to get fancy to deal with last-significant-bit issues? 134 double ds1 = metrics[2].getStrikethroughOffset() - metrics[1].getStrikethroughOffset(); 135 double du1 = metrics[2].getUnderlineThickness() - metrics[1].getUnderlineThickness(); 136 double ds2 = metrics[3].getStrikethroughOffset() - metrics[2].getStrikethroughOffset(); 137 double du2 = metrics[3].getUnderlineThickness() - metrics[2].getUnderlineThickness(); 138 if (ds2 != ds1 * 2 || du2 != du1 * 2) { 139 throw new IllegalStateException("non-linear scale: " + ds1 + " / " + ds2 + ", " + 140 du1 + " / " + du2); 141 } 142 143 JFrame jf = new JFrame("Fonts"); 144 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 145 jf.add(new JScrollPane(new FontsPanel(fonts))); 146 jf.pack(); 147 jf.setVisible(true); 148 } 149 150 static void dumpMetrics(String header, LineMetrics lm) { 151 if (header != null) { 152 System.out.println(header); 153 } 154 System.out.println("asc: " + lm.getAscent()); 155 System.out.println("dsc: " + lm.getDescent()); 156 System.out.println("ulo: " + lm.getUnderlineOffset()); 157 System.out.println("ult: " + lm.getUnderlineThickness()); 158 System.out.println("sto: " + lm.getStrikethroughOffset()); 159 System.out.println("stt: " + lm.getStrikethroughThickness()); 160 } 161 } 162