package gameEngine.views;
import org.joml.Vector3f;
import java.util.Map;
import static java.awt.Font.PLAIN;
import static java.awt.Font.SANS_SERIF;
import static org.lwjgl.opengl.GL11.*;
public class Text extends Renderer {
private Texture fontTexture;
private Map<Character, Glyph> fontGlyphs;
private int fontHeight;
public String text;
public int textSize;
public Text(float posX, float posY, String text, int textSize) {
this.position = new Vector3f(posX,posY,0);
this.rotation = new Vector3f(0,0,0);
this.scale = new Vector3f(1,1,1);
this.text = text;
this.textSize = textSize;
this.color = new Color(0,0,0,1);
Font font = new Font(new java.awt.Font(SANS_SERIF, PLAIN, textSize), true);
fontTexture = font.getTexture();
fontGlyphs = font.getGlyphs();
fontHeight = font.getFontHeight();
}
public void update(){
Integer id = fontTexture.getId();
if(id == null) {
fontTexture.init();
}
render();
}
public void setText(String newText) {
this.text = newText;
render();
}
public void setTextSize(int newTextSize) {
if (newTextSize < 3 || newTextSize > 127) return;
this.textSize = newTextSize;
Font font = new Font(new java.awt.Font(SANS_SERIF, PLAIN, textSize), true);
this.fontTexture = font.getTexture();
this.fontGlyphs = font.getGlyphs();
this.fontHeight = font.getFontHeight();
render();
}
public void setColor(Color color) {
this.color = color;
render();
}
public boolean isMouseOver(float mouseX, float mouseY) {
float width = getDisplayedWidth();
float height = getDisplayedHeight();
return mouseX >= position.x && mouseX <= position.x + width &&
mouseY >= position.y && mouseY <= position.y + height;
}
@Override
public void render() {
prepareRendering();
glBindTexture(GL_TEXTURE_2D, fontTexture.getId());
float drawX = 0; // Render relative to the transformed position
float drawY = 0;
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (ch == '\n') {
drawY += fontHeight;
drawX = 0;
continue;
}
Glyph g = fontGlyphs.get(ch);
if (g != null) {
glBegin(GL_QUADS);
glTexCoord2f(g.x / (float) fontTexture.getWidth(), g.y / (float) fontTexture.getHeight());
glVertex3f(drawX, drawY, 0);
glTexCoord2f((g.x + g.width) / (float) fontTexture.getWidth(), g.y / (float) fontTexture.getHeight());
glVertex3f(drawX + g.width, drawY, 0);
glTexCoord2f((g.x + g.width) / (float) fontTexture.getWidth(), (g.y + g.height) / (float) fontTexture.getHeight());
glVertex3f(drawX + g.width, drawY + g.height, 0);
glTexCoord2f(g.x / (float) fontTexture.getWidth(), (g.y + g.height) / (float) fontTexture.getHeight());
glVertex3f(drawX, drawY + g.height, 0);
glEnd();
drawX += g.width; // Advance x position by character width
}
}
endRendering();
}
public int getHeight(CharSequence text) {
int height = 0;
int lineHeight = 0;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == '\n') {
height += lineHeight;
lineHeight = 0;
continue;
}
if (c == '\r') {
continue;
}
Glyph g = fontGlyphs.get(c);
lineHeight = Math.max(lineHeight, g.height);
}
height += lineHeight;
return height;
}
public float getDisplayedWidth() {
float width = 0;
float lineWidth = 0;
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
if (ch == '\n') {
width = Math.max(width, lineWidth);
lineWidth = 0; // 新しい行に移行するためにリセット
} else {
Glyph g = fontGlyphs.get(ch);
if (g != null) {
lineWidth += g.width; // 文字の幅を加算
}
}
}
width = Math.max(width, lineWidth); // 最後の行の幅も確認
return width * scale.x;
}
public float getWidthAtIndex(int index) {
float width = 0;
float drawX = 0;
for (int i = 0; i < index; i++) {
char ch = text.charAt(i);
if (ch == '\n') {
drawX = 0;
continue;
}
Glyph g = fontGlyphs.get(ch);
if (g != null) {
drawX += g.width; // 文字の幅を加算
}
}
return drawX * scale.x;
}
public float getDisplayedHeight() {
int numLines = 1; // 初期行は1行
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == '\n') {
numLines++;
}
}
return numLines * fontHeight * scale.y;
}
}