initial commit
Signed-off-by: Peter Siegmund <mars3142@noreply.mars3142.dev>
This commit is contained in:
537
libs/wxWidgets-3.3.1/tests/graphics/affinematrix.cpp
Normal file
537
libs/wxWidgets-3.3.1/tests/graphics/affinematrix.cpp
Normal file
@@ -0,0 +1,537 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/affinetransform.cpp
|
||||
// Purpose: Unit test for transformations implemented for wxAffineMatrix2D
|
||||
// Author: Catalin Raceanu
|
||||
// Created: 2011-04-14
|
||||
// Copyright: (c) 2011 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/affinematrix2d.h"
|
||||
#include "wx/math.h"
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
#include "wx/dcgraph.h"
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#include "testimage.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Affine transform test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class AffineTransformTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
AffineTransformTestCase() {}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( AffineTransformTestCase );
|
||||
CPPUNIT_TEST( InvertMatrix );
|
||||
CPPUNIT_TEST( Concat );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void InvertMatrix();
|
||||
void Concat();
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(AffineTransformTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( AffineTransformTestCase );
|
||||
|
||||
// also include in its own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AffineTransformTestCase, "AffineTransformTestCase" );
|
||||
|
||||
void AffineTransformTestCase::InvertMatrix()
|
||||
{
|
||||
wxAffineMatrix2D matrix1;
|
||||
matrix1.Set(wxMatrix2D(2, 1, 1, 1), wxPoint2DDouble(1, 1));
|
||||
|
||||
wxAffineMatrix2D matrix2(matrix1);
|
||||
|
||||
matrix2.Invert();
|
||||
|
||||
wxMatrix2D m;
|
||||
wxPoint2DDouble p;
|
||||
matrix2.Get(&m, &p);
|
||||
CPPUNIT_ASSERT_EQUAL( 1, (int)m.m_11 );
|
||||
CPPUNIT_ASSERT_EQUAL( -1, (int)m.m_12 );
|
||||
CPPUNIT_ASSERT_EQUAL( -1, (int)m.m_21 );
|
||||
CPPUNIT_ASSERT_EQUAL( 2, (int)m.m_22 );
|
||||
CPPUNIT_ASSERT_EQUAL( 0, (int)p.m_x );
|
||||
CPPUNIT_ASSERT_EQUAL( -1, (int)p.m_y );
|
||||
|
||||
matrix2.Concat(matrix1);
|
||||
CPPUNIT_ASSERT( matrix2.IsIdentity() );
|
||||
}
|
||||
|
||||
void AffineTransformTestCase::Concat()
|
||||
{
|
||||
wxAffineMatrix2D m1;
|
||||
m1.Set(wxMatrix2D(0.9, 0.4, -0.4, 0.9), wxPoint2DDouble(0.0, 0.0));
|
||||
wxAffineMatrix2D m2;
|
||||
m2.Set(wxMatrix2D(1.0, 0.0, 0.0, 1.0), wxPoint2DDouble(3.0, 5.0));
|
||||
m1.Concat(m2);
|
||||
|
||||
wxMatrix2D m;
|
||||
wxPoint2DDouble p;
|
||||
m1.Get(&m, &p);
|
||||
|
||||
const double delta = 0.01;
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.9, m.m_11, delta );
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.4, m.m_12, delta );
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( -0.4, m.m_21, delta );
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.9, m.m_22, delta );
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.7, p.m_x, delta );
|
||||
CPPUNIT_ASSERT_DOUBLES_EQUAL( 5.7, p.m_y, delta );
|
||||
}
|
||||
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
// -------------------------------
|
||||
// Transform matrix test classes
|
||||
// -------------------------------
|
||||
|
||||
// ====================
|
||||
// wxDC / wxGCDC tests
|
||||
// ====================
|
||||
|
||||
class TransformMatrixTestCaseDCBase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseDCBase()
|
||||
{
|
||||
m_dc = nullptr;
|
||||
wxImage::AddHandler(new wxJPEGHandler);
|
||||
m_imgOrig.LoadFile(wxS("horse.jpg"));
|
||||
CPPUNIT_ASSERT( m_imgOrig.IsOk() );
|
||||
}
|
||||
|
||||
virtual ~TransformMatrixTestCaseDCBase()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
m_bmpOrig = wxBitmap(m_imgOrig);
|
||||
m_bmpUsingMatrix.Create(m_bmpOrig.GetSize(), m_bmpOrig.GetDepth());
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FlushDC() = 0;
|
||||
|
||||
void VMirrorAndTranslate();
|
||||
void Rotate90Clockwise();
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
void CompareToGraphicsContext();
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
protected:
|
||||
wxImage m_imgOrig;
|
||||
wxBitmap m_bmpOrig;
|
||||
|
||||
wxBitmap m_bmpUsingMatrix;
|
||||
wxDC* m_dc;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseDCBase);
|
||||
};
|
||||
|
||||
// ===========
|
||||
// wxDC tests
|
||||
// ===========
|
||||
|
||||
class TransformMatrixTestCaseDC : public TransformMatrixTestCaseDCBase
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseDC()
|
||||
{
|
||||
m_dc = &m_mdc;
|
||||
}
|
||||
|
||||
virtual ~TransformMatrixTestCaseDC()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
TransformMatrixTestCaseDCBase::setUp();
|
||||
m_mdc.SelectObject(m_bmpUsingMatrix);
|
||||
}
|
||||
|
||||
virtual void tearDown() override
|
||||
{
|
||||
m_mdc.SelectObject(wxNullBitmap);
|
||||
TransformMatrixTestCaseDCBase::tearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FlushDC() override {}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TransformMatrixTestCaseDC );
|
||||
CPPUNIT_TEST( VMirrorAndTranslate );
|
||||
CPPUNIT_TEST( Rotate90Clockwise );
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
CPPUNIT_TEST( CompareToGraphicsContext );
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
wxMemoryDC m_mdc;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseDC);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( TransformMatrixTestCaseDC );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TransformMatrixTestCaseDC, "TransformMatrixTestCaseDC" );
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
// =============
|
||||
// wxGCDC tests
|
||||
// =============
|
||||
|
||||
class TransformMatrixTestCaseGCDC : public TransformMatrixTestCaseDC
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseGCDC() {}
|
||||
|
||||
virtual ~TransformMatrixTestCaseGCDC() {}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
TransformMatrixTestCaseDC::setUp();
|
||||
|
||||
m_gcdc = new wxGCDC(m_mdc);
|
||||
m_dc = m_gcdc;
|
||||
|
||||
wxGraphicsContext* ctx = m_gcdc->GetGraphicsContext();
|
||||
ctx->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
}
|
||||
|
||||
virtual void tearDown() override
|
||||
{
|
||||
delete m_gcdc;
|
||||
TransformMatrixTestCaseDC::tearDown();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void FlushDC() override
|
||||
{
|
||||
m_gcdc->GetGraphicsContext()->Flush();
|
||||
}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TransformMatrixTestCaseGCDC );
|
||||
CPPUNIT_TEST( VMirrorAndTranslate );
|
||||
CPPUNIT_TEST( Rotate90Clockwise );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
wxGCDC* m_gcdc;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseGCDC);
|
||||
};
|
||||
|
||||
// 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( TransformMatrixTestCaseGCDC );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TransformMatrixTestCaseGCDC, "TransformMatrixTestCaseGCDC" );
|
||||
#endif // !__WXMSW__
|
||||
|
||||
#ifdef __WXMSW__
|
||||
// GDI+ and Direct2D are available only under MSW.
|
||||
|
||||
#if wxUSE_GRAPHICS_GDIPLUS
|
||||
class TransformMatrixTestCaseGCDCGDIPlus : public TransformMatrixTestCaseGCDC
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseGCDCGDIPlus() {}
|
||||
|
||||
virtual ~TransformMatrixTestCaseGCDCGDIPlus() {}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
TransformMatrixTestCaseGCDC::setUp();
|
||||
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetGDIPlusRenderer();
|
||||
wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
|
||||
m_gcdc->SetGraphicsContext(ctx);
|
||||
}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TransformMatrixTestCaseGCDCGDIPlus );
|
||||
CPPUNIT_TEST( VMirrorAndTranslate );
|
||||
CPPUNIT_TEST( Rotate90Clockwise );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseGCDCGDIPlus);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( TransformMatrixTestCaseGCDCGDIPlus );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TransformMatrixTestCaseGCDCGDIPlus, "TransformMatrixTestCaseGCDCGDIPlus" );
|
||||
|
||||
#endif // wxUSE_GRAPHICS_GDIPLUS
|
||||
|
||||
#if wxUSE_GRAPHICS_DIRECT2D
|
||||
class TransformMatrixTestCaseGCDCDirect2D : public TransformMatrixTestCaseGCDC
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseGCDCDirect2D() {}
|
||||
|
||||
virtual ~TransformMatrixTestCaseGCDCDirect2D() {}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
TransformMatrixTestCaseGCDC::setUp();
|
||||
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetDirect2DRenderer();
|
||||
wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
|
||||
m_gcdc->SetGraphicsContext(ctx);
|
||||
}
|
||||
|
||||
virtual void FlushDC() override
|
||||
{
|
||||
// Apparently, flushing native Direct2D renderer
|
||||
// is not enough to update underlying DC (bitmap)
|
||||
// and therefore we have to destroy the renderer
|
||||
// to do so.
|
||||
TransformMatrixTestCaseGCDC::FlushDC();
|
||||
m_gcdc->SetGraphicsContext(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TransformMatrixTestCaseGCDCDirect2D );
|
||||
CPPUNIT_TEST( VMirrorAndTranslate );
|
||||
CPPUNIT_TEST( Rotate90Clockwise );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseGCDCDirect2D);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( TransformMatrixTestCaseGCDCDirect2D );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TransformMatrixTestCaseGCDCDirect2D, "TransformMatrixTestCaseGCDCDirect2D" );
|
||||
|
||||
#endif // wxUSE_GRAPHICS_DIRECT2D
|
||||
|
||||
#endif // __WXMSW__
|
||||
|
||||
#if wxUSE_CAIRO
|
||||
class TransformMatrixTestCaseGCDCCairo : public TransformMatrixTestCaseGCDC
|
||||
{
|
||||
public:
|
||||
TransformMatrixTestCaseGCDCCairo() {}
|
||||
|
||||
virtual ~TransformMatrixTestCaseGCDCCairo() {}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
TransformMatrixTestCaseGCDC::setUp();
|
||||
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetCairoRenderer();
|
||||
wxGraphicsContext* ctx = rend->CreateContext(m_mdc);
|
||||
m_gcdc->SetGraphicsContext(ctx);
|
||||
}
|
||||
|
||||
private:
|
||||
CPPUNIT_TEST_SUITE( TransformMatrixTestCaseGCDCCairo );
|
||||
CPPUNIT_TEST( VMirrorAndTranslate );
|
||||
CPPUNIT_TEST( Rotate90Clockwise );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
protected:
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(TransformMatrixTestCaseGCDCCairo);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( TransformMatrixTestCaseGCDCCairo );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( TransformMatrixTestCaseGCDCCairo, "TransformMatrixTestCaseGCDCCairo" );
|
||||
|
||||
#endif // wxUSE_CAIRO
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
void TransformMatrixTestCaseDCBase::VMirrorAndTranslate()
|
||||
{
|
||||
// build the mirrored image using the transformation matrix
|
||||
if ( !m_dc->CanUseTransformMatrix() )
|
||||
return;
|
||||
|
||||
wxAffineMatrix2D matrix;
|
||||
matrix.Mirror(wxVERTICAL);
|
||||
// For wxDC pixel center is at (0, 0) so row 0 of the bitmap is the axis
|
||||
// of mirroring and it is left intact by the transformation. In this case
|
||||
// mirrored bitmap needs to be shifted by dim-1 pixels.
|
||||
// For wxGCDC pixel center of underlying wxGraphicsContext is at (0.5, 0.5)
|
||||
// so the axis of mirroring is above row 0 of the bitmap and this row
|
||||
// is affected by the transformation. In this case mirrored bitmap
|
||||
// needs to be shifthed by dim pixels.
|
||||
int ty;
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
if ( m_dc->GetGraphicsContext() )
|
||||
ty = m_bmpOrig.GetHeight();
|
||||
else
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
ty = m_bmpOrig.GetHeight() - 1;
|
||||
matrix.Translate(0, -ty);
|
||||
m_dc->SetTransformMatrix(matrix);
|
||||
m_dc->DrawBitmap(m_bmpOrig, 0, 0);
|
||||
FlushDC();
|
||||
|
||||
CHECK_THAT( m_bmpUsingMatrix.ConvertToImage(),
|
||||
RGBSameAs(m_imgOrig.Mirror(false)) );
|
||||
}
|
||||
|
||||
void TransformMatrixTestCaseDCBase::Rotate90Clockwise()
|
||||
{
|
||||
// build the rotated image using the transformation matrix
|
||||
if ( !m_dc->CanUseTransformMatrix() )
|
||||
return;
|
||||
|
||||
wxAffineMatrix2D matrix;
|
||||
matrix.Rotate(0.5 * M_PI);
|
||||
matrix.Translate(0, -m_bmpOrig.GetHeight());
|
||||
m_dc->SetTransformMatrix(matrix);
|
||||
m_dc->DrawBitmap(m_bmpOrig, 0, 0);
|
||||
FlushDC();
|
||||
|
||||
CHECK_THAT( m_bmpUsingMatrix.ConvertToImage(),
|
||||
RGBSameAs(m_imgOrig.Rotate90(true)) );
|
||||
}
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
void TransformMatrixTestCaseDCBase::CompareToGraphicsContext()
|
||||
{
|
||||
wxPoint2DDouble pointA1(1.0, 3.0), pointA2(60.0, 50.0),
|
||||
pointG1(1.0, 3.0), pointG2(60.0, 50.0);
|
||||
|
||||
// Create affine matrix and transform it
|
||||
wxAffineMatrix2D matrixA1, matrixA2;
|
||||
matrixA2.Rotate(M_PI / 3);
|
||||
matrixA1.Translate(-m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
|
||||
matrixA1.Rotate(-M_PI *2/ 6);
|
||||
matrixA1.Translate(m_bmpOrig.GetWidth()/2, m_bmpOrig.GetHeight()/2);
|
||||
matrixA1.Mirror(wxHORIZONTAL);
|
||||
matrixA1.Concat(matrixA2);
|
||||
matrixA1.Mirror(wxVERTICAL);
|
||||
matrixA1.Translate(m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
|
||||
matrixA1.Scale(0.9, 0.9);
|
||||
matrixA1.Invert();
|
||||
|
||||
// Create image using first matrix
|
||||
wxBitmap bmpUsingMatrixA1(m_bmpOrig.GetSize(), m_bmpOrig.GetDepth());
|
||||
|
||||
// Build the transformed image using the transformation matrix
|
||||
{
|
||||
wxMemoryDC dc(bmpUsingMatrixA1);
|
||||
|
||||
if ( !dc.CanUseTransformMatrix() )
|
||||
return;
|
||||
|
||||
// Draw the bitmap
|
||||
dc.SetTransformMatrix(matrixA1);
|
||||
dc.DrawBitmap(m_bmpOrig, 0, 0);
|
||||
|
||||
// Draw a line
|
||||
matrixA1.TransformPoint(&pointA1.m_x, &pointA1.m_y);
|
||||
matrixA1.TransformDistance(&pointA2.m_x, &pointA2.m_y);
|
||||
|
||||
dc.DrawLine(wxRound(pointA1.m_x), wxRound(pointA1.m_y),
|
||||
wxRound(pointA1.m_x + pointA2.m_x), wxRound(pointA1.m_x + pointA2.m_y));
|
||||
}
|
||||
|
||||
|
||||
// Create graphics matrix and transform it
|
||||
wxGraphicsRenderer* r;
|
||||
if ( m_dc->GetGraphicsContext() )
|
||||
{
|
||||
r = m_dc->GetGraphicsContext()->GetRenderer();
|
||||
}
|
||||
else
|
||||
{
|
||||
r = wxGraphicsRenderer::GetDefaultRenderer();
|
||||
}
|
||||
|
||||
wxBitmap bmp(10, 10);
|
||||
wxMemoryDC mDc(bmp);
|
||||
wxGraphicsContext* gDc = r->CreateContext(mDc);
|
||||
wxGraphicsMatrix matrixG1 = gDc->CreateMatrix();
|
||||
wxGraphicsMatrix matrixG2 = gDc->CreateMatrix();
|
||||
matrixG2.Rotate(M_PI / 3);
|
||||
matrixG1.Translate(-m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
|
||||
matrixG1.Rotate(-M_PI*2 / 6);
|
||||
matrixG1.Translate(m_bmpOrig.GetWidth()/2, m_bmpOrig.GetHeight()/2);
|
||||
matrixG1.Scale(-1, 1);
|
||||
matrixG1.Concat(matrixG2);
|
||||
matrixG1.Scale(1, -1);
|
||||
matrixG1.Translate(m_bmpOrig.GetWidth()/2, -m_bmpOrig.GetHeight()/2);
|
||||
matrixG1.Scale(0.9, 0.9);
|
||||
matrixG1.Invert();
|
||||
// Create affine matrix from the graphics matrix
|
||||
wxMatrix2D mat2D;
|
||||
wxPoint2DDouble tr;
|
||||
matrixG1.Get(&mat2D.m_11, &mat2D.m_12, &mat2D.m_21, &mat2D.m_22, &tr.m_x, &tr.m_y);
|
||||
wxAffineMatrix2D matrixAG;
|
||||
matrixAG.Set(mat2D, tr);
|
||||
|
||||
delete gDc;
|
||||
|
||||
// Create image using last matrix
|
||||
wxBitmap bmpUsingMatrixAG(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth());
|
||||
|
||||
// Build the transformed image using the transformation matrix
|
||||
{
|
||||
wxMemoryDC dc(bmpUsingMatrixAG);
|
||||
|
||||
if ( !dc.CanUseTransformMatrix() )
|
||||
return;
|
||||
|
||||
// Draw the bitmap
|
||||
dc.SetTransformMatrix(matrixAG);
|
||||
dc.DrawBitmap(m_bmpOrig, 0, 0);
|
||||
|
||||
// Draw a line
|
||||
matrixG1.TransformPoint(&pointG1.m_x, &pointG1.m_y);
|
||||
matrixG1.TransformDistance(&pointG2.m_x, &pointG2.m_y);
|
||||
|
||||
dc.DrawLine(wxRound(pointG1.m_x), wxRound(pointG1.m_y),
|
||||
wxRound(pointG1.m_x + pointG2.m_x), wxRound(pointG1.m_x + pointG2.m_y));
|
||||
}
|
||||
|
||||
|
||||
CHECK_THAT( bmpUsingMatrixA1.ConvertToImage(),
|
||||
RGBSameAs(bmpUsingMatrixAG.ConvertToImage()) );
|
||||
|
||||
// Save the images to check that something _is_ inside the visible area.
|
||||
//bmpUsingMatrixA1.SaveFile("matrixA1.jpg", wxBITMAP_TYPE_JPEG);
|
||||
//bmpUsingMatrixAG.SaveFile("matrixAG.jpg", wxBITMAP_TYPE_JPEG);
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
2094
libs/wxWidgets-3.3.1/tests/graphics/bitmap.cpp
Normal file
2094
libs/wxWidgets-3.3.1/tests/graphics/bitmap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
653
libs/wxWidgets-3.3.1/tests/graphics/bmpbundle.cpp
Normal file
653
libs/wxWidgets-3.3.1/tests/graphics/bmpbundle.cpp
Normal file
@@ -0,0 +1,653 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/bmpbundle.cpp
|
||||
// Purpose: wxBitmapBundle unit test
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2021-09-27
|
||||
// Copyright: (c) 2021 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
#include "wx/bmpbndl.h"
|
||||
|
||||
#include "wx/artprov.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/imaglist.h"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
#include "wx/msw/private/resource_usage.h"
|
||||
#endif // __WINDOWS__
|
||||
|
||||
#include "asserthelper.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("BitmapBundle::Create", "[bmpbundle]")
|
||||
{
|
||||
wxBitmapBundle b;
|
||||
CHECK( !b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == wxDefaultSize );
|
||||
|
||||
b = wxBitmap(16, 16);
|
||||
CHECK( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == wxSize(16, 16) );
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::FromBitmaps", "[bmpbundle]")
|
||||
{
|
||||
wxVector<wxBitmap> bitmaps;
|
||||
bitmaps.push_back(wxBitmap(16, 16));
|
||||
bitmaps.push_back(wxBitmap(24, 24));
|
||||
|
||||
wxBitmapBundle b = wxBitmapBundle::FromBitmaps(bitmaps);
|
||||
REQUIRE( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == wxSize(16, 16) );
|
||||
|
||||
CHECK( b.GetBitmap(wxDefaultSize ).GetSize() == wxSize(16, 16) );
|
||||
CHECK( b.GetBitmap(wxSize(16, 16)).GetSize() == wxSize(16, 16) );
|
||||
CHECK( b.GetBitmap(wxSize(20, 20)).GetSize() == wxSize(20, 20) );
|
||||
CHECK( b.GetBitmap(wxSize(24, 24)).GetSize() == wxSize(24, 24) );
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::GetBitmap", "[bmpbundle]")
|
||||
{
|
||||
wxBitmapBundle b = wxBitmapBundle::FromBitmap(wxBitmap(16, 16));
|
||||
|
||||
CHECK( b.GetBitmap(wxSize(16, 16)).GetSize() == wxSize(16, 16) );
|
||||
CHECK( b.GetBitmap(wxSize(32, 32)).GetSize() == wxSize(32, 32) );
|
||||
CHECK( b.GetBitmap(wxSize(24, 24)).GetSize() == wxSize(24, 24) );
|
||||
|
||||
// Test for the special case when the requested size uses the same height
|
||||
// but not the same width.
|
||||
wxBitmap nonSquare(wxSize(51, 41));
|
||||
b = wxBitmapBundle::FromBitmap(nonSquare);
|
||||
|
||||
const wxSize scaledSize(52, 41);
|
||||
CHECK( b.GetBitmap(scaledSize).GetSize() == scaledSize );
|
||||
|
||||
// Test upscaling too.
|
||||
b = wxBitmapBundle::FromBitmap(wxBitmap(32, 32));
|
||||
CHECK( b.GetBitmap(wxSize(24, 24)).GetSize() == wxSize(24, 24) );
|
||||
CHECK( b.GetBitmap(wxSize(48, 48)).GetSize() == wxSize(48, 48) );
|
||||
}
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
std::string wxGUIObjectUsageAsString(const wxGUIObjectUsage& useCount)
|
||||
{
|
||||
return wxString::Format("%lu GDI, %lu USER",
|
||||
useCount.numGDI, useCount.numUSER)
|
||||
.utf8_string();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
template <>
|
||||
struct StringMaker<wxGUIObjectUsage>
|
||||
{
|
||||
static std::string convert(const wxGUIObjectUsage& useCount)
|
||||
{
|
||||
return wxGUIObjectUsageAsString(useCount);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::ResourceLeak", "[bmpbundle]")
|
||||
{
|
||||
wxBitmapBundle bb = wxBitmapBundle::FromBitmap(wxBitmap(32, 32));
|
||||
|
||||
const auto usageBefore = wxGetCurrentlyUsedResources();
|
||||
INFO("Usage before: " << wxGUIObjectUsageAsString(usageBefore));
|
||||
|
||||
for ( int n = 0; n < 10000; ++n )
|
||||
{
|
||||
wxBitmap bmp = bb.GetBitmap(wxSize(24, 24));
|
||||
if ( !bmp.GetHandle() )
|
||||
{
|
||||
FAIL("Failed to create bitmap");
|
||||
}
|
||||
}
|
||||
|
||||
const auto usageAfter = wxGetCurrentlyUsedResources();
|
||||
INFO("Usage after: " << wxGUIObjectUsageAsString(usageAfter));
|
||||
|
||||
INFO("Usage peak: " << wxGUIObjectUsageAsString(wxGetMaxUsedResources()));
|
||||
|
||||
// We shouldn't have used any USER resources.
|
||||
CHECK( usageAfter.numUSER == usageBefore.numUSER );
|
||||
|
||||
// Ideally we'd want the GDI usage to be exactly the same as before too,
|
||||
// but at least one extra resource gets allocated somewhere, so allow for
|
||||
// it.
|
||||
REQUIRE( usageAfter.numGDI >= usageBefore.numGDI );
|
||||
CHECK( usageAfter.numGDI - usageBefore.numGDI < 10 );
|
||||
}
|
||||
|
||||
#endif // __WINDOWS__
|
||||
|
||||
// Helper functions for the test below.
|
||||
namespace
|
||||
{
|
||||
|
||||
// Default size here doesn't really matter.
|
||||
const wxSize BITMAP_SIZE(16, 16);
|
||||
|
||||
// The choice of colours here is arbitrary too, but they need to be all
|
||||
// different to allow identifying which bitmap got scaled.
|
||||
struct ColourAtScale
|
||||
{
|
||||
double scale;
|
||||
wxUint32 rgb;
|
||||
};
|
||||
|
||||
const ColourAtScale colours[] =
|
||||
{
|
||||
{ 1.0, 0x000000ff },
|
||||
{ 1.5, 0x0000ff00 },
|
||||
{ 2.0, 0x00ff0000 },
|
||||
};
|
||||
|
||||
// Return the colour used for the (original) bitmap at the given scale.
|
||||
wxColour GetColourForScale(double scale)
|
||||
{
|
||||
wxColour col;
|
||||
for ( size_t n = 0; n < WXSIZEOF(colours); ++n )
|
||||
{
|
||||
if ( colours[n].scale == scale )
|
||||
{
|
||||
col.SetRGB(colours[n].rgb);
|
||||
return col;
|
||||
}
|
||||
}
|
||||
|
||||
wxFAIL_MSG("no colour for this scale");
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
double GetScaleFromColour(const wxColour& col)
|
||||
{
|
||||
const wxUint32 rgb = col.GetRGB();
|
||||
for ( size_t n = 0; n < WXSIZEOF(colours); ++n )
|
||||
{
|
||||
if ( colours[n].rgb == rgb )
|
||||
return colours[n].scale;
|
||||
}
|
||||
|
||||
wxFAIL_MSG(wxString::Format("no scale for colour %s", col.GetAsString()));
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double SizeToScale(const wxSize& size)
|
||||
{
|
||||
return static_cast<double>(size.y) / BITMAP_SIZE.y;
|
||||
}
|
||||
|
||||
wxBitmap MakeSolidBitmap(double scale)
|
||||
{
|
||||
wxBitmap bmp(BITMAP_SIZE*scale);
|
||||
|
||||
wxMemoryDC dc(bmp);
|
||||
dc.SetBackground(GetColourForScale(scale));
|
||||
dc.Clear();
|
||||
|
||||
return bmp;
|
||||
}
|
||||
|
||||
wxColour GetBitmapColour(const wxBitmap& bmp)
|
||||
{
|
||||
const wxImage img = bmp.ConvertToImage();
|
||||
|
||||
// We just assume the bitmap is solid colour, we could check it, but it
|
||||
// doesn't seem really useful to do it.
|
||||
return wxColour(img.GetRed(0, 0), img.GetGreen(0, 0), img.GetBlue(0, 0));
|
||||
}
|
||||
|
||||
// This struct exists just to allow using it conveniently in CHECK_THAT().
|
||||
struct BitmapAtScale
|
||||
{
|
||||
BitmapAtScale(const wxBitmapBundle& b, double scale)
|
||||
: size(b.GetPreferredBitmapSizeAtScale(scale)),
|
||||
bitmap(b.GetBitmap(size))
|
||||
{
|
||||
}
|
||||
|
||||
const wxSize size;
|
||||
const wxBitmap bitmap;
|
||||
};
|
||||
|
||||
class BitmapAtScaleMatcher : public Catch::MatcherBase<BitmapAtScale>
|
||||
{
|
||||
public:
|
||||
explicit BitmapAtScaleMatcher(double scale, double scaleOrig)
|
||||
: m_scale(scale),
|
||||
m_scaleOrig(scaleOrig)
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const BitmapAtScale& bitmapAtScale) const override
|
||||
{
|
||||
const wxBitmap& bmp = bitmapAtScale.bitmap;
|
||||
|
||||
if ( SizeToScale(bitmapAtScale.size) != m_scale ||
|
||||
SizeToScale(bmp.GetSize()) != m_scale )
|
||||
{
|
||||
m_diffDesc.Printf("should have scale %.1f", m_scale);
|
||||
}
|
||||
|
||||
if ( GetBitmapColour(bmp) != GetColourForScale(m_scaleOrig) )
|
||||
{
|
||||
if ( m_diffDesc.empty() )
|
||||
m_diffDesc = "should be ";
|
||||
else
|
||||
m_diffDesc += " and be ";
|
||||
|
||||
m_diffDesc += wxString::Format("created from x%.1f", m_scaleOrig);
|
||||
}
|
||||
|
||||
return m_diffDesc.empty();
|
||||
}
|
||||
|
||||
std::string describe() const override
|
||||
{
|
||||
return m_diffDesc.utf8_string();
|
||||
}
|
||||
|
||||
private:
|
||||
const double m_scale;
|
||||
const double m_scaleOrig;
|
||||
mutable wxString m_diffDesc;
|
||||
};
|
||||
|
||||
// The first parameter here determines the size of the expected bitmap and the
|
||||
// second one, which defaults to the first one if it's not specified, the size
|
||||
// of the bitmap which must have been scaled to create the bitmap of the right
|
||||
// size.
|
||||
BitmapAtScaleMatcher SameAs(double scale, double scaleOrig = 0.0)
|
||||
{
|
||||
if ( scaleOrig == 0.0 )
|
||||
scaleOrig = scale;
|
||||
|
||||
return BitmapAtScaleMatcher(scale, scaleOrig);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace Catch
|
||||
{
|
||||
template <>
|
||||
struct StringMaker<BitmapAtScale>
|
||||
{
|
||||
static std::string convert(const BitmapAtScale& bitmapAtScale)
|
||||
{
|
||||
const wxBitmap& bmp = bitmapAtScale.bitmap;
|
||||
|
||||
wxString scaleError;
|
||||
if ( bmp.GetSize() != bitmapAtScale.size )
|
||||
{
|
||||
scaleError.Printf(" (DIFFERENT from expected %.1f)",
|
||||
SizeToScale(bitmapAtScale.size));
|
||||
}
|
||||
|
||||
return wxString::Format
|
||||
(
|
||||
"x%.1f bitmap%s created from x%.1f",
|
||||
SizeToScale(bmp.GetSize()),
|
||||
scaleError,
|
||||
GetScaleFromColour(GetBitmapColour(bmp))
|
||||
).utf8_string();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::GetPreferredSize", "[bmpbundle]")
|
||||
{
|
||||
// Check that empty bundle doesn't have any preferred size.
|
||||
wxBitmapBundle b;
|
||||
CHECK( b.GetPreferredBitmapSizeAtScale(1) == wxDefaultSize );
|
||||
|
||||
const wxBitmap normal = MakeSolidBitmap(1.0);
|
||||
const wxBitmap middle = MakeSolidBitmap(1.5);
|
||||
const wxBitmap bigger = MakeSolidBitmap(2.0);
|
||||
|
||||
|
||||
// Then check what happens if there is only a single bitmap.
|
||||
b = wxBitmapBundle::FromBitmap(normal);
|
||||
|
||||
// We should avoid scaling as long as the size is close enough to the
|
||||
// actual bitmap size.
|
||||
CHECK_THAT( BitmapAtScale(b, 0 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.25), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.4 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.5 ), SameAs(1) );
|
||||
|
||||
// Once it becomes too big, we're going to need to scale, but we should be
|
||||
// scaling by an integer factor.
|
||||
CHECK_THAT( BitmapAtScale(b, 1.75), SameAs(2, 1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2 ), SameAs(2, 1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2.25), SameAs(2, 1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2.5 ), SameAs(3, 1) );
|
||||
|
||||
|
||||
// Now check what happens when there is also a double size bitmap.
|
||||
b = wxBitmapBundle::FromBitmaps(normal, bigger);
|
||||
|
||||
// Check that the existing bitmaps are used without scaling for most of the
|
||||
// typical scaling values.
|
||||
CHECK_THAT( BitmapAtScale(b, 0 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.25), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.4 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.5 ), SameAs(1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.75), SameAs(2) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2 ), SameAs(2) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2.5 ), SameAs(2) );
|
||||
CHECK_THAT( BitmapAtScale(b, 3 ), SameAs(2) );
|
||||
|
||||
// This scale is too big to use any of the existing bitmaps, so they will
|
||||
// be scaled, but use integer factors and, importantly, scale the correct
|
||||
// bitmap using them: we need to scale the small bitmap by a factor of 3,
|
||||
// rather than scaling the larger bitmap by a factor of 1.5 here, but we
|
||||
// must also scale the larger one by a factor of 2 rather than scaling the
|
||||
// small one by a factor of 4.
|
||||
CHECK_THAT( BitmapAtScale(b, 3.33), SameAs(3, 1) );
|
||||
CHECK_THAT( BitmapAtScale(b, 4 ), SameAs(4, 2) );
|
||||
CHECK_THAT( BitmapAtScale(b, 5 ), SameAs(5, 1) );
|
||||
|
||||
|
||||
// Finally check that things work as expected when we have 3 versions.
|
||||
wxVector<wxBitmap> bitmaps;
|
||||
bitmaps.push_back(normal);
|
||||
bitmaps.push_back(middle);
|
||||
bitmaps.push_back(bigger);
|
||||
b = wxBitmapBundle::FromBitmaps(bitmaps);
|
||||
|
||||
CHECK_THAT( BitmapAtScale(b, 0 ), SameAs(1.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1 ), SameAs(1.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.25), SameAs(1.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.4 ), SameAs(1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.5 ), SameAs(1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 1.75), SameAs(1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2 ), SameAs(2.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 2.5 ), SameAs(2.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 3 ), SameAs(2.0) );
|
||||
|
||||
CHECK_THAT( BitmapAtScale(b, 3.33), SameAs(3.0, 1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 4.25), SameAs(4.0, 2.0) );
|
||||
CHECK_THAT( BitmapAtScale(b, 4.50), SameAs(4.5, 1.5) );
|
||||
CHECK_THAT( BitmapAtScale(b, 5 ), SameAs(5.0, 1.0) );
|
||||
|
||||
|
||||
// Another check to detect that the scale is computed correctly even when
|
||||
// rounding is involved.
|
||||
wxBitmap nonSquare(wxSize(51, 41));
|
||||
nonSquare.SetScaleFactor(1.5);
|
||||
b = wxBitmapBundle::FromBitmap(nonSquare);
|
||||
CHECK( b.GetPreferredBitmapSizeAtScale(1.5) == nonSquare.GetSize() );
|
||||
}
|
||||
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
|
||||
TEST_CASE("BitmapBundle::Scaled", "[bmpbundle]")
|
||||
{
|
||||
// Adding a bitmap with scale factor > 1 should create the bundle using the
|
||||
// scaled size as default size.
|
||||
wxBitmap scaled2x(64, 64);
|
||||
scaled2x.SetScaleFactor(2);
|
||||
CHECK( scaled2x.GetLogicalSize() == wxSize(32, 32) );
|
||||
|
||||
wxBitmapBundle b(scaled2x);
|
||||
CHECK( b.GetDefaultSize() == wxSize(32, 32) );
|
||||
|
||||
// Retrieving this bitmap back from the bundle should preserve its scale.
|
||||
scaled2x = b.GetBitmap(wxSize(64, 64));
|
||||
CHECK( scaled2x.GetSize() == wxSize(64, 64) );
|
||||
CHECK( scaled2x.GetScaleFactor() == 2 );
|
||||
|
||||
// And retrieving the bitmap from the bundle should set scale factor for it
|
||||
// even if it hadn't originally been added with it.
|
||||
b = wxBitmapBundle::FromBitmaps(wxBitmap(32, 32), wxBitmap(64, 64));
|
||||
scaled2x = b.GetBitmap(wxSize(64, 64));
|
||||
CHECK( scaled2x.GetSize() == wxSize(64, 64) );
|
||||
CHECK( scaled2x.GetScaleFactor() == 2 );
|
||||
|
||||
// Using scaled bitmaps when there is more than one of them is a bad idea
|
||||
// in general, as only physical size matters, but the default size should
|
||||
// still be the scaled size of the smallest one.
|
||||
b = wxBitmapBundle::FromBitmaps(scaled2x, wxBitmap(64, 64));
|
||||
CHECK( b.GetDefaultSize() == wxSize(32, 32) );
|
||||
}
|
||||
|
||||
#endif // wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
|
||||
#ifdef wxHAS_SVG
|
||||
|
||||
TEST_CASE("BitmapBundle::FromSVG", "[bmpbundle][svg]")
|
||||
{
|
||||
static const char svg_data[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
|
||||
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
|
||||
"<svg width=\"200\" height=\"200\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns=\"http://www.w3.org/2000/svg\">"
|
||||
"<g>"
|
||||
"<circle cx=\"100\" cy=\"100\" r=\"50\" fill=\"blue\"/>"
|
||||
"</g>"
|
||||
"</svg>"
|
||||
;
|
||||
|
||||
wxBitmapBundle b = wxBitmapBundle::FromSVG(svg_data, wxSize(20, 20));
|
||||
REQUIRE( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == wxSize(20, 20) );
|
||||
|
||||
CHECK( b.GetBitmap(wxSize(32, 32)).GetSize() == wxSize(32, 32) );
|
||||
|
||||
// Check that not using XML header works too.
|
||||
const char* svg_tag_start = strstr(svg_data, "<svg");
|
||||
REQUIRE( svg_tag_start );
|
||||
|
||||
b = wxBitmapBundle::FromSVG(svg_data, wxSize(20, 20));
|
||||
REQUIRE( b.IsOk() );
|
||||
CHECK( b.GetBitmap(wxSize(16, 16)).GetSize() == wxSize(16, 16) );
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::FromSVG-alpha", "[bmpbundle][svg][alpha]")
|
||||
{
|
||||
static const char svg_data[] =
|
||||
"<svg viewBox=\"0 0 100 100\">"
|
||||
"<line x1=\"0\" y1=\"0\" x2=\"100%\" y2=\"100%\" stroke=\"#3f7fff\" stroke-width=\"71%\"/>"
|
||||
"</svg>"
|
||||
;
|
||||
|
||||
wxBitmapBundle b = wxBitmapBundle::FromSVG(svg_data, wxSize(2, 2));
|
||||
REQUIRE( b.IsOk() );
|
||||
|
||||
wxImage img = b.GetBitmap(wxDefaultSize).ConvertToImage();
|
||||
REQUIRE( img.HasAlpha() );
|
||||
// Check that anti-aliased edge at 50% alpha round-trips (after possibly
|
||||
// premultiplied storage in wxBitmap) to substantially original straight
|
||||
// alpha pixel values in wxImage, allowing for roundoff error.
|
||||
CHECK( (int)img.GetRed(0, 1) >= 0x3c );
|
||||
CHECK( (int)img.GetRed(0, 1) <= 0x3f );
|
||||
CHECK( (int)img.GetGreen(0, 1) >= 0x7b );
|
||||
CHECK( (int)img.GetGreen(0, 1) <= 0x7f);
|
||||
CHECK( (int)img.GetBlue(0, 1) == 0xff );
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::FromSVGFile", "[bmpbundle][svg][file]")
|
||||
{
|
||||
const wxSize size(20, 20); // completely arbitrary
|
||||
|
||||
CHECK( !wxBitmapBundle::FromSVGFile("horse.bmp", size).IsOk() );
|
||||
|
||||
wxBitmapBundle b = wxBitmapBundle::FromSVGFile("horse.svg", size);
|
||||
REQUIRE( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == size );
|
||||
}
|
||||
|
||||
// This can be used to test loading an arbitrary image file by setting the
|
||||
// environment variable WX_TEST_IMAGE_PATH to point to it.
|
||||
TEST_CASE("BitmapBundle::Load", "[.]")
|
||||
{
|
||||
wxString path;
|
||||
REQUIRE( wxGetEnv("WX_TEST_SVG", &path) );
|
||||
|
||||
wxBitmapBundle bb = wxBitmapBundle::FromSVGFile(path, wxSize(32, 32));
|
||||
REQUIRE( bb.IsOk() );
|
||||
}
|
||||
|
||||
#endif // wxHAS_SVG
|
||||
|
||||
TEST_CASE("BitmapBundle::ArtProvider", "[bmpbundle][art]")
|
||||
{
|
||||
// Check that creating a bogus bundle fails as expected.
|
||||
wxBitmapBundle b = wxArtProvider::GetBitmapBundle("bloordyblop");
|
||||
CHECK( !b.IsOk() );
|
||||
|
||||
// And that creating a bundle using a standard icon works.
|
||||
const wxSize size(16, 16);
|
||||
b = wxArtProvider::GetBitmapBundle(wxART_INFORMATION, wxART_MENU, size);
|
||||
CHECK( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == size );
|
||||
|
||||
#if wxUSE_ARTPROVIDER_TANGO
|
||||
// Tango art provider is supposed to use 16px for the default size of the
|
||||
// menu and button images and 24px for all the other ones, but we need to
|
||||
// choose the client kind for which the current platform doesn't define its
|
||||
// own default/fallback size to be able to test for it, i.e. this is the
|
||||
// client for which GetNativeSizeHint() of the native art provider returns
|
||||
// wxDefaultSize.
|
||||
const wxArtClient artClient =
|
||||
#ifdef __WXMSW__
|
||||
wxART_TOOLBAR
|
||||
#else
|
||||
wxART_LIST
|
||||
#endif
|
||||
;
|
||||
|
||||
// We also need to use an image provided by Tango but not by the native art
|
||||
// provider, but here we can at least avoid the platform checks by using an
|
||||
// image not provided by any native providers.
|
||||
b = wxArtProvider::GetBitmapBundle(wxART_REFRESH, artClient);
|
||||
|
||||
CHECK( b.IsOk() );
|
||||
CHECK( b.GetDefaultSize() == wxSize(24, 24) );
|
||||
#endif // wxUSE_ARTPROVIDER_TANGO
|
||||
}
|
||||
|
||||
// This test only makes sense for the ports that actually support scaled
|
||||
// bitmaps, which is the case for the ports using real logical pixels (they
|
||||
// have to support bitmap scale for things to work) and MSW, which doesn't, but
|
||||
// still implements support for at least storing and retrieving bitmap scale in
|
||||
// its wxBitmap.
|
||||
#if defined(wxHAS_DPI_INDEPENDENT_PIXELS) || defined(__WXMSW__)
|
||||
|
||||
TEST_CASE("BitmapBundle::Scale", "[bmpbundle][scale]")
|
||||
{
|
||||
// This is not a wxBitmapBundle test, strictly speaking, but check that
|
||||
// setting scale factor works correctly for bitmaps, as wxBitmapBundle does
|
||||
// this internally.
|
||||
wxBitmap bmp;
|
||||
bmp.CreateWithDIPSize(8, 8, 2);
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
CHECK( bmp.GetLogicalSize() == wxSize(8, 8) );
|
||||
#endif
|
||||
CHECK( bmp.GetDIPSize() == wxSize(8, 8) );
|
||||
CHECK( bmp.GetSize() == wxSize(16, 16) );
|
||||
CHECK( bmp.GetScaleFactor() == 2 );
|
||||
|
||||
wxBitmap bmp2(bmp);
|
||||
bmp.SetScaleFactor(3);
|
||||
CHECK( bmp2.GetScaleFactor() == 2 );
|
||||
CHECK( bmp.GetScaleFactor() == 3 );
|
||||
|
||||
// Check that creating bitmap bundle from a bitmap with a scale factor
|
||||
// works as expected.
|
||||
wxBitmapBundle b = bmp2;
|
||||
CHECK( b.GetDefaultSize() == wxSize(8, 8) );
|
||||
}
|
||||
|
||||
TEST_CASE("BitmapBundle::ImageList", "[bmpbundle][imagelist]")
|
||||
{
|
||||
wxVector<wxBitmapBundle> images;
|
||||
images.push_back(wxBitmapBundle::FromBitmaps(wxBitmap(16, 16), wxBitmap(32, 32)));
|
||||
images.push_back(wxBitmapBundle::FromBitmap(wxBitmap(24, 24)));
|
||||
images.push_back(wxBitmapBundle::FromBitmaps(wxBitmap(16, 16), wxBitmap(32, 32)));
|
||||
|
||||
// There are 2 bundles with preferred size of 32x32, so they should win.
|
||||
const wxSize size = wxBitmapBundle::GetConsensusSizeFor(2.0, images);
|
||||
CHECK( size == wxSize(32, 32) );
|
||||
|
||||
wxImageList iml(size.x, size.y);
|
||||
for ( const auto& bundle : images )
|
||||
{
|
||||
wxBitmap bmp = bundle.GetBitmap(size);
|
||||
REQUIRE( bmp.IsOk() );
|
||||
CHECK( bmp.GetSize() == size );
|
||||
REQUIRE( iml.Add(bmp) != -1 );
|
||||
}
|
||||
|
||||
CHECK( iml.GetBitmap(0).GetSize() == size );
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
CHECK( iml.GetBitmap(0).GetScaleFactor() == 2 );
|
||||
#endif
|
||||
|
||||
CHECK( iml.GetBitmap(1).GetSize() == size );
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
CHECK( iml.GetBitmap(1).GetScaleFactor() == Approx(1.3333333333) );
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // ports with scaled bitmaps support
|
||||
|
||||
TEST_CASE("BitmapBundle::GetConsensusSize", "[bmpbundle]")
|
||||
{
|
||||
// Just a trivial helper to make writing the tests below simpler.
|
||||
struct Bundles
|
||||
{
|
||||
wxVector<wxBitmapBundle> vec;
|
||||
|
||||
void Add(int size)
|
||||
{
|
||||
vec.push_back(wxBitmapBundle::FromBitmap(wxSize(size, size)));
|
||||
}
|
||||
|
||||
int GetConsensusSize(double scale) const
|
||||
{
|
||||
return wxBitmapBundle::GetConsensusSizeFor(scale, vec).y;
|
||||
}
|
||||
} bundles;
|
||||
|
||||
// When there is a tie, a larger size is chosen by default.
|
||||
bundles.Add(16);
|
||||
bundles.Add(24);
|
||||
CHECK( bundles.GetConsensusSize(2) == 48 );
|
||||
|
||||
// Breaking the tie results in the smaller size winning now.
|
||||
bundles.Add(16);
|
||||
CHECK( bundles.GetConsensusSize(2) == 32 );
|
||||
|
||||
// Integer scaling factors should be preferred.
|
||||
CHECK( bundles.GetConsensusSize(1.5) == 16 );
|
||||
}
|
||||
|
||||
// This test is not really related to wxBitmapBundle, but is just here because
|
||||
// this file already uses wxArtProvider and we don't have any tests for it
|
||||
// specifically right now.
|
||||
TEST_CASE("wxArtProvider::Delete", "[artprov]")
|
||||
{
|
||||
auto* artprov = new wxArtProvider{};
|
||||
wxArtProvider::Push(artprov);
|
||||
delete artprov;
|
||||
}
|
||||
364
libs/wxWidgets-3.3.1/tests/graphics/boundingbox.cpp
Normal file
364
libs/wxWidgets-3.3.1/tests/graphics/boundingbox.cpp
Normal file
@@ -0,0 +1,364 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/boundingbox.cpp
|
||||
// Purpose: wxGCDC bounding box unit tests
|
||||
// Author: Vadim Zeitlin / Maarten Spoek / Toni Ruža
|
||||
// Created: 2011-01-36
|
||||
// Copyright: (c) 2011 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// (c) 2014 Toni Ruža <toni.ruza@gmail.com>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/dcgraph.h"
|
||||
#include "wx/icon.h"
|
||||
#include "wx/colour.h"
|
||||
#include "wx/gdicmn.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class GCDCBoundingBoxTestCase : public CppUnit::TestCase
|
||||
{
|
||||
public:
|
||||
GCDCBoundingBoxTestCase()
|
||||
{
|
||||
m_bmp.Create(100, 100);
|
||||
m_dc.SelectObject(m_bmp);
|
||||
m_gcdc = new wxGCDC(m_dc);
|
||||
}
|
||||
|
||||
~GCDCBoundingBoxTestCase()
|
||||
{
|
||||
delete m_gcdc;
|
||||
m_dc.SelectObject(wxNullBitmap);
|
||||
m_bmp = wxNullBitmap;
|
||||
}
|
||||
|
||||
virtual void setUp() override
|
||||
{
|
||||
m_gcdc->ResetBoundingBox();
|
||||
}
|
||||
|
||||
private:
|
||||
wxBitmap m_bmp;
|
||||
wxMemoryDC m_dc;
|
||||
|
||||
wxGCDC *m_gcdc;
|
||||
|
||||
void AssertBox(int minX, int minY, int width, int height, int margin = 0)
|
||||
{
|
||||
int maxX = minX + width;
|
||||
int maxY = minY + height;
|
||||
|
||||
// Allow for a margin of error due to different implementation
|
||||
// specificities regarding drawing paths.
|
||||
if ( margin )
|
||||
{
|
||||
#define WX_ASSERT_CLOSE(expected, actual, delta) \
|
||||
WX_ASSERT_MESSAGE(("%d != %d", actual, expected), \
|
||||
abs(actual - expected) <= delta)
|
||||
|
||||
WX_ASSERT_CLOSE(minX, m_gcdc->MinX(), margin);
|
||||
WX_ASSERT_CLOSE(minY, m_gcdc->MinY(), margin);
|
||||
WX_ASSERT_CLOSE(maxX, m_gcdc->MaxX(), margin);
|
||||
WX_ASSERT_CLOSE(maxY, m_gcdc->MaxY(), margin);
|
||||
|
||||
#undef WX_ASSERT_CLOSE
|
||||
}
|
||||
else
|
||||
{
|
||||
CPPUNIT_ASSERT_EQUAL(minX, m_gcdc->MinX());
|
||||
CPPUNIT_ASSERT_EQUAL(minY, m_gcdc->MinY());
|
||||
CPPUNIT_ASSERT_EQUAL(maxX, m_gcdc->MaxX());
|
||||
CPPUNIT_ASSERT_EQUAL(maxY, m_gcdc->MaxY());
|
||||
}
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_SUITE( GCDCBoundingBoxTestCase );
|
||||
CPPUNIT_TEST( DrawBitmap );
|
||||
CPPUNIT_TEST( DrawIcon );
|
||||
CPPUNIT_TEST( DrawLine );
|
||||
CPPUNIT_TEST( CrossHair );
|
||||
CPPUNIT_TEST( DrawArc );
|
||||
CPPUNIT_TEST( DrawEllipticArc );
|
||||
CPPUNIT_TEST( DrawPoint );
|
||||
CPPUNIT_TEST( DrawLines );
|
||||
#if wxUSE_SPLINES
|
||||
CPPUNIT_TEST( DrawSpline );
|
||||
#endif
|
||||
CPPUNIT_TEST( DrawPolygon );
|
||||
CPPUNIT_TEST( DrawPolyPolygon );
|
||||
CPPUNIT_TEST( DrawRectangle );
|
||||
CPPUNIT_TEST( DrawTwoRectangles );
|
||||
CPPUNIT_TEST( DrawRectsOnTransformedDC );
|
||||
CPPUNIT_TEST( DrawRoundedRectangle );
|
||||
CPPUNIT_TEST( DrawRectangleAndReset );
|
||||
CPPUNIT_TEST( DrawEllipse );
|
||||
CPPUNIT_TEST( Blit );
|
||||
CPPUNIT_TEST( StretchBlit );
|
||||
CPPUNIT_TEST( DrawRotatedText );
|
||||
CPPUNIT_TEST( DrawText );
|
||||
CPPUNIT_TEST( GradientFillLinear );
|
||||
CPPUNIT_TEST( GradientFillConcentric );
|
||||
CPPUNIT_TEST( DrawCheckMark );
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
void DrawBitmap();
|
||||
void DrawIcon();
|
||||
void DrawLine();
|
||||
void CrossHair();
|
||||
void DrawArc();
|
||||
void DrawEllipticArc();
|
||||
void DrawPoint();
|
||||
void DrawLines();
|
||||
#if wxUSE_SPLINES
|
||||
void DrawSpline();
|
||||
#endif
|
||||
void DrawPolygon();
|
||||
void DrawPolyPolygon();
|
||||
void DrawRectangle();
|
||||
void DrawTwoRectangles();
|
||||
void DrawRectsOnTransformedDC();
|
||||
void DrawRoundedRectangle();
|
||||
void DrawRectangleAndReset();
|
||||
void DrawEllipse();
|
||||
void Blit();
|
||||
void StretchBlit();
|
||||
void DrawRotatedText();
|
||||
void DrawText();
|
||||
void GradientFillLinear();
|
||||
void GradientFillConcentric();
|
||||
void DrawCheckMark();
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(GCDCBoundingBoxTestCase);
|
||||
};
|
||||
|
||||
// register in the unnamed registry so that these tests are run by default
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION( GCDCBoundingBoxTestCase );
|
||||
|
||||
// also include in it's own registry so that these tests can be run alone
|
||||
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( GCDCBoundingBoxTestCase, "GCDCBoundingBoxTestCase" );
|
||||
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawBitmap()
|
||||
{
|
||||
wxBitmap bitmap;
|
||||
bitmap.Create(12, 12);
|
||||
|
||||
m_gcdc->DrawBitmap(bitmap, 5, 5);
|
||||
AssertBox(5, 5, 12, 12);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawIcon()
|
||||
{
|
||||
wxBitmap bitmap;
|
||||
bitmap.Create(16, 16);
|
||||
wxIcon icon;
|
||||
icon.CopyFromBitmap(bitmap);
|
||||
|
||||
m_gcdc->DrawIcon(icon, 42, 42);
|
||||
AssertBox(42, 42, 16, 16);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawLine()
|
||||
{
|
||||
m_gcdc->DrawLine(10, 10, 20, 15);
|
||||
AssertBox(10, 10, 10, 5);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::CrossHair()
|
||||
{
|
||||
int w, h;
|
||||
m_gcdc->GetSize(&w, &h);
|
||||
|
||||
m_gcdc->CrossHair(33, 33);
|
||||
AssertBox(0, 0, w, h);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawArc()
|
||||
{
|
||||
m_gcdc->DrawArc(25, 30, 15, 40, 25, 40); // quarter circle
|
||||
AssertBox(15, 30, 10, 10, 3);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawEllipticArc()
|
||||
{
|
||||
m_gcdc->DrawEllipticArc(40, 50, 30, 20, 0, 180); // half circle
|
||||
AssertBox(40, 50, 30, 10, 3);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawPoint()
|
||||
{
|
||||
m_gcdc->DrawPoint(20, 20);
|
||||
AssertBox(20, 20, 0, 0);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawLines()
|
||||
{
|
||||
wxPoint points[4];
|
||||
points[0] = wxPoint(10, 20);
|
||||
points[1] = wxPoint(20, 10);
|
||||
points[2] = wxPoint(30, 20);
|
||||
points[3] = wxPoint(20, 30);
|
||||
|
||||
m_gcdc->DrawLines(4, points, 7, 8);
|
||||
AssertBox(17, 18, 20, 20);
|
||||
}
|
||||
|
||||
#if wxUSE_SPLINES
|
||||
void GCDCBoundingBoxTestCase::DrawSpline()
|
||||
{
|
||||
wxPoint points[3];
|
||||
points[0] = wxPoint(10, 30);
|
||||
points[1] = wxPoint(20, 20);
|
||||
points[2] = wxPoint(40, 50);
|
||||
|
||||
m_gcdc->DrawSpline(3, points);
|
||||
AssertBox(10, 20, 30, 30, 5);
|
||||
}
|
||||
#endif // wxUSE_SPLINES
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawPolygon()
|
||||
{
|
||||
wxPoint points[3];
|
||||
points[0] = wxPoint(10, 30);
|
||||
points[1] = wxPoint(20, 10);
|
||||
points[2] = wxPoint(30, 30);
|
||||
|
||||
m_gcdc->DrawPolygon(3, points, -5, -7);
|
||||
AssertBox(5, 3, 20, 20);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawPolyPolygon()
|
||||
{
|
||||
int lenghts[2];
|
||||
lenghts[0] = 3;
|
||||
lenghts[1] = 3;
|
||||
wxPoint points[6];
|
||||
points[0] = wxPoint(10, 30);
|
||||
points[1] = wxPoint(20, 10);
|
||||
points[2] = wxPoint(30, 30);
|
||||
points[3] = wxPoint(20, 60);
|
||||
points[4] = wxPoint(30, 40);
|
||||
points[5] = wxPoint(40, 60);
|
||||
|
||||
m_gcdc->DrawPolyPolygon(2, lenghts, points, 12, 5);
|
||||
AssertBox(22, 15, 30, 50, 4);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawRectangle()
|
||||
{
|
||||
m_gcdc->DrawRectangle(2, 2, 12, 12);
|
||||
AssertBox(2, 2, 12, 12);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawRoundedRectangle()
|
||||
{
|
||||
m_gcdc->DrawRoundedRectangle(27, 27, 12, 12, 2);
|
||||
AssertBox(27, 27, 12, 12);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawEllipse()
|
||||
{
|
||||
m_gcdc->DrawEllipse(54, 45, 23, 12);
|
||||
AssertBox(54, 45, 23, 12);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::Blit()
|
||||
{
|
||||
wxBitmap bitmap;
|
||||
bitmap.Create(20, 20);
|
||||
wxMemoryDC dc(bitmap);
|
||||
|
||||
m_gcdc->Blit(20, 10, 12, 7, &dc, 0, 0);
|
||||
AssertBox(20, 10, 12, 7);
|
||||
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::StretchBlit()
|
||||
{
|
||||
wxBitmap bitmap;
|
||||
bitmap.Create(20, 20);
|
||||
wxMemoryDC dc(bitmap);
|
||||
|
||||
m_gcdc->StretchBlit(30, 50, 5, 5, &dc, 0, 0, 12, 4);
|
||||
AssertBox(30, 50, 5, 5);
|
||||
|
||||
dc.SelectObject(wxNullBitmap);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawRotatedText()
|
||||
{
|
||||
wxString text("vertical");
|
||||
wxCoord w, h;
|
||||
m_gcdc->GetTextExtent(text, &w, &h);
|
||||
|
||||
m_gcdc->DrawRotatedText(text, 43, 22, -90);
|
||||
AssertBox(43 - h, 22, h, w, 3);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawText()
|
||||
{
|
||||
wxString text("H");
|
||||
wxCoord w, h;
|
||||
m_gcdc->GetTextExtent(text, &w, &h);
|
||||
|
||||
m_gcdc->DrawText(text, 3, 3);
|
||||
AssertBox(3, 3, w, h, 3);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::GradientFillLinear()
|
||||
{
|
||||
wxRect rect(16, 16, 30, 40);
|
||||
m_gcdc->GradientFillLinear(rect, *wxWHITE, *wxBLACK, wxNORTH);
|
||||
AssertBox(16, 16, 30, 40);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::GradientFillConcentric()
|
||||
{
|
||||
wxRect rect(6, 6, 30, 40);
|
||||
m_gcdc->GradientFillConcentric(rect, *wxWHITE, *wxBLACK, wxPoint(10, 10));
|
||||
AssertBox(6, 6, 30, 40);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawCheckMark()
|
||||
{
|
||||
m_gcdc->DrawCheckMark(32, 24, 16, 16);
|
||||
AssertBox(32, 24, 16, 16);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawRectangleAndReset()
|
||||
{
|
||||
m_gcdc->DrawRectangle(2, 2, 12, 12);
|
||||
m_gcdc->ResetBoundingBox();
|
||||
AssertBox(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawTwoRectangles()
|
||||
{
|
||||
m_gcdc->DrawRectangle(10, 15, 50, 30);
|
||||
m_gcdc->DrawRectangle(15, 20, 55, 35);
|
||||
AssertBox(10, 15, 60, 40);
|
||||
}
|
||||
|
||||
void GCDCBoundingBoxTestCase::DrawRectsOnTransformedDC()
|
||||
{
|
||||
m_gcdc->DrawRectangle(10, 15, 50, 30);
|
||||
m_gcdc->SetDeviceOrigin(15, 20);
|
||||
m_gcdc->DrawRectangle(15, 20, 45, 35);
|
||||
m_gcdc->SetDeviceOrigin(5, 10);
|
||||
AssertBox(5, 5, 65, 60);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
757
libs/wxWidgets-3.3.1/tests/graphics/clipper.cpp
Normal file
757
libs/wxWidgets-3.3.1/tests/graphics/clipper.cpp
Normal file
@@ -0,0 +1,757 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/clipper.cpp
|
||||
// Purpose: wxDCClipper unit tests
|
||||
// Author: Artur Wieczorek
|
||||
// Created: 2022-12-27
|
||||
// Copyright: (c) 2022 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/dcclient.h"
|
||||
#include "wx/dcgraph.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/dcsvg.h"
|
||||
#include "wx/app.h"
|
||||
#include "wx/window.h"
|
||||
|
||||
#include "testfile.h"
|
||||
#include "waitfor.h"
|
||||
|
||||
static const wxSize s_dcSize(260, 300);
|
||||
|
||||
static inline wxRect DeviceToLogical(wxDC& dc, const wxRect& r)
|
||||
{
|
||||
return wxRect(dc.DeviceToLogical(r.GetPosition()), dc.DeviceToLogicalRel(r.GetSize()));
|
||||
}
|
||||
|
||||
static void NoTransform(wxDC& dc)
|
||||
{
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r(10, 20, 30, 40);
|
||||
wxDCClipper clipper(dc, r);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(r == clipBox);
|
||||
}
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipBox == clipBox);
|
||||
}
|
||||
|
||||
static void ExternalTransform(wxDC& dc, bool useTransformMatrix)
|
||||
{
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix && !dc.CanUseTransformMatrix() )
|
||||
return;
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix )
|
||||
{
|
||||
wxAffineMatrix2D m;
|
||||
m.Translate(40, 75);
|
||||
m.Scale(2.0, 3.0);
|
||||
dc.SetTransformMatrix(m);
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
{
|
||||
dc.SetDeviceOrigin(10, 15);
|
||||
dc.SetUserScale(0.5, 1.5);
|
||||
dc.SetLogicalScale(4.0, 2.0);
|
||||
dc.SetLogicalOrigin(-15, -20);
|
||||
}
|
||||
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r(10, 20, 30, 40);
|
||||
wxDCClipper clipper(dc, r);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(r == clipBox);
|
||||
}
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipBox == clipBox);
|
||||
}
|
||||
|
||||
static void InternalTransform(wxDC& dc, bool useTransformMatrix)
|
||||
{
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix && !dc.CanUseTransformMatrix() )
|
||||
return;
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r(10, 20, 30, 40);
|
||||
wxDCClipper clipper(dc, r);
|
||||
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix )
|
||||
{
|
||||
wxAffineMatrix2D m;
|
||||
m.Translate(40, 75);
|
||||
m.Scale(2.0, 3.0);
|
||||
dc.SetTransformMatrix(m);
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
{
|
||||
dc.SetDeviceOrigin(10, 15);
|
||||
dc.SetUserScale(0.5, 1.5);
|
||||
dc.SetLogicalScale(4.0, 2.0);
|
||||
dc.SetLogicalOrigin(-15, -20);
|
||||
}
|
||||
|
||||
wxRect clipExpected = DeviceToLogical(dc, r);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(clipExpected == clipBox);
|
||||
}
|
||||
wxRect initClipExpected = DeviceToLogical(dc, initClipBox);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipExpected == clipBox);
|
||||
}
|
||||
|
||||
static void SpecificClipping(wxDC& dc)
|
||||
{
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r(10, 20, 30, 40);
|
||||
wxDCClipper clipper(dc, r);
|
||||
|
||||
const wxRect r1(16, 25, 20, 30);
|
||||
dc.SetClippingRegion(r1);
|
||||
|
||||
wxRect clipExpected = DeviceToLogical(dc, r1);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(clipExpected == clipBox);
|
||||
}
|
||||
wxRect initClipExpected = DeviceToLogical(dc, initClipBox);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipExpected == clipBox);
|
||||
}
|
||||
|
||||
static void InternalTransformSpecificClipping(wxDC& dc, bool useTransformMatrix)
|
||||
{
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix && !dc.CanUseTransformMatrix() )
|
||||
return;
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r(10, 20, 30, 40);
|
||||
wxDCClipper clipper(dc, r);
|
||||
|
||||
const wxRect r1(16, 25, 20, 30);
|
||||
dc.SetClippingRegion(r1);
|
||||
|
||||
#if wxUSE_DC_TRANSFORM_MATRIX
|
||||
if ( useTransformMatrix )
|
||||
{
|
||||
wxAffineMatrix2D m;
|
||||
m.Translate(40, 75);
|
||||
m.Scale(2.0, 3.0);
|
||||
dc.SetTransformMatrix(m);
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_DC_TRANSFORM_MATRIX
|
||||
{
|
||||
dc.SetDeviceOrigin(10, 15);
|
||||
dc.SetUserScale(0.5, 1.5);
|
||||
dc.SetLogicalScale(4.0, 2.0);
|
||||
dc.SetLogicalOrigin(-15, -20);
|
||||
}
|
||||
|
||||
wxRect clipExpected = DeviceToLogical(dc, r1);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(clipExpected == clipBox);
|
||||
}
|
||||
wxRect initClipExpected = DeviceToLogical(dc, initClipBox);
|
||||
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipExpected == clipBox);
|
||||
}
|
||||
|
||||
static void NoTransformEmbeddedClip(wxDC& dc)
|
||||
{
|
||||
wxRect initClipBox;
|
||||
dc.GetClippingBox(initClipBox);
|
||||
{
|
||||
const wxRect r1(10, 20, 30, 40);
|
||||
wxDCClipper clipper1(dc, r1);
|
||||
{
|
||||
const wxRect r2(15, 25, 20, 30);
|
||||
wxDCClipper clipper2(dc, r2);
|
||||
|
||||
wxRect clipBox2;
|
||||
dc.GetClippingBox(clipBox2);
|
||||
CHECK(r2 == clipBox2);
|
||||
}
|
||||
|
||||
wxRect clipBox1;
|
||||
dc.GetClippingBox(clipBox1);
|
||||
CHECK(r1 == clipBox1);
|
||||
}
|
||||
wxRect clipBox;
|
||||
dc.GetClippingBox(clipBox);
|
||||
CHECK(initClipBox == clipBox);
|
||||
}
|
||||
|
||||
static void DCAttributes(wxDC& dc)
|
||||
{
|
||||
// Check if wxDC atrributes left unchanged
|
||||
wxFont font = dc.GetFont().Bold().Smaller();
|
||||
wxPen pen(*wxYELLOW, 2);
|
||||
wxBrush brush = *wxBLUE_BRUSH;
|
||||
|
||||
wxDCFontChanger fontChanger(dc, font);
|
||||
wxDCPenChanger penChanger(dc,pen);
|
||||
wxDCBrushChanger brushChanger(dc, brush);
|
||||
wxCoord chWidth = dc.GetCharWidth();
|
||||
wxCoord chHeight = dc.GetCharHeight();
|
||||
wxFontMetrics fm = dc.GetFontMetrics();
|
||||
{
|
||||
wxDCClipper clipper(dc, 10, 20, 30, 40);
|
||||
}
|
||||
CHECK(dc.GetFont() == font);
|
||||
CHECK(dc.GetPen() == pen);
|
||||
CHECK(dc.GetBrush() == brush);
|
||||
CHECK(dc.GetCharWidth() == chWidth);
|
||||
CHECK(dc.GetCharHeight() == chHeight);
|
||||
wxFontMetrics fm2 = dc.GetFontMetrics();
|
||||
CHECK(fm2.ascent == fm.ascent);
|
||||
CHECK(fm2.averageWidth == fm.averageWidth);
|
||||
CHECK(fm2.descent == fm.descent);
|
||||
CHECK(fm2.externalLeading == fm.externalLeading);
|
||||
CHECK(fm2.height == fm.height);
|
||||
CHECK(fm2.internalLeading == fm.internalLeading);
|
||||
}
|
||||
|
||||
TEST_CASE("ClipperTestCase::wxDC", "[clipper][dc]")
|
||||
{
|
||||
wxBitmap bmp(s_dcSize);
|
||||
wxMemoryDC dc(bmp);
|
||||
dc.SetBackground(*wxWHITE_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
TEST_CASE("ClipperTestCase::wxGCDC", "[clipper][dc][gcdc]")
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
int depth = GENERATE(24, 32);
|
||||
|
||||
wxBitmap bmp(s_dcSize, depth);
|
||||
#else
|
||||
wxBitmap bmp(s_dcSize);
|
||||
#endif
|
||||
wxMemoryDC mdc(bmp);
|
||||
mdc.SetBackground(*wxWHITE_BRUSH);
|
||||
mdc.Clear();
|
||||
wxGCDC dc(mdc);
|
||||
dc.GetGraphicsContext()->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
dc.GetGraphicsContext()->DisableOffset();
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#if wxUSE_GRAPHICS_GDIPLUS
|
||||
TEST_CASE("ClipperTestCase::wxGCDC(GDI+)", "[clipper][dc][gcdc][gdiplus]")
|
||||
{
|
||||
int depth = GENERATE(24, 32);
|
||||
|
||||
wxBitmap bmp(s_dcSize, depth);
|
||||
wxMemoryDC mdc(bmp);
|
||||
mdc.SetBackground(*wxWHITE_BRUSH);
|
||||
mdc.Clear();
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetGDIPlusRenderer();
|
||||
REQUIRE(rend);
|
||||
wxGraphicsContext* gc = rend->CreateContext(mdc);
|
||||
gc->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
gc->DisableOffset();
|
||||
wxGCDC dc(gc);
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_GDIPLUS
|
||||
|
||||
#if wxUSE_GRAPHICS_DIRECT2D
|
||||
TEST_CASE("ClipperTestCase::wxGCDC(Direct2D)", "[clipper][dc][gcdc][direct2d]")
|
||||
{
|
||||
if ( wxIsRunningUnderWine() )
|
||||
{
|
||||
WARN("Skipping tests known to fail in Wine");
|
||||
}
|
||||
else
|
||||
{
|
||||
int depth = GENERATE(24, 32);
|
||||
|
||||
wxBitmap bmp(s_dcSize, depth);
|
||||
wxMemoryDC mdc(bmp);
|
||||
mdc.SetBackground(*wxWHITE_BRUSH);
|
||||
mdc.Clear();
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetDirect2DRenderer();
|
||||
REQUIRE(rend);
|
||||
wxGraphicsContext* gc = rend->CreateContext(mdc);
|
||||
gc->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
gc->DisableOffset();
|
||||
wxGCDC dc(gc);
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_DIRECT2D
|
||||
#endif // __WXMSW__
|
||||
|
||||
#if wxUSE_CAIRO
|
||||
TEST_CASE("ClipperTestCase::wxGCDC(Cairo)", "[clipper][dc][gcdc][cairo]")
|
||||
{
|
||||
#ifdef __WXMSW__
|
||||
int depth = GENERATE(24, 32);
|
||||
|
||||
wxBitmap bmp(s_dcSize, depth);
|
||||
#else
|
||||
wxBitmap bmp(s_dcSize);
|
||||
#endif
|
||||
wxMemoryDC mdc(bmp);
|
||||
mdc.SetBackground(*wxWHITE_BRUSH);
|
||||
mdc.Clear();
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetCairoRenderer();
|
||||
REQUIRE(rend);
|
||||
wxGraphicsContext* gc = rend->CreateContext(mdc);
|
||||
gc->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
gc->DisableOffset();
|
||||
wxGCDC dc(gc);
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_CAIRO
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#if wxUSE_SVG
|
||||
TEST_CASE("ClipperTestCase::wxSVGFileDC", "[clipper][dc][svgdc]")
|
||||
{
|
||||
TestFile tf;
|
||||
wxSVGFileDC dc(tf.GetName(), s_dcSize.x, s_dcSize.y);
|
||||
dc.SetBackground(*wxWHITE_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_SVG
|
||||
|
||||
TEST_CASE("ClipperTestCase::wxPaintDC", "[clipper][dc][paintdc]")
|
||||
{
|
||||
// Ensure window is shown and large enough for testing
|
||||
wxTheApp->GetTopWindow()->Raise();
|
||||
REQUIRE(wxTheApp->GetTopWindow()->IsShown());
|
||||
wxSize winSize = wxTheApp->GetTopWindow()->GetSize();
|
||||
winSize.x = wxMax(winSize.x, s_dcSize.x + 50);
|
||||
winSize.y = wxMax(winSize.y, s_dcSize.y + 50);
|
||||
wxTheApp->GetTopWindow()->SetSize(winSize);
|
||||
#if defined(__WXGTK__)
|
||||
// Under wxGTK we need to have two children (at least) because if there
|
||||
// is one child its paint area is set to fill the whole parent frame.
|
||||
std::unique_ptr<wxWindow> w0(new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY));
|
||||
#endif // wxGTK
|
||||
std::unique_ptr<wxWindow> win(new wxWindow(wxTheApp->GetTopWindow(), wxID_ANY, wxPoint(0, 0)));
|
||||
win->SetClientSize(s_dcSize);
|
||||
|
||||
// Wait for the first paint event to be sure
|
||||
// that window really has its final size.
|
||||
wxWindow* testWin = win.get();
|
||||
{
|
||||
WaitForPaint waitForPaint(testWin);
|
||||
testWin->Show();
|
||||
waitForPaint.YieldUntilPainted();
|
||||
}
|
||||
|
||||
bool paintExecuted = false;
|
||||
testWin->Bind(wxEVT_PAINT, [=, &paintExecuted](wxPaintEvent&)
|
||||
{
|
||||
wxPaintDC dc(testWin);
|
||||
REQUIRE(dc.GetSize() == s_dcSize);
|
||||
dc.SetBackground(*wxWHITE_BRUSH);
|
||||
dc.Clear();
|
||||
|
||||
SECTION("NoTransform")
|
||||
{
|
||||
NoTransform(dc);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 1")
|
||||
{
|
||||
ExternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("ExternalTransform 2")
|
||||
{
|
||||
ExternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 1")
|
||||
{
|
||||
InternalTransform(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransform 2")
|
||||
{
|
||||
InternalTransform(dc, true);
|
||||
}
|
||||
|
||||
SECTION("SpecificClipping")
|
||||
{
|
||||
SpecificClipping(dc);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 1")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, false);
|
||||
}
|
||||
|
||||
SECTION("InternalTransformSpecificClipping 2")
|
||||
{
|
||||
InternalTransformSpecificClipping(dc, true);
|
||||
}
|
||||
|
||||
SECTION("NoTransformEmbeddedClip")
|
||||
{
|
||||
NoTransformEmbeddedClip(dc);
|
||||
}
|
||||
|
||||
SECTION("DCAttributes")
|
||||
{
|
||||
DCAttributes(dc);
|
||||
}
|
||||
|
||||
paintExecuted = true;
|
||||
});
|
||||
|
||||
testWin->Refresh();
|
||||
testWin->Update();
|
||||
// Wait for update to be done
|
||||
YieldForAWhile();
|
||||
|
||||
CHECK(paintExecuted == true);
|
||||
}
|
||||
5205
libs/wxWidgets-3.3.1/tests/graphics/clippingbox.cpp
Normal file
5205
libs/wxWidgets-3.3.1/tests/graphics/clippingbox.cpp
Normal file
File diff suppressed because it is too large
Load Diff
202
libs/wxWidgets-3.3.1/tests/graphics/colour.cpp
Normal file
202
libs/wxWidgets-3.3.1/tests/graphics/colour.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/colour.cpp
|
||||
// Purpose: wxColour unit test
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2009-09-19
|
||||
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/colour.h"
|
||||
#include "asserthelper.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helpers for checking wxColour RGB[A] values
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
typedef wxColour::ChannelType ChannelType;
|
||||
|
||||
class ColourRGBMatcher : public Catch::MatcherBase<wxColour>
|
||||
{
|
||||
public:
|
||||
ColourRGBMatcher(ChannelType red, ChannelType green, ChannelType blue)
|
||||
: m_red(red),
|
||||
m_green(green),
|
||||
m_blue(blue)
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const wxColour& c) const override
|
||||
{
|
||||
return c.Red() == m_red && c.Green() == m_green && c.Blue() == m_blue;
|
||||
}
|
||||
|
||||
std::string describe() const override
|
||||
{
|
||||
return wxString::Format("!= RGB(%#02x, %#02x, %#02x)",
|
||||
m_red, m_green, m_blue).ToStdString();
|
||||
}
|
||||
|
||||
protected:
|
||||
const ChannelType m_red, m_green, m_blue;
|
||||
};
|
||||
|
||||
class ColourRGBAMatcher : public ColourRGBMatcher
|
||||
{
|
||||
public:
|
||||
ColourRGBAMatcher(ChannelType red, ChannelType green, ChannelType blue,
|
||||
ChannelType alpha)
|
||||
: ColourRGBMatcher(red, green, blue),
|
||||
m_alpha(alpha)
|
||||
{
|
||||
}
|
||||
|
||||
bool match(const wxColour& c) const override
|
||||
{
|
||||
return ColourRGBMatcher::match(c) && c.Alpha() == m_alpha;
|
||||
}
|
||||
|
||||
std::string describe() const override
|
||||
{
|
||||
return wxString::Format("!= RGBA(%#02x, %#02x, %#02x, %#02x)",
|
||||
m_red, m_green, m_blue, m_alpha).ToStdString();
|
||||
}
|
||||
|
||||
private:
|
||||
const ChannelType m_alpha;
|
||||
};
|
||||
|
||||
inline
|
||||
ColourRGBMatcher
|
||||
RGBSameAs(ChannelType red, ChannelType green, ChannelType blue)
|
||||
{
|
||||
return ColourRGBMatcher(red, green, blue);
|
||||
}
|
||||
|
||||
inline
|
||||
ColourRGBAMatcher
|
||||
RGBASameAs(ChannelType red, ChannelType green, ChannelType blue, ChannelType alpha)
|
||||
{
|
||||
return ColourRGBAMatcher(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("wxColour::GetSetRGB", "[colour][rgb]")
|
||||
{
|
||||
wxColour c;
|
||||
c.SetRGB(0x123456);
|
||||
|
||||
CHECK( c.Red() == 0x56 );
|
||||
CHECK( c.Green() == 0x34 );
|
||||
CHECK( c.Blue() == 0x12 );
|
||||
CHECK( c.Alpha() == wxALPHA_OPAQUE );
|
||||
|
||||
CHECK( c == wxColour(0x123456) );
|
||||
CHECK( c.GetRGB() == 0x123456 );
|
||||
|
||||
c.SetRGBA(0xaabbccdd);
|
||||
|
||||
CHECK( c.Red() == 0xdd);
|
||||
CHECK( c.Green() == 0xcc);
|
||||
CHECK( c.Blue() == 0xbb);
|
||||
|
||||
// wxX11 doesn't support alpha at all currently.
|
||||
#ifndef __WXX11__
|
||||
CHECK( c.Alpha() == 0xaa );
|
||||
#endif // __WXX11__
|
||||
|
||||
// FIXME: at least under wxGTK wxColour ctor doesn't take alpha channel
|
||||
// into account: bug or feature?
|
||||
//CHECK( c == wxColour(0xaabbccdd) );
|
||||
CHECK( c.GetRGB() == 0xbbccdd );
|
||||
#ifndef __WXX11__
|
||||
CHECK( c.GetRGBA() == 0xaabbccdd );
|
||||
#endif // __WXX11__
|
||||
}
|
||||
|
||||
TEST_CASE("wxColour::FromString", "[colour][string]")
|
||||
{
|
||||
CHECK_THAT( wxColour("rgb(11, 22, 33)"), RGBSameAs(11, 22, 33) );
|
||||
// wxX11 doesn't support alpha at all currently.
|
||||
#ifndef __WXX11__
|
||||
CHECK_THAT( wxColour("rgba(11, 22, 33, 0.5)"), RGBASameAs(11, 22, 33, 128) );
|
||||
CHECK_THAT( wxColour("rgba( 11, 22, 33, 0.5 )"), RGBASameAs(11, 22, 33, 128) );
|
||||
#endif // __WXX11__
|
||||
|
||||
CHECK_THAT( wxColour("#aabbcc"), RGBSameAs(0xaa, 0xbb, 0xcc) );
|
||||
|
||||
CHECK_THAT( wxColour("red"), RGBSameAs(0xff, 0, 0) );
|
||||
|
||||
wxColour col;
|
||||
CHECK( !wxFromString("rgb(1, 2)", &col) );
|
||||
CHECK( !wxFromString("rgba(1, 2, 3.456)", &col) );
|
||||
CHECK( !wxFromString("rgba(1, 2, 3.456, foo)", &col) );
|
||||
}
|
||||
|
||||
TEST_CASE("wxColour::GetAsString", "[colour][string]")
|
||||
{
|
||||
CHECK( wxColour().GetAsString() == "" );
|
||||
|
||||
wxColour red("red");
|
||||
CHECK( red.GetAsString() == "red" );
|
||||
CHECK( red.GetAsString(wxC2S_CSS_SYNTAX) == "rgb(255, 0, 0)" );
|
||||
CHECK( red.GetAsString(wxC2S_HTML_SYNTAX) == "#FF0000" );
|
||||
}
|
||||
|
||||
TEST_CASE("wxColour::GetLuminance", "[colour][luminance]")
|
||||
{
|
||||
CHECK( wxBLACK->GetLuminance() == Approx(0.0) );
|
||||
CHECK( wxWHITE->GetLuminance() == Approx(1.0) );
|
||||
CHECK( wxRED->GetLuminance() > 0 );
|
||||
CHECK( wxRED->GetLuminance() < 1 );
|
||||
}
|
||||
|
||||
TEST_CASE("wxColour::IsXXX", "[colour][opacity]")
|
||||
{
|
||||
CHECK(wxColour{ 0, 0, 0, 0 }.IsTransparent());
|
||||
CHECK_FALSE(wxColour{ 0, 0, 0, 1 }.IsTransparent());
|
||||
|
||||
CHECK(wxColour{ 0, 0, 0, 255 }.IsOpaque());
|
||||
CHECK_FALSE(wxColour{ 0, 0, 0, 1 }.IsOpaque());
|
||||
|
||||
CHECK(wxColour{ 0, 0, 0, 254 }.IsTranslucent());
|
||||
CHECK(wxColour{ 0, 0, 0, 10 }.IsTranslucent());
|
||||
CHECK_FALSE(wxColour{ 0, 0, 0, 0 }.IsTranslucent());
|
||||
CHECK_FALSE(wxColour{ 0, 0, 0, 255 }.IsTranslucent());
|
||||
}
|
||||
|
||||
TEST_CASE("wxColour::Database", "[colour][database]")
|
||||
{
|
||||
wxColourDatabase db;
|
||||
|
||||
// Check that we can add custom colours.
|
||||
db.AddColour("NQB", wxColour(0x010203)); // Not quite black.
|
||||
CHECK_THAT( db.Find("nqb"), RGBSameAs(0x03, 0x02, 0x01) );
|
||||
|
||||
// Unfortunately we can't check that all colours round trip because this is
|
||||
// not the case for the colours present in the database under multiple
|
||||
// names, such as "GREY" and "GRAY" for example. But we can at least check
|
||||
// that the name found for all colours uses the same colour.
|
||||
for ( const auto& name : db.GetAllNames() )
|
||||
{
|
||||
const wxColour& colour = db.Find(name);
|
||||
const wxString& maybeOtherName = db.FindName(colour);
|
||||
CHECK( db.Find(maybeOtherName) == colour );
|
||||
}
|
||||
|
||||
// Check that green uses CSS value by default.
|
||||
CHECK_THAT( db.Find("green"), RGBSameAs(0, 0x80, 0) );
|
||||
|
||||
// But we can use the legacy value for it too.
|
||||
db.UseScheme(wxColourDatabase::Traditional);
|
||||
CHECK_THAT( db.Find("green"), RGBSameAs(0, 0xff, 0) );
|
||||
}
|
||||
1298
libs/wxWidgets-3.3.1/tests/graphics/coords.cpp
Normal file
1298
libs/wxWidgets-3.3.1/tests/graphics/coords.cpp
Normal file
File diff suppressed because it is too large
Load Diff
156
libs/wxWidgets-3.3.1/tests/graphics/ellipsization.cpp
Normal file
156
libs/wxWidgets-3.3.1/tests/graphics/ellipsization.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/ellipsization.cpp
|
||||
// Purpose: wxControlBase::*Ellipsize* unit test
|
||||
// Author: Francesco Montorsi
|
||||
// Created: 2010-03-10
|
||||
// Copyright: (c) 2010 Francesco Montorsi
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/control.h"
|
||||
#include "wx/dcmemory.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test class
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("Ellipsization::NormalCase", "[ellipsization]")
|
||||
{
|
||||
wxMemoryDC dc;
|
||||
|
||||
static const char *stringsToTest[] =
|
||||
{
|
||||
"N",
|
||||
".",
|
||||
"x",
|
||||
"foobar",
|
||||
"\xCE\xB1", // U03B1 (GREEK SMALL LETTER ALPHA)
|
||||
"Another test",
|
||||
"a very very very very very very very long string",
|
||||
// alpha+beta+gamma+delta+epsilon+zeta+eta+theta+iota
|
||||
"\xCE\xB1\xCE\xB2\xCE\xB3\xCE\xB4\xCE\xB5\xCE\xB6\xCE\xB7\xCE\xB8\xCE\xB9",
|
||||
"\t", "\t\t\t\t\t", "a\tstring\twith\ttabs",
|
||||
"\n", "\n\n\n\n\n", "a\nstring\nwith\nnewlines",
|
||||
"&", "&&&&&&&", "a&string&with&newlines",
|
||||
"\t\n&", "a\t\n&string\t\n&with\t\n&many\t\n&chars"
|
||||
};
|
||||
|
||||
static const int flagsToTest[] =
|
||||
{
|
||||
0,
|
||||
wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS,
|
||||
wxELLIPSIZE_FLAGS_EXPAND_TABS,
|
||||
wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS | wxELLIPSIZE_FLAGS_EXPAND_TABS
|
||||
};
|
||||
|
||||
static const wxEllipsizeMode modesToTest[] =
|
||||
{
|
||||
wxELLIPSIZE_START,
|
||||
wxELLIPSIZE_MIDDLE,
|
||||
wxELLIPSIZE_END
|
||||
};
|
||||
|
||||
const int charWidth = dc.GetCharWidth();
|
||||
int widthsToTest[] = { 6*charWidth, 10*charWidth, 15*charWidth };
|
||||
|
||||
for ( unsigned int s = 0; s < WXSIZEOF(stringsToTest); s++ )
|
||||
{
|
||||
const wxString str = wxString::FromUTF8(stringsToTest[s]);
|
||||
|
||||
for ( unsigned int f = 0; f < WXSIZEOF(flagsToTest); f++ )
|
||||
{
|
||||
for ( unsigned int m = 0; m < WXSIZEOF(modesToTest); m++ )
|
||||
{
|
||||
for ( unsigned int w = 0; w < WXSIZEOF(widthsToTest); w++ )
|
||||
{
|
||||
wxString ret = wxControl::Ellipsize
|
||||
(
|
||||
str,
|
||||
dc,
|
||||
modesToTest[m],
|
||||
widthsToTest[w],
|
||||
flagsToTest[f]
|
||||
);
|
||||
|
||||
// Note that we must measure the width of the text that
|
||||
// will be rendered, and when mnemonics are used, this
|
||||
// means we have to remove them first.
|
||||
const wxString
|
||||
displayed = flagsToTest[f] & wxELLIPSIZE_FLAGS_PROCESS_MNEMONICS
|
||||
? wxControl::RemoveMnemonics(ret)
|
||||
: ret;
|
||||
const int
|
||||
width = dc.GetMultiLineTextExtent(displayed).GetWidth();
|
||||
|
||||
WX_ASSERT_MESSAGE
|
||||
(
|
||||
(
|
||||
"Test #(%u,%u.%u): %s\n\"%s\" -> \"%s\"; width=%dpx > %dpx",
|
||||
s, f, m,
|
||||
dc.GetFont().GetNativeFontInfoUserDesc(),
|
||||
str,
|
||||
ret,
|
||||
width,
|
||||
widthsToTest[w]
|
||||
),
|
||||
width <= widthsToTest[w]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Ellipsization::EnoughSpace", "[ellipsization]")
|
||||
{
|
||||
// No ellipsization should occur if there's plenty of space.
|
||||
|
||||
wxMemoryDC dc;
|
||||
|
||||
wxString testString("some label");
|
||||
const int width = dc.GetTextExtent(testString).GetWidth() + 50;
|
||||
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_START, width) == testString );
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_MIDDLE, width) == testString );
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_END, width) == testString );
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Ellipsization::VeryLittleSpace", "[ellipsization]")
|
||||
{
|
||||
// If there's not enough space, the shortened label should still contain "..." and one character
|
||||
|
||||
wxMemoryDC dc;
|
||||
|
||||
const int width = dc.GetTextExtent("s...").GetWidth();
|
||||
|
||||
CHECK( wxControl::Ellipsize("some label", dc, wxELLIPSIZE_START, width) == "...l" );
|
||||
CHECK( wxControl::Ellipsize("some label", dc, wxELLIPSIZE_MIDDLE, width) == "s..." );
|
||||
CHECK( wxControl::Ellipsize("some label1", dc, wxELLIPSIZE_MIDDLE, width) == "s..." );
|
||||
CHECK( wxControl::Ellipsize("some label", dc, wxELLIPSIZE_END, width) == "s..." );
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Ellipsization::HasThreeDots", "[ellipsization]")
|
||||
{
|
||||
wxMemoryDC dc;
|
||||
|
||||
wxString testString("some longer text");
|
||||
const int width = dc.GetTextExtent(testString).GetWidth() - 5;
|
||||
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_START, width).StartsWith("...") );
|
||||
CHECK( !wxControl::Ellipsize(testString, dc, wxELLIPSIZE_START, width).EndsWith("...") );
|
||||
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_END, width).EndsWith("...") );
|
||||
|
||||
CHECK( wxControl::Ellipsize(testString, dc, wxELLIPSIZE_MIDDLE, width).Contains("...") );
|
||||
CHECK( !wxControl::Ellipsize(testString, dc, wxELLIPSIZE_MIDDLE, width).StartsWith("...") );
|
||||
CHECK( !wxControl::Ellipsize(testString, dc, wxELLIPSIZE_MIDDLE, width).EndsWith("...") );
|
||||
}
|
||||
1172
libs/wxWidgets-3.3.1/tests/graphics/graphbitmap.cpp
Normal file
1172
libs/wxWidgets-3.3.1/tests/graphics/graphbitmap.cpp
Normal file
File diff suppressed because it is too large
Load Diff
303
libs/wxWidgets-3.3.1/tests/graphics/graphmatrix.cpp
Normal file
303
libs/wxWidgets-3.3.1/tests/graphics/graphmatrix.cpp
Normal file
@@ -0,0 +1,303 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/graphmatrix.cpp
|
||||
// Purpose: Graphics matrix unit test
|
||||
// Author: Artur Wieczorek
|
||||
// Created: 2016-09-18
|
||||
// Copyright: (c) 2016 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/dcmemory.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
static void InitState(wxGraphicsContext* gc);
|
||||
static void InvertMatrix(wxGraphicsContext* gc);
|
||||
static void Concat1(wxGraphicsContext* gc);
|
||||
static void Concat2(wxGraphicsContext* gc);
|
||||
static void Concat3(wxGraphicsContext* gc);
|
||||
|
||||
TEST_CASE("GraphicsMatrixTestCase::DefaultRenderer", "[graphmatrix][default]")
|
||||
{
|
||||
wxBitmap bmp(100, 100);
|
||||
wxMemoryDC dc(bmp);
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetDefaultRenderer();
|
||||
REQUIRE(rend);
|
||||
std::unique_ptr<wxGraphicsContext> gc(rend->CreateContext(dc));
|
||||
REQUIRE(gc.get());
|
||||
|
||||
SECTION("InitState")
|
||||
{
|
||||
InitState(gc.get());
|
||||
}
|
||||
|
||||
SECTION("InvertMatrix")
|
||||
{
|
||||
InvertMatrix(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat1")
|
||||
{
|
||||
Concat1(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat2")
|
||||
{
|
||||
Concat2(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat3")
|
||||
{
|
||||
Concat3(gc.get());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __WXMSW__
|
||||
|
||||
#if wxUSE_GRAPHICS_GDIPLUS
|
||||
TEST_CASE("GraphicsMatrixTestCase::GDIPlusRenderer", "[graphmatrix][gdiplus]")
|
||||
{
|
||||
wxBitmap bmp(100, 100);
|
||||
wxMemoryDC dc(bmp);
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetGDIPlusRenderer();
|
||||
REQUIRE(rend);
|
||||
std::unique_ptr<wxGraphicsContext> gc(rend->CreateContext(dc));
|
||||
REQUIRE(gc.get());
|
||||
|
||||
SECTION("InitState")
|
||||
{
|
||||
InitState(gc.get());
|
||||
}
|
||||
|
||||
SECTION("InvertMatrix")
|
||||
{
|
||||
InvertMatrix(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat1")
|
||||
{
|
||||
Concat1(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat2")
|
||||
{
|
||||
Concat2(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat3")
|
||||
{
|
||||
Concat3(gc.get());
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_GDIPLUS
|
||||
|
||||
#if wxUSE_GRAPHICS_DIRECT2D
|
||||
TEST_CASE("GraphicsMatrixTestCase::Direct2DRenderer", "[graphmatrix][direct2d]")
|
||||
{
|
||||
wxBitmap bmp(100, 100);
|
||||
wxMemoryDC dc(bmp);
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetDirect2DRenderer();
|
||||
REQUIRE(rend);
|
||||
std::unique_ptr<wxGraphicsContext> gc(rend->CreateContext(dc));
|
||||
REQUIRE(gc.get());
|
||||
|
||||
SECTION("InitState")
|
||||
{
|
||||
InitState(gc.get());
|
||||
}
|
||||
|
||||
SECTION("InvertMatrix")
|
||||
{
|
||||
InvertMatrix(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat1")
|
||||
{
|
||||
Concat1(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat2")
|
||||
{
|
||||
Concat2(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat3")
|
||||
{
|
||||
Concat3(gc.get());
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_DIRECT2D
|
||||
|
||||
#endif // __WXMSW__
|
||||
|
||||
#if wxUSE_CAIRO
|
||||
TEST_CASE("GraphicsMatrixTestCase::CairoRenderer", "[graphmatrix][cairo]")
|
||||
{
|
||||
wxBitmap bmp(100, 100);
|
||||
wxMemoryDC dc(bmp);
|
||||
wxGraphicsRenderer* rend = wxGraphicsRenderer::GetCairoRenderer();
|
||||
REQUIRE(rend);
|
||||
std::unique_ptr<wxGraphicsContext> gc(rend->CreateContext(dc));
|
||||
REQUIRE(gc.get());
|
||||
|
||||
SECTION("InitState")
|
||||
{
|
||||
InitState(gc.get());
|
||||
}
|
||||
|
||||
SECTION("InvertMatrix")
|
||||
{
|
||||
InvertMatrix(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat1")
|
||||
{
|
||||
Concat1(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat2")
|
||||
{
|
||||
Concat2(gc.get());
|
||||
}
|
||||
|
||||
SECTION("Concat3")
|
||||
{
|
||||
Concat3(gc.get());
|
||||
}
|
||||
}
|
||||
#endif // wxUSE_CAIRO
|
||||
|
||||
// ===== Implementation =====
|
||||
|
||||
static inline double RoundVal(double v)
|
||||
{
|
||||
wxString s = wxString::Format("%g", v);
|
||||
s.ToDouble(&v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static void CheckMatrix(const wxGraphicsMatrix& m,
|
||||
double a, double b, double c, double d,
|
||||
double tx, double ty)
|
||||
{
|
||||
double cur_a, cur_b, cur_c, cur_d, cur_tx, cur_ty;
|
||||
m.Get(&cur_a, &cur_b, &cur_c, &cur_d, &cur_tx, &cur_ty);
|
||||
|
||||
wxString msg;
|
||||
|
||||
if ( RoundVal(a) != RoundVal(cur_a) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid m11 value: Actual: %g Expected: %g",
|
||||
cur_a, a );
|
||||
}
|
||||
|
||||
if ( RoundVal(b) != RoundVal(cur_b) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid m12 value: Actual: %g Expected: %g",
|
||||
cur_b, b );
|
||||
}
|
||||
|
||||
if ( RoundVal(c) != RoundVal(cur_c) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid m21 value: Actual: %g Expected: %g",
|
||||
cur_c, c );
|
||||
}
|
||||
|
||||
if ( RoundVal(d) != RoundVal(cur_d) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid m22 value: Actual: %g Expected: %g",
|
||||
cur_d, d );
|
||||
}
|
||||
|
||||
if ( RoundVal(tx) != RoundVal(cur_tx) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid tx value: Actual: %g Expected: %g",
|
||||
cur_tx, tx );
|
||||
}
|
||||
|
||||
if ( RoundVal(ty) != RoundVal(cur_ty) )
|
||||
{
|
||||
if ( !msg.empty() )
|
||||
{
|
||||
msg += "\n- ";
|
||||
}
|
||||
msg += wxString::Format("Invalid ty value: Actual: %g Expected: %g",
|
||||
cur_ty, ty );
|
||||
}
|
||||
|
||||
if( !msg.empty() )
|
||||
{
|
||||
wxCharBuffer buffer = msg.ToUTF8();
|
||||
FAIL_CHECK( buffer.data() );
|
||||
}
|
||||
}
|
||||
|
||||
static void InitState(wxGraphicsContext* gc)
|
||||
{
|
||||
wxGraphicsMatrix m = gc->CreateMatrix();
|
||||
|
||||
CheckMatrix(m, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
static void InvertMatrix(wxGraphicsContext* gc)
|
||||
{
|
||||
wxGraphicsMatrix m = gc->CreateMatrix(2.0, 1.0, 1.0, 1.0, 1.0, 1.0);
|
||||
m.Invert();
|
||||
|
||||
CheckMatrix(m, 1.0, -1.0, -1.0, 2.0, 0.0, -1.0);
|
||||
}
|
||||
|
||||
static void Concat1(wxGraphicsContext* gc)
|
||||
{
|
||||
wxGraphicsMatrix m1 = gc->CreateMatrix(0.9, 0.4, -0.4, 0.9, 0.0, 0.0);
|
||||
wxGraphicsMatrix m2 = gc->CreateMatrix(1.0, 0.0, 0.0, 1.0, 3.0, 5.0);
|
||||
m1.Concat(m2);
|
||||
|
||||
CheckMatrix(m1, 0.9, 0.4, -0.4, 0.9, 0.7, 5.7);
|
||||
}
|
||||
|
||||
static void Concat2(wxGraphicsContext* gc)
|
||||
{
|
||||
wxGraphicsMatrix m1 = gc->CreateMatrix(0.9, 0.4, -0.4, 0.9, 0.0, 0.0);
|
||||
wxGraphicsMatrix m2 = gc->CreateMatrix(1.0, 0.0, 0.0, 1.0, 3.0, 5.0);
|
||||
m2.Concat(m1);
|
||||
|
||||
CheckMatrix(m2, 0.9, 0.4, -0.4, 0.9, 3.0, 5.0);
|
||||
}
|
||||
|
||||
static void Concat3(wxGraphicsContext* gc)
|
||||
{
|
||||
wxGraphicsMatrix m1 = gc->CreateMatrix(0.9, 0.4, -0.4, 0.9, 0.0, 0.0);
|
||||
wxGraphicsMatrix m2 = gc->CreateMatrix(1.0, 0.0, 0.0, 1.0, 3.0, 5.0);
|
||||
wxGraphicsMatrix m = m1;
|
||||
m.Concat(m2);
|
||||
|
||||
CheckMatrix(m, 0.9, 0.4, -0.4, 0.9, 0.7, 5.7);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
851
libs/wxWidgets-3.3.1/tests/graphics/graphpath.cpp
Normal file
851
libs/wxWidgets-3.3.1/tests/graphics/graphpath.cpp
Normal file
@@ -0,0 +1,851 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/grappath.cpp
|
||||
// Purpose: graphics path unit tests
|
||||
// Author: Artur Wieczorek
|
||||
// Created: 2018-07-01
|
||||
// Copyright: (c) 2018 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/dcgraph.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
static void DoAllTests(wxGraphicsContext* gc);
|
||||
|
||||
// For MSW we have individual test cases for each graphics renderer
|
||||
// so we don't need to execute tests with default renderer.
|
||||
#ifndef __WXMSW__
|
||||
|
||||
TEST_CASE("GraphicsPathTestCase", "[path]")
|
||||
{
|
||||
wxBitmap bmp(500, 500);
|
||||
wxMemoryDC mdc(bmp);
|
||||
std::unique_ptr<wxGraphicsContext> gc(wxGraphicsRenderer::GetDefaultRenderer()->CreateContext(mdc));
|
||||
REQUIRE(gc);
|
||||
DoAllTests(gc.get());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if wxUSE_GRAPHICS_GDIPLUS
|
||||
TEST_CASE("GraphicsPathTestCaseGDIPlus", "[path][gdi+]")
|
||||
{
|
||||
wxBitmap bmp(500, 500);
|
||||
wxMemoryDC mdc(bmp);
|
||||
std::unique_ptr<wxGraphicsContext> gc(wxGraphicsRenderer::GetGDIPlusRenderer()->CreateContext(mdc));
|
||||
REQUIRE(gc);
|
||||
DoAllTests(gc.get());
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_GDIPLUS
|
||||
|
||||
#if wxUSE_GRAPHICS_DIRECT2D
|
||||
TEST_CASE("GraphicsPathTestCaseDirect2D", "[path][d2d]")
|
||||
{
|
||||
if ( wxIsRunningUnderWine() )
|
||||
return;
|
||||
|
||||
wxBitmap bmp(500, 500);
|
||||
wxMemoryDC mdc(bmp);
|
||||
std::unique_ptr<wxGraphicsContext> gc(wxGraphicsRenderer::GetDirect2DRenderer()->CreateContext(mdc));
|
||||
REQUIRE(gc);
|
||||
DoAllTests(gc.get());
|
||||
}
|
||||
#endif // wxUSE_GRAPHICS_DIRECT2D
|
||||
|
||||
#endif // __WXMSW__ / !__WXMSW__
|
||||
|
||||
#if wxUSE_CAIRO
|
||||
TEST_CASE("GraphicsPathTestCaseCairo", "[path][cairo]")
|
||||
{
|
||||
wxBitmap bmp(500, 500);
|
||||
wxMemoryDC mdc(bmp);
|
||||
std::unique_ptr<wxGraphicsContext> gc(wxGraphicsRenderer::GetCairoRenderer()->CreateContext(mdc));
|
||||
REQUIRE(gc);
|
||||
DoAllTests(gc.get());
|
||||
}
|
||||
#endif // wxUSE_CAIRO
|
||||
|
||||
#define WX_CHECK_POINT(p1, p2, tolerance) \
|
||||
CHECK(fabs(p1.m_x - p2.m_x) <= tolerance); \
|
||||
CHECK(fabs(p1.m_y - p2.m_y) <= tolerance)
|
||||
|
||||
static void TestCurrentPoint(wxGraphicsContext* gc)
|
||||
{
|
||||
// No current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
// Should return (0, 0) if current point is not yet set.
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(0, 0), 0);
|
||||
}
|
||||
// MoveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
wxPoint2DDouble pt(27, 35);
|
||||
path.MoveToPoint(pt);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, pt, 1E-3);
|
||||
}
|
||||
// AddLineToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
wxPoint2DDouble pt(27, 35);
|
||||
path.AddLineToPoint(pt);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, pt, 1E-3);
|
||||
}
|
||||
// AddLineToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(10, 18);
|
||||
wxPoint2DDouble pt(37, 45);
|
||||
path.AddLineToPoint(pt);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, pt, 1E-3);
|
||||
}
|
||||
// AddArc - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble r = 40;
|
||||
path.AddArc(x, y, r, 0, M_PI/2, true);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y + r), 1E-3);
|
||||
}
|
||||
// AddArc
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(20, 38);
|
||||
const wxDouble x = 200;
|
||||
const wxDouble y = 50;
|
||||
const wxDouble r = 40;
|
||||
path.AddArc(x, y, r, 0, M_PI / 2, true);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y + r), 1E-3);
|
||||
}
|
||||
// AddArcToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 80;
|
||||
const wxDouble y1 = 80;
|
||||
const wxDouble x2 = -30;
|
||||
const wxDouble y2 = y1;
|
||||
const wxDouble r = 20;
|
||||
wxASSERT(x1 == y1 && y2 == y1); // alpha = 45 deg
|
||||
double d = r / tan(45 / 180.0 * M_PI / 2.0);
|
||||
path.AddArcToPoint(x1, y1, x2, y2, r);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x1 - d, y2), 1E-3);
|
||||
}
|
||||
// AddArcToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 20;
|
||||
const wxDouble y0 = 20;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 80;
|
||||
const wxDouble y1 = 80;
|
||||
const wxDouble x2 = 140;
|
||||
const wxDouble y2 = y1;
|
||||
const wxDouble r = 20;
|
||||
wxASSERT(x0 == y0 && x1 == y1 && y2 == y1); // alpha = 135 deg
|
||||
double d = r / tan(135 / 180.0 * M_PI / 2.0);
|
||||
path.AddArcToPoint(x1, y1, x2, y2, r);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x1 + d, y2), 1E-3);
|
||||
}
|
||||
// AddCurveToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 102;
|
||||
const wxDouble y1 = 230;
|
||||
const wxDouble x2 = 153;
|
||||
const wxDouble y2 = 25;
|
||||
const wxDouble x3 = 230;
|
||||
const wxDouble y3 = 128;
|
||||
path.AddCurveToPoint(x1, y1, x2, y2, x3, y3);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x3, y3), 1E-3);
|
||||
}
|
||||
// AddCurveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 25;
|
||||
const wxDouble y0 = 128;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 102;
|
||||
const wxDouble y1 = 230;
|
||||
const wxDouble x2 = 153;
|
||||
const wxDouble y2 = 25;
|
||||
const wxDouble x3 = 230;
|
||||
const wxDouble y3 = 128;
|
||||
path.AddCurveToPoint(x1, y1, x2, y2, x3, y3);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x3, y3), 1E-3);
|
||||
}
|
||||
// AddQuadCurveToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 200;
|
||||
const wxDouble y1 = 200;
|
||||
const wxDouble x2 = 300;
|
||||
const wxDouble y2 = 100;
|
||||
path.AddQuadCurveToPoint(x1, y1, x2, y2);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x2, y2), 1E-3);
|
||||
}
|
||||
// AddQuadCurveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 20;
|
||||
const wxDouble y0 = 100;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 200;
|
||||
const wxDouble y1 = 200;
|
||||
const wxDouble x2 = 300;
|
||||
const wxDouble y2 = 100;
|
||||
path.AddQuadCurveToPoint(x1, y1, x2, y2);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x2, y2), 1E-3);
|
||||
}
|
||||
// AddCircle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble r = 30;
|
||||
path.AddCircle(x, y, r);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + r, y), 1E-3);
|
||||
}
|
||||
// AddCircle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
const wxDouble r = 40;
|
||||
path.AddCircle(x, y, r);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + r, y), 1E-3);
|
||||
}
|
||||
// AddEllipse - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddEllipse(x, y, w, h);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + w, y + h / 2), 1E-3);
|
||||
}
|
||||
// AddEllipse
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddEllipse(x, y, w, h);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + w, y + h / 2), 1E-3);
|
||||
}
|
||||
// AddRectangle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
path.AddRectangle(x, y, 40, 20);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y), 1E-3);
|
||||
}
|
||||
// AddRectangle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
path.AddRectangle(x, y, 50, 30);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 5);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + w, y + h / 2), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - no current point, radius = 0
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
path.AddRoundedRectangle(x, y, 40, 20, 0); // Should behave like AddRectangle
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 5);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x + w, y + h / 2), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - radius = 0
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 50;
|
||||
const wxDouble y0 = 60;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 0); // Should behave like AddRectangle
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x, y), 1E-3);
|
||||
}
|
||||
// CloseSubpath - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 50;
|
||||
const wxDouble y0 = 80;
|
||||
path.AddLineToPoint(x0, y0);
|
||||
path.AddArcToPoint(100, 160, 50, 200, 30);
|
||||
path.CloseSubpath();
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x0, y0), 1E-3);
|
||||
}
|
||||
// CloseSubpath
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 10;
|
||||
const wxDouble y0 = 20;
|
||||
path.MoveToPoint(x0, y0);
|
||||
path.AddLineToPoint(50, 80);
|
||||
path.AddArcToPoint(100, 160, 50, 200, 30);
|
||||
path.CloseSubpath();
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, wxPoint2DDouble(x0, y0), 1E-3);
|
||||
}
|
||||
// AddPath - no current point
|
||||
{
|
||||
// Path to be added
|
||||
wxGraphicsPath path2 = gc->CreatePath();
|
||||
path2.AddArcToPoint(100, 160, 50, 200, 30);
|
||||
path2.AddLineToPoint(50, 80);
|
||||
path2.CloseSubpath();
|
||||
wxPoint2DDouble cp2 = path2.GetCurrentPoint();
|
||||
// Main path
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.AddLineToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
path.AddRectangle(x, y, 50, 200);
|
||||
path.AddPath(path2);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, cp2, 1E-3);
|
||||
}
|
||||
// AddPath
|
||||
{
|
||||
// Path to be added
|
||||
wxGraphicsPath path2 = gc->CreatePath();
|
||||
path2.AddArcToPoint(100, 160, 50, 200, 30);
|
||||
path2.AddLineToPoint(50, 80);
|
||||
path2.CloseSubpath();
|
||||
wxPoint2DDouble cp2 = path2.GetCurrentPoint();
|
||||
// Main path
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(15, 35);
|
||||
path.AddLineToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
const wxDouble r = 20;
|
||||
path.AddCircle(x, y, r);
|
||||
path.AddPath(path2);
|
||||
wxPoint2DDouble cp = path.GetCurrentPoint();
|
||||
WX_CHECK_POINT(cp, cp2, 1E-3);
|
||||
}
|
||||
}
|
||||
|
||||
#define WX_CHECK_BOX(r1, r2, tolerance) \
|
||||
WX_CHECK_POINT(r1.GetLeftTop(), r2.GetLeftTop(), tolerance); \
|
||||
WX_CHECK_POINT(r1.GetRightBottom(), r2.GetRightBottom(), tolerance)
|
||||
|
||||
static void TestBox(wxGraphicsContext* gc)
|
||||
{
|
||||
// No current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(0, 0, 0, 0), 0);
|
||||
}
|
||||
// MoveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(28, 38);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(0, 0, 0, 0), 0);
|
||||
}
|
||||
// AddLineToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.AddLineToPoint(28, 36);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(0, 0, 0, 0), 0);
|
||||
}
|
||||
// AddLineToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 10;
|
||||
const wxDouble y0 = 18;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble w = 20;
|
||||
const wxDouble h = 46;
|
||||
path.AddLineToPoint(x0 + w, y0 + h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x0, y0, w, h), 0);
|
||||
}
|
||||
// AddArc - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble r = 40;
|
||||
path.AddArc(x, y, r, 0, M_PI / 2, true);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, r, r), 1E-3);
|
||||
}
|
||||
// AddArc
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 20;
|
||||
const wxDouble y0 = 20;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x = 200;
|
||||
const wxDouble y = 50;
|
||||
const wxDouble r = 40;
|
||||
path.AddArc(x, y, r, 0, M_PI / 2, true);
|
||||
const wxDouble x2 = x + r;
|
||||
const wxDouble y2 = y + r;
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x0, y0, x2 - x0, y2 - y0), 1E-3);
|
||||
}
|
||||
// AddArcToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 80;
|
||||
const wxDouble y1 = 0;
|
||||
const wxDouble x2 = x1;
|
||||
const wxDouble y2 = 40;
|
||||
const wxDouble r = 20;
|
||||
wxASSERT(y1 == 0 && x2 == x1); // alpha = 90 deg
|
||||
path.AddArcToPoint(x1, y1, x2, y2, r);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(0, 0, x1, r), 1E-3);
|
||||
}
|
||||
// AddArcToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 20;
|
||||
const wxDouble y0 = 20;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 80;
|
||||
const wxDouble y1 = y0;
|
||||
const wxDouble x2 = x1;
|
||||
const wxDouble y2 = 140;
|
||||
const wxDouble r = 20;
|
||||
wxASSERT(y1 == y0 && x2 == x1); // alpha = 90 deg
|
||||
path.AddArcToPoint(x1, y1, x2, y2, r);
|
||||
const wxDouble xe = x1;
|
||||
const wxDouble ye = y1 + r;
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x0, y0, xe - x0, ye - y0), 1E-3);
|
||||
}
|
||||
// AddCurveToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 102;
|
||||
const wxDouble y1 = 230;
|
||||
const wxDouble x2 = 153;
|
||||
const wxDouble y2 = 25;
|
||||
const wxDouble x3 = 230;
|
||||
const wxDouble y3 = 128;
|
||||
path.AddCurveToPoint(x1, y1, x2, y2, x3, y3);
|
||||
const wxDouble xmin = wxMin(wxMin(x1, x2), x3);
|
||||
const wxDouble ymin = wxMin(wxMin(y1, y2), y3);
|
||||
const wxDouble xmax = wxMax(wxMax(x1, x2), x3);
|
||||
const wxDouble ymax = wxMax(wxMax(y1, y2), y3);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
const wxDouble tolerance = 1E-3;
|
||||
CHECK(xmin - tolerance <= b.GetLeft());
|
||||
CHECK(ymin - tolerance <= b.GetTop());
|
||||
CHECK(xmax + tolerance >= b.GetRight());
|
||||
CHECK(ymax + tolerance >= b.GetBottom());
|
||||
}
|
||||
// AddCurveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 25;
|
||||
const wxDouble y0 = 128;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 102;
|
||||
const wxDouble y1 = 230;
|
||||
const wxDouble x2 = 153;
|
||||
const wxDouble y2 = 25;
|
||||
const wxDouble x3 = 230;
|
||||
const wxDouble y3 = 128;
|
||||
path.AddCurveToPoint(x1, y1, x2, y2, x3, y3);
|
||||
const wxDouble xmin = wxMin(wxMin(wxMin(x0, x1), x2), x3);
|
||||
const wxDouble ymin = wxMin(wxMin(wxMin(y0, y1), y2), y3);
|
||||
const wxDouble xmax = wxMax(wxMax(wxMax(x0, x1), x2), x3);
|
||||
const wxDouble ymax = wxMax(wxMax(wxMax(y0, y1), y2), y3);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
const wxDouble tolerance = 1E-3;
|
||||
CHECK(xmin - tolerance <= b.GetLeft());
|
||||
CHECK(ymin - tolerance <= b.GetTop());
|
||||
CHECK(xmax + tolerance >= b.GetRight());
|
||||
CHECK(ymax + tolerance >= b.GetBottom());
|
||||
}
|
||||
// AddQuadCurveToPoint - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x1 = 200;
|
||||
const wxDouble y1 = 200;
|
||||
const wxDouble x2 = 300;
|
||||
const wxDouble y2 = 100;
|
||||
path.AddQuadCurveToPoint(x1, y1, x2, y2);
|
||||
// const wxDouble xmin = wxMin(x1, x2);
|
||||
const wxDouble xmin = 133;
|
||||
const wxDouble ymin = wxMin(y1, y2);
|
||||
const wxDouble xmax = wxMax(x1, x2);
|
||||
const wxDouble ymax = wxMax(y1, y2);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
const wxDouble tolerance = 1E-3;
|
||||
CHECK(xmin - tolerance <= b.GetLeft());
|
||||
CHECK(ymin - tolerance <= b.GetTop());
|
||||
CHECK(xmax + tolerance >= b.GetRight());
|
||||
CHECK(ymax + tolerance >= b.GetBottom());
|
||||
}
|
||||
// AddQuadCurveToPoint
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 20;
|
||||
const wxDouble y0 = 100;
|
||||
path.MoveToPoint(x0, y0);
|
||||
const wxDouble x1 = 200;
|
||||
const wxDouble y1 = 200;
|
||||
const wxDouble x2 = 300;
|
||||
const wxDouble y2 = 100;
|
||||
path.AddQuadCurveToPoint(x1, y1, x2, y2);
|
||||
const wxDouble xmin = wxMin(wxMin(x0, x1), x2);
|
||||
const wxDouble ymin = wxMin(wxMin(y0, y1), y2);
|
||||
const wxDouble xmax = wxMax(wxMax(x0, x1), x2);
|
||||
const wxDouble ymax = wxMax(wxMax(y0, y1), y2);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
const wxDouble tolerance = 1E-3;
|
||||
CHECK(xmin - tolerance <= b.GetLeft());
|
||||
CHECK(ymin - tolerance <= b.GetTop());
|
||||
CHECK(xmax + tolerance >= b.GetRight());
|
||||
CHECK(ymax + tolerance >= b.GetBottom());
|
||||
}
|
||||
// AddCircle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble r = 30;
|
||||
path.AddCircle(x, y, r);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x - r, y - r, 2 * r, 2 * r), 1E-3);
|
||||
}
|
||||
// AddCircle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
const wxDouble r = 40;
|
||||
path.AddCircle(x, y, r);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x - r, y - r, 2 * r, 2 * r), 1E-3);
|
||||
}
|
||||
// AddEllipse - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddEllipse(x, y, w, h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddEllipse
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddEllipse(x, y, w, h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRectangle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRectangle(x, y, w, h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRectangle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 50;
|
||||
const wxDouble h = 30;
|
||||
path.AddRectangle(x, y, w, h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 5);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - no current point, radius = 0
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 0);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 5);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// AddRoundedRectangle - radius = 0
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 40;
|
||||
const wxDouble h = 20;
|
||||
path.AddRoundedRectangle(x, y, w, h, 0);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
// CloseSubpath - empty path
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.CloseSubpath();
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(0, 0, 0, 0), 0);
|
||||
}
|
||||
// CloseSubpath - no current point
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 50;
|
||||
const wxDouble y0 = 80;
|
||||
path.AddLineToPoint(x0, y0);
|
||||
const wxDouble x1 = 100;
|
||||
const wxDouble y1 = 160;
|
||||
path.AddLineToPoint(x1, y1);
|
||||
path.CloseSubpath();
|
||||
const wxDouble w = x1 - x0;
|
||||
const wxDouble h = y1 - y0;
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x0, y0, w, h), 1E-3);
|
||||
}
|
||||
// CloseSubpath
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
const wxDouble x0 = 10;
|
||||
const wxDouble y0 = 20;
|
||||
path.MoveToPoint(x0, y0);
|
||||
path.AddLineToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 160;
|
||||
path.AddLineToPoint(x, y);
|
||||
path.CloseSubpath();
|
||||
const wxDouble w = x - x0;
|
||||
const wxDouble h = y - y0;
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x0, y0, w, h), 1E-3);
|
||||
}
|
||||
// AddPath - no current point
|
||||
{
|
||||
// Path to be added
|
||||
wxGraphicsPath path2 = gc->CreatePath();
|
||||
path2.AddLineToPoint(100, 160);
|
||||
path2.AddLineToPoint(50, 80);
|
||||
path2.CloseSubpath();
|
||||
wxRect2DDouble b2 = path2.GetBox();
|
||||
// Main path
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.AddLineToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
path.AddRectangle(x, y, 50, 200);
|
||||
wxRect2DDouble b0 = path.GetBox();
|
||||
b0.Union(b2);
|
||||
path.AddPath(path2);
|
||||
wxRect2DDouble b1 = path.GetBox();
|
||||
WX_CHECK_BOX(b0, b1, 1E-3);
|
||||
}
|
||||
// AddPath
|
||||
{
|
||||
// Path to be added
|
||||
wxGraphicsPath path2 = gc->CreatePath();
|
||||
path2.AddArcToPoint(100, 160, 50, 200, 30);
|
||||
path2.AddLineToPoint(50, 80);
|
||||
path2.CloseSubpath();
|
||||
wxRect2DDouble b2 = path2.GetBox();
|
||||
// Main path
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(15, 35);
|
||||
path.AddLineToPoint(50, 80);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 140;
|
||||
const wxDouble r = 20;
|
||||
path.AddCircle(x, y, r);
|
||||
wxRect2DDouble b0 = path.GetBox();
|
||||
b0.Union(b2);
|
||||
path.AddPath(path2);
|
||||
wxRect2DDouble b1 = path.GetBox();
|
||||
WX_CHECK_BOX(b0, b1, 1E-3);
|
||||
}
|
||||
// Overlapping figures
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble xr = 100;
|
||||
const wxDouble yr = 150;
|
||||
const wxDouble wr = 80;
|
||||
const wxDouble hr = 40;
|
||||
path.AddRectangle(xr, yr, wr, hr);
|
||||
const wxDouble xe = xr + wr / 4;
|
||||
const wxDouble ye = yr + hr / 4;
|
||||
const wxDouble we = wr / 2;
|
||||
const wxDouble he = hr / 2;
|
||||
path.AddEllipse(xe, ye, we, he);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
wxRect2DDouble r;
|
||||
wxRect2DDouble::Union(wxRect2DDouble(xe, ye, we, he), wxRect2DDouble(xr, yr, wr, hr), &r);
|
||||
WX_CHECK_BOX(b, r, 1E-3);
|
||||
}
|
||||
// Partially overlapping figures
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble xe = 100;
|
||||
const wxDouble ye = 150;
|
||||
const wxDouble we = 40;
|
||||
const wxDouble he = 20;
|
||||
path.AddEllipse(xe, ye, we, he);
|
||||
const wxDouble xr = xe + he / 2;
|
||||
const wxDouble yr = ye + we / 2;
|
||||
const wxDouble wr = we + 10;
|
||||
const wxDouble hr = he + 10;
|
||||
path.AddRectangle(xr, yr, wr, hr);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
wxRect2DDouble r;
|
||||
wxRect2DDouble::Union(wxRect2DDouble(xe, ye, we, he), wxRect2DDouble(xr, yr, wr, hr), &r);
|
||||
WX_CHECK_BOX(b, r, 1E-3);
|
||||
}
|
||||
// Non-overlapping figures
|
||||
{
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble xe = 100;
|
||||
const wxDouble ye = 150;
|
||||
const wxDouble we = 40;
|
||||
const wxDouble he = 20;
|
||||
path.AddEllipse(xe, ye, we, he);
|
||||
const wxDouble xr = xe + he + 10;
|
||||
const wxDouble yr = ye + we + 20;
|
||||
const wxDouble wr = 50;
|
||||
const wxDouble hr = 30;
|
||||
path.AddRectangle(xr, yr, wr, hr);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
wxRect2DDouble r;
|
||||
wxRect2DDouble::Union(wxRect2DDouble(xe, ye, we, he), wxRect2DDouble(xr, yr, wr, hr), &r);
|
||||
WX_CHECK_BOX(b, r, 1E-3);
|
||||
}
|
||||
// Path from transformed graphics context
|
||||
{
|
||||
gc->PushState();
|
||||
gc->Translate(5, 15);
|
||||
gc->Rotate(10 * M_PI / 180);
|
||||
wxGraphicsPath path = gc->CreatePath();
|
||||
path.MoveToPoint(50, 60);
|
||||
const wxDouble x = 100;
|
||||
const wxDouble y = 150;
|
||||
const wxDouble w = 50;
|
||||
const wxDouble h = 30;
|
||||
path.AddRectangle(x, y, w, h);
|
||||
wxRect2DDouble b = path.GetBox();
|
||||
gc->PopState();
|
||||
WX_CHECK_BOX(b, wxRect2DDouble(x, y, w, h), 1E-3);
|
||||
}
|
||||
}
|
||||
|
||||
static void DoAllTests(wxGraphicsContext* gc)
|
||||
{
|
||||
gc->DisableOffset();
|
||||
TestCurrentPoint(gc);
|
||||
TestBox(gc);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GRAPHICS_CONTEXT
|
||||
790
libs/wxWidgets-3.3.1/tests/graphics/imagelist.cpp
Normal file
790
libs/wxWidgets-3.3.1/tests/graphics/imagelist.cpp
Normal file
@@ -0,0 +1,790 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/imagelist.cpp
|
||||
// Purpose: image list unit tests
|
||||
// Author: Artur Wieczorek
|
||||
// Created: 2021-01-11
|
||||
// Copyright: (c) 2021 wxWidgets development team
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#include "wx/bitmap.h"
|
||||
#include "wx/graphics.h"
|
||||
#include "wx/icon.h"
|
||||
#include "wx/imaglist.h"
|
||||
|
||||
#include "wx/dcmemory.h"
|
||||
|
||||
static bool HasNoRealAlpha(const wxBitmap& bmp)
|
||||
{
|
||||
if ( !bmp.HasAlpha() )
|
||||
return true;
|
||||
|
||||
// wxMSW can add a fully opaque alpha channel to the bitmaps used in the
|
||||
// image list.
|
||||
const wxImage img = bmp.ConvertToImage();
|
||||
const unsigned char* p = img.GetAlpha();
|
||||
if ( !p )
|
||||
return true;
|
||||
|
||||
const unsigned char* const end = p + img.GetWidth()*img.GetHeight();
|
||||
for ( ; p < end; ++p )
|
||||
{
|
||||
if ( *p != wxALPHA_OPAQUE )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HasMaskOrAlpha(const wxBitmap& bmp)
|
||||
{
|
||||
// When adding bitmaps with mask to the image list, the mask can be
|
||||
// transformed to alpha channel internally, so check that the bitmap has
|
||||
// either mask or alpha.
|
||||
return bmp.HasAlpha() || bmp.GetMask();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// test fixture
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class ImageListTestCase
|
||||
{
|
||||
protected:
|
||||
ImageListTestCase();
|
||||
|
||||
const wxSize BITMAP_SIZE;
|
||||
|
||||
wxBitmap bmpRGB, bmpRGBA, bmpMask,
|
||||
bmpRGBWithMask, bmpRGBAWithMask;
|
||||
wxIcon ico;
|
||||
};
|
||||
|
||||
ImageListTestCase::ImageListTestCase()
|
||||
: BITMAP_SIZE(32, 32),
|
||||
bmpRGB(BITMAP_SIZE, 24),
|
||||
bmpMask(BITMAP_SIZE, 1)
|
||||
{
|
||||
{
|
||||
wxMemoryDC mdc(bmpRGB);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
mdc.SetBrush(*wxRED_BRUSH);
|
||||
mdc.DrawRectangle(4, 4, 24, 24);
|
||||
}
|
||||
REQUIRE(bmpRGB.IsOk());
|
||||
|
||||
// Make a bitmap with some transparent and semi-transparent pixels.
|
||||
wxImage imgWithAlpha(BITMAP_SIZE.x, BITMAP_SIZE.y);
|
||||
imgWithAlpha.SetAlpha();
|
||||
unsigned char* const alpha = imgWithAlpha.GetAlpha();
|
||||
for ( unsigned char* a = alpha; a < alpha + BITMAP_SIZE.x*BITMAP_SIZE.y; ++a )
|
||||
*a = wxALPHA_OPAQUE;
|
||||
alpha[0] = wxALPHA_TRANSPARENT;
|
||||
alpha[1] = wxALPHA_OPAQUE / 2;
|
||||
bmpRGBA = wxBitmap(imgWithAlpha);
|
||||
REQUIRE(bmpRGBA.IsOk());
|
||||
|
||||
{
|
||||
wxMemoryDC mdc(bmpMask);
|
||||
#if wxUSE_GRAPHICS_CONTEXT
|
||||
wxGraphicsContext* gc = mdc.GetGraphicsContext();
|
||||
if ( gc )
|
||||
gc->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
#endif //wxUSE_GRAPHICS_CONTEXT
|
||||
mdc.SetBackground(*wxBLACK_BRUSH);
|
||||
mdc.Clear();
|
||||
mdc.SetBrush(*wxWHITE_BRUSH);
|
||||
mdc.DrawRectangle(0, 0, 16, 32);
|
||||
}
|
||||
|
||||
bmpRGBWithMask = bmpRGB;
|
||||
bmpRGBWithMask.SetMask(new wxMask(bmpMask));
|
||||
REQUIRE(bmpRGBWithMask.IsOk());
|
||||
|
||||
bmpRGBAWithMask = bmpRGBA;
|
||||
bmpRGBAWithMask.SetMask(new wxMask(bmpMask));
|
||||
REQUIRE(bmpRGBAWithMask.IsOk());
|
||||
|
||||
ico.CopyFromBitmap(bmpRGBWithMask);
|
||||
REQUIRE(ico.IsOk());
|
||||
|
||||
REQUIRE(bmpRGB.HasAlpha() == false);
|
||||
REQUIRE(bmpRGB.GetMask() == nullptr);
|
||||
|
||||
REQUIRE(bmpRGBWithMask.HasAlpha() == false);
|
||||
REQUIRE(bmpRGBWithMask.GetMask() != nullptr);
|
||||
|
||||
REQUIRE(bmpRGBA.HasAlpha() == true);
|
||||
REQUIRE(bmpRGBA.GetMask() == nullptr);
|
||||
|
||||
REQUIRE(bmpRGBAWithMask.HasAlpha() == true);
|
||||
REQUIRE(bmpRGBAWithMask.GetMask() != nullptr);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE_METHOD(ImageListTestCase,
|
||||
"ImageList:WithMask", "[imagelist][withmask]")
|
||||
{
|
||||
wxImageList il(BITMAP_SIZE.x, BITMAP_SIZE.y, true);
|
||||
|
||||
SECTION("Add RGB image to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(bmpRGB);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxBitmap bmp1 = il.GetBitmap(idx);
|
||||
CHECK(HasNoRealAlpha(bmp1));
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
wxBitmap bmp2 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGB, *wxRED);
|
||||
CHECK(il.GetImageCount() == 3);
|
||||
wxBitmap bmp3 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp3));
|
||||
CHECK(bmp3.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add RGBA image to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(bmpRGBA);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxBitmap bmp1 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp1));
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBAWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
wxBitmap bmp2 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBA, *wxRED);
|
||||
CHECK(il.GetImageCount() == 3);
|
||||
wxBitmap bmp3 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp3));
|
||||
CHECK(bmp3.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add icon to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(ico);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxIcon icon1 = il.GetIcon(idx);
|
||||
CHECK(icon1.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Replace with RGB image")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx1 = il.Add(bmpRGBA);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
int idx2 = il.Add(bmpRGBAWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
|
||||
il.Replace(idx1, bmpRGB);
|
||||
il.Replace(idx2, bmpRGBWithMask);
|
||||
|
||||
wxBitmap bmp1 = il.GetBitmap(idx1);
|
||||
CHECK(HasMaskOrAlpha(bmp1));
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
wxBitmap bmp2 = il.GetBitmap(idx2);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Replace with RGBA image")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx1 = il.Add(bmpRGB);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
int idx2 = il.Add(bmpRGBWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
|
||||
il.Replace(idx1, bmpRGBA);
|
||||
il.Replace(idx2, bmpRGBAWithMask);
|
||||
|
||||
wxBitmap bmp1 = il.GetBitmap(idx1);
|
||||
CHECK(HasMaskOrAlpha(bmp1));
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
wxBitmap bmp2 = il.GetBitmap(idx2);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add images with incompatible sizes")
|
||||
{
|
||||
il.RemoveAll();
|
||||
wxSize sz = il.GetSize();
|
||||
|
||||
wxBitmap bmpSmallerW(sz.GetWidth() / 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerW);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerW.IsOk());
|
||||
|
||||
wxBitmap bmpSmallerH(sz.GetWidth(), sz.GetHeight() / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerH.IsOk());
|
||||
|
||||
wxBitmap bmpSmallerWH(sz.GetWidth() / 2, sz.GetHeight() / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpSmallerWH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpSmallerWH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerW(sz.GetWidth() * 3 / 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerW);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerW.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerW2x(sz.GetWidth() * 2, sz.GetHeight(), 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerW2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerW2x.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerH(sz.GetWidth(), sz.GetHeight() * 3 / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerH2x(sz.GetWidth(), sz.GetHeight() * 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerH2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerH2x.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerWH(sz.GetWidth() * 3 / 2, sz.GetHeight() * 3 / 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerWH);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerWH.IsOk());
|
||||
|
||||
wxBitmap bmpBiggerWH2x(sz.GetWidth() * 2, sz.GetHeight() * 2, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmpBiggerWH2x);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
}
|
||||
REQUIRE(bmpBiggerWH2x.IsOk());
|
||||
|
||||
// Adding
|
||||
int cnt = il.GetImageCount();
|
||||
int idx = il.Add(bmpSmallerW);
|
||||
CHECK(idx == -1);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpSmallerH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
wxBitmap bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpSmallerWH);
|
||||
CHECK(idx == -1);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerW);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerW2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 2);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerH2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerWH);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 1);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
idx = il.Add(bmpBiggerWH2x);
|
||||
CHECK(idx >= 0);
|
||||
CHECK(il.GetImageCount() == cnt + 2);
|
||||
bmp = il.GetBitmap(idx);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
// Replacing
|
||||
il.RemoveAll();
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
bool ok = il.Replace(0, bmpRGBA);
|
||||
CHECK(ok == false);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
|
||||
// List with 1 image
|
||||
idx = il.Add(bmpRGB);
|
||||
CHECK(idx >= 0);
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpRGBA);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerW);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpSmallerWH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerW);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerW2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerH2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerWH);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
|
||||
cnt = il.GetImageCount();
|
||||
ok = il.Replace(0, bmpBiggerWH2x);
|
||||
CHECK(ok == true);
|
||||
CHECK(il.GetImageCount() == cnt);
|
||||
bmp = il.GetBitmap(0);
|
||||
CHECK(bmp.GetWidth() == sz.GetWidth());
|
||||
CHECK(bmp.GetHeight() == sz.GetHeight());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ImageListTestCase,
|
||||
"ImageList:NoMask", "[imagelist][nomask]")
|
||||
{
|
||||
wxImageList il(BITMAP_SIZE.x, BITMAP_SIZE.y, false);
|
||||
|
||||
SECTION("Add RGB image to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(bmpRGB);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxBitmap bmp1 = il.GetBitmap(idx);
|
||||
CHECK(bmp1.HasAlpha() == false);
|
||||
CHECK(bmp1.GetMask() == nullptr);
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
wxBitmap bmp2 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGB, *wxRED);
|
||||
CHECK(il.GetImageCount() == 3);
|
||||
wxBitmap bmp3 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp3));
|
||||
CHECK(bmp3.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add RGBA image to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(bmpRGBA);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxBitmap bmp1 = il.GetBitmap(idx);
|
||||
CHECK(bmp1.HasAlpha() == true);
|
||||
CHECK(bmp1.GetMask() == nullptr);
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBAWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
wxBitmap bmp2 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
|
||||
idx = il.Add(bmpRGBA, *wxRED);
|
||||
CHECK(il.GetImageCount() == 3);
|
||||
wxBitmap bmp3 = il.GetBitmap(idx);
|
||||
CHECK(HasMaskOrAlpha(bmp3));
|
||||
CHECK(bmp3.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add icon to list")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(ico);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
wxIcon icon1 = il.GetIcon(idx);
|
||||
CHECK(icon1.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Replace with RGB image")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx1 = il.Add(bmpRGBA);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
int idx2 = il.Add(bmpRGBAWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
|
||||
il.Replace(idx1, bmpRGB);
|
||||
il.Replace(idx2, bmpRGBWithMask);
|
||||
|
||||
wxBitmap bmp1 = il.GetBitmap(idx1);
|
||||
CHECK(bmp1.HasAlpha() == false);
|
||||
CHECK(bmp1.GetMask() == nullptr);
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
wxBitmap bmp2 = il.GetBitmap(idx2);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Replace with RGBA image")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx1 = il.Add(bmpRGB);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
int idx2 = il.Add(bmpRGBWithMask);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
|
||||
il.Replace(idx1, bmpRGBA);
|
||||
il.Replace(idx2, bmpRGBAWithMask);
|
||||
|
||||
wxBitmap bmp1 = il.GetBitmap(idx1);
|
||||
CHECK(bmp1.HasAlpha() == true);
|
||||
CHECK(bmp1.GetMask() == nullptr);
|
||||
CHECK(bmp1.GetSize() == BITMAP_SIZE);
|
||||
|
||||
wxBitmap bmp2 = il.GetBitmap(idx2);
|
||||
CHECK(HasMaskOrAlpha(bmp2));
|
||||
CHECK(bmp2.GetSize() == BITMAP_SIZE);
|
||||
}
|
||||
|
||||
SECTION("Add 2x width image")
|
||||
{
|
||||
il.RemoveAll();
|
||||
int idx = il.Add(wxBitmap(BITMAP_SIZE.x * 2, BITMAP_SIZE.y));
|
||||
CHECK(idx == 0);
|
||||
CHECK(il.GetImageCount() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ImageList:NegativeTests", "[imagelist][negative]")
|
||||
{
|
||||
wxBitmap bmp(32, 32, 24);
|
||||
{
|
||||
wxMemoryDC mdc(bmp);
|
||||
mdc.SetBackground(*wxBLUE_BRUSH);
|
||||
mdc.Clear();
|
||||
mdc.SetBrush(*wxRED_BRUSH);
|
||||
mdc.DrawRectangle(4, 4, 24, 24);
|
||||
}
|
||||
REQUIRE(bmp.IsOk());
|
||||
|
||||
SECTION("Invalid size (negative)")
|
||||
{
|
||||
wxImageList il;
|
||||
bool ok = il.Create(-1, -1);
|
||||
CHECK_FALSE(ok);
|
||||
#ifdef __WXDEBUG__
|
||||
REQUIRE_THROWS(il.GetImageCount());
|
||||
#else
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
#endif
|
||||
|
||||
wxSize sz = il.GetSize();
|
||||
CHECK(sz.x == 0);
|
||||
CHECK(sz.y == 0);
|
||||
|
||||
int w = -1;
|
||||
int h = -1;
|
||||
#ifdef __WXDEBUG__
|
||||
REQUIRE_THROWS(il.GetSize(0, w, h));
|
||||
#else
|
||||
ok = il.GetSize(0, w, h);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(w == 0);
|
||||
CHECK(h == 0);
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
CHECK_THROWS(il.Add(bmp));
|
||||
REQUIRE_THROWS(il.GetImageCount());
|
||||
#else
|
||||
CHECK(il.Add(bmp) == -1);
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("Invalid size (zero)")
|
||||
{
|
||||
wxImageList il;
|
||||
bool ok = il.Create(0, 0);
|
||||
CHECK_FALSE(ok);
|
||||
#ifdef __WXDEBUG__
|
||||
REQUIRE_THROWS(il.GetImageCount());
|
||||
#else
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
#endif
|
||||
|
||||
wxSize sz = il.GetSize();
|
||||
CHECK(sz.x == 0);
|
||||
CHECK(sz.y == 0);
|
||||
|
||||
int w = -1;
|
||||
int h = -1;
|
||||
#ifdef __WXDEBUG__
|
||||
REQUIRE_THROWS(ok = il.GetSize(0, w, h));
|
||||
#else
|
||||
ok = il.GetSize(0, w, h);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(w == 0);
|
||||
CHECK(h == 0);
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
CHECK_THROWS(il.Add(bmp));
|
||||
REQUIRE_THROWS(il.GetImageCount());
|
||||
#else
|
||||
CHECK(il.Add(bmp) == -1);
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
#endif
|
||||
|
||||
#ifdef __WXDEBUG__
|
||||
CHECK_THROWS(il.Replace(0, bmp));
|
||||
REQUIRE_THROWS(il.GetImageCount());
|
||||
#else
|
||||
CHECK_FALSE(il.Replace(0, bmp));
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("Add to invalid image list")
|
||||
{
|
||||
wxImageList il;
|
||||
#ifdef __WXDEBUG__
|
||||
CHECK_THROWS( il.Add(bmp) );
|
||||
#else
|
||||
CHECK( il.Add(bmp) == -1 );
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("Invalid Get/Replace/Remove indices")
|
||||
{
|
||||
wxImageList il(32, 32, false);
|
||||
CHECK(il.GetImageCount() == 0);
|
||||
|
||||
wxSize sz = il.GetSize();
|
||||
CHECK(sz.x == 32);
|
||||
CHECK(sz.y == 32);
|
||||
|
||||
int w = -1;
|
||||
int h = -1;
|
||||
bool ok = il.GetSize(0, w, h);
|
||||
CHECK(ok == true);
|
||||
CHECK(w == 32);
|
||||
CHECK(h == 32);
|
||||
|
||||
int idx = il.Add(bmp);
|
||||
CHECK(idx == 0);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
wxBitmap bmp2 = il.GetBitmap(-1);
|
||||
CHECK_FALSE(bmp2.IsOk());
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
wxBitmap bmp3 = il.GetBitmap(5);
|
||||
CHECK_FALSE(bmp3.IsOk());
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
wxIcon icon2 = il.GetIcon(-1);
|
||||
CHECK_FALSE(icon2.IsOk());
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
wxBitmap icon3 = il.GetIcon(5);
|
||||
CHECK_FALSE(icon3.IsOk());
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
ok = il.Replace(-1, bmp);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
ok = il.Replace(5, bmp);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
ok = il.Remove(-1);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
|
||||
ok = il.Remove(5);
|
||||
CHECK_FALSE(ok);
|
||||
CHECK(il.GetImageCount() == 1);
|
||||
}
|
||||
}
|
||||
|
||||
// This test relies on logical pixels being different from physical ones.
|
||||
#ifdef wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
|
||||
TEST_CASE("ImageList:HiDPI", "[imagelist][hidpi]")
|
||||
{
|
||||
wxImage img1(8, 4);
|
||||
img1.SetRGB(wxRect(0, 0, 8, 4), 0, 63, 127);
|
||||
REQUIRE(img1.IsOk());
|
||||
|
||||
wxImage img2(16, 8);
|
||||
img2.SetRGB(wxRect(0, 0, 16, 8), 255, 128, 64);
|
||||
REQUIRE(img2.IsOk());
|
||||
|
||||
wxBitmap bmp1x(img1, -1, 1.0);
|
||||
REQUIRE(bmp1x.IsOk());
|
||||
CHECK(bmp1x.GetSize() == wxSize(8, 4));
|
||||
CHECK(bmp1x.GetLogicalSize() == wxSize(8, 4));
|
||||
CHECK_FALSE(bmp1x.HasAlpha());
|
||||
CHECK(bmp1x.GetMask() == nullptr);
|
||||
|
||||
wxBitmap bmp2x(img2, -1, 2.0);
|
||||
REQUIRE(bmp2x.IsOk());
|
||||
CHECK(bmp2x.GetSize() == wxSize(16, 8));
|
||||
CHECK(bmp2x.GetLogicalSize() == wxSize(8, 4));
|
||||
CHECK_FALSE(bmp2x.HasAlpha());
|
||||
CHECK(bmp2x.GetMask() == nullptr);
|
||||
|
||||
// Logical image size
|
||||
wxImageList il(8, 4, false);
|
||||
|
||||
int idx = il.Add(bmp2x);
|
||||
REQUIRE(idx == 0);
|
||||
REQUIRE(il.GetImageCount() == 1);
|
||||
|
||||
idx = il.Add(bmp1x);
|
||||
REQUIRE(idx == 1);
|
||||
REQUIRE(il.GetImageCount() == 2);
|
||||
|
||||
wxBitmap bmp = il.GetBitmap(0);
|
||||
REQUIRE(bmp.IsOk() == true);
|
||||
CHECK(bmp.GetScaleFactor() == 2.0);
|
||||
CHECK(bmp.GetSize() == wxSize(16, 8));
|
||||
CHECK(bmp.GetLogicalSize() == wxSize(8, 4));
|
||||
CHECK_FALSE(bmp.HasAlpha());
|
||||
CHECK(bmp.GetMask() == nullptr);
|
||||
|
||||
bmp = il.GetBitmap(1);
|
||||
REQUIRE(bmp.IsOk() == true);
|
||||
CHECK(bmp.GetScaleFactor() == 1.0);
|
||||
CHECK(bmp.GetSize() == wxSize(8, 4));
|
||||
CHECK(bmp.GetLogicalSize() == wxSize(8, 4));
|
||||
CHECK_FALSE(bmp.HasAlpha());
|
||||
CHECK(bmp.GetMask() == nullptr);
|
||||
}
|
||||
#endif // wxHAS_DPI_INDEPENDENT_PIXELS
|
||||
190
libs/wxWidgets-3.3.1/tests/graphics/measuring.cpp
Normal file
190
libs/wxWidgets-3.3.1/tests/graphics/measuring.cpp
Normal file
@@ -0,0 +1,190 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/graphics/measuring.cpp
|
||||
// Purpose: Tests for wxGraphicsRenderer::CreateMeasuringContext
|
||||
// Author: Kevin Ollivier, Vadim Zeitlin (non wxGC parts)
|
||||
// Created: 2008-02-12
|
||||
// Copyright: (c) 2008 Kevin Ollivier <kevino@theolliviers.com>
|
||||
// (c) 2012 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/font.h"
|
||||
#include "wx/window.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
// wxCairoRenderer::CreateMeasuringContext() is not implement for wxX11
|
||||
#if wxUSE_GRAPHICS_CONTEXT && !defined(__WXX11__)
|
||||
#include "wx/graphics.h"
|
||||
#define TEST_GC
|
||||
#endif
|
||||
|
||||
#include "wx/dcclient.h"
|
||||
#include "wx/dcmemory.h"
|
||||
#include "wx/dcps.h"
|
||||
#include "wx/metafile.h"
|
||||
|
||||
#include "asserthelper.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// helper for XXXTextExtent() methods
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// Run a couple of simple tests for GetTextExtent().
|
||||
template <typename T>
|
||||
void GetTextExtentTester(const T& obj)
|
||||
{
|
||||
// Test that getting the height only doesn't crash.
|
||||
int y;
|
||||
obj.GetTextExtent("H", nullptr, &y);
|
||||
|
||||
CHECK( y > 1 );
|
||||
|
||||
wxSize size = obj.GetTextExtent("Hello");
|
||||
CHECK( size.x > 1 );
|
||||
CHECK( size.y == y );
|
||||
|
||||
// Test that getting text extent of an empty string returns (0, 0).
|
||||
CHECK( obj.GetTextExtent(wxString()) == wxSize() );
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// tests themselves
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("wxDC::GetTextExtent", "[dc][text-extent]")
|
||||
{
|
||||
wxClientDC dc(wxTheApp->GetTopWindow());
|
||||
|
||||
GetTextExtentTester(dc);
|
||||
|
||||
int w;
|
||||
dc.GetMultiLineTextExtent("Good\nbye", &w, nullptr);
|
||||
const wxSize sz = dc.GetTextExtent("Good");
|
||||
CHECK( w == sz.x );
|
||||
|
||||
CHECK( dc.GetMultiLineTextExtent("Good\nbye").y >= 2*sz.y );
|
||||
|
||||
// Check that empty lines get counted
|
||||
CHECK( dc.GetMultiLineTextExtent("\n\n\n").y >= 3*sz.y );
|
||||
|
||||
// And even empty strings count like one line.
|
||||
CHECK( dc.GetMultiLineTextExtent(wxString()) == wxSize(0, sz.y) );
|
||||
}
|
||||
|
||||
TEST_CASE("wxMemoryDC::GetTextExtent", "[memdc][text-extent]")
|
||||
{
|
||||
wxBitmap bmp(100, 100);
|
||||
wxMemoryDC memdc(bmp);
|
||||
GetTextExtentTester(memdc);
|
||||
|
||||
// Under MSW, this wxDC should work even without any valid font -- but
|
||||
// this is not the case under wxGTK and probably neither elsewhere, so
|
||||
// restrict this test to that platform only.
|
||||
#ifdef __WXMSW__
|
||||
memdc.SetFont(wxNullFont);
|
||||
GetTextExtentTester(memdc);
|
||||
#endif // __WXMSW__
|
||||
}
|
||||
|
||||
#if wxUSE_PRINTING_ARCHITECTURE && wxUSE_POSTSCRIPT
|
||||
TEST_CASE("wxPostScriptDC::GetTextExtent", "[psdc][text-extent]")
|
||||
{
|
||||
wxPostScriptDC psdc;
|
||||
// wxPostScriptDC doesn't have any font set by default but its
|
||||
// GetTextExtent() requires one to be set. This is probably a bug and we
|
||||
// should set the default font in it implicitly but for now just work
|
||||
// around it.
|
||||
psdc.SetFont(*wxNORMAL_FONT);
|
||||
GetTextExtentTester(psdc);
|
||||
}
|
||||
#endif // wxUSE_POSTSCRIPT
|
||||
|
||||
#if wxUSE_ENH_METAFILE
|
||||
TEST_CASE("wxEnhMetaFileDC::GetTextExtent", "[emfdc][text-extent]")
|
||||
{
|
||||
wxEnhMetaFileDC metadc;
|
||||
GetTextExtentTester(metadc);
|
||||
}
|
||||
#endif // wxUSE_ENH_METAFILE
|
||||
|
||||
TEST_CASE("wxDC::LeadingAndDescent", "[dc][text-extent]")
|
||||
{
|
||||
wxClientDC dc(wxTheApp->GetTopWindow());
|
||||
|
||||
// Retrieving just the descent should work.
|
||||
int descent = -17;
|
||||
dc.GetTextExtent("foo", nullptr, nullptr, &descent);
|
||||
CHECK( descent != -17 );
|
||||
|
||||
// Same for external leading.
|
||||
int leading = -289;
|
||||
dc.GetTextExtent("foo", nullptr, nullptr, nullptr, &leading);
|
||||
CHECK( leading != -289 );
|
||||
|
||||
// And both should also work for the empty string as they retrieve the
|
||||
// values valid for the entire font and not just this string.
|
||||
int descent2,
|
||||
leading2;
|
||||
dc.GetTextExtent("", nullptr, nullptr, &descent2, &leading2);
|
||||
|
||||
CHECK( descent2 == descent );
|
||||
CHECK( leading2 == leading );
|
||||
}
|
||||
|
||||
TEST_CASE("wxWindow::GetTextExtent", "[window][text-extent]")
|
||||
{
|
||||
wxWindow* const win = wxTheApp->GetTopWindow();
|
||||
|
||||
GetTextExtentTester(*win);
|
||||
}
|
||||
|
||||
TEST_CASE("wxDC::GetPartialTextExtent", "[dc][text-extent][partial]")
|
||||
{
|
||||
wxClientDC dc(wxTheApp->GetTopWindow());
|
||||
|
||||
wxArrayInt widths;
|
||||
REQUIRE( dc.GetPartialTextExtents("Hello", widths) );
|
||||
REQUIRE( widths.size() == 5 );
|
||||
CHECK( widths[0] == dc.GetTextExtent("H").x );
|
||||
#ifdef __WXQT__
|
||||
// Skip test which work locally, but not when run on GitHub CI
|
||||
if ( IsAutomaticTest() )
|
||||
return;
|
||||
#endif
|
||||
CHECK( widths[4] == dc.GetTextExtent("Hello").x );
|
||||
}
|
||||
|
||||
#ifdef TEST_GC
|
||||
|
||||
TEST_CASE("wxGC::GetTextExtent", "[dc][text-extent]")
|
||||
{
|
||||
wxGraphicsRenderer* renderer = wxGraphicsRenderer::GetDefaultRenderer();
|
||||
REQUIRE(renderer);
|
||||
wxGraphicsContext* context = renderer->CreateMeasuringContext();
|
||||
REQUIRE(context);
|
||||
wxFont font(12, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
||||
REQUIRE(font.IsOk());
|
||||
context->SetFont(font, *wxBLACK);
|
||||
double width, height, descent, externalLeading = 0.0;
|
||||
context->GetTextExtent("x", &width, &height, &descent, &externalLeading);
|
||||
delete context;
|
||||
|
||||
// TODO: Determine a way to make these tests more robust.
|
||||
CHECK(width > 0.0);
|
||||
CHECK(height > 0.0);
|
||||
}
|
||||
|
||||
#endif // TEST_GC
|
||||
Reference in New Issue
Block a user