Advertisement
Guest User

Untitled

a guest
Nov 26th, 2013
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.54 KB | None | 0 0
  1. import java.awt.Color;
  2. import java.awt.Font;
  3. import java.awt.FontMetrics;
  4. import java.awt.Graphics2D;
  5. import java.awt.RenderingHints;
  6. import java.awt.image.BufferedImage;
  7. import java.awt.image.DataBuffer;
  8. import java.awt.image.DataBufferByte;
  9. import java.awt.image.DataBufferInt;
  10. import java.nio.ByteBuffer;
  11. import java.nio.ByteOrder;
  12. import java.nio.IntBuffer;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import java.awt.GraphicsEnvironment;
  16.  
  17. import org.lwjgl.BufferUtils;
  18. import org.lwjgl.opengl.GL11;
  19. import org.lwjgl.util.glu.GLU;
  20.  
  21.  
  22. /**
  23. * A TrueType font implementation originally for Slick, edited for Bobjob's Engine
  24. *
  25. * @original author James Chambers (Jimmy)
  26. * @original author Jeremy Adams (elias4444)
  27. * @original author Kevin Glass (kevglass)
  28. * @original author Peter Korzuszek (genail)
  29. *
  30. * @new version edited by David Aaron Muhar (bobjob)
  31. */
  32. public class TrueTypeFont {
  33. public final static int
  34. ALIGN_LEFT = 0,
  35. ALIGN_RIGHT = 1,
  36. ALIGN_CENTER = 2;
  37. /** Array that holds necessary information about the font characters */
  38. private IntObject[] charArray = new IntObject[256];
  39.  
  40. /** Map of user defined font characters (Character <-> IntObject) */
  41. private Map customChars = new HashMap();
  42.  
  43. /** Boolean flag on whether AntiAliasing is enabled or not */
  44. private boolean antiAlias;
  45.  
  46. /** Font's size */
  47. private int fontSize = 0;
  48.  
  49. /** Font's height */
  50. private int fontHeight = 0;
  51.  
  52. /** Texture used to cache the font 0-255 characters */
  53. private int fontTextureID;
  54.  
  55. /** Default font texture width */
  56. private int textureWidth = 512;
  57.  
  58. /** Default font texture height */
  59. private int textureHeight = 512;
  60.  
  61. /** A reference to Java's AWT Font that we create our font texture from */
  62. private Font font;
  63.  
  64. /** The font metrics for our Java AWT font */
  65. private FontMetrics fontMetrics;
  66.  
  67.  
  68. private int correctL = 9, correctR = 8;
  69.  
  70. private class IntObject {
  71. /** Character's width */
  72. public int width;
  73.  
  74. /** Character's height */
  75. public int height;
  76.  
  77. /** Character's stored x position */
  78. public int storedX;
  79.  
  80. /** Character's stored y position */
  81. public int storedY;
  82. }
  83.  
  84.  
  85. public TrueTypeFont(Font font, boolean antiAlias, char[] additionalChars) {
  86. this.font = font;
  87. this.fontSize = font.getSize()+3;
  88. this.antiAlias = antiAlias;
  89.  
  90. createSet( additionalChars );
  91.  
  92. fontHeight -= 1;
  93. if (fontHeight <= 0) fontHeight = 1;
  94. }
  95.  
  96. public TrueTypeFont(Font font, boolean antiAlias) {
  97. this( font, antiAlias, null );
  98. }
  99. public void setCorrection(boolean on) {
  100. if (on) {
  101. correctL = 2;
  102. correctR = 1;
  103. } else {
  104. correctL = 0;
  105. correctR = 0;
  106. }
  107. }
  108. private BufferedImage getFontImage(char ch) {
  109. // Create a temporary image to extract the character's size
  110. BufferedImage tempfontImage = new BufferedImage(1, 1,
  111. BufferedImage.TYPE_INT_ARGB);
  112. Graphics2D g = (Graphics2D) tempfontImage.getGraphics();
  113. if (antiAlias == true) {
  114. g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  115. RenderingHints.VALUE_ANTIALIAS_ON);
  116. }
  117. g.setFont(font);
  118. fontMetrics = g.getFontMetrics();
  119. int charwidth = fontMetrics.charWidth(ch)+8;
  120.  
  121. if (charwidth <= 0) {
  122. charwidth = 7;
  123. }
  124. int charheight = fontMetrics.getHeight()+3;
  125. if (charheight <= 0) {
  126. charheight = fontSize;
  127. }
  128.  
  129. // Create another image holding the character we are creating
  130. BufferedImage fontImage;
  131. fontImage = new BufferedImage(charwidth, charheight,
  132. BufferedImage.TYPE_INT_ARGB);
  133. Graphics2D gt = (Graphics2D) fontImage.getGraphics();
  134. if (antiAlias == true) {
  135. gt.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  136. RenderingHints.VALUE_ANTIALIAS_ON);
  137. }
  138. gt.setFont(font);
  139.  
  140. gt.setColor(Color.WHITE);
  141. int charx = 3;
  142. int chary = 1;
  143. gt.drawString(String.valueOf(ch), (charx), (chary)
  144. + fontMetrics.getAscent());
  145.  
  146. return fontImage;
  147.  
  148. }
  149.  
  150. private void createSet( char[] customCharsArray ) {
  151. // If there are custom chars then I expand the font texture twice
  152. if (customCharsArray != null && customCharsArray.length > 0) {
  153. textureWidth *= 2;
  154. }
  155.  
  156. // In any case this should be done in other way. Texture with size 512x512
  157. // can maintain only 256 characters with resolution of 32x32. The texture
  158. // size should be calculated dynamicaly by looking at character sizes.
  159.  
  160. try {
  161.  
  162. BufferedImage imgTemp = new BufferedImage(textureWidth, textureHeight, BufferedImage.TYPE_INT_ARGB);
  163. Graphics2D g = (Graphics2D) imgTemp.getGraphics();
  164.  
  165. g.setColor(new Color(0,0,0,1));
  166. g.fillRect(0,0,textureWidth,textureHeight);
  167.  
  168. int rowHeight = 0;
  169. int positionX = 0;
  170. int positionY = 0;
  171.  
  172. int customCharsLength = ( customCharsArray != null ) ? customCharsArray.length : 0;
  173.  
  174. for (int i = 0; i < 256 + customCharsLength; i++) {
  175.  
  176. // get 0-255 characters and then custom characters
  177. char ch = ( i < 256 ) ? (char) i : customCharsArray[i-256];
  178.  
  179. BufferedImage fontImage = getFontImage(ch);
  180.  
  181. IntObject newIntObject = new IntObject();
  182.  
  183. newIntObject.width = fontImage.getWidth();
  184. newIntObject.height = fontImage.getHeight();
  185.  
  186. if (positionX + newIntObject.width >= textureWidth) {
  187. positionX = 0;
  188. positionY += rowHeight;
  189. rowHeight = 0;
  190. }
  191.  
  192. newIntObject.storedX = positionX;
  193. newIntObject.storedY = positionY;
  194.  
  195. if (newIntObject.height > fontHeight) {
  196. fontHeight = newIntObject.height;
  197. }
  198.  
  199. if (newIntObject.height > rowHeight) {
  200. rowHeight = newIntObject.height;
  201. }
  202.  
  203. // Draw it here
  204. g.drawImage(fontImage, positionX, positionY, null);
  205.  
  206. positionX += newIntObject.width;
  207.  
  208. if( i < 256 ) { // standard characters
  209. charArray[i] = newIntObject;
  210. } else { // custom characters
  211. customChars.put( new Character( ch ), newIntObject );
  212. }
  213.  
  214. fontImage = null;
  215. }
  216.  
  217. fontTextureID = loadImage(imgTemp);
  218.  
  219.  
  220.  
  221. //.getTexture(font.toString(), imgTemp);
  222.  
  223. } catch (Exception e) {
  224. System.err.println("Failed to create font.");
  225. e.printStackTrace();
  226. }
  227. }
  228.  
  229. private void drawQuad(float drawX, float drawY, float drawX2, float drawY2,
  230. float srcX, float srcY, float srcX2, float srcY2) {
  231. float DrawWidth = drawX2 - drawX;
  232. float DrawHeight = drawY2 - drawY;
  233. float TextureSrcX = srcX / textureWidth;
  234. float TextureSrcY = srcY / textureHeight;
  235. float SrcWidth = srcX2 - srcX;
  236. float SrcHeight = srcY2 - srcY;
  237. float RenderWidth = (SrcWidth / textureWidth);
  238. float RenderHeight = (SrcHeight / textureHeight);
  239.  
  240. GL11.glTexCoord2f(TextureSrcX, TextureSrcY);
  241. GL11.glVertex2f(drawX, drawY);
  242. GL11.glTexCoord2f(TextureSrcX, TextureSrcY + RenderHeight);
  243. GL11.glVertex2f(drawX, drawY + DrawHeight);
  244. GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY + RenderHeight);
  245. GL11.glVertex2f(drawX + DrawWidth, drawY + DrawHeight);
  246. GL11.glTexCoord2f(TextureSrcX + RenderWidth, TextureSrcY);
  247. GL11.glVertex2f(drawX + DrawWidth, drawY);
  248. }
  249.  
  250. public int getWidth(String whatchars) {
  251. int totalwidth = 0;
  252. IntObject intObject = null;
  253. int currentChar = 0;
  254. for (int i = 0; i < whatchars.length(); i++) {
  255. currentChar = whatchars.charAt(i);
  256. if (currentChar < 256) {
  257. intObject = charArray[currentChar];
  258. } else {
  259. intObject = (IntObject)customChars.get( new Character( (char) currentChar ) );
  260. }
  261.  
  262. if( intObject != null )
  263. totalwidth += intObject.width;
  264. }
  265. return totalwidth;
  266. }
  267.  
  268. public int getHeight() {
  269. return fontHeight;
  270. }
  271.  
  272.  
  273. public int getHeight(String HeightString) {
  274. return fontHeight;
  275. }
  276.  
  277. public int getLineHeight() {
  278. return fontHeight;
  279. }
  280.  
  281. public void drawString(float x, float y,
  282. String whatchars, float scaleX, float scaleY) {
  283. drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, ALIGN_LEFT);
  284. }
  285. public void drawString(float x, float y,
  286. String whatchars, float scaleX, float scaleY, int format) {
  287. drawString(x,y,whatchars, 0, whatchars.length()-1, scaleX, scaleY, format);
  288. }
  289.  
  290.  
  291. public void drawString(float x, float y,
  292. String whatchars, int startIndex, int endIndex,
  293. float scaleX, float scaleY,
  294. int format
  295. ) {
  296.  
  297. IntObject intObject = null;
  298. int charCurrent;
  299.  
  300.  
  301. int totalwidth = 0;
  302. int i = startIndex, d, c;
  303. float startY = 0;
  304.  
  305.  
  306.  
  307. switch (format) {
  308. case ALIGN_RIGHT: {
  309. d = -1;
  310. c = correctR;
  311.  
  312. while (i < endIndex) {
  313. if (whatchars.charAt(i) == '\n') startY -= fontHeight;
  314. i++;
  315. }
  316. break;
  317. }
  318. case ALIGN_CENTER: {
  319. for (int l = startIndex; l <= endIndex; l++) {
  320. charCurrent = whatchars.charAt(l);
  321. if (charCurrent == '\n') break;
  322. if (charCurrent < 256) {
  323. intObject = charArray[charCurrent];
  324. } else {
  325. intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
  326. }
  327. totalwidth += intObject.width-correctL;
  328. }
  329. totalwidth /= -2;
  330. }
  331. case ALIGN_LEFT:
  332. default: {
  333. d = 1;
  334. c = correctL;
  335. break;
  336. }
  337.  
  338. }
  339.  
  340. GL11.glBindTexture(GL11.GL_TEXTURE_2D, fontTextureID);
  341. GL11.glBegin(GL11.GL_QUADS);
  342.  
  343. while (i >= startIndex && i <= endIndex) {
  344.  
  345. charCurrent = whatchars.charAt(i);
  346. if (charCurrent < 256) {
  347. intObject = charArray[charCurrent];
  348. } else {
  349. intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
  350. }
  351.  
  352. if( intObject != null ) {
  353. if (d < 0) totalwidth += (intObject.width-c) * d;
  354. if (charCurrent == '\n') {
  355. startY -= fontHeight * d;
  356. totalwidth = 0;
  357. if (format == ALIGN_CENTER) {
  358. for (int l = i+1; l <= endIndex; l++) {
  359. charCurrent = whatchars.charAt(l);
  360. if (charCurrent == '\n') break;
  361. if (charCurrent < 256) {
  362. intObject = charArray[charCurrent];
  363. } else {
  364. intObject = (IntObject)customChars.get( new Character( (char) charCurrent ) );
  365. }
  366. totalwidth += intObject.width-correctL;
  367. }
  368. totalwidth /= -2;
  369. }
  370. //if center get next lines total width/2;
  371. }
  372. else {
  373. drawQuad((totalwidth + intObject.width) * scaleX + x, startY * scaleY + y,
  374. totalwidth * scaleX + x,
  375. (startY + intObject.height) * scaleY + y, intObject.storedX + intObject.width,
  376. intObject.storedY + intObject.height,intObject.storedX,
  377. intObject.storedY);
  378. if (d > 0) totalwidth += (intObject.width-c) * d ;
  379. }
  380. i += d;
  381.  
  382. }
  383. }
  384. GL11.glEnd();
  385. }
  386. public static int loadImage(BufferedImage bufferedImage) {
  387. try {
  388. short width = (short)bufferedImage.getWidth();
  389. short height = (short)bufferedImage.getHeight();
  390. //textureLoader.bpp = bufferedImage.getColorModel().hasAlpha() ? (byte)32 : (byte)24;
  391. int bpp = (byte)bufferedImage.getColorModel().getPixelSize();
  392. ByteBuffer byteBuffer;
  393. DataBuffer db = bufferedImage.getData().getDataBuffer();
  394. if (db instanceof DataBufferInt) {
  395. int intI[] = ((DataBufferInt)(bufferedImage.getData().getDataBuffer())).getData();
  396. byte newI[] = new byte[intI.length * 4];
  397. for (int i = 0; i < intI.length; i++) {
  398. byte b[] = intToByteArray(intI[i]);
  399. int newIndex = i*4;
  400.  
  401. newI[newIndex] = b[1];
  402. newI[newIndex+1] = b[2];
  403. newI[newIndex+2] = b[3];
  404. newI[newIndex+3] = b[0];
  405. }
  406.  
  407. byteBuffer = ByteBuffer.allocateDirect(
  408. width*height*(bpp/8))
  409. .order(ByteOrder.nativeOrder())
  410. .put(newI);
  411. } else {
  412. byteBuffer = ByteBuffer.allocateDirect(
  413. width*height*(bpp/8))
  414. .order(ByteOrder.nativeOrder())
  415. .put(((DataBufferByte)(bufferedImage.getData().getDataBuffer())).getData());
  416. }
  417. byteBuffer.flip();
  418.  
  419.  
  420. int internalFormat = GL11.GL_RGBA8,
  421. format = GL11.GL_RGBA;
  422. IntBuffer textureId = BufferUtils.createIntBuffer(1);;
  423. GL11.glGenTextures(textureId);
  424. GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId.get(0));
  425.  
  426.  
  427. GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
  428. GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
  429.  
  430. GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
  431. GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
  432.  
  433. GL11.glTexEnvf(GL11.GL_TEXTURE_ENV, GL11.GL_TEXTURE_ENV_MODE, GL11.GL_MODULATE);
  434.  
  435.  
  436.  
  437. GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D,
  438. internalFormat,
  439. width,
  440. height,
  441. format,
  442. GL11.GL_UNSIGNED_BYTE,
  443. byteBuffer);
  444. return textureId.get(0);
  445.  
  446. } catch (Exception e) {
  447. e.printStackTrace();
  448. System.exit(-1);
  449. }
  450.  
  451. return -1;
  452. }
  453. public static boolean isSupported(String fontname) {
  454. Font font[] = getFonts();
  455. for (int i = font.length-1; i >= 0; i--) {
  456. if (font[i].getName().equalsIgnoreCase(fontname))
  457. return true;
  458. }
  459. return false;
  460. }
  461. public static Font[] getFonts() {
  462. return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
  463. }
  464. public static byte[] intToByteArray(int value) {
  465. return new byte[] {
  466. (byte)(value >>> 24),
  467. (byte)(value >>> 16),
  468. (byte)(value >>> 8),
  469. (byte)value};
  470. }
  471.  
  472. public void destroy() {
  473. IntBuffer scratch = BufferUtils.createIntBuffer(1);
  474. scratch.put(0, fontTextureID);
  475. GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
  476. GL11.glDeleteTextures(scratch);
  477. }
  478. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement