Weirdness when drawing a path

I’m drawing a quite simple path in my plugin, It’s a closed path consisting of 5 points.
But when I draw it, the diagonal lines come out much thicker than the rest, and I have no idea why:

Screenshot 2021-11-27 at 16.56.03

For reference, here’s the code:

Path outline;
outline.startNewSubPath(0, 0);
outline.lineTo(20, 0);
outline.lineTo(20, 10);
outline.lineTo(10, 15);
outline.lineTo(0, 10);
outline.closeSubPath();

g.setColour(kDisplayBackgroundColour);
g.fillPath(outline);
g.setColour(Colours::black);
g.strokePath(outline, PathStrokeType(2));

Does anyone know what’s going on?
I’m using JUCE 6.1.2 on macOS 12.0.1.

Your path is being clipped by the edge of the component because you’ve got points at X=0 and Y=0. When you stroke a path, each line segment goes through the middle of each point, meaning if you’ve got a stroke width of 2px, 1px of the line is on the outside of the filled area, while 1px is on the inside of the filled area.

You’ll be able to see this more clearly if you stroke the path before you fill it, you’ll see the stroked segment ‘spilling’ out from behind the filled area.

The best solution (IME) is to simply reduce the path by 1/2 the stroke width. So in your case, with a stroke width of 2px, you want to bring the path inwards by 1px. You’d start at (1, 1), then go to (19, 1), etc.

4 Likes

Ah, yes, of course, that’s it! :smiley:

Thank you so much, it was driving me crazy!

1 Like

in my current main project i have a static constexpr for the thickness of everything, because i found it cool to be consistent across the project. also that lets me easily try different thicknesses by just changing one variable. now in every component that does something with its bounds i always start with

const auto bounds = getLocalBounds().toFloat().reducedBy(thickness);

because then if you use these bounds rather than the “real” bounds you always have bounds you can savely work with while also being right at the edge with everything.

now that i see this though… i consider deliberately clipping the bounds sometimes. kind of a cool 3d effect

3 Likes

A lazy quick dirty hack is to do setPaintingIsUnclipped(true); in the component’s constructor where the out of bounds painting is done.

This would only work if your drawing is static - if the component in question moved, or the path changed in some way, the part of the path that was painted outside the component’s bounds won’t be repainted. You’d have to manually flag those external bounds to be painted in the parent.