These new tests are about setting clipping region and retrieving clipping box for wxDC and wxGCDC with applied transformations. See #17646
		
			
				
	
	
		
			2161 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			2161 lines
		
	
	
		
			69 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // Name:        tests/graphics/clippingbox.cpp
 | |
| // Purpose:     clipping box unit tests
 | |
| // Author:      Artur Wieczorek
 | |
| // Created:     2016-06-29
 | |
| // Copyright:   (c) 2016 wxWidgets development team
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // headers
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| #include "testprec.h"
 | |
| 
 | |
| #ifdef __BORLANDC__
 | |
|     #pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| #include "wx/bitmap.h"
 | |
| #include "wx/dcmemory.h"
 | |
| #if wxUSE_GRAPHICS_CONTEXT
 | |
| #include "wx/dcgraph.h"
 | |
| #endif // wxUSE_GRAPHICS_CONTEXT
 | |
| 
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // test class
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| 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 const wxColour s_tmpColour(*wxBLUE);
 | |
| 
 | |
| #if wxUSE_IMAGE
 | |
| 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;
 | |
| }
 | |
| #endif // wxUSE_IMAGE
 | |
| 
 | |
| class ClippingBoxTestCaseBase : public CppUnit::TestCase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseBase()
 | |
|     {
 | |
|         m_bmp.Create(s_dcSize);
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseBase()
 | |
|     {
 | |
|         m_bmp = wxNullBitmap;
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     void CheckBoxPosition(int cur_x, int cur_y, int cur_w, int cur_h,
 | |
|                           int act_x, int act_y, int act_w, int act_h,
 | |
|                           int posTolerance = 0);
 | |
|     void CheckClipRect(int x, int y, int width, int height);
 | |
|     void CheckClipWithBitmap(const wxBitmap& bmpRef, int posTolerance = 0);
 | |
| 
 | |
|     wxBitmap m_bmp;
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseBase);
 | |
| };
 | |
| 
 | |
| // ====================
 | |
| // wxDC / wxGCDC tests
 | |
| // ====================
 | |
| 
 | |
| class ClippingBoxTestCaseDCBase : public ClippingBoxTestCaseBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseDCBase()
 | |
|     {
 | |
|         m_dc = NULL;
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseDCBase()
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual void setUp() { wxASSERT( m_dc ); }
 | |
|     virtual wxDC* GetDC(wxMemoryDC* dc) = 0;
 | |
| 
 | |
| protected:
 | |
|     void CheckClipPos(int x, int y, int width, int height, int posTolerance = 0);
 | |
|     void CheckClipBox(int x, int y, int width, int height,
 | |
|                       int devX, int devY, int devWidth, int devHeight);
 | |
|     void CheckClipShape(const wxBitmap& bmpRef, int posTolerance);
 | |
| 
 | |
|     void InitialState();
 | |
|     void InitialStateWithTransformedDC();
 | |
|     void InitialStateWithRotatedDC();
 | |
|     void OneRegion();
 | |
|     void OneLargeRegion();
 | |
|     void OneOuterRegion();
 | |
|     void OneRegionNegDim();
 | |
|     void OneRegionAndReset();
 | |
|     void OneRegionAndEmpty();
 | |
|     void OneRegionOverTransformedDC();
 | |
|     void OneRegionAndDCTransformation();
 | |
|     void TwoRegionsOverlapping();
 | |
|     void TwoRegionsOverlappingNegDim();
 | |
|     void TwoRegionsNonOverlapping();
 | |
|     void TwoRegionsNonOverlappingNegDim();
 | |
|     void OneDevRegion();
 | |
|     void OneLargeDevRegion();
 | |
|     void OneOuterDevRegion();
 | |
|     void OneDevRegionNegDim();
 | |
|     void OneDevRegionNonRect();
 | |
|     void OneDevRegionAndReset();
 | |
|     void OneDevRegionAndEmpty();
 | |
|     void OneDevRegionOverTransformedDC();
 | |
|     void OneDevRegionAndDCTransformation();
 | |
|     void TwoDevRegionsOverlapping();
 | |
|     void TwoDevRegionsOverlappingNegDim();
 | |
|     void TwoDevRegionsNonOverlapping();
 | |
|     void TwoDevRegionsNonOverlappingNegDim();
 | |
| 
 | |
|     virtual void FlushDC() = 0;
 | |
| 
 | |
|     wxDC* m_dc;
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseDCBase);
 | |
| };
 | |
| 
 | |
| // ===========
 | |
| // wxDC tests
 | |
| // ===========
 | |
| 
 | |
| class ClippingBoxTestCaseDC : public ClippingBoxTestCaseDCBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseDC()
 | |
|     {
 | |
|         m_mdc.SelectObject(m_bmp);
 | |
|         m_dc = &m_mdc;
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseDC()
 | |
|     {
 | |
|         m_mdc.SelectObject(wxNullBitmap);
 | |
|     }
 | |
| 
 | |
|     virtual void setUp() wxOVERRIDE
 | |
|     {
 | |
|         m_mdc.DestroyClippingRegion();
 | |
|         wxBrush bgBrush(s_bgColour, wxBRUSHSTYLE_SOLID);
 | |
|         m_mdc.SetBackground(bgBrush);
 | |
|         m_mdc.Clear();
 | |
|     }
 | |
| 
 | |
|     virtual wxDC* GetDC(wxMemoryDC* dc) wxOVERRIDE
 | |
|     {
 | |
|         return dc;
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     virtual void FlushDC() wxOVERRIDE {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseDC );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedDC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionOverTransformedDC );
 | |
|         CPPUNIT_TEST( OneRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegion);
 | |
|         CPPUNIT_TEST( OneLargeDevRegion );
 | |
|         CPPUNIT_TEST( OneOuterDevRegion );
 | |
|         CPPUNIT_TEST( OneDevRegionNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegionNonRect );
 | |
|         CPPUNIT_TEST( OneDevRegionAndReset);
 | |
|         CPPUNIT_TEST( OneDevRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneDevRegionOverTransformedDC);
 | |
|         CPPUNIT_TEST( OneDevRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlappingNegDim);
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlappingNegDim );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| protected:
 | |
|     wxMemoryDC m_mdc;
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseDC);
 | |
| };
 | |
| 
 | |
| // For GTK+ 3 wxDC is equivalent to wxGCDC
 | |
| // and hence doesn't need to be tested individually.
 | |
| #if !defined(__WXGTK3__)
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseDC );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseDC, "ClippingBoxTestCaseDC" );
 | |
| #endif // !__WXGTK3__
 | |
| 
 | |
| #if wxUSE_GRAPHICS_CONTEXT
 | |
| // =============
 | |
| // wxGCDC tests
 | |
| // =============
 | |
| 
 | |
| class ClippingBoxTestCaseGCDC : public ClippingBoxTestCaseDC
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCDC()
 | |
|     {
 | |
|         m_gcdc = new wxGCDC(m_mdc);
 | |
|         m_dc = m_gcdc;
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCDC()
 | |
|     {
 | |
|         delete m_gcdc;
 | |
|     }
 | |
| 
 | |
|     virtual void setUp() wxOVERRIDE
 | |
|     {
 | |
|         CPPUNIT_ASSERT_MESSAGE("Invalid wxGCDC", m_gcdc);
 | |
| 
 | |
|         wxGraphicsContext* ctx = m_gcdc->GetGraphicsContext();
 | |
|         ctx->SetAntialiasMode(wxANTIALIAS_NONE);
 | |
|         ctx->DisableOffset();
 | |
|         m_gcdc->DestroyClippingRegion();
 | |
|         wxBrush bgBrush(s_bgColour, wxBRUSHSTYLE_SOLID);
 | |
|         m_gcdc->SetBackground(bgBrush);
 | |
|         m_gcdc->Clear();
 | |
|     }
 | |
| 
 | |
|     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();
 | |
|     }
 | |
| 
 | |
|     void InitialStateWithRotatedGCForDC();
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDC );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedGCForDC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionOverTransformedDC );
 | |
|         CPPUNIT_TEST( OneRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegion);
 | |
|         CPPUNIT_TEST( OneLargeDevRegion );
 | |
