content: package dk.aau.netsec.hostage.ui.fragment.opengl;
  
  import android.content.res.AssetManager;
  import android.opengl.GLES20;
  
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.nio.ByteBuffer;
  import java.nio.ByteOrder;
  import java.nio.FloatBuffer;
  
  import dk.aau.netsec.hostage.ui.activity.MainActivity;
  
  /**
   * Created by Fabio Arnold on 13.02.15.
   */
  public class GLFont {
  	private class GlyphMetric {
  		float x0,y0,s0,t0; // top-left
  		float x1,y1,s1,t1; // bottom-right
  		float advance;
  	}
  
  	private int mTexture;
  	private int mVertexBuffer;
  	private GlyphMetric[] mMetrics;
  
  	public GLFont(String texFilePath, String metricsFilePath) {
  		AssetManager assets = MainActivity.getInstance().getAssets();
  
  		mTexture = ThreatIndicatorGLRenderer.loadTexture(texFilePath);
  
  		InputStream is = null;
  		try {
  			is = assets.open(metricsFilePath);
  		} catch (IOException e) {
  			e.printStackTrace();
  			return;
  		}
  		//DataInputStream dis = new DataInputStream(is);
  		ByteArrayOutputStream out = new ByteArrayOutputStream();
  		try {
  			final int EOF = -1;
  			int len;
  			byte[] buffer = new byte[1 << 12];
  			while (EOF != (len = is.read(buffer)))
  				out.write(buffer, 0, len);
  		} catch (IOException e) {
  			e.printStackTrace();
  			return;
  		}
  
  		//data = ByteBuffer.wrap(out.toByteArray()); // doesn't work data needs to be direct
  		ByteBuffer data = ByteBuffer.allocateDirect(out.size());
  		data.order(ByteOrder.nativeOrder());
  		data.put(out.toByteArray());
  		data.position(0);
  
  		mMetrics = new GlyphMetric[96];
  		for (int i = 0; i < 96; i++) {
  			mMetrics[i] = new GlyphMetric();
  
  			mMetrics[i].x0 = data.getFloat();
  			mMetrics[i].y0 = data.getFloat();
  			mMetrics[i].s0 = data.getFloat();
  			mMetrics[i].t0 = data.getFloat();
  			mMetrics[i].x1 = data.getFloat();
  			mMetrics[i].y1 = data.getFloat();
  			mMetrics[i].s1 = data.getFloat();
  			mMetrics[i].t1 = data.getFloat();
  			mMetrics[i].advance = data.getFloat();
  		}
  
  		int[] buffers = new int[1];
  		GLES20.glGenBuffers(1, buffers, 0); // buffer names
  		mVertexBuffer = buffers[0];
  	}
  
  	public float getTextWidth(String text) {
  		float x = 0.0f;
  		for (int i = 0; i < text.length(); i++) {
  			x += mMetrics[(int)text.charAt(i)-32].advance;
  		}
  		return x;
  	}
  
  	public void drawText(int program, String text, float x, float y) {
  		int vertexCount = text.length() * 6;
  		int vertexSize = (2+2)*4; // size in bytes
  
  		FloatBuffer buffer = ByteBuffer.allocateDirect(vertexCount * vertexSize).order(ByteOrder.nativeOrder()).asFloatBuffer();
  		for (int i = 0; i < text.length(); i++) {
  			int glyph = ((int)text.charAt(i))-32;
  			GlyphMetric metric = mMetrics[glyph];
  
  			buffer.put(x+metric.x0); buffer.put(y+metric.y0);
  			buffer.put(metric.s0); buffer.put(metric.t1);
  			buffer.put(x+metric.x1); buffer.put(y+metric.y0);
  			buffer.put(metric.s1); buffer.put(metric.t1);
  			buffer.put(x+metric.x1); buffer.put(y+metric.y1);
  			buffer.put(metric.s1); buffer.put(metric.t0);
  
  			buffer.put(x+metric.x0); buffer.put(y+metric.y0);
  			buffer.put(metric.s0); buffer.put(metric.t1);
  			buffer.put(x+metric.x1); buffer.put(y+metric.y1);
  			buffer.put(metric.s1); buffer.put(metric.t0);
  			buffer.put(x+metric.x0); buffer.put(y+metric.y1);
  			buffer.put(metric.s0); buffer.put(metric.t0);
  
  			x += metric.advance;
  		}
  		buffer.position(0); // rewind
  
  		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture);
  
  		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mVertexBuffer);
  		GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexSize * vertexCount, buffer, GLES20.GL_STREAM_DRAW);
  
  		int positionIndex = GLES20.glGetAttribLocation(program, "position");
  		int texCoordIndex = GLES20.glGetAttribLocation(program, "texCoord");
  
  		GLES20.glEnableVertexAttribArray(positionIndex);
  		GLES20.glEnableVertexAttribArray(texCoordIndex);
  
  		GLES20.glVertexAttribPointer(positionIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 0);
  		GLES20.glVertexAttribPointer(texCoordIndex, 2, GLES20.GL_FLOAT, false, vertexSize, 8);
  
  		GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
  
  		GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
  
  		GLES20.glDisableVertexAttribArray(positionIndex);
  		GLES20.glDisableVertexAttribArray(texCoordIndex);
  	}
  }
  