Package stephencarmody.fonttexture

Source Code of stephencarmody.fonttexture.Texture$GlyphMetrics

package stephencarmody.fonttexture;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

public final class Texture extends JLabel {
   
  private final class GlyphMetrics {
   
      public float x, y, ascent, boundx, boundy, boundwidth, boundheight;
     
      /** Sets metrics */
      public void setMetrics(java.awt.font.GlyphMetrics gm) {
        Rectangle2D bounds = gm.getBounds2D();

        boundwidth = (float)(bounds.getWidth() + 2);
            boundheight = (float)(bounds.getHeight() + 2);

            // Check for start of new row
            if ((nextx + boundwidth) > image.getWidth()) {
                nexty += maxHeight;
                nextx = maxHeight = 0;
            }

          ascent = (float)-bounds.getY();
            x = nextx - (float)bounds.getX() + 1;
        y = nexty + ascent + 1;
        boundx = nextx;
        boundy = nexty;
         
            if (boundheight > maxHeight) {
                maxHeight = boundheight;
            }
           
          nextx += boundwidth;
      }
     
  }
 
    private static final long serialVersionUID = 0;
    // Array of characters to draw to texture
    private static char[] chars = "{|}$()[\\]j/@QABCDEFGHIJKLMNOPRSTUVWXYZ#%&0123456789bdfghiklpqy!?;tacemnorsuvwxz+:<>~',-.*^_`=\"".toCharArray();

    // Image of texture, graphics and fontrender contexts
    private BufferedImage image;
    private Graphics2D g;
    private FontRenderContext frc;
   
    // Array of metrics
    private GlyphMetrics[] metrics;
   
    // Calculated size of font
    private int size;
   
    // The Font used
    private Font font;
    private String name;
    private int style;

  // Layout variables
  private static float nextx, nexty, maxHeight;
   
    /** Creates a new instance of Texture */
    public Texture(int size) {
        // Create and initialise array of GlyphMetrics
        metrics = new GlyphMetrics[chars.length];
        for ( int i = 0; i < chars.length; i++ ) {
          metrics[i] = new GlyphMetrics();
        }
        setSize(size);
    }
   
    /**
     * Sets the size of the texture.
     *
     * size is rounded to the nearest value that meets the rule:
     *
     *     log(size) / log(2) = whole integer
     *
     * i.e. 2, 4, 8, 16, 32, 64, 128, 256, 512, etc...
     */
    public int setSize(int size) {
      double n = Math.log(size) / Math.log(2);
    size = (int) Math.pow(2, Math.round(n));
    if ( image != null && image.getWidth() == size ) return size;
    image = new BufferedImage(size, size, BufferedImage.TYPE_BYTE_BINARY);
    g = (Graphics2D) image.getGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        frc = g.getFontRenderContext();
        layoutGlyphs();
        return size;
    }
   
    /** Set the font. */
    public void setFont(String name, int style) {
      if ( this.name == name && this.style == style ) return;
        this.name = name;
        this.style = style;
        layoutGlyphs();
    }
   
    /**
     * Saves font texture to specified file.
     * 
     * @throws IOException
     */
    public void save(File file) throws IOException {
        // Write the texture to the specified file
        ImageIO.write(image, ImageFilter.getExtension(file), file);
       
        // Open a data output stream on the file to append metrics
        FileOutputStream fstream = new FileOutputStream(file, true);
        DataOutputStream out = new DataOutputStream(fstream);

        // Start with a marker so we can determine which PNG's are font textures
        out.writeBytes("FTX");
       
        // Write character|x|y|width|height|ascent for each glyph
        for ( int i = 0; i < chars.length; i++ ) {
            GlyphMetrics g = metrics[i];
            out.writeByte(chars[i]);
            out.writeInt(Math.round(g.boundx));
            out.writeInt(Math.round(g.boundy));
            out.writeByte(Math.round(g.boundwidth));
            out.writeByte(Math.round(g.boundheight));
            out.writeByte(Math.round(g.ascent));
        }
        // Close the stream
        out.close();
    }
   
    /** Layouts out glyphs on the texture. */
    private void layoutGlyphs() {
      if ( name == null ) return;
     
      GlyphVector glyphVector;
      java.awt.font.GlyphMetrics gm = null;
      int lowest = 1;
      int highest = 200;
      float overrun;
      int lastsize = 0;
     
        size = 100;
      
        // Binary search for optimal font size
        do {
          font = new Font(name, style, size);
          glyphVector = font.createGlyphVector(frc, chars);
            nextx = maxHeight = 0;
            nexty = 1;
          for (int i = 0; i < chars.length; i++) {
            gm = glyphVector.getGlyphMetrics(i);
              metrics[i].setMetrics(gm);
          }
          overrun = (metrics[chars.length-1].boundy + maxHeight) - image.getHeight();
          if ( overrun > 0 ) {
            lastsize = highest = size;
          } else {
            lastsize = lowest = size;
          }
        size = (lowest + highest) / 2;
        } while ( overrun > 0 || lastsize != size );

        // Clear image, set font and colour
        g.clearRect(0, 0, image.getWidth(), image.getHeight());
        g.setFont(font);
        g.setColor(Color.WHITE);

        // Draw each glyph to the texture
        for (int i = 0; i < chars.length; i++) {
          g.drawChars(chars, i, 1, (int)Math.ceil(metrics[i].x),
                    (int)Math.ceil(metrics[i].y));
        }
       
        setIcon(new ImageIcon(image));
    }
   
}
TOP

Related Classes of stephencarmody.fonttexture.Texture$GlyphMetrics

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.