Fix wxMemoryDC::Blit() with itself as source in wxMSW
Don't use StretchDIBits() native function as it doesn't seem to handle the case when its source and destination are the same correctly. Closes #17666.
This commit is contained in:
committed by
Vadim Zeitlin
parent
6bd6c94511
commit
607b800444
@@ -134,6 +134,7 @@ wxMSW:
|
|||||||
- Fix wxGraphicsMatrix::TransformDistance for Direct2D renderer.
|
- Fix wxGraphicsMatrix::TransformDistance for Direct2D renderer.
|
||||||
- Fix wxDC::Clear() for rotated DC.
|
- Fix wxDC::Clear() for rotated DC.
|
||||||
- Fix wxDC::GetClippingBox() for transformed wxDC.
|
- Fix wxDC::GetClippingBox() for transformed wxDC.
|
||||||
|
- Fix wxMemoryDC::Blit() with itself as source (Tim Roberts).
|
||||||
|
|
||||||
wxOSX:
|
wxOSX:
|
||||||
|
|
||||||
|
@@ -2294,8 +2294,10 @@ bool wxMSWDCImpl::DoStretchBlit(wxCoord xdest, wxCoord ydest,
|
|||||||
// if we already have a DIB, draw it using StretchDIBits(), otherwise
|
// if we already have a DIB, draw it using StretchDIBits(), otherwise
|
||||||
// use StretchBlt() if available and finally fall back to BitBlt()
|
// use StretchBlt() if available and finally fall back to BitBlt()
|
||||||
|
|
||||||
|
// Notice that we can't use StretchDIBits() when source and destination
|
||||||
|
// are the same as it can't, apparently, handle overlapping surfaces.
|
||||||
const int caps = ::GetDeviceCaps(GetHdc(), RASTERCAPS);
|
const int caps = ::GetDeviceCaps(GetHdc(), RASTERCAPS);
|
||||||
if ( bmpSrc.IsOk() && (caps & RC_STRETCHDIB) )
|
if ( bmpSrc.IsOk() && (GetHdc() != hdcSrc) && (caps & RC_STRETCHDIB) )
|
||||||
{
|
{
|
||||||
DIBSECTION ds;
|
DIBSECTION ds;
|
||||||
wxZeroMemory(ds);
|
wxZeroMemory(ds);
|
||||||
|
@@ -17,8 +17,14 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/bitmap.h"
|
#include "wx/bitmap.h"
|
||||||
|
#include "wx/rawbmp.h"
|
||||||
#include "wx/dcmemory.h"
|
#include "wx/dcmemory.h"
|
||||||
|
|
||||||
|
#define ASSERT_EQUAL_RGB(c, r, g, b) \
|
||||||
|
CPPUNIT_ASSERT_EQUAL( r, (int)c.Red() ); \
|
||||||
|
CPPUNIT_ASSERT_EQUAL( g, (int)c.Green() ); \
|
||||||
|
CPPUNIT_ASSERT_EQUAL( b, (int)c.Blue() )
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// test class
|
// test class
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -34,9 +40,11 @@ public:
|
|||||||
private:
|
private:
|
||||||
CPPUNIT_TEST_SUITE( BitmapTestCase );
|
CPPUNIT_TEST_SUITE( BitmapTestCase );
|
||||||
CPPUNIT_TEST( Mask );
|
CPPUNIT_TEST( Mask );
|
||||||
|
CPPUNIT_TEST( OverlappingBlit );
|
||||||
CPPUNIT_TEST_SUITE_END();
|
CPPUNIT_TEST_SUITE_END();
|
||||||
|
|
||||||
void Mask();
|
void Mask();
|
||||||
|
void OverlappingBlit();
|
||||||
|
|
||||||
wxBitmap m_bmp;
|
wxBitmap m_bmp;
|
||||||
|
|
||||||
@@ -80,3 +88,35 @@ void BitmapTestCase::Mask()
|
|||||||
m_bmp.SetMask(mask2);
|
m_bmp.SetMask(mask2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitmapTestCase::OverlappingBlit()
|
||||||
|
{
|
||||||
|
m_bmp.SetMask( NULL );
|
||||||
|
|
||||||
|
// Clear to white.
|
||||||
|
|
||||||
|
wxMemoryDC dc(m_bmp);
|
||||||
|
dc.SetBackground( *wxWHITE );
|
||||||
|
dc.Clear();
|
||||||
|
|
||||||
|
// Draw red line across the top.
|
||||||
|
|
||||||
|
dc.SetPen(*wxRED_PEN);
|
||||||
|
dc.DrawLine(0, 0, 10, 0);
|
||||||
|
|
||||||
|
// Scroll down one line.
|
||||||
|
|
||||||
|
dc.Blit( 0, 1, 10, 9, &dc, 0, 0 );
|
||||||
|
|
||||||
|
// Now, lines 0 and 1 should be red, lines 2++ should still be white.
|
||||||
|
|
||||||
|
wxNativePixelData npd( m_bmp );
|
||||||
|
wxNativePixelData::Iterator it( npd );
|
||||||
|
|
||||||
|
ASSERT_EQUAL_RGB( it, 255, 0, 0 );
|
||||||
|
it.OffsetY( npd, 1 );
|
||||||
|
ASSERT_EQUAL_RGB( it, 255, 0, 0 );
|
||||||
|
it.OffsetY( npd, 1 );
|
||||||
|
ASSERT_EQUAL_RGB( it, 255, 255, 255 );
|
||||||
|
it.OffsetY( npd, 1 );
|
||||||
|
ASSERT_EQUAL_RGB( it, 255, 255, 255 );
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user