   return mix(white, circleColor, circleColor.a);
 }
 
+vec4 draw_dashed_edge() {
+  // Everything here should be in device pixels.
+  // We want the dot to be roughly the size of the whole border spacing
+  float dash_interval = min(vBorders.w, vBorders.z) * 2;
+  vec2 edge_size = vec2(vBorders.z, vBorders.w);
+  vec2 dash_size = vec2(dash_interval / 2.0, dash_interval / 2.0);
+  vec2 position = vDevicePos - vBorders.xy;
+
+  vec2 dash_count = floor(edge_size/ dash_interval);
+  vec2 dist_between_dashes = edge_size / dash_count;
+
+  vec2 target_rect_index = floor(position / dist_between_dashes);
+  vec2 target_rect_loc = target_rect_index * dist_between_dashes;
+
+  // TODO correct for center spacing.
+  vec4 target_rect = vec4(target_rect_loc, dash_size);
+
+  vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
+  vec3 black = vec3(0.0, 0.0, 0.0);
+  vec4 target_colored_rect = drawRect(position, target_rect, black);
+
+  return mix(white, target_colored_rect, target_colored_rect.a);
+
+  //vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
+  //return white;
+}
+
 void draw_dotted_border(void) {
   switch (vBorderPart) {
     // These are the layer tile part PrimitivePart as uploaded by the tiling.rs

	}

  switch (vBorderStyle) {
    case BORDER_STYLE_DOTTED:
    {
      draw_dotted_border();

  }
}

void draw_dashed_border(void) {
  switch (vBorderPart) {
    // These are the layer tile part PrimitivePart as uploaded by the tiling.rs
    case PST_TOP_LEFT:
    case PST_TOP_RIGHT:
    case PST_BOTTOM_LEFT:
    case PST_BOTTOM_RIGHT:
      // TODO: Fix for corners with a border-radius
      oFragColor = draw_dashed_edge();
      break;
    case PST_BOTTOM:
    case PST_TOP:
    case PST_LEFT:
    case PST_RIGHT:
      oFragColor = draw_dashed_edge();
      break;
  }
}

void main(void) {
	if (vRadii.x > 0.0 &&
		(distance(vRefPoint, vLocalPos) > vRadii.x ||
