Opened 8 years ago

Closed 3 years ago

#11612 closed defect (fixed)

wxBufferedDC used with wxScrolledWindow fails in trunk

Reported by: troelsk Owned by: robind
Priority: normal Milestone: 3.0.0
Component: GUI-all Version: stable-latest
Keywords: wxBufferedDC wxScrolledWindow regression Cc:
Blocked By: Blocking:
Patch: yes

Description

The content of wxBufferedDC is clipped beyond the window client area, in trunk. This works fine in 2.8 branch.

Patch:
Applying wxBufferedDC to samples/image just to see it fail, in trunk.

How to reproduce:

  1. Apply scroll-clip.patch to trunk
  2. Run samples/image
  3. Scroll down; the view is clipped

Seen with wxMSW, using Visual Studio 2008.

Attachments (4)

scroll-clip.patch download (1.3 KB) - added by troelsk 8 years ago.
Trunk. Clipped
scroll-clip28.patch download (1.2 KB) - added by troelsk 8 years ago.
2.8 branch. Ok
Redraw-full-target-area-in-wxBufferedDC-UnMask.patch download (1.0 KB) - added by awi 3 years ago.
Redraw full target area in wxBufferedDC::UnMask
Account-device-origin-at-redrawing-also-when-buffering-virtual-area.patch download (428 bytes) - added by awi 3 years ago.
Account device origin at redrawing also when buffering virtual area

Download all attachments as: .zip

Change History (12)

Changed 8 years ago by troelsk

Trunk. Clipped

Changed 8 years ago by troelsk

2.8 branch. Ok

comment:1 Changed 7 years ago by vadz

  • Component changed from wxMSW to GUI-all
  • Keywords regression added
  • Milestone changed from 2.9.1 to 3.0
  • Status changed from new to confirmed

I don't know this class really well but your patch works correctly for me if I call PrepareDC() on the buffered DC itself, not the underlying wxPaintDC. This seems logical to me but it's worrisome that the behaviour changed compared to 2.8 here, does anybody know if this was intentional?

Related to this, the handling of wxBUFFER_VIRTUAL_AREA in wxBufferedPaintDC is wrong too as it also calls PrepareDC() on a wrong DC. I.e. this:

  • samples/image/canvas.cpp

    a b MyCanvas::~MyCanvas() 
    383383    delete [] my_horse_ani;
    384384}
    385385
     386#include "wx/dcbuffer.h"
     387
    386388void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
    387389{
    388     wxPaintDC dc( this );
     390    wxBufferedPaintDC dc( this );
     391    dc.Clear();
    389392    PrepareDC( dc );
    390393
    391394    dc.DrawText( wxT("Loaded image"), 30, 10 );

works but if you add wxBUFFER_VIRTUAL_AREA to the ctor, it doesn't work any more, whether you call PrepareDC() or not.

I don't know what to do about this, i.e. what is the desired behaviour but something is clearly wrong here. Unfortunately I won't have time to look at this closer for 2.9.1. It would be great if someone else could help with this.

comment:2 Changed 6 years ago by vadz

  • Patch unset

comment:3 Changed 5 years ago by jonmarbach

This issue has come up for us in our application - the contents of our wxScrolledWindow are clipped at the edges or repeat their last pixel.

I'm no expert in any of this, but on a whim I tried undoing the logic from
Changeset 53624 for wxWidgets/trunk/src/common/dcbufcmn.cpp (http://trac.wxwidgets.org/changeset/53624/wxWidgets/trunk/src/common/dcbufcmn.cpp)

That change sets the size of the blitted area to the min of the buffer and the dc sizes. I don't really understand why having that in breaks the scrolled behavior...

Hope that helps,
Jon

comment:4 Changed 5 years ago by robind

  • Owner set to robind
  • Status changed from confirmed to accepted

I was actually just working on this myself and have a fix I'll be committing soon.

comment:5 Changed 5 years ago by RD

  • Resolution set to fixed
  • Status changed from accepted to closed

(In [71704]) Keep track of the area intended to be buffered, and use that in UnMask instead of defaulting to the buffer size. Only clip to the DC size if wxBUFFER_VIRTUAL_AREA is not set. This fixes the issue where buffering the full virtual area in a wxScrolledWindow would only draw an area the physical size of the window. Fixes #11612.

comment:6 Changed 3 years ago by troelsk

  • Resolution fixed deleted
  • Status changed from closed to reopened

This seems to be not fixed.
"The content of wxBufferedDC is clipped beyond the window client area, in trunk. This works fine in 2.8 branch. Patch: Applying wxBufferedDC to samples/image just to see it fail, in trunk."

comment:7 Changed 3 years ago by awi

  • Patch set

Reverting optimization implementing in r71704 and redrawing full target area in wxBufferedDC::UnMask seems to fix the main issue (see attachment:Redraw-full-target-area-in-wxBufferedDC-UnMask.patch).

The issue reported in comment:1 when wxBufferedDC is created with wxBUFFER_VIRTUAL_AREA flag:

wxBufferedDC dc(&_dc, GetVirtualSize(), wxBUFFER_VIRTUAL_AREA);

can be observed because device origin is accounted at redrawing only in wxBUFFER_CLIENT_AREA mode. Attached patch fixes this issue: attachment:Account-device-origin-at-redrawing-also-when-buffering-virtual-area.patch).

Changed 3 years ago by awi

Redraw full target area in wxBufferedDC::UnMask

Changed 3 years ago by awi

Account device origin at redrawing also when buffering virtual area

comment:8 Changed 3 years ago by troelsk

  • Resolution set to fixed
  • Status changed from reopened to closed

Explicitly specifying wxBUFFER_VIRTUAL_AREA in the ctor (instead of using the default) in user code makes the code work as expected, in both trunk and 2.8.

Note: See TracTickets for help on using tickets.