LWJGL Font metrics not working

Hi

So I am fixing up some font rendering code (and improving upon it). The font sheet is created/shown perfectly, but when the regions for each character are checked when rendering individual characters, everything is offset. Just to prevent this, I know I’m “rolling out my own” but it almost works perfectly like it should.

Code:


package game.util;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.HashMap;

import static org.lwjgl.opengl.GL11.*;

public class GLFont {
	
	public static HashMap<Float, Texture> textures = new HashMap<Float, Texture>();
	
	private Font font;
	private float fontsize;
	private IntObject[] objects = new IntObject[256];
	private FontMetrics metrics;
	private Texture fontTexture;
	private BufferedImage image;
	private int fontHeight = 0;
	
	public static class IntObject {
		public int x, y, width, height;
		public void debug(){
			System.out.println("IntObject[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]");
		}
	}
	
	public GLFont(Font _font, float fontsize){
		this.fontsize = fontsize;
		font = _font.deriveFont(fontsize);
		if(textures.get(fontsize) != null){
			fontTexture = textures.get(fontsize);
		} else {
			createTexture();
			textures.put(fontsize, fontTexture);
		}
	}
	
	private float textureWidth = 512, textureHeight = 512;
	public void drawText(float x, float y, String text, Color color){
		glColor3f(color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f);
		fontTexture.bind();
		float drawX = x;
		float drawY = y;
		glBegin(GL_QUADS);
		for(char letter : text.toCharArray()){
			IntObject intObject = objects[(int)letter];
			intObject.debug();
			float drawX2 = drawX + intObject.width;
			float drawY2 = drawY + intObject.height;
			float srcX = intObject.x; //
			float srcY = intObject.y; //
			float srcX2 = srcX + intObject.width;
			float srcY2 = srcY + intObject.height;
			float DrawWidth = drawX2 - drawX;
			float DrawHeight = drawY2 - drawY;
			float TextureSrcX = srcX / textureWidth; //
			float TextureSrcY = srcY / textureHeight; //
			float SrcWidth = srcX2 - srcX;
			float SrcHeight = srcY2 - srcY;
			float RenderWidth = (SrcWidth / textureWidth);
			float RenderHeight = (SrcHeight / textureHeight);
			// Shift the render row.
			TextureSrcY -= RenderHeight;
			TextureSrcY += (5.0f / 512.0f);
			// Draw the letter
			glTexCoord2f(TextureSrcX, TextureSrcY);
			glVertex2f(drawX, drawY);
			glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
			glVertex2f(drawX, drawY + DrawHeight);
			glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
			glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
			glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
			glVertex2f(drawX + DrawWidth, drawY);
			drawX += intObject.width;
		}
		glEnd();
		glColor3f(1.0f, 1.0f, 1.0f);
	}
	
	public void debug(){
		fontTexture.bind();
		glBegin(GL_QUADS);
		glTexCoord2f(0, 0);
		glVertex2f(100, 100);
		glTexCoord2f(1, 0);
		glVertex2f(612, 100);
		glTexCoord2f(1, 1);
		glVertex2f(612, 612);
		glTexCoord2f(0, 1);
		glVertex2f(100, 612);
		glEnd();
	}
	
	public void createTexture(){
		image = new BufferedImage(512, 512, BufferedImage.TYPE_INT_ARGB);
		BufferedImage scratch = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
		Graphics2D graphics = scratch.createGraphics();
		// get the dimensions
		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		graphics.setFont(font);
		metrics = graphics.getFontMetrics();
		// prepare the graphics
		Graphics2D realGraphics = image.createGraphics();
		realGraphics.setColor(new Color(255, 255, 255, 0));
		realGraphics.drawRect(0, 0, 512, 512);
		realGraphics.setColor(new Color(255, 255, 255));
		realGraphics.setFont(font);
		// real work
		int rowHeight = 0;
		int positionX = 0;
		int positionY = 0;
		for(int index = 0; index < 256; index++){
			char letter = (char) index;
			int charwidth = metrics.charWidth(letter);
			if (charwidth <= 0) {
				charwidth = 1;
			}
			int charheight = metrics.getHeight();
			if (charheight <= 0) {
				charheight = Math.round(fontsize);
			}
			IntObject intObject = new IntObject();
			intObject.width = charwidth;
			intObject.height = charheight;
			if (positionX + intObject.width >= 512) {
				positionX = 0;
				positionY += rowHeight;
				rowHeight = 0;
			}
			intObject.x = positionX;
			intObject.y = positionY;
			if(intObject.height > fontHeight){
				fontHeight = intObject.height;
			}
			if(intObject.height > rowHeight){
				rowHeight = intObject.height;
			}
			realGraphics.drawString(String.valueOf(letter), positionX, positionY);
			positionX += intObject.width;
			objects[index] = intObject;
		}
		fontTexture = new Texture(image);
	}

}

Any assistance in fixing the character regions would be appreciated :slight_smile:

CopyableCougar4