Merge branch 'dc-clear-white-default'

Fix regression in wxDC::Clear() and make wxGCDC::Clear() consistent with
it by using white if the background brush hadn't been explicitly set.

See https://github.com/wxWidgets/wxWidgets/pull/1582
This commit is contained in:
Vadim Zeitlin
2019-10-05 18:47:44 +02:00
6 changed files with 153 additions and 26 deletions

View File

@@ -261,6 +261,9 @@ public:
Note that SetBackground() method must be used to set the brush used by
Clear(), the brush used for filling the shapes set by SetBrush() is
ignored by it.
If no background brush was set, solid white brush is used to clear the
device context.
*/
void Clear();

View File

@@ -543,8 +543,6 @@ void wxGCDCImpl::SetBrush( const wxBrush &brush )
void wxGCDCImpl::SetBackground( const wxBrush &brush )
{
m_backgroundBrush = brush;
if (!m_backgroundBrush.IsOk())
return;
}
void wxGCDCImpl::SetLogicalFunction( wxRasterOperationMode function )
@@ -1286,28 +1284,23 @@ void wxGCDCImpl::Clear()
{
wxCHECK_RET( IsOk(), wxT("wxGCDC(cg)::Clear - invalid DC") );
if ( m_backgroundBrush.IsOk() )
{
m_graphicContext->SetBrush( m_backgroundBrush );
wxPen p = *wxTRANSPARENT_PEN;
m_graphicContext->SetPen( p );
wxCompositionMode formerMode = m_graphicContext->GetCompositionMode();
m_graphicContext->SetCompositionMode(wxCOMPOSITION_SOURCE);
if ( m_backgroundBrush.IsTransparent() )
return;
double x, y, w, h;
m_graphicContext->GetClipBox(&x, &y, &w, &h);
m_graphicContext->DrawRectangle(x, y, w, h);
m_graphicContext->SetBrush( m_backgroundBrush.IsOk() ? m_backgroundBrush
: *wxWHITE_BRUSH );
wxPen p = *wxTRANSPARENT_PEN;
m_graphicContext->SetPen( p );
wxCompositionMode formerMode = m_graphicContext->GetCompositionMode();
m_graphicContext->SetCompositionMode(wxCOMPOSITION_SOURCE);
m_graphicContext->SetCompositionMode(formerMode);
m_graphicContext->SetPen( m_pen );
m_graphicContext->SetBrush( m_brush );
}
else
{
double x, y, w, h;
m_graphicContext->GetClipBox(&x, &y, &w, &h);
m_graphicContext->ClearRectangle(x, y, w, h);
}
double x, y, w, h;
m_graphicContext->GetClipBox(&x, &y, &w, &h);
m_graphicContext->DrawRectangle(x, y, w, h);
m_graphicContext->SetCompositionMode(formerMode);
m_graphicContext->SetPen( m_pen );
m_graphicContext->SetBrush( m_brush );
}
void wxGCDCImpl::DoGetSize(int *width, int *height) const

View File

@@ -2054,7 +2054,6 @@ bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
{
wxMemoryDC memoryDC;
memoryDC.SelectObject(bmp);
memoryDC.SetBackground(*wxWHITE_BRUSH);
memoryDC.Clear();
return RenderPageIntoDC(memoryDC, pageNum);

View File

@@ -1508,7 +1508,7 @@ void wxWindowDCImpl::Clear()
if (!m_gdkwindow) return;
if (!m_backgroundBrush.IsOk() || m_backgroundBrush.GetStyle() == wxBRUSHSTYLE_TRANSPARENT)
if (m_backgroundBrush.IsTransparent())
return;
int width,height;
@@ -1738,7 +1738,8 @@ void wxWindowDCImpl::SetBackground( const wxBrush &brush )
m_backgroundBrush = brush;
if (!m_backgroundBrush.IsOk()) return;
if (!m_backgroundBrush.IsOk())
m_backgroundBrush = *wxWHITE_BRUSH;
if (!m_gdkwindow) return;

View File

@@ -729,8 +729,23 @@ void wxMSWDCImpl::Clear()
return;
}
HBRUSH hbr;
if ( !m_backgroundBrush.IsOk() )
{
// By default, use the stock white brush for compatibility with the
// previous wx versions.
hbr = WHITE_BRUSH;
}
else if ( !m_backgroundBrush.IsTransparent() )
{
hbr = GetHbrushOf(m_backgroundBrush);
}
else // Using transparent background brush.
{
// Clearing with transparent brush doesn't do anything, just as drawing
// with transparent pen doesn't.
return;
}
RECT rect;
::GetClipBox(GetHdc(), &rect);
@@ -738,7 +753,7 @@ void wxMSWDCImpl::Clear()
// to compensate rounding errors if DC is the subject
// of complex transformation (is e.g. rotated).
::InflateRect(&rect, 1, 1);
::FillRect(GetHdc(), &rect, GetHbrushOf(m_backgroundBrush));
::FillRect(GetHdc(), &rect, hbr);
RealizeScaleAndOrigin();
}

