/*
* Copyright ( c ) 2006 , 2016 , 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
* @ key headful
* @ bug 6216010
* @ summary check to see that underline thickness scales .
* @ run main UnderlineTest
*/
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.util.HashMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class UnderlineTest {
static class FontsPanel extends Container {
FontsPanel(Font[] fonts) {
setLayout(new GridLayout(0 , 1 ));
for (int i = 0 ; i < fonts.length; ++i) {
add(new FontPanel(fonts[i]));
}
}
}
static String fps = "Stellar glyphs" ;
static Dimension fpd = new Dimension(600 , 120 );
static class FontPanel extends JComponent {
Font f;
FontPanel(Font f) {
this .f = f;
setPreferredSize(fpd);
setMinimumSize(fpd);
setMaximumSize(fpd);
setSize(fpd);
}
public void paintComponent(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0 , 0 , fpd.width, fpd.height);
g.setColor(Color.RED);
FontRenderContext frc = ((Graphics2D)g).getFontRenderContext();
LineMetrics lm = f.getLineMetrics(fps, frc);
int h = (int )(fpd.height - 20 - lm.getAscent());
g.drawLine(20 , h, fpd.width - 20 , h);
h = fpd.height - 20 ;
g.drawLine(20 , h, fpd.width - 20 , h);
h = (int )(fpd.height - 20 + lm.getDescent());
g.drawLine(20 , h, fpd.width - 20 , h);
g.setColor(Color.BLACK);
g.setFont(f);
g.drawString(fps, 50 , fpd.height - 20 );
}
}
public static void main(String args[]) {
String fontName = Font.DIALOG;
if (args.length > 0 ) {
fontName = args[0 ];
}
FontRenderContext frc = new FontRenderContext(null , false , false );
FontRenderContext frc2 = new FontRenderContext(AffineTransform.getScaleInstance(1 .5 , 1 .5 ), false , false );
Font font0 = new Font(fontName, 0 , 20 );
HashMap map = new HashMap();
map.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
map.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
Font font = font0.deriveFont(map);
System.out.println("Using font: " + font);
double rot = -Math.PI/4 ;
AffineTransform scrtx = AffineTransform.getRotateInstance(rot);
scrtx.scale(1 , 2 );
Font[] fonts = {
font.deriveFont(1 f),
font.deriveFont(20 f),
font.deriveFont(40 f),
font.deriveFont(80 f),
font.deriveFont(AffineTransform.getRotateInstance(rot)),
font.deriveFont(AffineTransform.getScaleInstance(1 , 2 )),
font.deriveFont(AffineTransform.getScaleInstance(2 , 4 )),
font.deriveFont(scrtx),
};
LineMetrics[] metrics = new LineMetrics[fonts.length * 2 ];
for (int i = 0 ; i < metrics.length; ++i) {
Font f = fonts[i % fonts.length];
FontRenderContext frcx = i < fonts.length ? frc : frc2;
metrics[i] = f.getLineMetrics("X" , frcx);
// dumpMetrics("Metrics for " + f.getSize2D() + " pt. font,\n tx: " +
// f.getTransform() + ",\n frctx: " + frcx.getTransform(), metrics[i]);
}
// test for linear scale
// this seems to work, might need to get fancy to deal with last-significant-bit issues?
double ds1 = metrics[2 ].getStrikethroughOffset() - metrics[1 ].getStrikethroughOffset();
double du1 = metrics[2 ].getUnderlineThickness() - metrics[1 ].getUnderlineThickness();
double ds2 = metrics[3 ].getStrikethroughOffset() - metrics[2 ].getStrikethroughOffset();
double du2 = metrics[3 ].getUnderlineThickness() - metrics[2 ].getUnderlineThickness();
if (ds2 != ds1 * 2 || du2 != du1 * 2 ) {
throw new IllegalStateException("non-linear scale: " + ds1 + " / " + ds2 + ", " +
du1 + " / " + du2);
}
JFrame jf = new JFrame("Fonts" );
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(new JScrollPane(new FontsPanel(fonts)));
jf.pack();
jf.setVisible(true );
}
static void dumpMetrics(String header, LineMetrics lm) {
if (header != null ) {
System.out.println(header);
}
System.out.println("asc: " + lm.getAscent());
System.out.println("dsc: " + lm.getDescent());
System.out.println("ulo: " + lm.getUnderlineOffset());
System.out.println("ult: " + lm.getUnderlineThickness());
System.out.println("sto: " + lm.getStrikethroughOffset());
System.out.println("stt: " + lm.getStrikethroughThickness());
}
}
Messung V0.5 in Prozent C=92 H=95 G=93
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland