Stack Exchange
Convert Gdiplus::Region to ID2D1Geometry* for clipping
I am trying to migrate my graphics interface project from Gdiplus to Direct2D.
Currently, I have a code that calculates clipping area for an rendering object:
Graphics g(hdc);
Region regC = Rect(x, y, cx + padding[2] + padding[0], cy + padding[3] + padding[1]);
RecursRegPos(this->parent, &regC);
RecursRegClip(this->parent, &regC);
g.setClip(g);

...

inline void RecursRegClip(Object *parent, Region* reg)
{
    if (parent == CARD_PARENT)
        return;

    if (parent->overflow != OVISIBLE)
    {
        Rect regC(parent->getAbsoluteX(), parent->getAbsoluteY(), parent->getCx(), parent->getCy()); // Implementation of these function is not necceassary

        GraphicsPath path;
        path.Reset();
        GetRoundRectPath(&path, regC, parent->borderRadius[0]);
        // source https://stackoverflow.com/a/71431813/15220214, but if diameter is zero, just plain rect is returned
        
        reg->Intersect(&path);
    }

    RecursRegClip(parent->parent, reg);
}

inline void RecursRegPos(Object* parent, Rect* reg)
{
    if (parent == CARD_PARENT)
        return;
    
    reg->X += parent->getX() + parent->padding[0];
    reg->Y += parent->getY() + parent->padding[1];
    if (parent->overflow == OSCROLL || parent->overflow == OSCROLLH)
    {
        reg->X -= parent->scrollLeft;
        reg->Y -= parent->scrollTop;
    }

    RecursRegPos(parent->parent, reg);
}

And now I need to convert it to Direct2D. As You may notice, there is no need to create Graphics object to get complete calculated clipping region, so I it would be cool if there is way to just convert Region to ID2D1Geometry*, that, as far, as I understand from msdn article need to create clipping layer.
Also, there is probably way to convert existing code (RecursRegClip, RecursRegPos) to Direct2D, but I am facing problems, because I need to work with path, but current functions get region as an argument.

Update 1
There is Region::GetData method that returns, as I understand array of points, so maybe there is possibility to define either ID2D1PathGeometry or ID2D1GeometrySink by points?

Update 2
Oh, maybe
ID2D1GeometrySink::AddLines(const D2D1_POINT_2F *points, UINT32 pointsCount)

is what do I need?

Unfortunately, GetData of region based on just (0,0,4,4) rectangle returns 36 mystique values:
Region reg(Rect(0, 0, 4, 4));
auto so = reg.GetDataSize();
BYTE* are = new BYTE[so];
UINT fi = 0;
reg.GetData(are, so, &fi);

wchar_t ou[1024]=L"\0";

for (int i = 0; i < fi; i++)
{
    wchar_t buf[10] = L"";
    _itow_s(are[i], buf, 10, 10);

    wcscat_s(ou, 1024, buf);
    wcscat_s(ou, 1024, L", ");
}

// ou - 28, 0, 0, 0, 188, 90, 187, 128, 2, 16, 192, 219, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 0, 0, 128, 64,


Once you have an ID2D1Geometry reference (such as ID2D1PathGeometry), there are many utility functions https://learn.microsoft.com/en-us/windows/win32/api/d2d1/nn-d2d1-id2d1geometry like GetBounds, Outline, etc.

@SimonMourier, yeah getBounds, not set

@SimonMourier, AddLines seems to do the job, but I currently thinking in which format GetData returns points array.

I rewrote the solution completely, it seems to be working:
        // zclip is ID2D1PathGeometry*
        
    inline void Render(ID2D1HwndRenderTarget *target)
    {
        ID2D1RoundedRectangleGeometry* mask = nullptr;
        ID2D1Layer* clip = nullptr;

        if(ONE_OF_PARENTS_CLIPS_THIS || THIS_HAS_BORDER_RADIUS)
        {
        Region reg = Rect(x, y, cx + padding[2] + padding[0], cy + padding[3] + padding[1]);

        RecursRegPos(this->parent, &reg);
        
        D2D1_ROUNDED_RECT maskRect;
        maskRect.rect.left = reg.X;
        maskRect.rect.top = reg.Y;
        maskRect.rect.right = reg.X + reg.Width;
        maskRect.rect.bottom = reg.Y + reg.Height;
        maskRect.radiusX = this->borderRadius[0];
        maskRect.radiusY = this->borderRadius[1];

        factory->CreateRoundedRectangleGeometry(maskRect, &mask);

        RecursGeoClip(this->parent, mask);

        
        target->CreateLayer(NULL, &clip);
        if(zclip)
            target->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), zclip), clip);
        else
            target->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), mask), clip);

        SafeRelease(&mask);
        }

        // Draw stuff here

        if (clip)
        {
            target->PopLayer();
            SafeRelease(&clip);
            SafeRelease(&mask);
            SafeRelease(&zclip);
        }
    }

    ...


    inline void RecursGeoClip(Object* parent, ID2D1Geometry* geo)
    {
    if (parent == CARD_PARENT)
        return;

    ID2D1RoundedRectangleGeometry* maskParent = nullptr;

    if (parent->overflow != OVISIBLE)
    {
        Rect regC(parent->getAbsoluteX(), parent->getAbsoluteY(), parent->getCx(), parent->getCy());

        ID2D1GeometrySink* sink = nullptr;
        ID2D1PathGeometry* path = nullptr;

        SafeRelease(&path);
        factory->CreatePathGeometry(&path);

        D2D1_ROUNDED_RECT maskRect;
        maskRect.rect.left = regC.X;
        maskRect.rect.top = regC.Y;
        maskRect.rect.right = regC.X + regC.Width;
        maskRect.rect.bottom = regC.Y + regC.Height;
        maskRect.radiusX = parent->borderRadius[0];
        maskRect.radiusY = parent->borderRadius[1];

        path->Open(&sink);

        factory->CreateRoundedRectangleGeometry(maskRect, &maskParent);

        geo->CombineWithGeometry(maskParent, D2D1_COMBINE_MODE_INTERSECT, NULL, sink);
                    
        sink->Close();
        SafeRelease(&sink);
        
        SafeRelease(&this->zclip);
        this->zclip = path;

        RecursGeoClip(parent->parent, this->zclip);
    }
    else
        RecursGeoClip(parent->parent, geo);

    SafeRelease(&maskParent);
    }

Now I can enjoy drawing one image and two rectangles in more than 60 fps, instead of 27 (in case of 200x200 image size, higher size - lower fps) with Gdi+ -_- :

