[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[gef3d-commits] r505 - branches/better_lod/org.eclipse.draw3d.lwjgl/src/java/org/eclipse/draw3d/graphics3d/lwjgl/font

Author: kduske
Date: 2010-07-27 12:11:49 -0400 (Tue, 27 Jul 2010)
New Revision: 505

Modified:
   branches/better_lod/org.eclipse.draw3d.lwjgl/src/java/org/eclipse/draw3d/graphics3d/lwjgl/font/LwjglVectorFont.java
Log:
NEW - bug 318148: Problems with LOD of fonts 
https://bugs.eclipse.org/bugs/show_bug.cgi?id=318148

Modified: branches/better_lod/org.eclipse.draw3d.lwjgl/src/java/org/eclipse/draw3d/graphics3d/lwjgl/font/LwjglVectorFont.java
===================================================================
--- branches/better_lod/org.eclipse.draw3d.lwjgl/src/java/org/eclipse/draw3d/graphics3d/lwjgl/font/LwjglVectorFont.java	2010-07-23 15:35:45 UTC (rev 504)
+++ branches/better_lod/org.eclipse.draw3d.lwjgl/src/java/org/eclipse/draw3d/graphics3d/lwjgl/font/LwjglVectorFont.java	2010-07-27 16:11:49 UTC (rev 505)
@@ -45,6 +45,80 @@
  */
 public class LwjglVectorFont {
 
+	private static class FontCallback extends GLUtessellatorCallbackAdapter {
+
+		private VectorCharData m_charData = new VectorCharData();
+
+		private int m_curType;
+
+		private List<IVector2f> m_curVerts = new LinkedList<IVector2f>();
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#begin(int)
+		 */
+		@Override
+		public void begin(int i_type) {
+			m_curType = i_type;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#combine(double[],
+		 *      java.lang.Object[], float[], java.lang.Object[])
+		 */
+		@Override
+		public void combine(double[] i_coords, Object[] i_data,
+			float[] i_weight, Object[] i_outData) {
+
+			i_outData[0] =
+				new Vector2fImpl((float) i_coords[0], (float) i_coords[1]);
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#end()
+		 */
+		@Override
+		public void end() {
+			m_charData.addPrimitive(m_curType, m_curVerts);
+			m_curVerts.clear();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#error(int)
+		 */
+		@Override
+		public void error(int i_errnum) {
+			throw new RuntimeException(
+				"caught error during polygon tesselation: " + i_errnum);
+		}
+
+		public VectorCharData getCharData() {
+			return m_charData;
+		}
+
+		public void reset() {
+			m_curVerts.clear();
+			m_charData = new VectorCharData();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#vertex(java.lang.Object)
+		 */
+		@Override
+		public void vertex(Object i_vertexData) {
+			m_curVerts.add((IVector2f) i_vertexData);
+		}
+	}
+
 	private static class PrimitiveData {
 		private float[] m_vertices;
 
@@ -56,253 +130,345 @@
 				vertex.toArray(m_vertices, 2 * i++);
 		}
 
+		public int getVertexCount() {
+			return m_vertices.length / 2;
+		}
+
 		public float[] getVertices() {
 			return m_vertices;
 		}
-
-		public int getVertexCount() {
-			return m_vertices.length / 2;
-		}
 	}
 
-	private static class VectorCharData {
+	private static class RangeCharacterIterator implements CharacterIterator {
 
-		private Map<Integer, List<PrimitiveData>> m_primitives =
-			new HashMap<Integer, List<PrimitiveData>>();
+		private int m_current = 0;
 
-		private int m_vertexCount = 0;
+		private int m_numChars;
 
-		public void addPrimitive(int i_type, List<IVector2f> i_primitive) {
-			if (i_primitive.size() > 0) {
-				List<PrimitiveData> primitivesOfType = m_primitives.get(i_type);
-				if (primitivesOfType == null) {
-					primitivesOfType = new LinkedList<PrimitiveData>();
-					m_primitives.put(i_type, primitivesOfType);
-				}
+		public RangeCharacterIterator(int i_numChars) {
+			m_numChars = i_numChars;
+		}
 
-				primitivesOfType.add(new PrimitiveData(i_primitive));
-				m_vertexCount += i_primitive.size();
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.lang.Object#clone()
+		 */
+		@Override
+		public Object clone() {
+			try {
+				return super.clone();
+			} catch (CloneNotSupportedException e) {
+				throw new RuntimeException(e);
 			}
 		}
 
-		public List<PrimitiveData> getPrimitives(int i_type) {
-			return m_primitives.get(i_type);
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#current()
+		 */
+		public char current() {
+			if (m_current < getBeginIndex() || m_current >= getEndIndex())
+				return DONE;
+
+			return (char) m_current;
 		}
 
-		public int getVertexCount() {
-			return m_vertexCount;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#first()
+		 */
+		public char first() {
+			m_current = getBeginIndex();
+			return current();
 		}
 
-	}
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#getBeginIndex()
+		 */
+		public int getBeginIndex() {
+			return 0;
+		}
 
-	private static class VectorChar {
-		private IntBuffer m_triFanIndices;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#getEndIndex()
+		 */
+		public int getEndIndex() {
+			return m_numChars;
+		}
 
-		private IntBuffer m_triFanLengths;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#getIndex()
+		 */
+		public int getIndex() {
+			return m_current;
+		}
 
-		private IntBuffer m_triStripIndices;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#last()
+		 */
+		public char last() {
+			m_current = getEndIndex() - 1;
+			return current();
+		}
 
-		private IntBuffer m_triStripLengths;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#next()
+		 */
+		public char next() {
+			m_current++;
+			if (m_current >= getEndIndex())
+				return DONE;
 
-		private IntBuffer m_trisIndices;
+			return current();
+		}
 
-		private IntBuffer m_trisLengths;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#previous()
+		 */
+		public char previous() {
+			m_current--;
+			if (m_current < getBeginIndex())
+				return DONE;
 
-		private IntBuffer m_loopIndices;
+			return current();
+		}
 
-		private IntBuffer m_loopLengths;
+		/**
+		 * {@inheritDoc}
+		 * 
+		 * @see java.text.CharacterIterator#setIndex(int)
+		 */
+		public char setIndex(int i_index) {
+			if (i_index < getBeginIndex() || i_index > getEndIndex())
+				throw new IllegalArgumentException("index is out of bounds: "
+					+ i_index);
 
+			m_current = i_index;
+			return current();
+		}
+
+	}
+
+	private static class VectorChar {
 		private float m_advanceX;
 
 		private float m_advanceY;
 
-		public VectorChar(float i_advanceX, float i_advanceY) {
-			m_advanceX = i_advanceX;
-			m_advanceY = i_advanceY;
-		}
+		private List<PrimitiveData> m_lineLoops;
 
-		public void render() {
-			if (m_triFanIndices != null) {
-				m_triFanIndices.rewind();
-				m_triFanLengths.rewind();
+		private IntBuffer m_loopIndices;
 
-				GL14.glMultiDrawArrays(GL11.GL_TRIANGLE_FAN, m_triFanIndices,
-					m_triFanLengths);
-			}
+		private IntBuffer m_loopLengths;
 
-			if (m_triStripIndices != null) {
-				m_triStripIndices.rewind();
-				m_triStripLengths.rewind();
+		private List<PrimitiveData> m_triangleFans;
 
-				GL14.glMultiDrawArrays(GL11.GL_TRIANGLE_STRIP,
-					m_triStripIndices, m_triStripLengths);
-			}
+		private List<PrimitiveData> m_triangles;
 
-			if (m_trisIndices != null) {
-				m_trisIndices.rewind();
-				m_trisLengths.rewind();
-				GL14.glMultiDrawArrays(GL11.GL_TRIANGLES, m_trisIndices,
-					m_trisLengths);
-			}
+		private List<PrimitiveData> m_triangleStrips;
 
-			if (m_loopIndices != null) {
-				m_loopIndices.rewind();
-				m_loopLengths.rewind();
-				GL14.glMultiDrawArrays(GL11.GL_LINE_LOOP, m_loopIndices,
-					m_loopLengths);
-			}
+		private IntBuffer m_triFanIndices;
 
-			GL11.glTranslatef(m_advanceX, m_advanceY, 0);
+		private IntBuffer m_triFanLengths;
+
+		private IntBuffer m_trisIndices;
+
+		private IntBuffer m_trisLengths;
+
+		private IntBuffer m_triStripIndices;
+
+		private IntBuffer m_triStripLengths;
+
+		public VectorChar(float i_advanceX, float i_advanceY) {
+			m_advanceX = i_advanceX;
+			m_advanceY = i_advanceY;
 		}
 
-		public int setTriangleFans(List<PrimitiveData> i_data,
-			FloatBuffer i_buffer, int i_startIndex) {
-			if (i_data.isEmpty())
+		public int compile(FloatBuffer i_buffer, int i_startIndex) {
+			int index = i_startIndex;
+
+			index = compileTriangleFans(i_buffer, index);
+			index = compileTriangleStrips(i_buffer, index);
+			index = compileTriangles(i_buffer, index);
+			index = compileLineLoops(i_buffer, index);
+
+			return index;
+		}
+
+		public int compileLineLoops(FloatBuffer i_buffer, int i_startIndex) {
+			if (m_lineLoops == null || m_lineLoops.isEmpty())
 				return i_startIndex;
 
-			m_triFanIndices = BufferUtils.createIntBuffer(i_data.size());
-			m_triFanLengths = BufferUtils.createIntBuffer(i_data.size());
+			m_loopIndices = BufferUtils.createIntBuffer(m_lineLoops.size());
+			m_loopLengths = BufferUtils.createIntBuffer(m_lineLoops.size());
 
 			int index = i_startIndex;
-			for (PrimitiveData primitive : i_data) {
+			for (PrimitiveData primitive : m_lineLoops) {
 				i_buffer.put(primitive.getVertices());
-				m_triFanIndices.put(index);
-				m_triFanLengths.put(primitive.getVertexCount());
+				m_loopIndices.put(index);
+				m_loopLengths.put(primitive.getVertexCount());
 				index += primitive.getVertexCount();
 			}
 
+			m_lineLoops = null;
 			return index;
 		}
 
-		public int setTriangleStrips(List<PrimitiveData> i_data,
-			FloatBuffer i_buffer, int i_startIndex) {
-			if (i_data.isEmpty())
+		private int compileTriangleFans(FloatBuffer i_buffer, int i_startIndex) {
+			if (m_triangleFans == null || m_triangleFans.isEmpty())
 				return i_startIndex;
 
-			m_triStripIndices = BufferUtils.createIntBuffer(i_data.size());
-			m_triStripLengths = BufferUtils.createIntBuffer(i_data.size());
+			m_triFanIndices =
+				BufferUtils.createIntBuffer(m_triangleFans.size());
+			m_triFanLengths =
+				BufferUtils.createIntBuffer(m_triangleFans.size());
 
 			int index = i_startIndex;
-			for (PrimitiveData primitive : i_data) {
+			for (PrimitiveData primitive : m_triangleFans) {
 				i_buffer.put(primitive.getVertices());
-				m_triStripIndices.put(index);
-				m_triStripLengths.put(primitive.getVertexCount());
+				m_triFanIndices.put(index);
+				m_triFanLengths.put(primitive.getVertexCount());
 				index += primitive.getVertexCount();
 			}
 
+			m_triangleFans = null;
 			return index;
 		}
 
-		public int setTriangles(List<PrimitiveData> i_data,
-			FloatBuffer i_buffer, int i_startIndex) {
-			if (i_data.isEmpty())
+		public int compileTriangles(FloatBuffer i_buffer, int i_startIndex) {
+			if (m_triangles == null || m_triangles.isEmpty())
 				return i_startIndex;
 
-			m_trisIndices = BufferUtils.createIntBuffer(i_data.size());
-			m_trisLengths = BufferUtils.createIntBuffer(i_data.size());
+			m_trisIndices = BufferUtils.createIntBuffer(m_triangles.size());
+			m_trisLengths = BufferUtils.createIntBuffer(m_triangles.size());
 
 			int index = i_startIndex;
-			for (PrimitiveData primitive : i_data) {
+			for (PrimitiveData primitive : m_triangles) {
 				i_buffer.put(primitive.getVertices());
 				m_trisIndices.put(index);
 				m_trisLengths.put(primitive.getVertexCount());
 				index += primitive.getVertexCount();
 			}
 
+			m_triangles = null;
 			return index;
 		}
 
-		public int setLoops(List<PrimitiveData> i_data, FloatBuffer i_buffer,
-			int i_startIndex) {
-			if (i_data.isEmpty())
+		public int compileTriangleStrips(FloatBuffer i_buffer, int i_startIndex) {
+			if (m_triangleStrips == null || m_triangleStrips.isEmpty())
 				return i_startIndex;
 
-			m_loopIndices = BufferUtils.createIntBuffer(i_data.size());
-			m_loopLengths = BufferUtils.createIntBuffer(i_data.size());
+			m_triStripIndices =
+				BufferUtils.createIntBuffer(m_triangleStrips.size());
+			m_triStripLengths =
+				BufferUtils.createIntBuffer(m_triangleStrips.size());
 
 			int index = i_startIndex;
-			for (PrimitiveData primitive : i_data) {
+			for (PrimitiveData primitive : m_triangleStrips) {
 				i_buffer.put(primitive.getVertices());
-				m_loopIndices.put(index);
-				m_loopLengths.put(primitive.getVertexCount());
+				m_triStripIndices.put(index);
+				m_triStripLengths.put(primitive.getVertexCount());
 				index += primitive.getVertexCount();
 			}
 
+			m_triangleStrips = null;
 			return index;
 		}
-	}
 
-	private static class FontCallback extends GLUtessellatorCallbackAdapter {
+		public void render() {
+			if (m_triFanIndices != null) {
+				m_triFanIndices.rewind();
+				m_triFanLengths.rewind();
 
-		private VectorCharData m_charData = new VectorCharData();
+				GL14.glMultiDrawArrays(GL11.GL_TRIANGLE_FAN, m_triFanIndices,
+					m_triFanLengths);
+			}
 
-		private int m_curType;
+			if (m_triStripIndices != null) {
+				m_triStripIndices.rewind();
+				m_triStripLengths.rewind();
 
-		private List<IVector2f> m_curVerts = new LinkedList<IVector2f>();
+				GL14.glMultiDrawArrays(GL11.GL_TRIANGLE_STRIP,
+					m_triStripIndices, m_triStripLengths);
+			}
 
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#begin(int)
-		 */
-		@Override
-		public void begin(int i_type) {
-			m_curType = i_type;
+			if (m_trisIndices != null) {
+				m_trisIndices.rewind();
+				m_trisLengths.rewind();
+				GL14.glMultiDrawArrays(GL11.GL_TRIANGLES, m_trisIndices,
+					m_trisLengths);
+			}
+
+			if (m_loopIndices != null) {
+				m_loopIndices.rewind();
+				m_loopLengths.rewind();
+				GL14.glMultiDrawArrays(GL11.GL_LINE_LOOP, m_loopIndices,
+					m_loopLengths);
+			}
+
+			GL11.glTranslatef(m_advanceX, m_advanceY, 0);
 		}
 
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#combine(double[],
-		 *      java.lang.Object[], float[], java.lang.Object[])
-		 */
-		@Override
-		public void combine(double[] i_coords, Object[] i_data,
-			float[] i_weight, Object[] i_outData) {
+		public void setLineLoops(List<PrimitiveData> i_lineLoops) {
+			m_lineLoops = i_lineLoops;
+		}
 
-			i_outData[0] =
-				new Vector2fImpl((float) i_coords[0], (float) i_coords[1]);
+		public void setTriangleFans(List<PrimitiveData> i_triangleFans) {
+			m_triangleFans = i_triangleFans;
 		}
 
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#end()
-		 */
-		@Override
-		public void end() {
-			m_charData.addPrimitive(m_curType, m_curVerts);
-			m_curVerts.clear();
+		public void setTriangles(List<PrimitiveData> i_triangles) {
+			m_triangles = i_triangles;
 		}
 
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#error(int)
-		 */
-		@Override
-		public void error(int i_errnum) {
-			throw new RuntimeException(
-				"caught error during polygon tesselation: " + i_errnum);
+		public void setTriangleStrips(List<PrimitiveData> i_triangleStrips) {
+			m_triangleStrips = i_triangleStrips;
 		}
+	}
 
-		public void reset() {
-			m_curVerts.clear();
-			m_charData = new VectorCharData();
+	private static class VectorCharData {
+
+		private Map<Integer, List<PrimitiveData>> m_primitives =
+			new HashMap<Integer, List<PrimitiveData>>();
+
+		private int m_vertexCount = 0;
+
+		public void addPrimitive(int i_type, List<IVector2f> i_primitive) {
+			if (i_primitive.size() > 0) {
+				List<PrimitiveData> primitivesOfType = m_primitives.get(i_type);
+				if (primitivesOfType == null) {
+					primitivesOfType = new LinkedList<PrimitiveData>();
+					m_primitives.put(i_type, primitivesOfType);
+				}
+
+				primitivesOfType.add(new PrimitiveData(i_primitive));
+				m_vertexCount += i_primitive.size();
+			}
 		}
 
-		public VectorCharData getCharData() {
-			return m_charData;
+		public int getVertexCount() {
+			return m_vertexCount;
 		}
 
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see org.lwjgl.util.glu.GLUtessellatorCallbackAdapter#vertex(java.lang.Object)
-		 */
-		@Override
-		public void vertex(Object i_vertexData) {
-			m_curVerts.add((IVector2f) i_vertexData);
+		public void setPrimitives(VectorChar i_vectorChar) {
+			i_vectorChar.setTriangleFans(m_primitives.get(GL11.GL_TRIANGLE_FAN));
+			i_vectorChar.setTriangleStrips(m_primitives.get(GL11.GL_TRIANGLE_STRIP));
+			i_vectorChar.setTriangles(m_primitives.get(GL11.GL_TRIANGLES));
+			i_vectorChar.setLineLoops(m_primitives.get(GL11.GL_LINE_LOOP));
 		}
 	}
 
@@ -321,8 +487,6 @@
 
 	private Font m_awtFont;
 
-	private int m_bufferId = 0;
-
 	private int m_numChars;
 
 	private int m_textureId = 0;
@@ -331,6 +495,8 @@
 
 	private int m_vectorListBaseId = -1;
 
+	private int m_vertexBufferId = 0;
+
 	public LwjglVectorFont(org.eclipse.swt.graphics.Font i_swtFont,
 			int i_numChars, boolean i_antialias) {
 
@@ -359,11 +525,31 @@
 		m_antialias = i_antialias;
 	}
 
+	private int createDisplayLists(VectorChar[] i_chars) {
+		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, m_vertexBufferId);
+		GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
+		try {
+			GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
+			int listBaseId = GL11.glGenLists(i_chars.length);
+			for (int i = 0; i < i_chars.length; i++) {
+				int listId = m_vectorListBaseId + i;
+				GL11.glNewList(listId, GL11.GL_COMPILE);
+				i_chars[i].render();
+				GL11.glEndList();
+			}
+
+			return listBaseId;
+		} finally {
+			GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
+		}
+	}
+
 	private void createTextureData(GlyphVector i_glyphs) {
 
 	}
 
-	private VectorChar[] createVectorData(GlyphVector i_glyphs) {
+	private int createVectorData(GlyphVector i_glyphs,
+		VectorChar[] i_vectorChars) {
 		GLUtessellator tesselator = GLU.gluNewTess();
 		try {
 			FontCallback callback = new FontCallback();
@@ -392,20 +578,20 @@
 			// character, so we have to store all of that data in different
 			// arrays.
 
-			int charCount = i_glyphs.getNumGlyphs();
-			VectorCharData[] charData = new VectorCharData[charCount];
-			VectorChar[] chars = new VectorChar[charCount];
 			int totalVertexCount = 0;
-
 			double[] coords = new double[] { 0, 0, 0 };
 
 			AffineTransform af = new AffineTransform();
 			af.translate(0, m_awtFont.getSize());
 
-			for (int i = 0; i < charCount; i++) {
+			for (int i = 0; i < i_glyphs.getNumGlyphs(); i++) {
 				Shape outline = i_glyphs.getGlyphOutline(i);
 				PathIterator path = outline.getPathIterator(af, 0.01d);
 
+				float advanceX = i_glyphs.getGlyphMetrics(i).getAdvanceX();
+				float advanceY = i_glyphs.getGlyphMetrics(i).getAdvanceY();
+				i_vectorChars[i] = new VectorChar(advanceX, advanceY);
+
 				if (!path.isDone()) {
 					if (path.getWindingRule() == PathIterator.WIND_EVEN_ODD)
 						tesselator.gluTessProperty(GLU.GLU_TESS_WINDING_RULE,
@@ -438,70 +624,44 @@
 					}
 					tesselator.gluTessEndPolygon();
 
-					charData[i] = callback.getCharData();
-					totalVertexCount += charData[i].getVertexCount();
+					VectorCharData charData = callback.getCharData();
 
+					charData.setPrimitives(i_vectorChars[i]);
+					totalVertexCount += charData.getVertexCount();
+
 					callback.reset();
 				}
 
-				float advanceX = i_glyphs.getGlyphMetrics(i).getAdvanceX();
-				float advanceY = i_glyphs.getGlyphMetrics(i).getAdvanceY();
 				af.translate(-advanceX, -advanceY);
-				chars[i] = new VectorChar(advanceX, advanceY);
 			}
 
-			int idx = 0;
-			FloatBuffer buf =
-				BufferUtils.createFloatBuffer(2 * totalVertexCount);
-			for (int i = 0; i < charData.length; i++) {
-				if (charData[i] != null && charData[i].getVertexCount() > 0) {
-					List<PrimitiveData> triFans =
-						charData[i].getPrimitives(GL11.GL_TRIANGLE_FAN);
-					if (triFans != null)
-						idx = chars[i].setTriangleFans(triFans, buf, idx);
-
-					List<PrimitiveData> triStrips =
-						charData[i].getPrimitives(GL11.GL_TRIANGLE_STRIP);
-					if (triStrips != null)
-						idx = chars[i].setTriangleStrips(triStrips, buf, idx);
-
-					List<PrimitiveData> triangles =
-						charData[i].getPrimitives(GL11.GL_TRIANGLES);
-					if (triangles != null)
-						idx = chars[i].setTriangles(triangles, buf, idx);
-
-					List<PrimitiveData> loops =
-						charData[i].getPrimitives(GL11.GL_LINE_LOOP);
-					if (loops != null)
-						idx = chars[i].setLoops(loops, buf, idx);
-				}
-			}
-
-			m_bufferId = generateBufferId();
-			uploadBuffer(m_bufferId, buf);
-
-			return chars;
+			return totalVertexCount;
 		} finally {
 			tesselator.gluDeleteTess();
 		}
 	}
 
-	private int createDisplayLists(VectorChar[] i_chars) {
-		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, m_bufferId);
-		GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
+	private int createVertexBuffer(VectorChar[] i_chars, int i_totalVertexCount) {
+
+		int idx = 0;
+		FloatBuffer buf = BufferUtils.createFloatBuffer(2 * i_totalVertexCount);
+		for (int i = 0; i < i_chars.length; i++)
+			idx = i_chars[i].compile(buf, idx);
+
+		IntBuffer idBuffer = Draw3DCache.getIntBuffer(1);
 		try {
-			GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
-			int listBaseId = GL11.glGenLists(i_chars.length);
-			for (int i = 0; i < i_chars.length; i++) {
-				int listId = m_vectorListBaseId + i;
-				GL11.glNewList(listId, GL11.GL_COMPILE);
-				i_chars[i].render();
-				GL11.glEndList();
-			}
+			idBuffer.rewind();
+			GL15.glGenBuffers(idBuffer);
 
-			return listBaseId;
+			int bufferId = idBuffer.get(0);
+			buf.rewind();
+
+			GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, bufferId);
+			GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buf, GL15.GL_STREAM_READ);
+
+			return bufferId;
 		} finally {
-			GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
+			Draw3DCache.returnIntBuffer(idBuffer);
 		}
 	}
 
@@ -519,14 +679,14 @@
 
 		IntBuffer idBuffer = Draw3DCache.getIntBuffer(1);
 		try {
-			if (m_bufferId != 0) {
+			if (m_vertexBufferId != 0) {
 				idBuffer.rewind();
-				idBuffer.put(m_bufferId);
+				idBuffer.put(m_vertexBufferId);
 
 				idBuffer.rewind();
 				GL15.glDeleteBuffers(idBuffer);
 
-				m_bufferId = 0;
+				m_vertexBufferId = 0;
 			}
 
 			if (m_textureId != 0) {
@@ -544,157 +704,23 @@
 
 	}
 
-	private int generateBufferId() {
-
-		IntBuffer idBuffer = Draw3DCache.getIntBuffer(1);
-		try {
-			idBuffer.rewind();
-			GL15.glGenBuffers(idBuffer);
-
-			return idBuffer.get(0);
-		} finally {
-			Draw3DCache.returnIntBuffer(idBuffer);
-		}
-	}
-
-	private static class RangeCharacterIterator implements CharacterIterator {
-
-		private int m_numChars;
-
-		private int m_current = 0;
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.lang.Object#clone()
-		 */
-		@Override
-		public Object clone() {
-			try {
-				return super.clone();
-			} catch (CloneNotSupportedException e) {
-				throw new RuntimeException(e);
-			}
-		}
-
-		public RangeCharacterIterator(int i_numChars) {
-			m_numChars = i_numChars;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#current()
-		 */
-		public char current() {
-			if (m_current < getBeginIndex() || m_current >= getEndIndex())
-				return DONE;
-
-			return (char) m_current;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#first()
-		 */
-		public char first() {
-			m_current = getBeginIndex();
-			return current();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#getBeginIndex()
-		 */
-		public int getBeginIndex() {
-			return 0;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#getEndIndex()
-		 */
-		public int getEndIndex() {
-			return m_numChars;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#getIndex()
-		 */
-		public int getIndex() {
-			return m_current;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#last()
-		 */
-		public char last() {
-			m_current = getEndIndex() - 1;
-			return current();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#next()
-		 */
-		public char next() {
-			m_current++;
-			if (m_current >= getEndIndex())
-				return DONE;
-
-			return current();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#previous()
-		 */
-		public char previous() {
-			m_current--;
-			if (m_current < getBeginIndex())
-				return DONE;
-
-			return current();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 * 
-		 * @see java.text.CharacterIterator#setIndex(int)
-		 */
-		public char setIndex(int i_index) {
-			if (i_index < getBeginIndex() || i_index > getEndIndex())
-				throw new IllegalArgumentException("index is out of bounds: "
-					+ i_index);
-
-			m_current = i_index;
-			return current();
-		}
-
-	}
-
 	public void initialize() {
-		// create a glyph vector that contains the missing char
+		// create a glyph vector for all chars
 		FontRenderContext ctx = new FontRenderContext(null, m_antialias, true);
 		RangeCharacterIterator charIter =
 			new RangeCharacterIterator(m_numChars);
 		GlyphVector glyphs = m_awtFont.createGlyphVector(ctx, charIter);
 
+		// add the missing char to the glyph vector
 		int[] codes = new int[m_numChars + 1];
 		glyphs.getGlyphCodes(0, m_numChars, codes);
 		codes[codes.length - 1] = m_awtFont.getMissingGlyphCode();
 		glyphs = m_awtFont.createGlyphVector(ctx, codes);
 
-		VectorChar[] vectorChars = createVectorData(glyphs);
+		// create vector font
+		VectorChar[] vectorChars = new VectorChar[glyphs.getNumGlyphs()];
+		int totalVertexCount = createVectorData(glyphs, vectorChars);
+		m_vertexBufferId = createVertexBuffer(vectorChars, totalVertexCount);
 		m_vectorListBaseId = createDisplayLists(vectorChars);
 
 		createTextureData(glyphs);
@@ -705,7 +731,7 @@
 		if (i_string == null)
 			throw new NullPointerException("i_string must not be null");
 
-		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, m_bufferId);
+		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, m_vertexBufferId);
 		GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
 		try {
 			GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
@@ -736,11 +762,4 @@
 		}
 	}
 
-	private void uploadBuffer(int i_bufferId, FloatBuffer i_buffer) {
-
-		i_buffer.rewind();
-		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, i_bufferId);
-		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, i_buffer, GL15.GL_STREAM_READ);
-	}
-
 }