Add to the test suite a test of setting non-rectangular clipping region
Added a test of creating triangular clipping region (with wxDC::SetDeviceClippingRegion). See #17609
This commit is contained in:
@@ -31,6 +31,56 @@ static const wxSize s_dcSize(100, 120);
|
||||
static const wxColour s_bgColour(*wxWHITE); // colour to draw outside clipping box
|
||||
static const wxColour s_fgColour(*wxGREEN); // colour to draw inside clipping box
|
||||
|
||||
static bool CompareImageFuzzy(const wxImage& img1, const wxImage& img2, int posTolerance = 0)
|
||||
{
|
||||
// For each (x,y) pixel in the image1 we check
|
||||
// if there is a pixel of the same value in the square
|
||||
// area (x-d..x+d, y-d..y+d) around the pixel (x,y)
|
||||
// in the image2. If not, we consider pixels
|
||||
// and images as different.
|
||||
|
||||
if ( img1.GetWidth() != img2.GetWidth() )
|
||||
return false;
|
||||
|
||||
if ( img1.GetHeight() != img2.GetHeight() )
|
||||
return false;
|
||||
|
||||
const int w = img1.GetWidth();
|
||||
const int h = img1.GetHeight();
|
||||
for ( int y1 = 0; y1 < h; y1++ )
|
||||
{
|
||||
int y2min = wxMax(y1 - posTolerance, 0);
|
||||
int y2max = wxMin(y1 + posTolerance, h);
|
||||
for( int x1 = 0; x1 < w; x1++ )
|
||||
{
|
||||
int x2min = wxMax(x1 - posTolerance, 0);
|
||||
int x2max = wxMin(x1 + posTolerance, w);
|
||||
|
||||
unsigned char r1 = img1.GetRed(x1, y1);
|
||||
unsigned char g1 = img1.GetGreen(x1, y1);
|
||||
unsigned char b1 = img1.GetBlue(x1, y1);
|
||||
|
||||
bool pix2Found = false;
|
||||
for( int y2 = y2min; y2 <= y2max && !pix2Found; y2++ )
|
||||
for( int x2 = x2min; x2 <= x2max; x2++ )
|
||||
{
|
||||
if( r1 == img2.GetRed(x2, y2) &&
|
||||
g1 == img2.GetGreen(x2, y2) &&
|
||||
b1 == img2.GetBlue(x2, y2))
|
||||
{
|
||||
pix2Found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !pix2Found )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class ClippingBoxTestCaseBase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
@@ -46,9 +96,11 @@ public:
|
||||
}
|
||||
|
||||
virtual void setUp() { wxASSERT( m_dc ); }
|
||||
virtual wxDC* GetDC(wxMemoryDC* dc) = 0;
|
||||
|
||||
private:
|
||||
void CheckBox(int x, int y, int width, int height);
|
||||
void CheckBox(int x, int y, int width, int height,
|
||||
const wxBitmap& bmpRef = wxNullBitmap, int posTolerance = 0);
|
||||
|
||||
protected:
|
||||
void InitialState();
|
||||
@@ -68,6 +120,7 @@ protected:
|
||||
void OneLargeDevRegion();
|
||||
void OneOuterDevRegion();
|
||||
void OneDevRegionNegDim();
|
||||
void OneDevRegionNonRect();
|
||||
void OneDevRegionAndReset();
|
||||
void OneDevRegionAndEmpty();
|
||||
void TwoDevRegionsOverlapping();
|
||||
@@ -99,7 +152,7 @@ public:
|
||||
m_mdc.SelectObject(wxNullBitmap);
|
||||
}
|
||||
|
||||
virtual void setUp()
|
||||
virtual void setUp() wxOVERRIDE
|
||||
{
|
||||
m_mdc.DestroyClippingRegion();
|
||||
wxBrush bgBrush(s_bgColour, wxBRUSHSTYLE_SOLID);
|
||||
@@ -107,7 +160,13 @@ public:
|
||||
m_mdc.Clear();
|
||||
}
|
||||
|
||||
virtual void FlushDC() {}
|
||||
virtual wxDC* GetDC(wxMemoryDC* dc) wxOVERRIDE
|
||||
{
|
||||
return dc;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FlushDC() wxOVERRIDE {}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( ClippingBoxTestCaseDC );
|
||||
@@ -128,6 +187,7 @@ private:
|
||||
CPPUNIT_TEST( OneLargeDevRegion );
|
||||
CPPUNIT_TEST( OneOuterDevRegion );
|
||||
CPPUNIT_TEST( OneDevRegionNegDim );
|
||||
CPPUNIT_TEST( OneDevRegionNonRect );
|
||||
CPPUNIT_TEST( OneDevRegionAndReset);
|
||||
CPPUNIT_TEST( OneDevRegionAndEmpty );
|
||||
CPPUNIT_TEST( TwoDevRegionsOverlapping );
|
||||
@@ -164,7 +224,7 @@ public:
|
||||
delete m_gcdc;
|
||||
}
|
||||
|
||||
virtual void setUp()
|
||||
virtual void setUp() wxOVERRIDE
|
||||
{
|
||||
CPPUNIT_ASSERT_MESSAGE("Invalid wxGCDC", m_gcdc);
|
||||
|
||||
@@ -177,7 +237,17 @@ public:
|
||||
m_gcdc->Clear();
|
||||
}
|
||||
|
||||
virtual void FlushDC()
|
||||
virtual wxDC* GetDC(wxMemoryDC* dc) wxOVERRIDE
|
||||
{
|
||||
wxGraphicsRenderer* rend = m_gcdc->GetGraphicsContext()->GetRenderer();
|
||||
wxGraphicsContext* ctx = rend->CreateContext(*dc);
|
||||
ctx->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
ctx->DisableOffset();
|
||||
return new wxGCDC(ctx);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FlushDC() wxOVERRIDE
|
||||
{
|
||||
m_gcdc->GetGraphicsContext()->Flush();
|
||||
}
|
||||
@@ -201,6 +271,7 @@ private:
|
||||
CPPUNIT_TEST( OneLargeDevRegion );
|
||||
CPPUNIT_TEST( OneOuterDevRegion );
|
||||
CPPUNIT_TEST( OneDevRegionNegDim );
|
||||
CPPUNIT_TEST( OneDevRegionNonRect );
|
||||
CPPUNIT_TEST( OneDevRegionAndReset);
|
||||
CPPUNIT_TEST( OneDevRegionAndEmpty );
|
||||
CPPUNIT_TEST( TwoDevRegionsOverlapping );
|
||||
@@ -260,6 +331,7 @@ private:
|
||||
CPPUNIT_TEST( OneLargeDevRegion );
|
||||
CPPUNIT_TEST( OneOuterDevRegion );
|
||||
CPPUNIT_TEST( OneDevRegionNegDim );
|
||||
CPPUNIT_TEST( OneDevRegionNonRect );
|
||||
CPPUNIT_TEST( OneDevRegionAndReset);
|
||||
CPPUNIT_TEST( OneDevRegionAndEmpty );
|
||||
CPPUNIT_TEST( TwoDevRegionsOverlapping );
|
||||
@@ -323,6 +395,7 @@ private:
|
||||
CPPUNIT_TEST( OneLargeDevRegion );
|
||||
CPPUNIT_TEST( OneOuterDevRegion );
|
||||
CPPUNIT_TEST( OneDevRegionNegDim );
|
||||
CPPUNIT_TEST( OneDevRegionNonRect );
|
||||
CPPUNIT_TEST( OneDevRegionAndReset);
|
||||
CPPUNIT_TEST( OneDevRegionAndEmpty );
|
||||
CPPUNIT_TEST( TwoDevRegionsOverlapping );
|
||||
@@ -378,6 +451,7 @@ private:
|
||||
CPPUNIT_TEST( OneLargeDevRegion );
|
||||
CPPUNIT_TEST( OneOuterDevRegion );
|
||||
CPPUNIT_TEST( OneDevRegionNegDim );
|
||||
CPPUNIT_TEST( OneDevRegionNonRect );
|
||||
CPPUNIT_TEST( OneDevRegionAndReset);
|
||||
CPPUNIT_TEST( OneDevRegionAndEmpty );
|
||||
CPPUNIT_TEST( TwoDevRegionsOverlapping );
|
||||
@@ -427,7 +501,8 @@ public:
|
||||
|
||||
// ===== Implementation =====
|
||||
|
||||
void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height)
|
||||
void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height,
|
||||
const wxBitmap& bmpRef, int posTolerance)
|
||||
{
|
||||
// Check clipping box boundaries.
|
||||
int clipX, clipY, clipW, clipH;
|
||||
@@ -479,18 +554,36 @@ void ClippingBoxTestCaseBase::CheckBox(int x, int y, int width, int height)
|
||||
// Update wxDC contents.
|
||||
FlushDC();
|
||||
|
||||
// Check whether diagonal corners of the clipping box
|
||||
// are actually drawn at the edge of the clipping region.
|
||||
#if wxUSE_IMAGE
|
||||
// For some renderers it's not possible to get pixels
|
||||
// value from wxDC so we would have to examine pixels
|
||||
// in the underlying bitmap.
|
||||
wxImage img;
|
||||
img = m_bmp.ConvertToImage();
|
||||
wxImage img = m_bmp.ConvertToImage();
|
||||
#else
|
||||
return;
|
||||
#endif // wxUSE_IMAGE
|
||||
|
||||
// If reference bitmap is given then it has to be
|
||||
// compared with current bitmap.
|
||||
if ( bmpRef.IsOk() )
|
||||
{
|
||||
wxImage imgRef = bmpRef.ConvertToImage();
|
||||
// Figures created by clipping and drawing procedures
|
||||
// can be slightly different (shifted by few pixels) due
|
||||
// to the different algorithms they can use so we need
|
||||
// to perform a "fuzzy" comparison of the images,
|
||||
// tolerating some drift of the pixels.
|
||||
if ( !CompareImageFuzzy(img, imgRef, posTolerance) )
|
||||
CPPUNIT_FAIL( "Invalid shape ot the clipping region" );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If no reference bitmap is given then rectangular
|
||||
// clipping region is assumed and we check whether
|
||||
// diagonal corners of the clipping box are actually
|
||||
// drawn at the edge of the clipping region.
|
||||
|
||||
// Check area near the top-left corner
|
||||
int ymin = y-1;
|
||||
int xmin = x-1;
|
||||
@@ -923,6 +1016,54 @@ void ClippingBoxTestCaseBase::OneDevRegionNegDim()
|
||||
m_dc->DeviceToLogicalYRel(r.GetHeight()));
|
||||
}
|
||||
|
||||
void ClippingBoxTestCaseBase::OneDevRegionNonRect()
|
||||
{
|
||||
// Setting one triangular clipping region in device coordinates.
|
||||
const wxPoint poly[3] =
|
||||
{
|
||||
wxPoint(3, 5),
|
||||
wxPoint(68, 18),
|
||||
wxPoint(40, 72)
|
||||
};
|
||||
// Expected clipping box in device coordinates.
|
||||
const int clipX = 4;
|
||||
const int clipY = 6;
|
||||
const int clipW = 64;
|
||||
const int clipH = 66;
|
||||
|
||||
// Draw image with reference triangle.
|
||||
wxBitmap bmpRef(s_dcSize);
|
||||
wxMemoryDC* memDC = new wxMemoryDC(bmpRef);
|
||||
wxDC* dcRef = GetDC(memDC);
|
||||
dcRef->SetBackground(wxBrush(s_bgColour, wxBRUSHSTYLE_SOLID));
|
||||
dcRef->Clear();
|
||||
dcRef->SetBrush(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
|
||||
dcRef->SetPen(wxPen(s_fgColour));
|
||||
dcRef->DrawPolygon(WXSIZEOF(poly), poly);
|
||||
delete dcRef;
|
||||
|
||||
m_dc->SetDeviceOrigin(10, 15);
|
||||
m_dc->SetUserScale(0.5, 1.5);
|
||||
m_dc->SetLogicalScale(4.0, 2.0);
|
||||
m_dc->SetLogicalOrigin(-15, -20);
|
||||
wxRegion r(WXSIZEOF(poly), poly);
|
||||
m_dc->SetDeviceClippingRegion(r);
|
||||
m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
|
||||
m_dc->Clear();
|
||||
// Check clipping box parameters and compare
|
||||
// filled in clipping region with reference triangle.
|
||||
// Triangles created by clipping and drawing procedures
|
||||
// can be slightly different (shifted by few pixels) due
|
||||
// to the different algorithms used for different operations
|
||||
// so we need to perform a "fuzzy" comparison of the images,
|
||||
// tolerating some drift of the pixels.
|
||||
CheckBox(m_dc->DeviceToLogicalX(clipX),
|
||||
m_dc->DeviceToLogicalY(clipY),
|
||||
m_dc->DeviceToLogicalXRel(clipW),
|
||||
m_dc->DeviceToLogicalYRel(clipH),
|
||||
bmpRef, 1);
|
||||
}
|
||||
|
||||
void ClippingBoxTestCaseBase::OneDevRegionAndReset()
|
||||
{
|
||||
// Setting one clipping region in device coordinates
|
||||
|
Reference in New Issue
Block a user