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);

}

}

crwooda at 2007-7-28 15:53:49 > top of Java-index,Security,Cryptography...
# 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);

}

digiboy86a at 2007-7-28 15:53:49 > top of Java-index,Security,Cryptography...