diff --git a/vtm-android-example/src/org/oscim/android/test/ThemeStylerActivity.java b/vtm-android-example/src/org/oscim/android/test/ThemeStylerActivity.java
index fc050dc2..c2949ce8 100644
--- a/vtm-android-example/src/org/oscim/android/test/ThemeStylerActivity.java
+++ b/vtm-android-example/src/org/oscim/android/test/ThemeStylerActivity.java
@@ -81,15 +81,7 @@ public class ThemeStylerActivity extends BaseMapActivity implements OnSeekBarCha
 					s.set(areaBuilder.set(s)
 					    .color(modColor(s.color, areaColor))
 					    .blendColor(modColor(s.blendColor, areaColor))
-					    .build());
-
-					if (s.outline == null)
-						continue;
-
-					s.outline.set(lineBuilder.set(s.outline)
-					    .color(modColor(s.outline.color, areaColor))
-					    .stippleColor(modColor(s.outline.stippleColor,
-					                           areaColor))
+					    .strokeColor(modColor(s.strokeColor, areaColor))
 					    .build());
 				}
 			}
diff --git a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
index 2d3d1987..3c44d6d5 100644
--- a/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
+++ b/vtm/src/org/oscim/renderer/elements/PolygonLayer.java
@@ -17,16 +17,21 @@
 package org.oscim.renderer.elements;
 
 import static org.oscim.backend.GL20.GL_ALWAYS;
+import static org.oscim.backend.GL20.GL_ELEMENT_ARRAY_BUFFER;
 import static org.oscim.backend.GL20.GL_EQUAL;
 import static org.oscim.backend.GL20.GL_INVERT;
 import static org.oscim.backend.GL20.GL_KEEP;
+import static org.oscim.backend.GL20.GL_LINES;
 import static org.oscim.backend.GL20.GL_REPLACE;
 import static org.oscim.backend.GL20.GL_SHORT;
 import static org.oscim.backend.GL20.GL_TRIANGLE_FAN;
 import static org.oscim.backend.GL20.GL_TRIANGLE_STRIP;
+import static org.oscim.backend.GL20.GL_UNSIGNED_SHORT;
 import static org.oscim.backend.GL20.GL_ZERO;
 import static org.oscim.utils.FastMath.clamp;
 
+import java.nio.ShortBuffer;
+
 import org.oscim.core.GeometryBuffer;
 import org.oscim.core.Tile;
 import org.oscim.renderer.GLMatrix;
@@ -43,7 +48,8 @@ import org.slf4j.LoggerFactory;
 /**
  * Special Renderer for drawing tile polygons using the stencil buffer method
  */
