Renderer/src/main/java/electrosphere/renderer/ui/font/FontUtils.java
austin 9407c13217
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
Font work
2024-02-28 21:21:05 -05:00

164 lines
5.0 KiB
Java

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<Font.Glyph> glyphs = new LinkedList<Font.Glyph>();
//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;
}
}