Fix setting clipping region for wxDC with rotated coordinate system (wxMSW)

We cannot assume that axis-aligned clipping box in local coordinates will
remain axis-aligned box in device coordinates so we need to take into
account all 4 corners of the clipping rectangle to create a polygonal
clipping region in device space.

Closes #19228.
This commit is contained in:
Artur Wieczorek
2021-07-20 22:30:56 +02:00
parent a35d8b932c
commit ce5e6cfc10

View File

@@ -642,13 +642,29 @@ void wxMSWDCImpl::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord w, wxCoord h
h = -h;
y -= (h - 1);
}
HRGN hrgn = ::CreateRectRgn(LogicalToDeviceX(x),
LogicalToDeviceY(y),
LogicalToDeviceX(x + w),
LogicalToDeviceY(y + h));
// Because world transform can be applied to HDC and its coordiante
// system may be e.g. rotated we shouldn't assume that axis-aligned
// clipping box in local coordinates will remain axis-aligned box in
// device coordinates. Therefore we need to take into account all
// 4 corners of the rectangle to create a polygonal clipping region
// in device coordinates.
POINT rect[4];
wxPoint p = LogicalToDevice(x, y);
rect[0].x = p.x;
rect[0].y = p.y;
p = LogicalToDevice(x + w, y);
rect[1].x = p.x;
rect[1].y = p.y;
p = LogicalToDevice(x + w, y + h);
rect[2].x = p.x;
rect[2].y = p.y;
p = LogicalToDevice(x, y + h);
rect[3].x = p.x;
rect[3].y = p.y;
HRGN hrgn = ::CreatePolygonRgn(rect, WXSIZEOF(rect), WINDING);
if ( !hrgn )
{
wxLogLastError(wxT("CreateRectRgn"));
wxLogLastError(wxT("CreatePolygonRgn"));
}
else
{