Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / views / Text.java
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 implements IUpdatable {

    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;
    }


}