|         CPPUNIT_TEST( OneOuterDevRegion );
 | |
|         CPPUNIT_TEST( OneDevRegionNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegionNonRect );
 | |
|         CPPUNIT_TEST( OneDevRegionAndReset);
 | |
|         CPPUNIT_TEST( OneDevRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneDevRegionOverTransformedDC);
 | |
|         CPPUNIT_TEST( OneDevRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlappingNegDim);
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlappingNegDim );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
|     wxGCDC* m_gcdc;
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCDC);
 | |
| };
 | |
| 
 | |
| // For MSW we have individual test cases for each graphics renderer
 | |
| // so we don't need to test wxGCDC with default renderer.
 | |
| #ifndef __WXMSW__
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCDC );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCDC, "ClippingBoxTestCaseGCDC" );
 | |
| #endif // !__WXMSW__
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
| // GDI+ and Direct2D are available only under MSW.
 | |
| 
 | |
| #if wxUSE_GRAPHICS_GDIPLUS
 | |
| class ClippingBoxTestCaseGCDCGDIPlus : public ClippingBoxTestCaseGCDC
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCDCGDIPlus()
 | |
|     {
 | |
|         wxGraphicsRenderer* rend = wxGraphicsRenderer::GetGDIPlusRenderer();
 | |
|         wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
 | |
|         m_gcdc->SetGraphicsContext(ctx);
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCDCGDIPlus() {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDCGDIPlus );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedGCForDC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionOverTransformedDC );
 | |
|         CPPUNIT_TEST( OneRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegion);
 | |
|         CPPUNIT_TEST( OneLargeDevRegion );
 | |
|         CPPUNIT_TEST( OneOuterDevRegion );
 | |
|         CPPUNIT_TEST( OneDevRegionNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegionNonRect );
 | |
|         CPPUNIT_TEST( OneDevRegionAndReset);
 | |
|         CPPUNIT_TEST( OneDevRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneDevRegionOverTransformedDC);
 | |
|         CPPUNIT_TEST( OneDevRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlappingNegDim);
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlappingNegDim );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCDCGDIPlus);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCDCGDIPlus );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCDCGDIPlus, "ClippingBoxTestCaseGCDCGDIPlus" );
 | |
| 
 | |
| #endif // wxUSE_GRAPHICS_GDIPLUS
 | |
| 
 | |
| #if wxUSE_GRAPHICS_DIRECT2D
 | |
| class ClippingBoxTestCaseGCDCDirect2D : public ClippingBoxTestCaseGCDC
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCDCDirect2D()
 | |
|     {
 | |
|         wxGraphicsRenderer* rend = wxGraphicsRenderer::GetDirect2DRenderer();
 | |
|         wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
 | |
|         m_gcdc->SetGraphicsContext(ctx);
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCDCDirect2D() {}
 | |
| 
 | |
|     virtual void FlushDC()
 | |
|     {
 | |
|         // Apparently, flushing native Direct2D renderer
 | |
|         // is not enough to update underlying DC (bitmap)
 | |
|         // and therefore we have to destroy the renderer
 | |
|         // to do so.
 | |
|         ClippingBoxTestCaseGCDC::FlushDC();
 | |
|         m_gcdc->SetGraphicsContext(NULL);
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDCDirect2D );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedGCForDC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionOverTransformedDC );
 | |
|         CPPUNIT_TEST( OneRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegion);
 | |
|         CPPUNIT_TEST( OneLargeDevRegion );
 | |
|         CPPUNIT_TEST( OneOuterDevRegion );
 | |
|         CPPUNIT_TEST( OneDevRegionNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegionNonRect );
 | |
|         CPPUNIT_TEST( OneDevRegionAndReset);
 | |
|         CPPUNIT_TEST( OneDevRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneDevRegionOverTransformedDC);
 | |
|         CPPUNIT_TEST( OneDevRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlappingNegDim);
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlappingNegDim );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCDCDirect2D);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCDCDirect2D );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCDCDirect2D, "ClippingBoxTestCaseGCDCDirect2D" );
 | |
| 
 | |
| #endif // wxUSE_GRAPHICS_DIRECT2D
 | |
| 
 | |
| #endif // __WXMSW__
 | |
| 
 | |
| #if wxUSE_CAIRO
 | |
| class ClippingBoxTestCaseGCDCCairo : public ClippingBoxTestCaseGCDC
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCDCCairo()
 | |
|     {
 | |
|         wxGraphicsRenderer* rend = wxGraphicsRenderer::GetCairoRenderer();
 | |
|         wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
 | |
|         m_gcdc->SetGraphicsContext(ctx);
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCDCCairo() {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDCCairo );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedDC );
 | |
|         CPPUNIT_TEST( InitialStateWithRotatedGCForDC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionOverTransformedDC );
 | |
|         CPPUNIT_TEST( OneRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegion);
 | |
|         CPPUNIT_TEST( OneLargeDevRegion );
 | |
|         CPPUNIT_TEST( OneOuterDevRegion );
 | |
|         CPPUNIT_TEST( OneDevRegionNegDim );
 | |
|         CPPUNIT_TEST( OneDevRegionNonRect );
 | |
|         CPPUNIT_TEST( OneDevRegionAndReset);
 | |
|         CPPUNIT_TEST( OneDevRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneDevRegionOverTransformedDC);
 | |
|         CPPUNIT_TEST( OneDevRegionAndDCTransformation );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsOverlappingNegDim);
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoDevRegionsNonOverlappingNegDim );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCDCCairo);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCDCCairo );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCDCCairo, "ClippingBoxTestCaseGCDCCairo" );
 | |
| 
 | |
| #endif // wxUSE_CAIRO
 | |
| 
 | |
| #endif //  wxUSE_GRAPHICS_CONTEXT
 | |
| 
 | |
| // Helper class to hold rectangle
 | |
| // which size is guaranteed to be >= 0
 | |
| class wxClipRect : public wxRect
 | |
| {
 | |
| public:
 | |
|     wxClipRect(int xx, int yy, int w, int h, int boundWidth = 1)
 | |
|     {
 | |
|         if ( w < 0 )
 | |
|         {
 | |
|             w = -w;
 | |
|             xx -= (w - boundWidth);
 | |
|         }
 | |
|         if ( h < 0 )
 | |
|         {
 | |
|             h = -h;
 | |
|             yy -= (h - boundWidth);
 | |
|         }
 | |
|         x = xx;
 | |
|         y = yy;
 | |
|         width = w;
 | |
|         height = h;
 | |
|     }
 | |
| };
 | |
| 
 | |
| // =====  Implementation  =====
 | |
| 
 | |
| static bool inline IsCoordEqual(int pos1, int pos2, int posTolerance = 0)
 | |
