Skip to content

[Win32] GC.getClipping(Region) loses the window origin in advanced mode on a double-buffered paint GC #3528

Description

@vogella

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions