On Windows, once the paint GC of a SWT.DOUBLE_BUFFERED control is in advanced graphics mode, set explicitly or implicitly by setAlpha/setAntialias, getClipping(Region) disagrees with getClipping(). The region is short by the window origin that the double buffering installed and initGdip() removed, so saving and restoring the clipping through a Region shrinks the clip and clips away everything drawn afterwards.
Composite.WM_PAINT calls SetWindowOrgEx(hdc, ps.left, ps.top). initGdip() then does SelectClipRgn(handle, 0) and the GDI+ graphics takes over the DC transform, after which GetWindowOrgEx is (0,0). GC.getClippingRegion() offsets by that lost origin, while the region held by GDI+ is still in the buffer's coordinates.
Measured (real CTabFolder paint, 150% zoom, damage {74,0,188,23}):
advanced=false getClipping()={74,0,188,23} windowOrg=(111,0) round-trip exact
advanced=true getClipping()={74,0,188,23} windowOrg=(0,0)
getClipping(Region) for {96,0,166,23} -> {96,0,92,23} short by 74
after restore: getClipping()={74,0,114,23}
Expected behavior
A getClipping(Region)/setClipping(Region) round-trip is lossless and agrees with getClipping(), regardless of the GC's advanced mode.
Environment
Windows 11 Home 10.0.26200, 150% zoom (also seen at emulated 100%).
Additional context
Found while fixing #3522. That fix avoids advanced mode for the rest of the paint and so dodges this defect, but does not repair it. Any code that switches a double-buffered paint GC to advanced mode and saves/restores clipping via a Region is exposed.
No standalone Canvas reproducer yet: a SWT.DOUBLE_BUFFERED Canvas came back lossless in both modes because that paint never took the buffered code path. The trace above is from a real CTabFolder paint.
On Windows, once the paint GC of a
SWT.DOUBLE_BUFFEREDcontrol is in advanced graphics mode, set explicitly or implicitly bysetAlpha/setAntialias,getClipping(Region)disagrees withgetClipping(). The region is short by the window origin that the double buffering installed andinitGdip()removed, so saving and restoring the clipping through aRegionshrinks the clip and clips away everything drawn afterwards.Composite.WM_PAINTcallsSetWindowOrgEx(hdc, ps.left, ps.top).initGdip()then doesSelectClipRgn(handle, 0)and the GDI+ graphics takes over the DC transform, after whichGetWindowOrgExis(0,0).GC.getClippingRegion()offsets by that lost origin, while the region held by GDI+ is still in the buffer's coordinates.Measured (real
CTabFolderpaint, 150% zoom, damage{74,0,188,23}):Expected behavior
A
getClipping(Region)/setClipping(Region)round-trip is lossless and agrees withgetClipping(), regardless of the GC's advanced mode.Environment
Windows 11 Home 10.0.26200, 150% zoom (also seen at emulated 100%).
Additional context
Found while fixing #3522. That fix avoids advanced mode for the rest of the paint and so dodges this defect, but does not repair it. Any code that switches a double-buffered paint GC to advanced mode and saves/restores clipping via a
Regionis exposed.No standalone
Canvasreproducer yet: aSWT.DOUBLE_BUFFEREDCanvas came back lossless in both modes because that paint never took the buffered code path. The trace above is from a realCTabFolderpaint.