drawing a font on an offscreen image
I'm trying to draw a font on my own offscreen image but I had to implement a few tweaks to get it to work and I would like to know how to do it properly. Here's my code:
privateint[] getPrintMetrics(Font fnt, String txt){
BufferedImage bi =new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D bg = (Graphics2D)bi.getGraphics();
FontRenderContext frc = bg.getFontRenderContext();
TextLayout tl =new TextLayout(txt, fnt, frc);
int ret[] =newint[2];
ret[0] = (int)tl.getBounds().getWidth();
ret[1] = (int)(tl.getBounds().getHeight() * 1.5);
//ret[0] = (int)tl.getPixelBounds(frc, 0, 0).getWidth();
//ret[1] = (int)(tl.getPixelBounds(frc, 0, 0).getHeight() * 1.5);
//BUG! WHY IS HEIGHT TOO SMALL? I HAVE TO ADD 50%
return ret;
}
publicvoid print(Font fnt,int x,int y, String txt,int clr){
int size[] = getPrintMetrics(fnt, txt);
BufferedImage bi =new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB);
Graphics2D bg = (Graphics2D)bi.getGraphics();
FontRenderContext frc = bg.getFontRenderContext();
TextLayout tl =new TextLayout(txt, fnt, frc);
/*
//this method draws the outline only
Shape shape = tl.getOutline(AffineTransform.getTranslateInstance(0, tl.getBounds().getHeight()));
bg.setColor(new Color(clr));
bg.draw(shape);
*/
bg.setColor(new Color(clr));
bg.setFont(fnt);
bg.drawString(txt, 0, -1 * tl.getBaselineOffsets()[tl.getBaseline()+2]);//BUG! HOW DO I KNOW WHICH BASELINE TO USE?
putPixels(bi.getRGB(0,0,size[0],size[1],null,0,size[0]), x, y, size[0], size[1], 0);
}
putPixels() is my own member that will draw to my own image buffer.
1) Why must I multiply the height by 1.5 in the getPrintMetrics() ?
2) How do I know which baseline to use (I just hacked it).
Thanks.
[2815 byte] By [
digiboy86a] at [2007-11-27 10:17:48]

# 1
Why is the height so small?
new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
The graphics context for this BufferedImage is very small.
For more size increase the width and height dimensions.
Try this.
import java.awt.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class GraphicsExercise {
private JLabel getContent() {
BufferedImage image = createImage();
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setPaint(Color.blue);
Font font = new Font("dialog", Font.PLAIN, 36);
g2.setFont(font);
FontRenderContext frc = g2.getFontRenderContext();
String s = "Hello World";
LineMetrics metrics = font.getLineMetrics(s, frc);
float height = metrics.getAscent() + metrics.getDescent();
float width = (float)font.getStringBounds(s, frc).getWidth();
float x = (image.getWidth() - width)/2f;
float y = (image.getHeight() + height)/2 - metrics.getDescent();
g2.drawString(s, x, y);
g2.dispose();
return new JLabel(new ImageIcon(image), JLabel.CENTER);
}
private BufferedImage createImage() {
int w = 240;
int h = 165;
int type = BufferedImage.TYPE_INT_RGB;
BufferedImage image = new BufferedImage(w, h, type);
Graphics2D g2 = image.createGraphics();
g2.setBackground(UIManager.getColor("Panel.background"));
g2.clearRect(0,0,w,h);
g2.dispose();
return image;
}
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new GraphicsExercise().getContent());
f.pack();
f.setLocation(200,200);
f.setVisible(true);
}
}
# 2
Thanks for the code, I think I understand the metrics stuff. Here is my updated source that works now.
private int[] getPrintMetrics(Font fnt, String txt) {
BufferedImage bi = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D bg = (Graphics2D)bi.getGraphics();
FontRenderContext frc = bg.getFontRenderContext();
TextLayout tl = new TextLayout(txt, fnt, frc);
int ret[] = new int[2];
ret[0] = (int)tl.getBounds().getWidth();
ret[1] = (int)(tl.getAscent() + tl.getDescent());
return ret;
}
public void print(Font fnt, int x, int y, String txt, int clr) {
int size[] = getPrintMetrics(fnt, txt);
BufferedImage bi = new BufferedImage(size[0], size[1], BufferedImage.TYPE_INT_RGB);
Graphics2D bg = (Graphics2D)bi.getGraphics();
FontRenderContext frc = bg.getFontRenderContext();
TextLayout tl = new TextLayout(txt, fnt, frc);
/*
//this method draws the outline only
Shape shape = tl.getOutline(AffineTransform.getTranslateInstance(0, tl.getBounds().getHeight()));
bg.setColor(new Color(clr));
bg.draw(shape);
*/
bg.setColor(new Color(clr));
bg.setFont(fnt);
bg.drawString(txt, 0, size[1] - tl.getDescent());
//bg.setColor(Color.BLUE); bg.drawRect(0,0,size[0]-1,size[1]-1); //TEST
putPixelsKeyClr(bi.getRGB(0,0,size[0],size[1],null,0,size[0]), x, y, size[0], size[1], 0, 0x000000);
}