tags:

views:

65

answers:

4

Exposition:

I'm writting an OpenGL app in Java via JOGL. The built in fonts with GLUT are very basic. I want to be able to take a Java Font, render all the characters in it to a 2D array of bytes (a greyscale image representing the characters), which I can then load as a texture in OpenGL.

Problem:

I can load the textures in OpenGL; I can use JOGL. My only problem is going from the "Font java cn read" --> "2D greyscale image of all the characters step". What functions / libraries should I be using?

A: 

Possible I'm missing something, but can java.awt not do most of this for you?

  • create a new BufferedImage
  • get its Graphics2D (image.getGraphics)
  • paint the text to the image
  • get the Raster (getData) from the buffered image.
  • dispose of the Graphics2D context when done.
William Billingsley
+1  A: 

I'm not sure I quite understand what you're looking for. I think what you want is some code that will generate grayscale bitmap images of a given size for every glyph in a font.

There isn't a way (that I am aware of anyway) to get all the glyphs a font supports (oddly, you can get the number of glyphs... so yeah, I may just be missing something, bah). However, you can get glyph metrics for given characters quite easily.

Something along these lines should work for you.

HashMap<int[], Rectangle2D> generateGlyphs(int fontSize, String characters, Font font){
  HashMap<int[], Rectangle2D> ret = new HashMap<int[], Rectangle>();
  FontRenderContext rendCont = new FontRenderContext(null, true, true);

  for(int i = 0; i < characters.length; i++){
    Rectangle2D bounds = font.getStringBounds(characters.substring(i, 1), rendCont);
    BufferedImage bi = new BufferedImage((int)bounds.getWidth(), (int)bounds.getHeight(), BufferedImage.TYPE_INT_GRAY);

    Graphics g = bi.getGraphcs();
    g.setFont(font);
    g.drawString(characters.substring(i, 1), 0, (int)bounds.getHeight());

   ret.put(bi.getData().getPixels(0, 0, (int)bounds.getWidth(), (int)bounds.getHeight()), bounds);
  }

  return ret;
}

Note that I'm clipping rather than rounding in some places, which could potentially be an issue.

Kevin Montrose
As `getGraphcs()` returns a `Graphics2D`, it's convenient to use rendering hits, e.g. `setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)`
trashgod
True, though my example is getting close to illegible as is.
Kevin Montrose
A: 

It's not infallible, but you can use the canDisplay() method to determine if a particular Font can display a certain glyph. This simple game uses the method to construct sets of glyphs.

trashgod
A: 

Processing can render fonts in OpenGL, and it uses it's own in house open source class PFont to "generate grayscale bitmap images of a given size for every glyph in a font," as Kevin put it. I recommend you look at the source, which is here.

Peter Nore