00001
00002
00003
00004
00005 package org.dronus.gl;
00006
00007 import java.io.UnsupportedEncodingException;
00008 import org.lwjgl.opengl.GL11;
00009
00010 public class GLTextPanel {
00011
00012
00013 public float w, h;
00014 public String text;
00015
00016 int dl;
00017
00018 public void render() {
00019 GL11.glCallList(dl);
00020 }
00021
00032 public GLTextPanel(String text, float maxwidth, float maxheight) {
00033 this.text=text;
00034
00035 GLFont font=GLFont.getDefault();
00036
00037 dl = GL11.glGenLists(1);
00038 GL11.glNewList(dl, GL11.GL_COMPILE);
00039 float y = 0, width = 0;
00040
00041 font.render();
00042
00043 GL11.glBegin(GL11.GL_QUADS);
00044 float textureDelta = 1.0f / font.N;
00045 LineIterator lit = new LineIterator(text, maxwidth, font);
00046 while (lit.hasNext() && (maxheight == 0 | -y < maxheight)) {
00047 float x = 0;
00048 byte[] line;
00049 try {
00050 String l=lit.nextLine();
00051 line = l.getBytes("latin1");
00052
00053 for (int i = 0; i < line.length; i++) {
00054 int c = line[i];
00055 if (c < 0)
00056 c += 256;
00057 if (c > 255)
00058 continue;
00059
00060 float w = font.charwidth[c];
00061 float u = ((float) (c % font.N)) / font.N;
00062 float v = ((float) (c / font.N)) / font.N;
00063
00064 GL11.glTexCoord2f(u, v);
00065 GL11.glVertex3f(x, y + 1, 0);
00066 GL11.glTexCoord2f((u + textureDelta * w / 2), v);
00067 GL11.glVertex3f(x + w, y + 1, 0);
00068 GL11.glTexCoord2f((u + textureDelta * w / 2), v
00069 + textureDelta);
00070 GL11.glVertex3f(x + w, y, 0);
00071 GL11.glTexCoord2f(u, v + textureDelta);
00072 GL11.glVertex3f(x, y, 0);
00073 x += w;
00074 }
00075 } catch (UnsupportedEncodingException e) {
00076 throw new RuntimeException(e);
00077 }
00078
00079 width = Math.max(width, x);
00080 y--;
00081 }
00082 GL11.glEnd();
00083 GL11.glEndList();
00084
00085 w = width;
00086 h = -y;
00087 }
00088
00089 class LineIterator {
00090 float width;
00091 GLFont font;
00092
00093 String textToGo;
00094
00095 LineIterator(String text, float width, GLFont font) {
00096 textToGo = text;
00097 if (width == 0)
00098 width = Float.POSITIVE_INFINITY;
00099 this.width = width;
00100 this.font=font;
00101 }
00102
00103 boolean hasNext() {
00104 return textToGo.length() > 0;
00105 }
00106
00107 String nextLine() {
00108 int i = 0, l = textToGo.length();
00109 float x = 0;
00110
00111 while (i < l && x < width) {
00112 char c = textToGo.charAt(i);
00113 i++;
00114 if (c < 255)
00115 x += font.charwidth[c];
00116 if (c == '\n')
00117 break;
00118 }
00119 int uncropped = i;
00120 if (x >= width) {
00121 i--;
00122 while (i > 0) {
00123 if (textToGo.charAt(i) == ' ')
00124 return crop(0, i + 1);
00125 if (possibleHyphen(textToGo, i))
00126 return crop(0, i) + "-";
00127 i--;
00128 }
00129 }
00130
00131 return crop(0, uncropped);
00132 }
00133
00134 String crop(int start, int end) {
00135 String result = textToGo.substring(start, end);
00136 textToGo = textToGo.substring(end);
00137 return result;
00138 }
00139
00140 boolean possibleHyphen(String text, int i) {
00141 if (i - 1 > 0 || i < text.length()) {
00142 char c1 = text.charAt(i - 1), c2 = text.charAt(i);
00143 return (Character.isLetter(c1) && Character.isLetter(c2)
00144 && !isVovel(c1) && !isVovel(c2));
00145 } else
00146 return false;
00147 }
00148
00149 boolean isVovel(char c) {
00150 final char[] vovels = { 'a', 'e', 'i', 'o', 'u', 'y' };
00151 for (char vovel : vovels)
00152 if (Character.toLowerCase(c) == vovel)
00153 return true;
00154 return false;
00155 }
00156 }
00157 }