1 16 17 package com.buchuki.ensmer.text; 18 19 import com.buchuki.ensmer.SceneGraphUtils; 20 import com.buchuki.annotations.*; 21 import java.awt.*; 22 import java.awt.image.BufferedImage ; 23 import java.util.*; 24 import javax.media.j3d.*; 25 26 27 37 public class TextDisplay extends Shape3D { 38 39 43 private static final float SCALE_FACTOR = 1f/1024f; 44 45 53 public TextDisplay(Color color, Font font) { 54 this.color = color; 55 this.font = font; 56 setCapability(ALLOW_GEOMETRY_WRITE); 57 Appearance app = new Appearance(); 58 app.setCapability(app.ALLOW_TEXTURE_WRITE); 59 TransparencyAttributes trAtt = new TransparencyAttributes(); 60 trAtt.setTransparencyMode(TransparencyAttributes.FASTEST); 61 trAtt.setTransparency(0f); 62 app.setTransparencyAttributes(trAtt); 63 setAppearance(app); 64 geom = new QuadArray(4, 65 QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_2); 66 geom.setCapability(geom.ALLOW_COORDINATE_WRITE); 67 geom.setTextureCoordinates(0, 0, new float[] { 68 0f, 1f, 69 0f, 0f, 70 1f, 0f, 71 1f, 1f 72 }); 73 setGeometry(geom); 74 SceneGraphUtils.enableEnsmerCapabilities(this); 75 } 76 77 82 public void setText(String text) { 83 TextInput newText = new TextInput(); 84 newText.setText(text); 85 newText.setFocused(false); 86 setText(newText); 87 } 88 89 94 @Optimize("The cursor positioning algorithm doesn't need to cycle through every character, but my other attempts all broke") 95 public void setText(TextInput text) { 96 StringTokenizer stok = new StringTokenizer(text.getText(), "\n", true); 97 java.util.List <String > lines = new ArrayList<String >(); 98 int numLines = 0; 99 boolean lastWasNewLine = true; 100 while (stok.hasMoreTokens()) { 101 String next = stok.nextToken(); 102 if (next.equals("\n")) { 103 if (lastWasNewLine == true) { 104 lines.add(""); 105 } 106 lastWasNewLine = true; 107 } 108 else { 109 lastWasNewLine = false; 110 lines.add(next); 111 } 112 } 113 graphics.setFont(font); 114 FontMetrics metrics = graphics.getFontMetrics(); 115 int width = longestString(lines, metrics) + 4; 116 int height = (lines.size() + 1) * metrics.getHeight(); 117 textWidth = width * SCALE_FACTOR; 118 textHeight = height * SCALE_FACTOR; 119 120 width = SceneGraphUtils.greaterBinaryPower(width, 16); 121 height = SceneGraphUtils.greaterBinaryPower(height, 16); 122 123 texture = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB); 124 graphics = texture.createGraphics(); 125 graphics.setFont(font); 126 graphics.setColor(new Color(0, 0, 0, 0)); graphics.fillRect(0, 0, width, height); 128 graphics.setColor(color); 129 graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 130 int baseLine = metrics.getHeight() - metrics.getDescent() + 1; 131 for (String line : lines) { 132 graphics.drawString(line, 1, baseLine); 133 baseLine += metrics.getHeight(); 134 } 135 136 if (text.isFocused()) { 138 String s = text.getText(); 139 int pos = text.getCursorPosition(); 140 int x = 0; 141 int y = 0; 142 StringBuffer currLine = new StringBuffer (); 143 for (int i = 0; i < pos; i++) { 144 if (s.charAt(i) == '\n') { 145 y += metrics.getHeight(); 146 currLine.delete(0, currLine.length()); 147 } 148 else { 149 currLine.append(s.charAt(i)); 150 } 151 } 152 x = metrics.stringWidth(currLine.toString()); 153 int y2 = y+metrics.getHeight(); 154 graphics.setColor(new Color(0.5f, 0.3f, 0.2f)); 155 graphics.drawLine(x, y, x, y2); 156 } 157 158 ImageComponent2D image = new ImageComponent2D( 159 ImageComponent.FORMAT_RGBA, texture); 160 161 Texture2D tex = new Texture2D(Texture2D.BASE_LEVEL, Texture2D.RGBA, 162 image.getWidth(), image.getHeight()); 163 tex.setImage(0, image); 164 getAppearance().setTexture(tex); 165 float gHeight = height * SCALE_FACTOR; 166 float gWidth = width * SCALE_FACTOR; 167 geom.setCoordinates(0, new float[] { 168 0, 0, 0, 169 0, -gHeight, 0, 170 gWidth, -gHeight, 0, 171 gWidth, 0, 0 172 }); 173 setGeometry(geom); 174 } 175 176 182 public float getWidth() { 183 return textWidth; 184 } 185 186 192 public float getHeight() { 193 return textHeight; 194 } 195 196 197 204 private int longestString(java.util.List <String > lines, FontMetrics metrics) { 205 int longestWidth = 1; for (String line : lines) { 207 int lineWidth = metrics.stringWidth(line); 208 if (lineWidth > longestWidth) { 209 longestWidth = lineWidth; 210 } 211 } 212 return longestWidth; 213 } 214 215 218 private Font font; 219 220 223 private Color color; 224 225 228 private BufferedImage texture = new BufferedImage (5, 5, BufferedImage.TYPE_INT_ARGB); 229 230 233 private Graphics2D graphics = texture.createGraphics(); 234 235 238 private GeometryArray geom; 239 240 243 private float textWidth; 244 245 249 private float textHeight; 250 251 } 252 | Popular Tags |