I have a few dozen rounded rectangles which I draw but frequently need to change the width of. I'm currently using the following (heavily simplified) class:
class RRPath
{
std::unique_ptr<GraphicsPath> pth;
bool newWidth{};
float xPos{};
PathData pd;
public:
RRPath()
{
GraphicsPath path;
path.AddArc(0.f, 12.f, 24.f, 24.f, 90, 90);
path.AddArc(0.f, 0.f, 24.f, 24.f, 180, 90);
path.AddArc(0.f, 0.f, 24.f, 24.f, 270, 90);
path.AddArc(0.f, 12.f, 24.f, 24.f, 0, 90);
path.GetPathData(&pd);
}
void setWidth(float tabW) { tabWidth = tabW; newWidth = true; }
GraphicsPath *getPath(float x) // return a GraphicsPath*, adjusted for starting position `x`
{
if (newWidth) mkNewPath();
Matrix m{ 1, 0, 0, 1, x - xPos, 0 };
pth->Transform(&m);
xPos = x;
return pth.get();
}
private:
void mkNewPath()
{
for (int i = 8; i < 19; i++) pd.Points[i].X += tabWidth;
pth = std::make_unique<GraphicsPath>(pd.Points, pd.Types, pd.Count);
for (int i = 8; i < 19; i++) pd.Points[i].X -= tabWidth;
xPos = 0.f;
}
};
It creates the PathData in the contructor and creates a new path every time the width changes (which is frequently) Now, this works fine but it bugs me that it needs to delete and create a new path (on the heap) every time. The number of points in the path never changes so I'm thinking there should be a way to use only one path, created in the contructor, and adjust it as needed to increase the width without having to create a new path every time. The only thing done with the path is FillPath.
Ok, seems like there's not much interest in this area, or at least not in this question. But I have been able to resolve it so I will post the answer here in case anyone is curious. I wasn't able to find a way to modify a
GraphicsPathhowever I was able to achieve the main result that being getting rid of the heap allocations.The code below enables me to create a single rounded rectangle path and use it for numerous paths with different widths and horizontal positioning. It also runs around 20% faster.