VisClient/org/dronus/gl/GLTextPanel.java

Go to the documentation of this file.
00001 /*
00002  * Created on 04.05.2008
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");  // TODO utf 8 compatibility
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) { // line exceed, do something..
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                         // text fits one line or no hyphen possible
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 }

Generated on Tue Apr 7 17:57:19 2009 for visclient by  doxygen 1.5.1