2

With AWT I draw a border using java.awt.Graphics#drawOval and java.awt.Graphics2D#setStroke. For situations when the set stroke has a size bigger than the oval's diameter the resulting border is not like expected. In that situation the stroke overlaps the stroke of the other side of the circle: Circles north stroke overlaps the south stroke. AWT renders this overlapping in an XOR way as you can see in the following image.

What I'd expect instead is that the stroke overlapping is drawn in an OR way, so that in all situations when stroke width > circle diameter the center is black.

Is there a simple way I can set to change the behaviour to an OR overlapping mode, even when width or height of the circle (then its an ellipse) is not equal?

Same diameter (10px) with increasing stroke width:

Same diameter (10px) with increasing stroke width

Sebastian Barth
  • 4,079
  • 7
  • 40
  • 59
  • Unexpected, indeed. I never noticed this, and comparing the result to that of `drawRect`, I'm close to considering that as a bug (although I assume it would not be classified as such, because it could hardly have remained unnoticed). I played around a bit, but did not find a sensible workaround. (The closest could be that sketched in https://stackoverflow.com/a/35526341/3182664 , but one should carefully check whether this is a sensible solution here...) – Marco13 Jan 11 '19 at 16:41

1 Answers1

0

Based on the solution that Marco13 mentioned in his comment I came up with this custom drawOval function. It basically switch from drawOval to fillOval once the stroke width is greater than the diameter. The position and dimensions for the fillOval function are calculated to match the drawOval output.

public static void drawOval(Graphics2D g2d, int strokeWidth, int x, int y, int width, int height) {
    int minLength = Math.min(width, height);
    int maxLength = Math.max(width, height);
    if (minLength >= strokeWidth) {
        g2d.drawOval(x, y, width, height);
    } else {
        int x1 = x - (strokeWidth - maxLength) / 2 - (maxLength / 2);
        int y1 = y - (strokeWidth - maxLength) / 2 - (maxLength / 2);
        int width1 = width + strokeWidth;
        int height1 = height + strokeWidth;
        g2d.fillOval(x1, y1, width1, height1);
    }
}

This is how it looks like

enter image description here

Victor Ortiz
  • 206
  • 1
  • 5