Inconsistency: drawRect and drawRoundedRectangle


#1

Graphics::drawRect frames a rectangle, insetting it completely within the passed bounding rectangles. (Side note: Which is really handy! It can also be optimized in the absence of a transform, since the integer version knows a-priori that with a RectangList clip region it can perform the operation using solid or blended rectangle fills, which can be made faster than general edge table rendering)

drawRoundedRectangle(), on the other hand, draws the rectangle with the frame centered around the bounding box. So the resulting shape is not confined to the passed rectangle.

This is inconsistent. It would be really handy if the draw###() series of shape drawing functions drew inside the bounding box, saving the caller from doing the extra calculation. For example:

  path.addRoundedRectangle( r.getX()+0.5, r.getY()+0.5, r.getWidth()-1, r.getHeight()-1, 2 );

This draws the rounded rectangle completely inset within ‘r’ (assuming lineThickness==1).

Now I realize that there is little chance of this getting changed, especially since it would break anyone who was calling those routines. I also realize it is trivial for me to write my own routines that perform the adjustment for lineThickness, and then just use that instead of the Graphics function. However, I point this out because drawRect() is the odd man out.


#2

Yes, can’t argue with any of that! These are some of the oldest methods in the library, which explains why they might seem a bit quirky, and also why I can’t easily change them without messing up people’s code!

Your example is a lot more verbose than it needs to be, though - it’d have been clearer to write it like this:


#3

DOH why didn’t I think of that!!

But are we looking at the same source code? Because I don’t see addRoundedRectangle() taking a Rectangle<> in my juce_Path.h… :frowning:

I just wrote my own routine for convenience:

void drawRoundedRectangle( Graphics& g,
                                       const Rectangle<int>& r,
                                       float cornerSize,
                                       float lineThickness )
{
  Path p;
  float d = lineThickness / 2;
  p.addRoundedRectangle(
    r.getX()+d, r.getY()+d, r.getWidth()-lineThickness, r.getHeight()-lineThickness, cornerSize );
  g.strokePath( p, lineThickness );
}

#4

Oh sorry, I was looking at the Graphics::drawRoundedRectangle methods.

I’ll double-check that the path class has something similar - I’ve been gradually retrofitting the older methods with Rectangles instead of raw coords, maybe I just didn’t do that one yet…