Skip to content

Instantly share code, notes, and snippets.

@wchargin
Created March 8, 2016 20:04
Show Gist options
  • Save wchargin/84a2d1934324193b0c06 to your computer and use it in GitHub Desktop.
Save wchargin/84a2d1934324193b0c06 to your computer and use it in GitHub Desktop.
how do you *actually* find the ascent of a letter? not getAscent, that's for sure
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
class AscentNoLeadingTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
return g2d.getFontMetrics().getAscent()
- g2d.getFontMetrics().getLeading();
}
}
class AscentTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
return g2d.getFontMetrics().getAscent();
}
}
class GlyphTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
final GlyphVector gv = g2d.getFont()
.createGlyphVector(g2d.getFontRenderContext(), text);
return (int) gv.getVisualBounds().getHeight();
}
}
class HeightTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
return g2d.getFontMetrics().getHeight();
}
}
class LineTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
return (int) g2d.getFont()
.getLineMetrics(text, g2d.getFontRenderContext()).getHeight();
}
}
class PixelBoundsTextMeasurer implements TextMeasurer {
@Override
public int getHeight(Graphics2D g2d, String text) {
final GlyphVector gv = g2d.getFont()
.createGlyphVector(g2d.getFontRenderContext(), text);
return -gv.getPixelBounds(g2d.getFontRenderContext(), 0, 0).y;
}
}
public class TextFixture extends JFrame {
private static class TextMeasurerView extends JComponent {
private final TextMeasurer measurer;
{
setPreferredSize(new Dimension(40, 60));
}
public TextMeasurerView(TextMeasurer measurer) {
super();
this.measurer = measurer;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 36));
final String text = "J";
final int height = measurer.getHeight(g2d, text);
final int width = g2d.getFontMetrics().stringWidth(text);
final int cx = (getWidth() - width) / 2;
final int cy = getHeight() * 4 / 5;
final Rectangle2D bounds = new Rectangle2D.Double(cx, cy - height,
width, height);
g2d.setColor(Color.BLUE);
g2d.draw(bounds);
g2d.setColor(Color.BLACK);
g2d.drawString(text, cx, cy);
}
}
public static List<TextMeasurer> measurers = Arrays.asList(
new HeightTextMeasurer(), new LineTextMeasurer(),
new AscentTextMeasurer(), new AscentNoLeadingTextMeasurer(),
new GlyphTextMeasurer(), new PixelBoundsTextMeasurer());
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
final TextFixture tf = new TextFixture();
tf.pack();
tf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tf.setLocationRelativeTo(null);
tf.setVisible(true);
});
}
public TextFixture() {
super("Text Fixture");
setLayout(new FlowLayout());
for (TextMeasurer measurer : measurers) {
add(new TextMeasurerView(measurer));
}
}
}
interface TextMeasurer {
public int getHeight(Graphics2D g2d, String text);
}
@wchargin
Copy link
Author

wchargin commented Mar 8, 2016

result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment