This allows to distinguish the results of the same renderer (e.g. GDI+-based one) on the different OS versions (because GDI+ produces different results under XP and Windows 8). Closes #16260. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76554 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			280 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			9.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // Name:        tests/graphics/drawing.cpp
 | |
| // Purpose:     Tests for wxGraphicsContent general drawing
 | |
| // Author:      Armel Asselin
 | |
| // Created:     2014-02-21
 | |
| // Copyright:   (c) 2014 Ellié Computing <opensource@elliecomputing.com>
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // headers
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| #include "testprec.h"
 | |
| #ifdef __BORLANDC__
 | |
|     #pragma hdrstop
 | |
| #endif
 | |
| 
 | |
| #include "drawing.h"
 | |
| 
 | |
| #if wxUSE_TEST_GC_DRAWING
 | |
| 
 | |
| #include "wx/image.h"
 | |
| #include "wx/wfstream.h"
 | |
| #include "wx/stdpaths.h"
 | |
| #include "wx/scopeguard.h"
 | |
| 
 | |
| #include "testimagefile.h"
 | |
| 
 | |
| #include <stdexcept>
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // test class
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| //// ORGANIZATION /////////////////////////////////////////////////////////////
 | |
| 
 | |
| // This test suite is organized around two axes:
 | |
| // - drawing test cases
 | |
| // - drawing contexts life cycle
 | |
| // => each drawing test case represent a serie of drawing primitives to execute
 | |
| //  for whichever context
 | |
| // => each drawing context life cycle represent a particular class of
 | |
| //  wxGraphicsContext and a way to create, dispose of and save it so that it is
 | |
| //  possible to compare it with a reference file
 | |
| 
 | |
| // A plugin system is implemented to let developers of contributed libraries
 | |
| // test their library without the need to impact the test system and its
 | |
| // dependencies. See RunPluginsDrawingCase.
 | |
| 
 | |
| // The crossing of drawing case and life cycles is implemented by
 | |
| // RunIndividualDrawingCase
 | |
| 
 | |
| // The CPPUNIT test case class present a test per drawing case per life cycle
 | |
| // so that it is easy to run a particular test
 | |
| 
 | |
| // The test requires reference files and must produce them when an
 | |
| // implementation changed and new good references are known to be produced.
 | |
| // Environment variables control where reference files are located and when to
 | |
| // produce them:
 | |
| //  - WX_TEST_SUITE_BUILD_REFERENCE must be "1" to request production of
 | |
| //      reference files (by default only testing is done)
 | |
| //  - WX_TEST_SUITE_REFERENCE_DIR must be a path to a directory containing the
 | |
| //      sub-directory "gcdrawing-references" (by default the parent directory
 | |
| //      of the directory of the test program is used)
 | |
| 
 | |
| //// WRITING NEW TEST CASES
 | |
| 
 | |
| // - add a new function to realize the drawing in the "cases functions" section
 | |
| // - add a case structure declaration for it in the "test cases" section
 | |
| // - use drawingbasic.cpp as a sample to add your own test case implementation
 | |
| 
 | |
| //// WRITING NEW FACTORIES
 | |
| 
 | |
| // - if the wxGraphicsContext is a class built-in wxWidgets, add a
 | |
| //      DrawingTestGCFactory derived sub-class in drawing.h header
 | |
| //      together with a declaration for it and its implementation
 | |
| //      can be placed in drawing.cpp
 | |
| //      Once this is done duplicate all the CPP UNIT test functions
 | |
| //      and entries "DrawToImage_YYY" to your new GC "DrawTo<newGc>_YYYY"
 | |
| //
 | |
| // - if it is not built-in (contributed library/wxCode...), make a plugin for it
 | |
| //      test.bkl contains a sample "test_drawingplugin" target, you can use
 | |
| //      drawingplgsample.cpp as a start, see RunPluginsDrawingCase declaration
 | |
| //      for information about how to run the tests
 | |
| 
 | |
| wxString GraphicsContextDrawingTestCase::ms_referenceDirectory;
 | |
| bool GraphicsContextDrawingTestCase::ms_buildReference;
 | |
| bool GraphicsContextDrawingTestCase::ms_buildReferenceDetermined;
 | |
| GraphicsContextDrawingTestCase::ImageGraphicsContextLifeCycle
 | |
|     GraphicsContextDrawingTestCase::ms_imageLifeCycle;
 | |
| 
 | |
| #if wxUSE_SVG
 | |
|     GraphicsContextDrawingTestCase::SvgGraphicsContextLifeCycle
 | |
|         GraphicsContextDrawingTestCase::ms_svgLifeCycle;
 | |
| #endif // wxUSE_SVG
 | |
| 
 | |
| // register in the unnamed registry so that these tests are run by default
 | |
| CPPUNIT_TEST_SUITE_REGISTRATION( GraphicsContextDrawingTestCase );
 | |
| 
 | |
| // also include in its own registry so that these tests can be run alone
 | |
| CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( GraphicsContextDrawingTestCase,
 | |
|     "GraphicsContextDrawingTestCase" );
 | |
| 
 | |
| // ----------------------------------------------------------------------------
 | |
| // tests themselves
 | |
| // ----------------------------------------------------------------------------
 | |
| 
 | |
| void GraphicsContextDrawingTestCase::RunIndividualDrawingCase (
 | |
|     DrawingTestGCFactory& gcFactory,
 | |
|     const DrawingTestCase & testCase)
 | |
| {
 | |
|     wxFileName fileName, refFileName;
 | |
|     wxString testsOutputDirectory = wxStandardPaths::Get().GetTempDir();
 | |
|     wxString refOutputDirectory = GetTestsReferenceDirectory();
 | |
| 
 | |
|     wxString platformTag;
 | |
|     if (!testCase.platformIndependent && !gcFactory.PlatformIndependent())
 | |
|         platformTag = wxString::Format("_%s", GetPlatformTag());
 | |
| 
 | |
|     fileName.Assign (testsOutputDirectory,
 | |
|         wxString::Format("image_test_%s%s_%d", gcFactory.GetIdForFileName(),
 | |
|                          platformTag, testCase.caseNumber),
 | |
|         gcFactory.GetExtensionForFileName());
 | |
| 
 | |
|     refFileName.Assign (refOutputDirectory,
 | |
|         wxString::Format("image_test_%s%s_%d_ref", gcFactory.GetIdForFileName(),
 | |
|                         platformTag, testCase.caseNumber),
 | |
|         gcFactory.GetExtensionForFileName());
 | |
| 
 | |
|     {
 | |
|         wxGraphicsContext *gc = NULL;
 | |
| 
 | |
|         wxON_BLOCK_EXIT_OBJ1(gcFactory, DrawingTestGCFactory::CleanUp, gc);
 | |
| 
 | |
|         gc = gcFactory.BuildNewContext(
 | |
|             wxSize(testCase.width, testCase.height),
 | |
|             testCase.pointsPerInch, fileName);
 | |
| 
 | |
|         (this->*testCase.m_drawingF)(gc);
 | |
| 
 | |
|         gcFactory.SaveBuiltContext(gc);
 | |
|     }
 | |
| 
 | |
|     if (GetBuildReference())
 | |
|     {
 | |
|          WX_ASSERT_MESSAGE(
 | |
|              ("Cannot copy file \"%s\" to \"%s\".",
 | |
|             fileName.GetFullPath(), refFileName.GetFullPath()),
 | |
|             wxCopyFile (fileName.GetFullPath(),
 | |
|                         refFileName.GetFullPath(), true));
 | |
|     }
 | |
|     else if (gcFactory.UseImageComparison())
 | |
|     {
 | |
|         WX_ASSERT_SAME_AS_IMAGE_FILE(fileName.GetFullPath(),
 | |
|                                      refFileName.GetFullPath());
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         WX_ASSERT_SAME_AS_FILE(fileName.GetFullPath(),
 | |
|                                refFileName.GetFullPath());
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| bool GraphicsContextDrawingTestCase::GetBuildReference() const
 | |
| {
 | |
|     if (!ms_buildReferenceDetermined)
 | |
|     {
 | |
|         wxString value;
 | |
|         if (wxGetEnv("WX_TEST_SUITE_BUILD_REFERENCE", &value))
 | |
|             ms_buildReference = value == "1";
 | |
|     }
 | |
|     return ms_buildReference;
 | |
| }
 | |
| 
 | |
| wxString GraphicsContextDrawingTestCase::GetTestsReferenceDirectory() const
 | |
| {
 | |
|     if (ms_referenceDirectory.empty())
 | |
|     {
 | |
|         wxFileName refDir;
 | |
| 
 | |
|         if ( !wxGetEnv("WX_TEST_SUITE_REFERENCE_DIR",
 | |
|                         &ms_referenceDirectory) )
 | |
|         {
 | |
|             refDir = wxFileName(wxStandardPaths::Get().GetExecutablePath());
 | |
|             refDir.RemoveLastDir();
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             refDir = wxFileName(ms_referenceDirectory, wxT(""));
 | |
|         }
 | |
|         refDir.AppendDir ("drawing");
 | |
|         refDir.AppendDir ("references");
 | |
|         ms_referenceDirectory = refDir.GetPath();
 | |
|     }
 | |
|     return ms_referenceDirectory;
 | |
| }
 | |
| 
 | |
| wxString GraphicsContextDrawingTestCase::GetPlatformTag() const
 | |
| {
 | |
|     // We consider that the platform tag is the kind of default renderer plus
 | |
|     // its major/minor versions.
 | |
|     // The reason why including major/minor version is important, is that the
 | |
|     // rendering engine typically evolves somewhat between two version
 | |
|     // (i.e. font rendering is not the same in Windows XP and Windows 8)
 | |
|     int major, minor;
 | |
|     const wxGraphicsRenderer *defaultRenderer = wxGraphicsRenderer::GetDefaultRenderer();
 | |
|     wxString rendererName = defaultRenderer->GetName();
 | |
|     defaultRenderer->GetVersion (&major, &minor);
 | |
| 
 | |
|     return wxString::Format("%s-%d.%d", rendererName, major, minor);
 | |
| }
 | |
| 
 | |
| ///////////////////////////////////////////////////////////////////////////////
 | |
| // BUILT-IN FACTORIES  ////////////////////////////////////////////////////////
 | |
| 
 | |
| wxGraphicsContext *
 | |
| GraphicsContextDrawingTestCase::ImageGraphicsContextLifeCycle::
 | |
|     BuildNewContext (wxSize expectedSize, double WXUNUSED(pointsPerInch),
 | |
|     const wxFileName &targetFileName)
 | |
| {
 | |
|     m_image = new wxImage (expectedSize);
 | |
|     m_image->InitAlpha();
 | |
| 
 | |
|     m_targetFileName = targetFileName.GetFullPath();
 | |
| 
 | |
|     // we should probably pass the number of points per inches somewhere...
 | |
|     //  but I don't see where yet...
 | |
|     return wxGraphicsContext::Create(*m_image);
 | |
| }
 | |
| 
 | |
| void
 | |
| GraphicsContextDrawingTestCase::ImageGraphicsContextLifeCycle::
 | |
|     SaveBuiltContext (wxGraphicsContext *&gc)
 | |
| {
 | |
|     wxDELETE(gc);
 | |
| 
 | |
|     m_image->SaveFile (m_targetFileName);
 | |
| }
 | |
| 
 | |
| void
 | |
| GraphicsContextDrawingTestCase::ImageGraphicsContextLifeCycle::
 | |
|     CleanUp (wxGraphicsContext *gc)
 | |
| {
 | |
|     delete gc;
 | |
|     m_targetFileName.clear();
 | |
|     wxDELETE(m_image);
 | |
| }
 | |
| 
 | |
| #if wxUSE_SVG
 | |
| wxGraphicsContext *
 | |
| GraphicsContextDrawingTestCase::SvgGraphicsContextLifeCycle::
 | |
|     BuildNewContext (wxSize WXUNUSED(expectedSize),
 | |
|     double WXUNUSED(pointsPerInch),
 | |
|     const wxFileName &WXUNUSED(targetFileName))
 | |
| {
 | |
|     m_svgFileDc = NULL;
 | |
|     //m_svg_file_dc = new wxSVGFileDC (target_file_name.GetFullPath(),
 | |
|     //    expected_size.GetWidth(), expected_size.GetHeight(), points_per_inch);
 | |
| 
 | |
|     // unfortunately cannot make GC over a DC yet :(
 | |
|     throw std::runtime_error("SVG as no wxGC interface yet");
 | |
| }
 | |
| 
 | |
| void
 | |
| GraphicsContextDrawingTestCase::SvgGraphicsContextLifeCycle::
 | |
|     SaveBuiltContext (wxGraphicsContext *&WXUNUSED(gc))
 | |
| {
 | |
| }
 | |
| 
 | |
| void
 | |
| GraphicsContextDrawingTestCase::SvgGraphicsContextLifeCycle::
 | |
|     CleanUp (wxGraphicsContext *WXUNUSED(gc))
 | |
| {
 | |
|     wxDELETE (m_svgFileDc);
 | |
| }
 | |
| #endif // wxUSE_SVG
 | |
| 
 | |
| #endif // wxUSE_TEST_GC_DRAWING
 |