Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmultirenderchecker.cpp 3 : : -------------------------------------- 4 : : Date : 6.11.2014 5 : : Copyright : (C) 2014 Matthias Kuhn 6 : : Email : matthias at opengis dot ch 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #include "qgsmultirenderchecker.h" 17 : : #include "qgslayout.h" 18 : : #include <QDebug> 19 : : 20 : 0 : void QgsMultiRenderChecker::setControlName( const QString &name ) 21 : : { 22 : 0 : mControlName = name; 23 : 0 : } 24 : : 25 : 0 : void QgsMultiRenderChecker::setControlPathPrefix( const QString &prefix ) 26 : : { 27 : 0 : mControlPathPrefix = prefix; 28 : 0 : } 29 : : 30 : 0 : void QgsMultiRenderChecker::setMapSettings( const QgsMapSettings &mapSettings ) 31 : : { 32 : 0 : mMapSettings = mapSettings; 33 : 0 : } 34 : : 35 : 0 : bool QgsMultiRenderChecker::runTest( const QString &testName, unsigned int mismatchCount ) 36 : : { 37 : 0 : bool successful = false; 38 : : 39 : 0 : const QString baseDir = controlImagePath(); 40 : : 41 : 0 : QStringList subDirs = QDir( baseDir ).entryList( QDir::Dirs | QDir::NoDotAndDotDot ); 42 : : 43 : 0 : if ( subDirs.isEmpty() ) 44 : : { 45 : 0 : subDirs << QString(); 46 : 0 : } 47 : : 48 : 0 : QVector<QgsDartMeasurement> dartMeasurements; 49 : : 50 : 0 : for ( const QString &suffix : std::as_const( subDirs ) ) 51 : : { 52 : 0 : if ( subDirs.count() > 1 ) 53 : : { 54 : 0 : qDebug() << "Checking subdir " << suffix; 55 : 0 : } 56 : : bool result; 57 : 0 : QgsRenderChecker checker; 58 : 0 : checker.enableDashBuffering( true ); 59 : 0 : checker.setColorTolerance( mColorTolerance ); 60 : 0 : checker.setSizeTolerance( mMaxSizeDifferenceX, mMaxSizeDifferenceY ); 61 : 0 : checker.setControlPathPrefix( mControlPathPrefix ); 62 : 0 : checker.setControlPathSuffix( suffix ); 63 : 0 : checker.setControlName( mControlName ); 64 : 0 : checker.setMapSettings( mMapSettings ); 65 : : 66 : 0 : if ( !mRenderedImage.isNull() ) 67 : : { 68 : 0 : checker.setRenderedImage( mRenderedImage ); 69 : 0 : result = checker.compareImages( testName, mismatchCount, mRenderedImage ); 70 : 0 : } 71 : : else 72 : : { 73 : 0 : result = checker.runTest( testName, mismatchCount ); 74 : 0 : mRenderedImage = checker.renderedImage(); 75 : : } 76 : : 77 : 0 : successful |= result; 78 : : 79 : 0 : dartMeasurements << checker.dartMeasurements(); 80 : : 81 : 0 : mReport += checker.report(); 82 : 0 : } 83 : : 84 : 0 : if ( !successful ) 85 : : { 86 : 0 : const auto constDartMeasurements = dartMeasurements; 87 : 0 : for ( const QgsDartMeasurement &measurement : constDartMeasurements ) 88 : 0 : measurement.send(); 89 : : 90 : 0 : QgsDartMeasurement msg( QStringLiteral( "Image not accepted by test" ), QgsDartMeasurement::Text, "This may be caused because the test is supposed to fail or rendering inconsistencies." 91 : : "If this is a rendering inconsistency, please add another control image folder, add an anomaly image or increase the color tolerance." ); 92 : 0 : msg.send(); 93 : 0 : } 94 : : 95 : 0 : return successful; 96 : 0 : } 97 : : 98 : 0 : QString QgsMultiRenderChecker::controlImagePath() const 99 : : { 100 : 0 : QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt 101 : 0 : QString myControlImageDir = myDataDir + QDir::separator() + "control_images" + 102 : 0 : QDir::separator() + mControlPathPrefix + QDir::separator() + mControlName + QDir::separator(); 103 : 0 : return myControlImageDir; 104 : 0 : } 105 : : 106 : : // 107 : : // QgsLayoutChecker 108 : : // 109 : : 110 : : ///@cond PRIVATE 111 : : 112 : 0 : QgsLayoutChecker::QgsLayoutChecker( const QString &testName, QgsLayout *layout ) 113 : 0 : : mTestName( testName ) 114 : 0 : , mLayout( layout ) 115 : 0 : , mSize( 1122, 794 ) 116 : 0 : , mDotsPerMeter( 96 / 25.4 * 1000 ) 117 : 0 : { 118 : : // Qt has some slight render inconsistencies on the whole image sometimes 119 : 0 : setColorTolerance( 5 ); 120 : 0 : } 121 : : 122 : 0 : bool QgsLayoutChecker::testLayout( QString &checkedReport, int page, int pixelDiff, bool createReferenceImage ) 123 : : { 124 : : #ifdef QT_NO_PRINTER 125 : : return false; 126 : : #else 127 : 0 : if ( !mLayout ) 128 : : { 129 : 0 : return false; 130 : : } 131 : : 132 : 0 : setControlName( "expected_" + mTestName ); 133 : : 134 : : 135 : 0 : if ( createReferenceImage ) 136 : : { 137 : : //fake mode to generate expected image 138 : : //assume 96 dpi 139 : : 140 : : 141 : 0 : QImage _outputImage( mSize, QImage::Format_RGB32 ); 142 : 0 : _outputImage.setDotsPerMeterX( 96 / 25.4 * 1000 ); 143 : 0 : _outputImage.setDotsPerMeterY( 96 / 25.4 * 1000 ); 144 : 0 : QPainter _p( &_outputImage ); 145 : 0 : QgsLayoutExporter _exporter( mLayout ); 146 : 0 : _exporter.renderPage( &_p, page ); 147 : 0 : _p.end(); 148 : : 149 : 0 : if ( ! QDir( controlImagePath() ).exists() ) 150 : : { 151 : 0 : QDir().mkdir( controlImagePath() ); 152 : 0 : } 153 : 0 : _outputImage.save( controlImagePath() + QDir::separator() + "expected_" + mTestName + ".png", "PNG" ); 154 : 0 : qDebug( ) << "Reference image saved to : " + controlImagePath() + QDir::separator() + "expected_" + mTestName + ".png"; 155 : : 156 : 0 : } 157 : : 158 : 0 : QImage outputImage( mSize, QImage::Format_RGB32 ); 159 : 0 : outputImage.setDotsPerMeterX( mDotsPerMeter ); 160 : 0 : outputImage.setDotsPerMeterY( mDotsPerMeter ); 161 : 0 : drawBackground( &outputImage ); 162 : 0 : QPainter p( &outputImage ); 163 : 0 : QgsLayoutExporter exporter( mLayout ); 164 : 0 : exporter.renderPage( &p, page ); 165 : 0 : p.end(); 166 : : 167 : 0 : QString renderedFilePath = QDir::tempPath() + '/' + QFileInfo( mTestName ).baseName() + "_rendered.png"; 168 : 0 : outputImage.save( renderedFilePath, "PNG" ); 169 : : 170 : 0 : setRenderedImage( renderedFilePath ); 171 : : 172 : 0 : bool testResult = runTest( mTestName, pixelDiff ); 173 : : 174 : 0 : checkedReport += report(); 175 : : 176 : 0 : return testResult; 177 : : #endif // QT_NO_PRINTER 178 : 0 : } 179 : : 180 : : 181 : : 182 : : ///@endcond