package electrosphere.renderer.ui.font; import electrosphere.renderer.Material; import electrosphere.renderer.texture.Texture; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.awt.RenderingHints; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.util.LinkedList; import java.util.List; import javax.imageio.ImageIO; /** * Utilities for loading fonts */ public class FontUtils { /** * Renders a single character to a buffered image * @param font The java font object * @param c the character * @param antiAlias whether to antialias the font or not * @return The buffered image with the rendered font */ private static BufferedImage createCharImage(java.awt.Font font, char c, boolean antiAlias) { //get the size of the character BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); if(antiAlias){ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } g.setFont(font); FontMetrics metrics = g.getFontMetrics(); g.dispose(); int charWidth = metrics.charWidth(c); int charHeight = metrics.getHeight(); //return 0 width characters if (charWidth == 0) { return null; } //render character to a properly sized buffered image image = new BufferedImage(charWidth, charHeight, BufferedImage.TYPE_INT_ARGB); g = image.createGraphics(); if (antiAlias) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); } g.setFont(font); g.setPaint(java.awt.Color.WHITE); g.drawString(String.valueOf(c), 0, metrics.getAscent()); g.dispose(); return image; } /** * Loads a java font object into an engine font object * @param font The java font object * @param antiAlias if true, antialias, otherwise dont * @return The engine font object */ protected static Font loadFont(java.awt.Font font, boolean antiAlias) { int imageWidth = 0; int imageHeight = 0; //data for parsing characters out of the font image List glyphs = new LinkedList(); //iterate through ascii codes for(int i = 32; i < 256; i++){ if(i == 127){ //skip del character continue; } char c = (char)i; BufferedImage ch = createCharImage(font, c, antiAlias); if(ch == null){ //skip characters with no images continue; } imageWidth += ch.getWidth(); imageHeight = Math.max(imageHeight, ch.getHeight()); } int fontHeight = imageHeight; //create font bitmap BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); int x = 0; //loop through ascii codes for (int i = 32; i < 256; i++) { if (i == 127) { //skip del character command continue; } char c = (char) i; BufferedImage charImage = createCharImage(font, c, antiAlias); if (charImage == null) { //don't render if the character is blank continue; } int charWidth = charImage.getWidth(); int charHeight = charImage.getHeight(); //draw the glyph to the image g.drawImage(charImage, x, 0, null); //create glyph and push it into the array Font.Glyph glyph = new Font.Glyph(); glyph.height = charHeight; glyph.width = charWidth; glyph.startX = x; glyph.startY = 0; glyph.symbol = (char)i + ""; glyphs.add(glyph); //increment image x += charWidth; } //uncomment if you need to flip the font // AffineTransform transform = AffineTransform.getScaleInstance(1f, -1f); // transform.translate(0, -image.getHeight()); // AffineTransformOp operation = new AffineTransformOp(transform, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); // image = operation.filter(image, null); try { ImageIO.write(image, "png", Files.newOutputStream(new File("C:/users/satellite/Pictures/testimg.png").toPath())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //create material with new font image Material uiMat = new Material(); Texture texture = new Texture(image); uiMat.setTexturePointer(texture.getTexturePointer()); //construct final font object and return Font rVal = new Font(uiMat,glyphs,imageWidth,imageHeight); rVal.process(); return rVal; } }