-public final class PolygonLayer extends RenderElement {
+public final class PolygonLayer extends IndexedRenderElement {
+
 	static final Logger log = LoggerFactory.getLogger(PolygonLayer.class);
 
 	public final static int CLIP_STENCIL = 1;
@@ -68,6 +74,10 @@ public final class PolygonLayer extends RenderElement {
 	public void addPolygon(float[] points, short[] index) {
 		short center = (short) ((Tile.SIZE >> 1) * S);
 
+		short id = (short) numVertices;
+
+		boolean outline = area.strokeWidth > 0;
+
 		for (int i = 0, pos = 0, n = index.length; i < n; i++) {
 			int length = index[i];
 			if (length < 0)
@@ -79,21 +89,45 @@ public final class PolygonLayer extends RenderElement {
 				continue;
 			}
 
-			numVertices += length / 2 + 2;
+			//numVertices += length / 2 + 2;
 			vertexItems.add(center, center);
+			id++;
 
 			int inPos = pos;
 
 			for (int j = 0; j < length; j += 2) {
 				vertexItems.add((short) (points[inPos++] * S),
 				                (short) (points[inPos++] * S));
+
+				if (outline) {
+					indiceItems.add(id++);
+					numIndices++;
+
+					indiceItems.add(id);
+					numIndices++;
+				} else {
+					id++;
+				}
 			}
 
 			vertexItems.add((short) (points[pos + 0] * S),
 			                (short) (points[pos + 1] * S));
+			id++;
 
 			pos += length;
 		}
+		numVertices = id;
+	}
+
+	@Override
+	protected void compile(ShortBuffer sbuf) {
+		if (area.strokeWidth == 0) {
+			/* add vertices to shared VBO */
+			compileVertexItems(sbuf);
+			return;
+		}
+		/* compile with indexed outline */
+		super.compile(sbuf);
 	}
 
 	static class Shader extends GLShader {
@@ -121,7 +155,7 @@ public final class PolygonLayer extends RenderElement {
 
 		private static final float FADE_START = 1.3f;
 
-		private static AreaStyle[] mAreaFills;
+		private static PolygonLayer[] mAreaFills;
 
 		private static Shader polyShader;
 		private static Shader texShader;
@@ -130,7 +164,7 @@ public final class PolygonLayer extends RenderElement {
 			polyShader = new Shader("base_shader");
 			texShader = new Shader("polygon_layer_tex");
 
-			mAreaFills = new AreaStyle[STENCIL_BITS];
+			mAreaFills = new PolygonLayer[STENCIL_BITS];
 
 			return true;
 		}
@@ -143,15 +177,19 @@ public final class PolygonLayer extends RenderElement {
 
 			/* do not modify stencil buffer */
 			GL.glStencilMask(0x00);
-			//int shader = polyShader;
+			Shader s;
 
-			Shader s = setShader(polyShader, v.mvp, false);
+			for (int i = start; i < end; i++) {
+				PolygonLayer l = mAreaFills[i];
+				AreaStyle a = l.area.current();
 
-			for (int c = start; c < end; c++) {
-				AreaStyle a = mAreaFills[c].current();
-
-				if (enableTexture && a.texture != null) {
+				boolean useTexture = enableTexture && a.texture != null;
+				if (useTexture)
 					s = setShader(texShader, v.mvp, false);
+				else
+					s = setShader(polyShader, v.mvp, false);
+
+				if (useTexture) {
 					float num = clamp((Tile.SIZE / a.texture.width) >> 1, 1, Tile.SIZE);
 					float transition = Interpolation.exp5.apply(clamp(scale - 1, 0, 1));
 					GL.glUniform2f(s.uScale, transition, div / num);
@@ -184,10 +222,8 @@ public final class PolygonLayer extends RenderElement {
 						GLUtils.setColor(s.uColor, a.blendColor, 1);
 
 				} else {
-					if (a.color < 0xff000000)
-						GLState.blend(true);
-					else
-						GLState.blend(false);
+					/* test if color contains alpha */
+					GLState.blend((a.color & OPAQUE) != OPAQUE);
 
 					GLUtils.setColor(s.uColor, a.color, 1);
 				}
@@ -195,14 +231,37 @@ public final class PolygonLayer extends RenderElement {
 				/* set stencil buffer mask used to draw this layer
 				 * also check that clip bit is set to avoid overdraw
 				 * of other tiles */
-				GL.glStencilFunc(GL_EQUAL, 0xff, CLIP_BIT | 1 << c);
+				GL.glStencilFunc(GL_EQUAL, 0xff, CLIP_BIT | 1 << i);
 
 				/* draw tile fill coordinates */
 				GL.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
 
-				/* disable texture shader */
-				if (s != polyShader)
-					s = setShader(polyShader, v.mvp, false);
+				if (l.indicesVbo == null)
+					continue;
+
+				GL.glStencilFunc(GL_EQUAL, CLIP_BIT, CLIP_BIT);
+
+				GLState.blend(true);
+				//GLState.testDepth(false);
+
+				HairLineLayer.Renderer.shader.set(v);
+
+				l.indicesVbo.bind();
+
+				GLUtils.setColor(HairLineLayer.Renderer.shader.uColor, l.area.strokeColor, 1);
+
+				GL.glVertexAttribPointer(HairLineLayer.Renderer.shader.aPos, 2, GL_SHORT,
+				                         false, 0, l.offset << 2);
+
+				GL.glDrawElements(GL_LINES, l.numIndices,
+				                  GL_UNSIGNED_SHORT, 0);
+				GL.glLineWidth(1);
+
+				GL.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+				///* disable texture shader */
+				//if (s != polyShader)
+				//s = setShader(polyShader, v, false);
 			}
 		}
 
@@ -280,7 +339,7 @@ public final class PolygonLayer extends RenderElement {
 					start = cur = 0;
 				}
 
-				mAreaFills[cur] = pl.area.current();
+				mAreaFills[cur] = pl;
 
 				/* set stencil mask to draw to */
 				GL.glStencilMask(1 << cur++);
diff --git a/vtm/src/org/oscim/theme/XmlThemeBuilder.java b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
index f0399e27..3c7bff0a 100644
--- a/vtm/src/org/oscim/theme/XmlThemeBuilder.java
+++ b/vtm/src/org/oscim/theme/XmlThemeBuilder.java
@@ -472,8 +472,7 @@ public class XmlThemeBuilder extends DefaultHandler {
 			}
 		}
 
-		AreaStyle area = createArea(style, localName, attributes, mLevels);
-		mLevels += 2;
+		AreaStyle area = createArea(style, localName, attributes, mLevels++);
 
 		if (isStyle) {
 			mStyles.put(AREA_STYLE + area.style, area);
@@ -509,12 +508,12 @@ public class XmlThemeBuilder extends DefaultHandler {
 				b.color(value);
 
 			else if ("stroke".equals(name))
-				b.outlineColor(value);
+				b.strokeColor(value);
 
 			else if ("stroke-width".equals(name)) {
 				float strokeWidth = Float.parseFloat(value);
 				validateNonNegative("stroke-width", strokeWidth);
-				b.outlineWidth = strokeWidth;
+				b.strokeWidth = strokeWidth;
 
 			} else if ("fade".equals(name))
 				b.fadeScale = Integer.parseInt(value);
diff --git a/vtm/src/org/oscim/theme/styles/AreaStyle.java b/vtm/src/org/oscim/theme/styles/AreaStyle.java
index 35adebbb..fa4f2e5d 100644
--- a/vtm/src/org/oscim/theme/styles/AreaStyle.java
+++ b/vtm/src/org/oscim/theme/styles/AreaStyle.java
@@ -46,7 +46,8 @@ public class AreaStyle extends RenderStyle {
 	public final TextureItem texture;
 
 	/** Outline */
-	public final LineStyle outline;
+	public final int strokeColor;
+	public final float strokeWidth;
 
 	public AreaStyle(int color) {
 		this(0, color);
@@ -60,7 +61,8 @@ public class AreaStyle extends RenderStyle {
 		this.blendScale = -1;
 		this.color = color;
 		this.texture = null;
-		this.outline = null;
+		this.strokeColor = color;
+		this.strokeWidth = 1;
 	}
 
 	public AreaStyle(AreaBuilder b) {
@@ -72,23 +74,8 @@ public class AreaStyle extends RenderStyle {
 		this.color = b.color;
 		this.texture = b.texture;
 
-		if (b.outline != null &&
-		        b.outlineColor == b.outline.color &&
-		        b.outlineWidth == b.outline.width) {
-			this.outline = b.outline;
-		} else if (b.outlineColor != Color.TRANSPARENT) {
-			this.outline = new LineStyle(-1, b.outlineColor, b.outlineWidth);
-		} else {
-			this.outline = null;
-		}
-	}
-
-	@Override
-	public void update() {
-		super.update();
-
-		if (outline != null)
-			outline.update();
+		this.strokeColor = b.strokeColor;
+		this.strokeWidth = b.strokeWidth;
 	}
 
 	@Override
@@ -99,22 +86,18 @@ public class AreaStyle extends RenderStyle {
 	@Override
 	public void renderWay(Callback renderCallback) {
 		renderCallback.renderArea(this, level);
-
-		if (outline != null)
-			renderCallback.renderWay(outline, level + 1);
 	}
 
 	public static class AreaBuilder implements StyleBuilder {
 		public int level;
 		public String style;
-		public LineStyle outline;
 		public int color;
 		public int fadeScale;
 		public int blendColor;
 		public int blendScale;
 
-		public int outlineColor;
-		public float outlineWidth;
+		public int strokeColor;
+		public float strokeWidth;
 
 		public TextureItem texture;
 
@@ -129,14 +112,8 @@ public class AreaStyle extends RenderStyle {
 			this.blendScale = area.blendScale;
 			this.color = area.color;
 			this.texture = area.texture;
-			this.outline = area.outline;
-			if (area.outline != null) {
-				this.outlineColor = outline.color;
-				this.outlineWidth = outline.width;
-			} else {
-				outlineColor = Color.TRANSPARENT;
-				outlineWidth = 1;
-			}
+			this.strokeColor = area.strokeColor;
+			this.strokeWidth = area.strokeWidth;
 
 			return this;
 		}
@@ -152,23 +129,23 @@ public class AreaStyle extends RenderStyle {
 		}
 
 		public AreaBuilder outline(int color, float width) {
-			this.outlineColor = color;
-			this.outlineWidth = width;
+			this.strokeColor = color;
+			this.strokeWidth = width;
 			return this;
 		}
 
-		public AreaBuilder outlineColor(int color) {
-			this.outlineColor = color;
+		public AreaBuilder strokeColor(int color) {
+			this.strokeColor = color;
 			return this;
 		}
 
-		public AreaBuilder outlineColor(String color) {
-			this.outlineColor = parseColor(color);
+		public AreaBuilder strokeColor(String color) {
+			this.strokeColor = parseColor(color);
 			return this;
 		}
 
-		public AreaBuilder outlineWidth(float width) {
-			this.outlineWidth = width;
+		public AreaBuilder strokeWidth(float width) {
+			this.strokeWidth = width;
 			return this;
 		}
 
@@ -209,10 +186,8 @@ public class AreaStyle extends RenderStyle {
 
 		public AreaBuilder reset() {
 			color = Color.BLACK;
-
-			outlineColor = Color.TRANSPARENT;
-			outlineWidth = 1;
-
+			strokeColor = Color.BLACK;
+			strokeWidth = 0;
 			fadeScale = -1;
 			blendScale = -1;
 			blendColor = Color.TRANSPARENT;