00001 package org.dronus.gl;
00002
00003 import java.awt.Color;
00004 import java.awt.Font;
00005 import java.awt.FontMetrics;
00006 import java.awt.Graphics2D;
00007 import java.awt.RenderingHints;
00008 import java.awt.image.BufferedImage;
00009
00010 import org.hfbk.vis.Prefs;
00011 import org.lwjgl.opengl.GL11;
00012
00024 public class GLFont {
00025 private static GLFont def;
00026
00027 String fontName;
00028
00029 final int N = 16, NUM_LETTERS = 256;
00030
00031 int resolution = 64;
00032
00033 int chars;
00034 float[] charwidth = new float[NUM_LETTERS];
00035
00036 Texture texture;
00037
00038 static final Color OPAQUE_WHITE = Color.WHITE, TRANSPARENT_WHITE = new Color(1, 1, 1, 0);
00039
00040
00041 public static GLFont getDefault() {
00042 if (def==null || def.fontName!=Prefs.current.font)
00043 def = new GLFont(Prefs.current.font);
00044 return def;
00045 }
00046
00047 public void render() {
00048 texture.render();
00049 }
00050
00051 public void print(String msg) {
00052 float carriage = 0;
00053 if (msg != null) {
00054 for (int i = 0; i < msg.length(); i++) {
00055 char c = msg.charAt(i);
00056 if (c > 255)
00057 continue;
00058 if (c == '\n') {
00059 GL11.glTranslatef(-carriage, 2, 0);
00060 carriage = 0;
00061 }
00062
00063 GL11.glCallList(chars + c);
00064 GL11.glTranslatef(charwidth[c], 0, 0);
00065 carriage += charwidth[c];
00066 }
00067 }
00068 }
00069
00073 public GLFont(String fontName)
00074 {
00075 this.fontName=fontName;
00076 texture = new Texture(buildBitmap(fontName));
00077 chars =buildChars();
00078 }
00079
00086 BufferedImage buildBitmap(String fontName){
00087
00088 int size = N * resolution;
00089
00090
00091 BufferedImage bitmap = new BufferedImage(size, size, BufferedImage.TYPE_4BYTE_ABGR);
00092 Graphics2D g = (Graphics2D) bitmap.getGraphics();
00093
00094
00095
00096 Font font = new Font(fontName, Font.BOLD, resolution);
00097 g.setFont(font);
00098 FontMetrics fm = g.getFontMetrics();
00099
00100 int rowColSize = N*Math.max(fm.stringWidth("W"), fm.getHeight());
00101
00102
00103 int fontSize=(int)(resolution*size/(float)rowColSize);
00104
00105
00106 font = font.deriveFont((float)fontSize);
00107 g.setFont(font);
00108 fm = g.getFontMetrics();
00109
00110 rowColSize = N*Math.max(fm.stringWidth("W"), fm.getHeight());
00111
00112
00113
00114
00115
00116
00117
00118
00119 g.setColor(TRANSPARENT_WHITE);
00120 g.fillRect(0, 0, size, size);
00121
00122 g.setColor(OPAQUE_WHITE);
00123
00124 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
00125 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
00126 fm = g.getFontMetrics();
00127
00128 for (int i = 0; i < 256; i++) {
00129 int x = i % N;
00130 int y = i / N;
00131 char ch[] = { (char) i };
00132 String temp = new String(ch);
00133 charwidth[i] = fm.charWidth((char) i) * 2f / resolution;
00134
00135
00136 g.drawString(temp, (x * resolution) + 1, (y * resolution) + fm.getAscent());
00137 }
00138
00139 return bitmap;
00140 }
00141
00146 int buildChars(){
00147 int dl= GL11.glGenLists(NUM_LETTERS);
00148
00149 float textureDelta = 1.0f / N;
00150
00151 for (int i = 0; i < NUM_LETTERS; i++) {
00152 float u = ((float) (i % N)) / N;
00153 float v = ((float) (i / N)) / N;
00154 GL11.glNewList(dl + i, GL11.GL_COMPILE);
00155 GL11.glBegin(GL11.GL_QUADS);
00156 GL11.glTexCoord2f(u, v);
00157 GL11.glVertex3f(0, 1, 0.0f);
00158 GL11.glTexCoord2f((u + textureDelta * charwidth[i] / 2), v);
00159 GL11.glVertex3f(charwidth[i], 1, 0.0f);
00160 GL11.glTexCoord2f((u + textureDelta * charwidth[i] / 2), v+ textureDelta);
00161 GL11.glVertex3f(charwidth[i], -1, 0.0f);
00162 GL11.glTexCoord2f(u, v + textureDelta);
00163 GL11.glVertex3f(0, -1, 0.0f);
00164 GL11.glEnd();
00165 GL11.glEndList();
00166 }
00167 return dl;
00168 }
00169
00170
00174 public float getLineLength(String text) {
00175 float l = 0;
00176 for (int i = 0; i < text.length(); i++) {
00177 char c = text.charAt(i);
00178 if (c <= 255)
00179 l += charwidth[c];
00180 }
00181 return l;
00182 }
00183
00184 public void finalize() throws Throwable {
00185
00186 GL11.glDeleteLists(chars, NUM_LETTERS);
00187 super.finalize();
00188 }
00189 }