View File

@@ -25,6 +25,8 @@
#include "wx/graphics.h"
#endif // wxUSE_GRAPHICS_CONTEXT
#include "testimage.h"
#define ASSERT_EQUAL_RGB(c, r, g, b) \
CHECK( (int)r == (int)c.Red() ); \
CHECK( (int)g == (int)c.Green() ); \
@@ -915,4 +917,118 @@ TEST_CASE("BitmapTestCase::SubBitmapAlphaWithMask", "[bitmap][subbitmap][alpha][
ASSERT_EQUAL_RGB(p, maskClrBottomRight.Red(), maskClrBottomRight.Green(), maskClrBottomRight.Blue());
}
}
namespace Catch
{
template <>
struct StringMaker<wxBitmap>
{
static std::string convert(const wxBitmap& bmp)
{
return wxString::Format("bitmap of size %d*%d",
bmp.GetWidth(),
bmp.GetHeight()).ToStdString();
}
};
}
class BitmapColourMatcher : public Catch::MatcherBase<wxBitmap>
{
public:
explicit BitmapColourMatcher(const wxColour& col)
: m_col(col)
{
}
bool match(const wxBitmap& bmp) const wxOVERRIDE
{
const wxImage img(bmp.ConvertToImage());
const unsigned char* data = img.GetData();
for ( int y = 0; y < img.GetHeight(); ++y )
{
for ( int x = 0; x < img.GetWidth(); ++x, data += 3 )
{
if ( wxColour(data[0], data[1], data[2]) != m_col )
return false;
}
}
return true;
}
std::string describe() const wxOVERRIDE
{
return wxString::Format("doesn't have all %s pixels",
m_col.GetAsString()).ToStdString();
}
private:
const wxColour m_col;
};
inline BitmapColourMatcher AllPixelsAre(const wxColour& col)
{
return BitmapColourMatcher(col);
}
TEST_CASE("DC::Clear", "[bitmap][dc]")
{
// Just some arbitrary pixel data.
static unsigned char data[] =
{
0xff, 0, 0,
0, 0xff, 0,
0, 0, 0xff,
0x7f, 0, 0x7f
};
const wxImage img(2, 2, data, true /* don't take ownership of data */);
wxBitmap bmp(img);
SECTION("Clearing uses white by default")
{
{
wxMemoryDC dc(bmp);
dc.Clear();
}
CHECK_THAT(bmp, AllPixelsAre(*wxWHITE));
}
SECTION("Clearing with specified brush works as expected")
{
{
wxMemoryDC dc(bmp);
dc.SetBackground(*wxRED_BRUSH);
dc.Clear();
}
CHECK_THAT(bmp, AllPixelsAre(*wxRED));
}
SECTION("Clearing with transparent brush does nothing")
{
{
wxMemoryDC dc(bmp);
dc.SetBackground(*wxTRANSPARENT_BRUSH);
dc.Clear();
}
CHECK_THAT(bmp.ConvertToImage(), RGBSameAs(img));
}
SECTION("Clearing with invalid brush uses white too")
{
{
wxMemoryDC dc(bmp);
dc.SetBackground(*wxBLACK_BRUSH);
dc.SetBackground(wxBrush());
dc.Clear();
}
CHECK_THAT(bmp, AllPixelsAre(*wxWHITE));
}
}
#endif //wxHAS_RAW_BITMAP