| {
 | |
|     return abs(pos1 - pos2) <= posTolerance;
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseBase::CheckBoxPosition(int cur_x, int cur_y, int cur_w, int cur_h,
 | |
|                                                int x, int y, int w, int h,
 | |
|                                                int posTolerance)
 | |
| {
 | |
|     wxString msgPos;
 | |
|     if ( !IsCoordEqual(x, cur_x, posTolerance) ||
 | |
|          !IsCoordEqual(y, cur_y, posTolerance) )
 | |
|     {
 | |
|         msgPos =
 | |
|             wxString::Format(wxS("Invalid position: Actual: (%i, %i)  Expected: (%i, %i)"),
 | |
|                                 cur_x, cur_y, x, y);
 | |
|     }
 | |
|     wxString msgDim;
 | |
|     if ( !IsCoordEqual(w, cur_w, 2*posTolerance) ||
 | |
|          !IsCoordEqual(h, cur_h, 2*posTolerance) )
 | |
|     {
 | |
|         msgDim =
 | |
|             wxString::Format(wxS("Invalid dimension: Actual: %i x %i  Expected: %i x %i"),
 | |
|                                 cur_w, cur_h, w, h);
 | |
|     }
 | |
| 
 | |
|     wxString msg;
 | |
|     if ( !msgPos.empty() )
 | |
|     {
 | |
|         msg = msgPos;
 | |
|         if ( !msgDim.empty() )
 | |
|         {
 | |
|             msg += wxS("\n- ");
 | |
|             msg += msgDim;
 | |
|         }
 | |
|     }
 | |
|     else if ( !msgDim.empty() )
 | |
|     {
 | |
|         msg = msgDim;
 | |
|     }
 | |
| 
 | |
|     if( !msg.empty() )
 | |
|     {
 | |
|         wxCharBuffer buffer = msg.ToUTF8();
 | |
|         CPPUNIT_FAIL( buffer.data() );
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseBase::CheckClipRect(int x, int y, int width, int height)
 | |
| {
 | |
| #if wxUSE_IMAGE
 | |
|     // We check whether diagonal corners of the clipping box are actually
 | |
|     // drawn at the edge of the clipping region.
 | |
|     wxImage img = m_bmp.ConvertToImage();
 | |
|     wxString msg;
 | |
| 
 | |
|     wxPoint corners[4];
 | |
|     corners[0] = wxPoint(x, y); // top-left corner
 | |
|     corners[1] = wxPoint(x+width-1, y); // top-right corner
 | |
|     corners[2] = wxPoint(x, y+height-1); // bottom-left corner
 | |
|     corners[3] = wxPoint(x+width-1, y+height-1); // bottom-right corner
 | |
| 
 | |
|     // Check area near every corner
 | |
|     for ( unsigned int c = 0; c < WXSIZEOF(corners); c++ )
 | |
|     {
 | |
|         int ymin = corners[c].y-1;
 | |
|         int xmin = corners[c].x-1;
 | |
|         int ymax = corners[c].y+1;
 | |
|         int xmax = corners[c].x+1;
 | |
|         ymin = wxMin(wxMax(ymin, 0), s_dcSize.GetHeight()-1);
 | |
|         xmin = wxMin(wxMax(xmin, 0), s_dcSize.GetWidth()-1);
 | |
|         ymax = wxMin(wxMax(ymax, 0), s_dcSize.GetHeight()-1);
 | |
|         xmax = wxMin(wxMax(xmax, 0), s_dcSize.GetWidth()-1);
 | |
| 
 | |
|         for( int py = ymin; py <= ymax; py++ )
 | |
|             for( int px = xmin; px <= xmax; px++ )
 | |
|             {
 | |
|                 wxColour c;
 | |
|                 unsigned char r = img.GetRed(px, py);
 | |
|                 unsigned char g = img.GetGreen(px, py);
 | |
|                 unsigned char b = img.GetBlue(px, py);
 | |
|                 c.Set(r, g, b);
 | |
| 
 | |
|                 wxString msgColour;
 | |
|                 if ( px >= x && px <= x + (width-1) &&
 | |
|                      py >= y && py <= y + (height-1) )
 | |
|                 {
 | |
|                     // Pixel inside the box.
 | |
|                     if ( c != s_fgColour )
 | |
|                     {
 | |
|                         msgColour =
 | |
|                             wxString::Format(wxS("Invalid colour drawn at (%i, %i): Actual: %s  Expected: %s"),
 | |
|                                     px, py, c.GetAsString().mbc_str(), s_fgColour.GetAsString().mbc_str());
 | |
| 
 | |
|                     }
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     // Pixel outside the box.
 | |
|                     if ( c != s_bgColour )
 | |
|                     {
 | |
|                         msgColour =
 | |
|                             wxString::Format(wxS("Invalid colour drawn at (%i, %i): Actual: %s  Expected: %s"),
 | |
|                                     px, py, c.GetAsString().mbc_str(), s_bgColour.GetAsString().mbc_str());
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if ( !msgColour.empty() )
 | |
|                 {
 | |
|                     if ( !msg.empty() )
 | |
|                     {
 | |
|                         msg += wxS("\n- ");
 | |
|                         msg += msgColour;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         msg = msgColour;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|     }
 | |
| 
 | |
|     if( !msg.empty() )
 | |
|     {
 | |
|         wxCharBuffer buffer = msg.ToUTF8();
 | |
|         CPPUNIT_FAIL( buffer.data() );
 | |
|     }
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseBase::CheckClipWithBitmap(const wxBitmap& bmpRef, int posTolerance)
 | |
| {
 | |
| #if wxUSE_IMAGE
 | |
|     wxImage img = m_bmp.ConvertToImage();
 | |
| 
 | |
|     // 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 of the clipping region" );
 | |
|     }
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::CheckClipPos(int x, int y, int width, int height, int posTolerance)
 | |
| {
 | |
|     // Check clipping box boundaries.
 | |
|     int clipX, clipY, clipW, clipH;
 | |
|     m_dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
 | |
| 
 | |
|     CheckBoxPosition(clipX, clipY, clipW, clipH, x, y, width, height, posTolerance);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::CheckClipBox(int x, int y, int width, int height,
 | |
|                                              int devX, int devY, int devWidth, int devHeight)
 | |
| {
 | |
|     // Check clipping box boundaries.
 | |
|     int clipX, clipY, clipW, clipH;
 | |
|     m_dc->GetClippingBox(&clipX, &clipY, &clipW, &clipH);
 | |
| 
 | |
|     CheckBoxPosition(clipX, clipY, clipW, clipH, x, y, width, height);
 | |
| 
 | |
|     // Update wxDC contents.
 | |
|     FlushDC();
 | |
| 
 | |
|     // We will examine pixels directly in the underlying bitmap
 | |
|     // so we need to use device coordinates of the examined area.
 | |
| #if wxUSE_IMAGE
 | |
|     // We check whether diagonal corners
 | |
|     // of the rectangular clipping box are actually
 | |
|     // drawn at the edge of the clipping region.
 | |
|     CheckClipRect(devX, devY, devWidth, devHeight);
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::CheckClipShape(const wxBitmap& bmpRef, int posTolerance)
 | |
| {
 | |
|     // Update wxDC contents.
 | |
|     FlushDC();
 | |
| 
 | |
| #if wxUSE_IMAGE
 | |
|     // 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 accept some shift of pixels.
 | |
|     CheckClipWithBitmap(bmpRef, posTolerance);
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| // Actual tests
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::InitialState()
 | |
| {
 | |
|     // Initial clipping box should be the same as the entire DC surface.
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight(),
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::InitialStateWithTransformedDC()
 | |
| {
 | |
|     // Initial clipping box with transformed DC.
 | |
|     m_dc->SetDeviceOrigin(10, 15);
 | |
|     m_dc->SetUserScale(0.5, 1.5);
 | |
|     m_dc->SetLogicalScale(4.0, 2.0);
 | |
|     m_dc->SetLogicalOrigin(-15, -20);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(0), m_dc->DeviceToLogicalY(0),
 | |
|              m_dc->DeviceToLogicalXRel(s_dcSize.GetWidth()),
 | |
|              m_dc->DeviceToLogicalYRel(s_dcSize.GetHeight()),
 | |
|              0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::InitialStateWithRotatedDC()
 | |
| {
 | |
|     // Initial clipping box with rotated DC.
 | |
| #if wxUSE_DC_TRANSFORM_MATRIX
 | |
|     int clipX, clipY, clipW, clipH;
 | |
|     if ( m_dc->CanUseTransformMatrix() )
 | |
|     {
 | |
|         // Apply rotation to DC.
 | |
|         wxAffineMatrix2D m = m_dc->GetTransformMatrix();
 | |
|         m.Rotate(6*M_PI/180.0);
 | |
|         m_dc->SetTransformMatrix(m);
 | |
| 
 | |
|         // Calculate expected clipping box.
 | |
|         m.Invert();
 | |
|         double x1, y1, x2, y2;
 | |
|         double x, y;
 | |
|         // Top-left corner
 | |
|         x = 0.0;
 | |
|         y = 0.0;
 | |
|         m.TransformPoint(&x, &y);
 | |
|         x1 = x;
 | |
|         y1 = y;
 | |
|         x2 = x;
 | |
|         y2 = y;
 | |
|         // Top-right corner
 | |
|         x = s_dcSize.GetWidth();
 | |
|         y = 0.0;
 | |
|         m.TransformPoint(&x, &y);
 | |
|         x1 = wxMin(x1, x);
 | |
|         y1 = wxMin(y1, y);
 | |
|         x2 = wxMax(x2, x);
 | |
|         y2 = wxMax(y2, y);
 | |
|         // Bottom-right corner
 | |
|         x = s_dcSize.GetWidth();
 | |
|         y = s_dcSize.GetHeight();
 | |
|         m.TransformPoint(&x, &y);
 | |
|         x1 = wxMin(x1, x);
 | |
|         y1 = wxMin(y1, y);
 | |
|         x2 = wxMax(x2, x);
 | |
|         y2 = wxMax(y2, y);
 | |
|         // Bottom-left corner
 | |
|         x = 0.0;
 | |
|         y = s_dcSize.GetHeight();
 | |
|         m.TransformPoint(&x, &y);
 | |
|         x1 = wxMin(x1, x);
 | |
|         y1 = wxMin(y1, y);
 | |
|         x2 = wxMax(x2, x);
 | |
|         y2 = wxMax(y2, y);
 | |
| 
 | |
|         clipX = wxRound(x1);
 | |
|         clipY = wxRound(y1);
 | |
|         clipW = wxRound(x2)-wxRound(x1);
 | |
|         clipH = wxRound(y2)-wxRound(y1);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         clipX = 0;
 | |
|         clipY = 0;
 | |
|         clipW = s_dcSize.GetWidth();
 | |
|         clipH = s_dcSize.GetHeight();
 | |
|     }
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(clipX, clipY, clipW, clipH,
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| #endif // wxUSE_DC_TRANSFORM_MATRIX
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegion()
 | |
| {
 | |
|     // Setting one clipping region inside DC area.
 | |
|     const int x = 10;
 | |
|     const int y = 20;
 | |
|     const int w = 80;
 | |
|     const int h = 75;
 | |
| 
 | |
|     m_dc->SetClippingRegion(x, y, w, h);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(x, y, w, h,
 | |
|                  x, y, w, h);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneLargeRegion()
 | |
| {
 | |
|     // Setting one clipping region larger then DC surface.
 | |
|     // Final clipping box should be limited to the DC extents.
 | |
|     m_dc->SetClippingRegion(-10, -20,
 | |
|                          s_dcSize.GetWidth()+30, s_dcSize.GetHeight()+50);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight(),
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneOuterRegion()
 | |
| {
 | |
|     // Setting one clipping region entirely outside DC surface.
 | |
|     // Final clipping box should be empty.
 | |
|     m_dc->SetClippingRegion(-100, -80, 20, 40);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegionNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative sizes values.
 | |
|     // Final clipping box should have standard positive size values.
 | |
|     const int x = 10;
 | |
|     const int y = 20;
 | |
|     const int w = -80;
 | |
|     const int h = -75;
 | |
|     wxClipRect r1(x, y, w, h);
 | |
|     wxRect r2(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     m_dc->SetClippingRegion(x, y, w, h);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight(),
 | |
|                  r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegionAndReset()
 | |
| {
 | |
|     // Setting one clipping region and next destroy it.
 | |
|     // Final clipping box should be the same as DC surface.
 | |
|     m_dc->SetClippingRegion(10, 20, 80, 75);
 | |
|     m_dc->DestroyClippingRegion();
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight(),
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegionAndEmpty()
 | |
| {
 | |
|     // Setting one clipping region and next an empty box.
 | |
|     // Final clipping box should empty.
 | |
|     m_dc->SetClippingRegion(10, 20, 80, 75);
 | |
|     m_dc->SetClippingRegion(0, 0, 0, 0);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegionOverTransformedDC()
 | |
| {
 | |
|     // Setting one clipping region inside DC area
 | |
|     // with applied some transformations.
 | |
|     wxRect r1(-10, -20, 80, 75);
 | |
| 
 | |
|     m_dc->SetDeviceOrigin(10, 15);
 | |
|     m_dc->SetUserScale(0.5, 1.5);
 | |
|     m_dc->SetLogicalScale(4.0, 2.0);
 | |
|     m_dc->SetLogicalOrigin(-15, -20);
 | |
|     m_dc->SetClippingRegion(r1);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     wxRect r2(m_dc->DeviceToLogicalX(0),
 | |
|               m_dc->DeviceToLogicalY(0),
 | |
|               m_dc->DeviceToLogicalXRel(s_dcSize.GetWidth()),
 | |
|               m_dc->DeviceToLogicalYRel(s_dcSize.GetHeight()));
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight(),
 | |
|                  m_dc->LogicalToDeviceX(r.GetLeft()),
 | |
|                  m_dc->LogicalToDeviceY(r.GetTop()),
 | |
|                  m_dc->LogicalToDeviceXRel(r.GetWidth()),
 | |
|                  m_dc->LogicalToDeviceYRel(r.GetHeight()));
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneRegionAndDCTransformation()
 | |
| {
 | |
|     // Setting one clipping region inside DC area
 | |
|     // and applying DC transformation afterwards.
 | |
|     wxRect r(-10, -21, 26, 21);
 | |
| 
 | |
|     m_dc->SetDeviceOrigin(10, 15);
 | |
|     m_dc->SetUserScale(0.5, 1.5);
 | |
|     m_dc->SetLogicalScale(4.0, 2.0);
 | |
|     m_dc->SetLogicalOrigin(-16, -21);
 | |
| 
 | |
|     m_dc->SetClippingRegion(r);
 | |
|     m_dc->SetBackground(wxBrush(s_tmpColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
| 
 | |
|     m_dc->SetDeviceOrigin(16, 24);
 | |
| 
 | |
|     // This should entirely overpaint previous clipping area.
 | |
|     wxCoord x, y, w, h;
 | |
|     m_dc->GetClippingBox(&x, &y, &w, &h);
 | |
|     m_dc->SetClippingRegion(x, y, w, h);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     const int clipX = -13;
 | |
|     const int clipY = -24;
 | |
|     const int clipW = 26;
 | |
|     const int clipH = 21;
 | |
|     CheckClipBox(clipX, clipY, clipW, clipH,
 | |
|                  m_dc->LogicalToDeviceX(clipX),
 | |
|                  m_dc->LogicalToDeviceY(clipY),
 | |
|                  m_dc->LogicalToDeviceXRel(clipW),
 | |
|                  m_dc->LogicalToDeviceYRel(clipH));
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoRegionsOverlapping()
 | |
| {
 | |
|     // Setting one clipping region and next another region (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two boxes.
 | |
|     wxRect r1(10, 20, 80, 75);
 | |
|     wxRect r2(50, 60, 50, 40);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     m_dc->SetClippingRegion(r1);
 | |
|     m_dc->SetClippingRegion(r2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight(),
 | |
|                  r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoRegionsOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative size values
 | |
|     // and next another region (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two boxes
 | |
|     // with positive size values.
 | |
|     const int x1 = 90;
 | |
|     const int y1 = 95;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 50;
 | |
|     const int y2 = 60;
 | |
|     const int w2 = 50;
 | |
|     const int h2 = 40;
 | |
|     wxClipRect r1(x1, y1, w1, h1);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
| 
 | |
|     m_dc->SetClippingRegion(x1, y1, w1, h1);
 | |
|     m_dc->SetClippingRegion(x2, y2, w2, h2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight(),
 | |
|                  r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoRegionsNonOverlapping()
 | |
| {
 | |
|     // Setting one clipping region and next another region (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     wxRect r1(10, 20, 30, 30);
 | |
|     wxRect r2(50, 60, 50, 40);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     m_dc->SetClippingRegion(r1);
 | |
|     m_dc->SetClippingRegion(r2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoRegionsNonOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative size values
 | |
|     // and next another region (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     const int x1 = 10;
 | |
|     const int y1 = 20;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 50;
 | |
|     const int y2 = 60;
 | |
|     const int w2 = 50;
 | |
|     const int h2 = 40;
 | |
|     wxClipRect r1(x1, y1, w1, h1);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     m_dc->SetClippingRegion(x1, y1, w1, h1);
 | |
|     m_dc->SetClippingRegion(x2, y2, w2, h2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegion()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // inside transformed DC area.
 | |
|     const int x = 10;
 | |
|     const int y = 21;
 | |
|     const int w = 80;
 | |
|     const int h = 75;
 | |
| 
 | |
|     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 reg(x, y, w, h);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(x),
 | |
|                  m_dc->DeviceToLogicalY(y),
 | |
|                  m_dc->DeviceToLogicalXRel(w),
 | |
|                  m_dc->DeviceToLogicalYRel(h),
 | |
|                  x, y, w, h);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneLargeDevRegion()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates larger
 | |
|     // then transformed DC surface.
 | |
|     // Final clipping box should be limited to the DC extents.
 | |
|     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 reg(-10, -20, s_dcSize.GetWidth()+30, s_dcSize.GetHeight()+50);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(0),
 | |
|                  m_dc->DeviceToLogicalY(0),
 | |
|                  m_dc->DeviceToLogicalXRel(s_dcSize.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(s_dcSize.GetHeight()),
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneOuterDevRegion()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // entirely outside transformed DC surface.
 | |
|     // Final clipping box should be empty.
 | |
|     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 reg(200, 80, 20, 40);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegionNegDim()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // with negative sizes values.
 | |
|     // Final clipping box should have standard positive size values.
 | |
|     const int x = 19;
 | |
|     const int y = 23;
 | |
|     const int w = -80;
 | |
|     const int h = -75;
 | |
|     wxClipRect r1(x, y, w, h);
 | |
|     wxRect r2(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     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 reg(x, y, w, h);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(r.GetLeft()),
 | |
|                  m_dc->DeviceToLogicalY(r.GetTop()),
 | |
|                  m_dc->DeviceToLogicalXRel(r.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(r.GetHeight()),
 | |
|                  r.GetLeft(), r.GetTop(), r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::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.
 | |
|     CheckClipPos(m_dc->DeviceToLogicalX(clipX),
 | |
|                  m_dc->DeviceToLogicalY(clipY),
 | |
|                  m_dc->DeviceToLogicalXRel(clipW),
 | |
|                  m_dc->DeviceToLogicalYRel(clipH), 1);
 | |
|     CheckClipShape(bmpRef, 1);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegionAndReset()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // and next destroy it.
 | |
|     // Final clipping box should be the same as DC surface.
 | |
|     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 reg(10, 20, 80, 75);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->DestroyClippingRegion();
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(0),
 | |
|                  m_dc->DeviceToLogicalY(0),
 | |
|                  m_dc->DeviceToLogicalXRel(s_dcSize.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(s_dcSize.GetHeight()),
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegionAndEmpty()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // and next an empty region.
 | |
|     // Final clipping box should empty.
 | |
|     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 reg1(10, 20, 80, 75);
 | |
|     m_dc->SetDeviceClippingRegion(reg1);
 | |
|     wxRegion reg2(0, 0, 0, 0);
 | |
|     m_dc->SetDeviceClippingRegion(reg2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegionOverTransformedDC()
 | |
| {
 | |
|     // Set one clipping region in device coordinates inside
 | |
|     // DC area with applied some transformations.
 | |
|     wxRect r1(8, 15, 60, 75);
 | |
| 
 | |
|     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 reg(r1);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     wxRect r2(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(r.GetLeft()),
 | |
|                  m_dc->DeviceToLogicalY(r.GetTop()),
 | |
|                  m_dc->DeviceToLogicalXRel(r.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(r.GetHeight()),
 | |
|                  r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::OneDevRegionAndDCTransformation()
 | |
| {
 | |
|     // Set one clipping region in device coordinates inside
 | |
|     // DC area and apply DC transformation afterwards.
 | |
|     wxRect r1(8, 15, 60, 75);
 | |
| 
 | |
|     m_dc->SetDeviceOrigin(10, 15);
 | |
|     m_dc->SetUserScale(0.5, 1.5);
 | |
|     m_dc->SetLogicalScale(4.0, 2.0);
 | |
|     m_dc->SetLogicalOrigin(-16, -21);
 | |
| 
 | |
|     wxRegion reg(r1);
 | |
|     m_dc->SetDeviceClippingRegion(reg);
 | |
|     m_dc->SetBackground(wxBrush(s_tmpColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
| 
 | |
|     m_dc->SetDeviceOrigin(16, 24);
 | |
| 
 | |
|     // This should entirely overpaint previous clipping area.
 | |
|     wxCoord x, y, w, h;
 | |
|     m_dc->GetClippingBox(&x, &y, &w, &h);
 | |
|     m_dc->SetClippingRegion(x, y, w, h);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     wxRect r2(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(r.GetLeft()),
 | |
|                  m_dc->DeviceToLogicalY(r.GetTop()),
 | |
|                  m_dc->DeviceToLogicalXRel(r.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(r.GetHeight()),
 | |
|                  r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoDevRegionsOverlapping()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // and next another region in device coordinates (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two regions.
 | |
|     wxRect r1(30, 39, 40, 30);
 | |
|     wxRect r2(60, 51, 40, 30);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     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 reg1(r1);
 | |
|     m_dc->SetDeviceClippingRegion(reg1);
 | |
|     wxRegion reg2(r2);
 | |
|     m_dc->SetDeviceClippingRegion(reg2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(r.GetLeft()),
 | |
|                  m_dc->DeviceToLogicalY(r.GetTop()),
 | |
|                  m_dc->DeviceToLogicalXRel(r.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(r.GetHeight()),
 | |
|                  r.GetLeft(), r.GetTop(), r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoDevRegionsOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates with negative size values
 | |
|     // and next another region in device coordinates (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two regions
 | |
|     // with positive size values.
 | |
|     const int x1 = 31;
 | |
|     const int y1 = 20;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 20;
 | |
|     const int y2 = 6;
 | |
|     const int w2 = 40;
 | |
|     const int h2 = 30;
 | |
|     wxClipRect r1(x1, y1, w1, h1);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     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 reg1(x1, y1, w1, h1);
 | |
|     m_dc->SetDeviceClippingRegion(reg1);
 | |
|     wxRegion reg2(x2, y2, w2, h2);
 | |
|     m_dc->SetDeviceClippingRegion(reg2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(m_dc->DeviceToLogicalX(r.GetLeft()),
 | |
|                  m_dc->DeviceToLogicalY(r.GetTop()),
 | |
|                  m_dc->DeviceToLogicalXRel(r.GetWidth()),
 | |
|                  m_dc->DeviceToLogicalYRel(r.GetHeight()),
 | |
|                  r.GetLeft(), r.GetTop(), r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoDevRegionsNonOverlapping()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates
 | |
|     // and next another region in device coordinates (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     wxRect r1(10, 20, 30, 30);
 | |
|     wxRect r2(50, 60, 50, 40);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     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 reg1(r1);
 | |
|     m_dc->SetDeviceClippingRegion(reg1);
 | |
|     wxRegion reg2(r2);
 | |
|     m_dc->SetDeviceClippingRegion(reg2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseDCBase::TwoDevRegionsNonOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region in device coordinates with negative size values
 | |
|     // and next another region (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     const int x1 = 10;
 | |
|     const int y1 = 20;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 50;
 | |
|     const int y2 = 60;
 | |
|     const int w2 = 50;
 | |
|     const int h2 = 40;
 | |
|     wxClipRect r1(x1, y1, w1, h1);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     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 reg1(x1, y1, w1, h1);
 | |
|     m_dc->SetDeviceClippingRegion(reg1);
 | |
|     wxRegion reg2(x2, y2, w2, h2);
 | |
|     m_dc->SetDeviceClippingRegion(reg2);
 | |
|     m_dc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_dc->Clear();
 | |
|     CheckClipBox(0, 0, 0, 0,
 | |
|                  0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| // Tests specific to wxGCDC
 | |
| #if wxUSE_GRAPHICS_CONTEXT
 | |
| void ClippingBoxTestCaseGCDC::InitialStateWithRotatedGCForDC()
 | |
| {
 | |
|     // Initial wxGCDC clipping box with rotated wxGraphicsContext.
 | |
|     wxGraphicsContext* gc = m_gcdc->GetGraphicsContext();
 | |
|     gc->Rotate(6*M_PI/180.0);
 | |
| 
 | |
|     m_gcdc->SetBackground(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_gcdc->Clear();
 | |
| 
 | |
|     // Calculate expected clipping box.
 | |
|     int clipX, clipY, clipW, clipH;
 | |
|     wxGraphicsMatrix m = gc->GetTransform();
 | |
|     m.Invert();
 | |
|     double x1, y1, x2, y2;
 | |
|     double x, y;
 | |
|     // Top-left corner
 | |
|     x = 0.0;
 | |
|     y = 0.0;
 | |
|     m.TransformPoint(&x, &y);
 | |
|     x1 = x;
 | |
|     y1 = y;
 | |
|     x2 = x;
 | |
|     y2 = y;
 | |
|     // Top-right corner
 | |
|     x = s_dcSize.GetWidth();
 | |
|     y = 0.0;
 | |
|     m.TransformPoint(&x, &y);
 | |
|     x1 = wxMin(x1, x);
 | |
|     y1 = wxMin(y1, y);
 | |
|     x2 = wxMax(x2, x);
 | |
|     y2 = wxMax(y2, y);
 | |
|     // Bottom-right corner
 | |
|     x = s_dcSize.GetWidth();
 | |
|     y = s_dcSize.GetHeight();
 | |
|     m.TransformPoint(&x, &y);
 | |
|     x1 = wxMin(x1, x);
 | |
|     y1 = wxMin(y1, y);
 | |
|     x2 = wxMax(x2, x);
 | |
|     y2 = wxMax(y2, y);
 | |
|     // Bottom-left corner
 | |
|     x = 0.0;
 | |
|     y = s_dcSize.GetHeight();
 | |
|     m.TransformPoint(&x, &y);
 | |
|     x1 = wxMin(x1, x);
 | |
|     y1 = wxMin(y1, y);
 | |
|     x2 = wxMax(x2, x);
 | |
|     y2 = wxMax(y2, y);
 | |
| 
 | |
|     clipX = wxRound(x1);
 | |
|     clipY = wxRound(y1);
 | |
|     clipW = wxRound(x2)-wxRound(x1);
 | |
|     clipH = wxRound(y2)-wxRound(y1);
 | |
| 
 | |
|     CheckClipBox(clipX, clipY, clipW, clipH,
 | |
|                  0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| #endif // wxUSE_GRAPHICS_CONTEXT
 | |
| 
 | |
| // ========================
 | |
| // wxGraphicsContext tests
 | |
| // ========================
 | |
| #if wxUSE_GRAPHICS_CONTEXT
 | |
| 
 | |
| class ClippingBoxTestCaseGCBase : public ClippingBoxTestCaseBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCBase()
 | |
|     {
 | |
|         m_rend = NULL;
 | |
|         m_gc = NULL;
 | |
|         m_mdc.SelectObject(m_bmp);
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCBase()
 | |
|     {
 | |
|         m_mdc.SelectObject(wxNullBitmap);
 | |
|         delete m_gc;
 | |
|     }
 | |
| 
 | |
|     virtual void setUp() wxOVERRIDE
 | |
|     {
 | |
|         m_mdc.DestroyClippingRegion();
 | |
|         wxBrush bgBrush(s_bgColour, wxBRUSHSTYLE_SOLID);
 | |
|         m_mdc.SetBackground(bgBrush);
 | |
|         m_mdc.Clear();
 | |
| 
 | |
|         CPPUNIT_ASSERT_MESSAGE("Invalid renderer", m_rend);
 | |
|         m_gc = m_rend->CreateContext(m_mdc);
 | |
|         m_gc->SetAntialiasMode(wxANTIALIAS_NONE);
 | |
|         m_gc->DisableOffset();
 | |
|         m_gc->ResetClip();
 | |
|     }
 | |
| 
 | |
| protected:
 | |
|     virtual void FlushGC()
 | |
|     {
 | |
|         m_gc->Flush();
 | |
|     }
 | |
| 
 | |
|     void CheckClipPos(int x, int y, int width, int height, int posTolerance = 0);
 | |
|     void CheckClipBox(int x, int y, int width, int height);
 | |
|     void CheckClipShape(const wxBitmap& bmpRef, int posTolerance);
 | |
|     void Clear();
 | |
| 
 | |
|     void InitialState();
 | |
|     void InitialStateWithTransformedGC();
 | |
|     void OneRegion();
 | |
|     void OneLargeRegion();
 | |
|     void OneOuterRegion();
 | |
|     void OneRegionNegDim();
 | |
|     void OneRegionAndReset();
 | |
|     void OneRegionAndEmpty();
 | |
|     void OneRegionWithTransformedGC();
 | |
|     void OneRegionWithRotatedGC();
 | |
|     void TwoRegionsOverlapping();
 | |
|     void TwoRegionsOverlappingNegDim();
 | |
|     void TwoRegionsNonOverlapping();
 | |
|     void TwoRegionsNonOverlappingNegDim();
 | |
|     void RegionsAndPushPopState();
 | |
| 
 | |
| protected:
 | |
|     wxGraphicsRenderer* m_rend;
 | |
|     wxGraphicsContext* m_gc;
 | |
|     wxMemoryDC m_mdc;
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCBase);
 | |
| };
 | |
| 
 | |
| #ifdef __WXMSW__
 | |
| // GDI+ and Direct2D are available only under MSW.
 | |
| 
 | |
| #if wxUSE_GRAPHICS_GDIPLUS
 | |
| class ClippingBoxTestCaseGCGDIPlus : public ClippingBoxTestCaseGCBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCGDIPlus()
 | |
|     {
 | |
|         m_rend = wxGraphicsRenderer::GetGDIPlusRenderer();
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCGDIPlus() {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCGDIPlus );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegionWithRotatedGC );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( RegionsAndPushPopState );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCGDIPlus);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCGDIPlus );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCGDIPlus, "ClippingBoxTestCaseGCGDIPlus" );
 | |
| 
 | |
| #endif // wxUSE_GRAPHICS_GDIPLUS
 | |
| 
 | |
| #if wxUSE_GRAPHICS_DIRECT2D
 | |
| class ClippingBoxTestCaseGCDirect2D : public ClippingBoxTestCaseGCBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCDirect2D()
 | |
|     {
 | |
|         m_rend = wxGraphicsRenderer::GetDirect2DRenderer();
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCDirect2D() {}
 | |
| 
 | |
|     virtual void FlushGC()
 | |
|     {
 | |
|         // Apparently, flushing native Direct2D renderer
 | |
|         // is not enough to update underlying DC (bitmap)
 | |
|         // and therefore we have to destroy the renderer
 | |
|         // to do so.
 | |
|         ClippingBoxTestCaseGCBase::FlushGC();
 | |
|         delete m_gc;
 | |
|         m_gc = NULL;
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCDirect2D );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegionWithRotatedGC );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( RegionsAndPushPopState );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCDirect2D);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCDirect2D );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCDirect2D, "ClippingBoxTestCaseGCDirect2D" );
 | |
| 
 | |
| #endif // wxUSE_GRAPHICS_DIRECT2D
 | |
| 
 | |
| #endif // __WXMSW__
 | |
| 
 | |
| #if wxUSE_CAIRO
 | |
| class ClippingBoxTestCaseGCCairo : public ClippingBoxTestCaseGCBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCCairo()
 | |
|     {
 | |
|         m_rend = wxGraphicsRenderer::GetCairoRenderer();
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCCairo() {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCCairo );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegionWithRotatedGC );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( RegionsAndPushPopState );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCCairo);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCCairo );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCCairo, "ClippingBoxTestCaseGCCairo" );
 | |
| 
 | |
| #endif // wxUSE_CAIRO
 | |
| 
 | |
| #ifdef __WXOSX__
 | |
| class ClippingBoxTestCaseGCCoreGraphics : public ClippingBoxTestCaseGCBase
 | |
| {
 | |
| public:
 | |
|     ClippingBoxTestCaseGCCoreGraphics()
 | |
|     {
 | |
|         m_rend = wxGraphicsRenderer::GetDefaultRenderer();
 | |
|     }
 | |
| 
 | |
|     virtual ~ClippingBoxTestCaseGCCoreGraphics() {}
 | |
| 
 | |
| private:
 | |
|     CPPUNIT_TEST_SUITE( ClippingBoxTestCaseGCCoreGraphics );
 | |
|         CPPUNIT_TEST( InitialState );
 | |
|         CPPUNIT_TEST( InitialStateWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegion );
 | |
|         CPPUNIT_TEST( OneLargeRegion );
 | |
|         CPPUNIT_TEST( OneOuterRegion );
 | |
|         CPPUNIT_TEST( OneRegionNegDim );
 | |
|         CPPUNIT_TEST( OneRegionAndReset );
 | |
|         CPPUNIT_TEST( OneRegionAndEmpty );
 | |
|         CPPUNIT_TEST( OneRegionWithTransformedGC );
 | |
|         CPPUNIT_TEST( OneRegionWithRotatedGC );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsOverlappingNegDim );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlapping );
 | |
|         CPPUNIT_TEST( TwoRegionsNonOverlappingNegDim );
 | |
|         CPPUNIT_TEST( RegionsAndPushPopState );
 | |
|     CPPUNIT_TEST_SUITE_END();
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     wxDECLARE_NO_COPY_CLASS(ClippingBoxTestCaseGCCoreGraphics);
 | |
| };
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( ClippingBoxTestCaseGCCoreGraphics );
 | |
| 
 | |
| // also include in it's own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ClippingBoxTestCaseGCCoreGraphics, "ClippingBoxTestCaseGCCoreGraphics" );
 | |
| 
 | |
| #endif // __WXOSX__
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::CheckClipPos(int x, int y, int width, int height, int posTolerance)
 | |
| {
 | |
|     // Check clipping box boundaries.
 | |
|     double clipX, clipY, clipW, clipH;
 | |
|     m_gc->GetClipBox(&clipX, &clipY, &clipW, &clipH);
 | |
| 
 | |
|     CheckBoxPosition(wxRound(clipX), wxRound(clipY), wxRound(clipW), wxRound(clipH),
 | |
|                      x, y, width, height, posTolerance);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::CheckClipBox(int x, int y, int width, int height)
 | |
| {
 | |
|     // Check clipping box boundaries.
 | |
|     double clipX, clipY, clipW, clipH;
 | |
|     m_gc->GetClipBox(&clipX, &clipY, &clipW, &clipH);
 | |
| 
 | |
|     CheckBoxPosition(wxRound(clipX), wxRound(clipY), wxRound(clipW), wxRound(clipH),
 | |
|                      x, y, width, height);
 | |
| 
 | |
|     // We will examine pixels directly in the underlying bitmap
 | |
|     // so we need to get device coordinates of examined area.
 | |
|     wxGraphicsMatrix m = m_gc->GetTransform();
 | |
|     double xdev = x;
 | |
|     double ydev = y;
 | |
|     m.TransformPoint(&xdev, &ydev);
 | |
|     double wdev = width;
 | |
|     double hdev = height;
 | |
|     m.TransformDistance(&wdev, &hdev);
 | |
| 
 | |
|     // Update wxGraphicsContext contents.
 | |
|     FlushGC();
 | |
| #if wxUSE_IMAGE
 | |
|     // We check whether diagonal corners
 | |
|     // of the rectangular clipping box are actually
 | |
|     // drawn at the edge of the clipping region.
 | |
|     CheckClipRect(wxRound(xdev), wxRound(ydev), wxRound(wdev), wxRound(hdev));
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::CheckClipShape(const wxBitmap& bmpRef, int posTolerance)
 | |
| {
 | |
|     // Update wxGraphicsContext contents.
 | |
|     FlushGC();
 | |
| 
 | |
| #if wxUSE_IMAGE
 | |
|     // 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 accept some shift of pixels.
 | |
|     CheckClipWithBitmap(bmpRef, posTolerance);
 | |
| #endif // wxUSE_IMAGE
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::Clear()
 | |
| {
 | |
|     double x, y, w, h;
 | |
|     m_gc->GetClipBox(&x, &y, &w, &h);
 | |
|     m_gc->SetBrush(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_gc->SetPen(*wxTRANSPARENT_PEN);
 | |
|     m_gc->SetCompositionMode(wxCOMPOSITION_SOURCE);
 | |
|     m_gc->DrawRectangle(x, y, w, h);
 | |
| }
 | |
| 
 | |
| // Actual tests
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::InitialState()
 | |
| {
 | |
|     // Initial clipping box should be the same as the entire GC surface.
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::InitialStateWithTransformedGC()
 | |
| {
 | |
|     // Initial clipping box with transformed GC.
 | |
|     wxGraphicsMatrix m = m_gc->CreateMatrix();
 | |
|     m.Translate(10, 15);
 | |
|     m.Scale(1/2.0, 1/3.0);
 | |
|     m.Translate(20, 30);
 | |
|     m_gc->SetTransform(m);
 | |
|     Clear();
 | |
|     m.Invert();
 | |
|     double x = 0;
 | |
|     double y = 0;
 | |
|     m.TransformPoint(&x, &y);
 | |
|     double w = s_dcSize.GetWidth();
 | |
|     double h = s_dcSize.GetHeight();
 | |
|     m.TransformDistance(&w, &h);
 | |
|     CheckClipBox(wxRound(x), wxRound(y), wxRound(w), wxRound(h));
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegion()
 | |
| {
 | |
|     // Setting one clipping region inside DC area.
 | |
|     const int x = 10;
 | |
|     const int y = 20;
 | |
|     const int w = 80;
 | |
|     const int h = 75;
 | |
| 
 | |
|     m_gc->Clip(x, y, w, h);
 | |
|     Clear();
 | |
|     CheckClipBox(x, y, w, h);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneLargeRegion()
 | |
| {
 | |
|     // Setting one clipping region larger then GC surface.
 | |
|     // Final clipping box should be limited to the GC extents.
 | |
|     m_gc->Clip(-10, -20,
 | |
|                s_dcSize.GetWidth()+30, s_dcSize.GetHeight()+50);
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneOuterRegion()
 | |
| {
 | |
|     // Setting one clipping region entirely outside GC surface.
 | |
|     // Final clipping box should be empty.
 | |
|     m_gc->Clip(-100, -80, 20, 40);
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegionNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative sizes values.
 | |
|     // Final clipping box should have standard positive size values.
 | |
|     const int x = 10;
 | |
|     const int y = 20;
 | |
|     const int w = -80;
 | |
|     const int h = -75;
 | |
|     wxClipRect r1(x, y, w, h, 0);
 | |
|     wxRect r2(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     m_gc->Clip(x, y, w, h);
 | |
|     Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegionAndReset()
 | |
| {
 | |
|     // Setting one clipping region and next destroy it.
 | |
|     // Final clipping box should be the same as GC surface.
 | |
|     m_gc->Clip(10, 20, 80, 75);
 | |
|     m_gc->ResetClip();
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegionAndEmpty()
 | |
| {
 | |
|     // Setting one clipping region and next an empty box.
 | |
|     // Final clipping box should empty.
 | |
|     m_gc->Clip(10, 20, 80, 75);
 | |
|     m_gc->Clip(0, 0, 0, 0);
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegionWithTransformedGC()
 | |
| {
 | |
|     // Setting one clipping region inside GC area
 | |
|     // with applied some transformations.
 | |
|     wxRect r1(-10, -21, 80, 75);
 | |
| 
 | |
|     wxGraphicsMatrix m = m_gc->CreateMatrix();
 | |
|     m.Translate(10, 15);
 | |
|     m.Scale(1/2.0, 1/3.0);
 | |
|     m.Translate(20, 30);
 | |
|     m_gc->SetTransform(m);
 | |
|     m_gc->Clip(r1.x, r1.y, r1.width, r1.height);
 | |
|     Clear();
 | |
|     m.Invert();
 | |
|     double x = 0;
 | |
|     double y = 0;
 | |
|     m.TransformPoint(&x, &y);
 | |
|     double w = s_dcSize.GetWidth();
 | |
|     double h = s_dcSize.GetHeight();
 | |
|     m.TransformDistance(&w, &h);
 | |
|     wxRect r2(wxRound(x), wxRound(y), wxRound(w), wxRound(h));
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::OneRegionWithRotatedGC()
 | |
| {
 | |
|     // Setting one rectangular clipping region for rotated graphics context.
 | |
|     const double rotAngle = 1.0*M_PI/180.0;
 | |
|     const int rectX = 16;
 | |
|     const int rectY = 14;
 | |
|     const int rectW = 60;
 | |
|     const int rectH = 55;
 | |
| 
 | |
|     // Set clipping region for rotated wxGC.
 | |
|     m_gc->Rotate(rotAngle);
 | |
|     m_gc->Clip(rectX, rectY, rectW, rectH);
 | |
|     // Fill in clipping region.
 | |
|     Clear();
 | |
| 
 | |
|     // Draw reference image with rotated rectangle which
 | |
|     // should look the same as rectangle drawn with Clip().
 | |
|     wxBitmap bmpRef(s_dcSize);
 | |
|     {
 | |
|         wxMemoryDC memDC(bmpRef);
 | |
|         wxGraphicsContext* gcRef = m_rend->CreateContext(memDC);
 | |
|         gcRef->SetAntialiasMode(wxANTIALIAS_NONE);
 | |
|         gcRef->DisableOffset();
 | |
|         gcRef->SetBrush(wxBrush(s_bgColour, wxBRUSHSTYLE_SOLID));
 | |
|         gcRef->SetPen(*wxTRANSPARENT_PEN);
 | |
|         gcRef->DrawRectangle(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
|         gcRef->Rotate(rotAngle);
 | |
|         gcRef->SetBrush(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|         gcRef->SetPen(wxPen(s_fgColour));
 | |
|         gcRef->DrawRectangle(rectX, rectY, rectW, rectH);
 | |
|         delete gcRef;
 | |
|     }
 | |
| 
 | |
|     // Compare filled in clipping region with reference rectangle.
 | |
|     // Rotated rectangles 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.
 | |
|     CheckClipShape(bmpRef, 1);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::TwoRegionsOverlapping()
 | |
| {
 | |
|     // Setting one clipping region and next another region (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two boxes.
 | |
|     wxRect r1(10, 20, 80, 75);
 | |
|     wxRect r2(50, 60, 50, 40);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
|     wxASSERT( !r.IsEmpty() );
 | |
| 
 | |
|     m_gc->Clip(r1.x, r1.y, r1.width, r1.height);
 | |
|     m_gc->Clip(r2.x, r2.y, r2.width, r2.height);
 | |
|     Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::TwoRegionsOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative size values
 | |
|     // and next another region (partially overlapping).
 | |
|     // Final clipping box should be an intersection of these two boxes
 | |
|     // with positive size values.
 | |
|     const int x1 = 90;
 | |
|     const int y1 = 95;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 50;
 | |
|     const int y2 = 60;
 | |
|     const int w2 = 50;
 | |
|     const int h2 = 40;
 | |
|     wxClipRect r1(x1, y1, w1, h1, 0);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxRect r = r1.Intersect(r2);
 | |
| 
 | |
|     m_gc->Clip(x1, y1, w1, h1);
 | |
|     m_gc->Clip(x2, y2, w2, h2);
 | |
|     Clear();
 | |
|     CheckClipBox(r.GetLeft(), r.GetTop(),
 | |
|                  r.GetWidth(), r.GetHeight());
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::TwoRegionsNonOverlapping()
 | |
| {
 | |
|     // Setting one clipping region and next another region (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     wxRect r1(10, 20, 30, 30);
 | |
|     wxRect r2(50, 60, 50, 40);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     m_gc->Clip(r1.x, r1.y, r1.width, r1.height);
 | |
|     m_gc->Clip(r2.x, r2.y, r2.width, r2.height);
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::TwoRegionsNonOverlappingNegDim()
 | |
| {
 | |
|     // Setting one clipping region with negative size values
 | |
|     // and next another region (non-overlapping).
 | |
|     // Final clipping box should be empty.
 | |
|     const int x1 = 10;
 | |
|     const int y1 = 20;
 | |
|     const int w1 = -80;
 | |
|     const int h1 = -75;
 | |
| 
 | |
|     const int x2 = 50;
 | |
|     const int y2 = 60;
 | |
|     const int w2 = 50;
 | |
|     const int h2 = 40;
 | |
|     wxClipRect r1(x1, y1, w1, h1, 0);
 | |
|     wxRect r2(x2, y2, w2, h2);
 | |
|     wxASSERT( !r1.Intersects(r2) );
 | |
| 
 | |
|     m_gc->Clip(x1, y1, w1, h1);
 | |
|     m_gc->Clip(x2, y2, w2, h2);
 | |
|     Clear();
 | |
|     CheckClipBox(0, 0, 0, 0);
 | |
| }
 | |
| 
 | |
| void ClippingBoxTestCaseGCBase::RegionsAndPushPopState()
 | |
| {
 | |
|     // Setting muliple rectangular clipping regions
 | |
|     // for transformed wxGC and store/restore them.
 | |
| 
 | |
|     // Get rectangle of the entire drawing area.
 | |
|     double x, y, w, h;
 | |
|     m_gc->GetClipBox(&x, &y, &w, &h);
 | |
| 
 | |
|     // Set clipping regions and store/restore them.
 | |
|     m_gc->SetBrush(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|     m_gc->SetPen(wxPen(s_fgColour));
 | |
| 
 | |
|     m_gc->Translate(5, 5);
 | |
|     m_gc->Rotate(5*M_PI/180);
 | |
|     m_gc->Clip(20, 15, 50, 45);
 | |
|     m_gc->PushState();
 | |
| 
 | |
|     m_gc->Rotate(5*M_PI/180);
 | |
|     m_gc->ResetClip();
 | |
|     m_gc->Clip(10, 5, 60, 15);
 | |
|     m_gc->PushState();
 | |
| 
 | |
|     m_gc->Rotate(-15*M_PI/180);
 | |
|     m_gc->ResetClip();
 | |
|     m_gc->Clip(5, 10, 30, 35);
 | |
|     m_gc->DrawRectangle(x, y, w, h);
 | |
| 
 | |
|     m_gc->PopState();
 | |
|     m_gc->DrawRectangle(x, y, w, h);
 | |
| 
 | |
|     m_gc->PopState();
 | |
|     m_gc->DrawRectangle(x, y, w, h);
 | |
| 
 | |
|     // Draw reference image with rotated rectangles which
 | |
|     // should look the same as rectangles drawn with Clip().
 | |
|     wxBitmap bmpRef(s_dcSize);
 | |
|     {
 | |
|         wxMemoryDC memDC(bmpRef);
 | |
|         wxGraphicsContext* gcRef = m_rend->CreateContext(memDC);
 | |
|         gcRef->SetAntialiasMode(wxANTIALIAS_NONE);
 | |
|         gcRef->DisableOffset();
 | |
|         gcRef->SetBrush(wxBrush(s_bgColour, wxBRUSHSTYLE_SOLID));
 | |
|         gcRef->SetPen(*wxTRANSPARENT_PEN);
 | |
|         gcRef->DrawRectangle(0, 0, s_dcSize.GetWidth(), s_dcSize.GetHeight());
 | |
| 
 | |
|         gcRef->SetBrush(wxBrush(s_fgColour, wxBRUSHSTYLE_SOLID));
 | |
|         gcRef->SetPen(wxPen(s_fgColour));
 | |
| 
 | |
|         gcRef->Translate(5, 5);
 | |
|         gcRef->Rotate(5*M_PI/180);
 | |
|         gcRef->PushState();
 | |
| 
 | |
|         gcRef->Rotate(5*M_PI/180);
 | |
|         gcRef->PushState();
 | |
| 
 | |
|         gcRef->Rotate(-15*M_PI/180);
 | |
|         gcRef->DrawRectangle(5, 10, 30, 35);
 | |
| 
 | |
|         gcRef->PopState();
 | |
|         gcRef->DrawRectangle(10, 5, 60, 15);
 | |
| 
 | |
|         gcRef->PopState();
 | |
|         gcRef->DrawRectangle(20, 15, 50, 45);
 | |
| 
 | |
|         delete gcRef;
 | |
|     }
 | |
| 
 | |
|     // Compare filled in clipping regions with reference image.
 | |
|     // Rotated rectangles 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.
 | |
|     CheckClipShape(bmpRef, 1);
 | |
| }
 | |
| 
 | |
| #endif // wxUSE_GRAPHICS_CONTEXT
 |