           draw_dashed_border(local_pos, distance_from_mix_line);
           break;
         case BORDER_STYLE_DOTTED:
+            draw_dotted_border(local_pos, distance_from_mix_line);
+            break;
         case BORDER_STYLE_OUTSET:
         case BORDER_STYLE_INSET:
         case BORDER_STYLE_SOLID:

  return alpha_for_solid_border(distance_from_ref, inner_radius, outer_radius, pixels_per_fragment);
}

#ifdef WR_FEATURE_TRANSFORM

#else
vec4 draw_dotted_edge(vec2 position, vec2 edge_size, float pixels_per_fragment) {
  float two_pixels = 2 * pixels_per_fragment;

  // Circle diameter is stroke width, minus a couple pixels to account for anti-aliasing.
  float circle_diameter = max(edge_size.x - two_pixels, min(edge_size.x, two_pixels));

  //// Divide the edge into segments which are the size of the circle diameter.
  float segments_in_edge = floor(edge_size.y / circle_diameter);

  // Every other segment has a circle.
  float number_of_circles = floor(segments_in_edge / 2);
  if (number_of_circles <= 0)
    return vec4(0, 0, 0, 0);

  // Spread the circles throughout the edge, to distribute the extra space evenly. We want
  // to ensure that we have at last two pixels of space for each circle so that they aren't
  // touching.
  float space_for_each_circle = ceil(max(edge_size.y / number_of_circles, two_pixels));

  // Find the circle index. We adjust the y position here because the first circle is a
  // half circle at the edge of this border side.
  float circle_index = floor((position.y + (space_for_each_circle / 2)) / space_for_each_circle);

  // Find the center of the circle that is closest to our position. We will then calculate
  // the distance from the edge of the circle.
  vec2 circle_center = vec2(edge_size.x / 2, circle_index * space_for_each_circle);
  float distance_from_circle_edge = length(circle_center - position) - (circle_diameter / 2);

  // Don't anti-alias if the circle diameter is small to avoid a blur of color.
  if (circle_diameter < two_pixels && distance_from_circle_edge > 0)

    }
    case PST_BOTTOM:
    case PST_TOP: {
      oFragColor = draw_dotted_edge(local_pos.yx, vPieceRect.yxwz, pixels_per_fragment);
      break;
    }
    case PST_LEFT:
    case PST_RIGHT:
    {
      oFragColor = draw_dotted_edge(local_pos.xy, vPieceRect.xyzw, pixels_per_fragment);
      break;
    }
  }
}

vec4 draw_dashed_edge(float position, float border_width, float pixels_per_fragment) {
  // TODO: Investigate exactly what FF does.
