如何增加GDI+中圆角矩形路径的宽度?

问题描述 投票:0回答:1

我绘制了几十个圆角矩形,但经常需要更改其宽度。我目前正在使用以下(大大简化的)类:

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;
    }
};

它在构造函数中创建

PathData
,并在每次宽度变化时创建一个新路径(这是经常发生的)现在,这工作正常,但它让我烦恼,它需要删除并创建一个新路径(在堆上)时间。路径中的点数永远不会改变,所以我认为应该有一种方法可以仅使用在构造函数中创建的一条路径,并根据需要调整它以增加宽度,而不必每次都创建新路径。该路径唯一完成的事情是
FillPath

c++ graphics drawing gdi+
1个回答
0
投票

好吧,似乎对这个领域没有太多兴趣,或者至少对这个问题没有太多兴趣。但我已经解决了这个问题,所以我将在这里发布答案,以防有人好奇。我无法找到修改

GraphicsPath
的方法,但是我能够实现摆脱堆分配的主要结果。

下面的代码使我能够创建单个圆角矩形路径,并将其用于具有不同宽度和水平定位的众多路径。它的运行速度也快了 20% 左右。

class RRPath
{
    GraphicsPath pth;
    float prevW{}, prevX{};
protected:
    GraphicsPath pS, pE;
public:
    RRPath() 
    {
        pS.AddArc(0.f, 12.f, 24.f, 24.f, 90, 90);
        pS.AddArc(0.f, 0.f, 24.f, 24.f, 180, 90);
        pE.AddArc(0.f, 0.f, 24.f, 24.f, 270, 90);
        pE.AddArc(0.f, 12.f, 24.f, 24.f, 0, 90);
    };

    void setWidth(float w)
    {
        pth.Reset();
        pth.AddPath(&pS, false);
        Matrix m{ 1, 0, 0, 1, w - prevW, 0 };
        pE.Transform(&m);
        pth.AddPath(&pE, true);
        prevX = 0.f;
        prevW = w;
    };
    GraphicsPath *getPath(float offsetX)
    {
        Matrix m{ 1, 0, 0, 1, offsetX - prevX, 0 };
        pth.Transform(&m);
        prevX = offsetX;
        return &pth;
    };
};
© www.soinside.com 2019 - 2024. All rights reserved.