Skip to content
Permalink
Browse files

Tweak logic regarding when a map item forces the whole layout

to be rasterised
  • Loading branch information
nyalldawson committed Dec 12, 2017
1 parent 261492d commit d3aee951ef13ae92de00f6598ad334e2a0dbb14e
@@ -377,6 +377,26 @@ bool QgsLayoutItemMap::containsWmsLayer() const
return false;
}

bool QgsLayoutItemMap::requiresRasterization() const
{
if ( QgsLayoutItem::requiresRasterization() )
return true;

// we MUST force the whole layout to render as a raster if any map item
// uses blend modes, and we are not drawing on a solid opaque background
// because in this case the map item needs to be rendered as a raster, but
// it also needs to interact with items below it
if ( !containsAdvancedEffects() )
return false;

// TODO layer transparency is probably ok to allow without forcing rasterization

if ( hasBackground() && qgsDoubleNear( backgroundColor().alphaF(), 1.0 ) )
return false;

return true;
}

bool QgsLayoutItemMap::containsAdvancedEffects() const
{
if ( QgsLayoutItem::containsAdvancedEffects() )
@@ -275,6 +275,7 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
//! Returns true if the map contains a WMS layer.
bool containsWmsLayer() const;

bool requiresRasterization() const override;
bool containsAdvancedEffects() const override;

/**
@@ -46,12 +46,12 @@ def make_item(self, layout):
else:
return self.createItem(layout)

def testContainsAdvancedEffects(self):
def testRequiresRasterization(self):
l = QgsLayout(QgsProject.instance())
item = self.make_item(l)
self.assertFalse(item.containsAdvancedEffects())
self.assertFalse(item.requiresRasterization())
item.setBlendMode(QPainter.CompositionMode_SourceIn)
self.assertTrue(item.containsAdvancedEffects())
self.assertTrue(item.requiresRasterization())


class TestQgsLayoutItem(unittest.TestCase):
@@ -16,9 +16,9 @@

import os

from qgis.PyQt.QtCore import QFileInfo, QRectF
from qgis.PyQt.QtCore import QFileInfo, QRectF, QDir
from qgis.PyQt.QtXml import QDomDocument
from qgis.PyQt.QtGui import QPainter
from qgis.PyQt.QtGui import QPainter, QColor

from qgis.core import (QgsLayoutItemMap,
QgsRectangle,
@@ -46,6 +46,14 @@ class TestQgsComposerMap(unittest.TestCase, LayoutItemTestCase):
def setUpClass(cls):
cls.item_class = QgsLayoutItemMap

def setUp(self):
self.report = "<h1>Python QgsLayoutItemMap Tests</h1>\n"

def tearDown(self):
report_file_path = "%s/qgistest.html" % QDir.tempPath()
with open(report_file_path, 'a') as report_file:
report_file.write(self.report)

def __init__(self, methodName):
"""Run once on class initialization."""
unittest.TestCase.__init__(self, methodName)
@@ -92,6 +100,7 @@ def testOverviewMap(self):
checker.setColorTolerance(6)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.layout.removeLayoutItem(overviewMap)
assert myTestResult, myMessage

@@ -111,6 +120,7 @@ def testOverviewMapBlend(self):
checker = QgsLayoutChecker('composermap_overview_blending', self.layout)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.layout.removeLayoutItem(overviewMap)
assert myTestResult, myMessage

@@ -130,6 +140,7 @@ def testOverviewMapInvert(self):
checker = QgsLayoutChecker('composermap_overview_invert', self.layout)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.layout.removeLayoutItem(overviewMap)
assert myTestResult, myMessage

@@ -150,6 +161,7 @@ def testOverviewMapCenter(self):
checker = QgsLayoutChecker('composermap_overview_center', self.layout)
checker.setControlPathPrefix("composer_mapoverview")
myTestResult, myMessage = checker.testLayout()
self.report += checker.report()
self.layout.removeLayoutItem(overviewMap)
assert myTestResult, myMessage

@@ -181,6 +193,7 @@ def testMapCrs(self):
checker = QgsLayoutChecker('composermap_crs3857', layout)
checker.setControlPathPrefix("composer_map")
result, message = checker.testLayout()
self.report += checker.report()
self.assertTrue(result, message)

# overwrite CRS
@@ -192,6 +205,7 @@ def testMapCrs(self):
checker = QgsLayoutChecker('composermap_crs4326', layout)
checker.setControlPathPrefix("composer_map")
result, message = checker.testLayout()
self.report += checker.report()
self.assertTrue(result, message)

# change back to project CRS
@@ -222,6 +236,37 @@ def testuniqueId(self):
myMessage = 'old: %s new: %s' % (oldId, newId)
assert oldId != newId, myMessage

def testContainsAdvancedEffects(self):
map_settings = QgsMapSettings()
map_settings.setLayers([self.vector_layer])
layout = QgsLayout(QgsProject.instance())
map = QgsLayoutItemMap(layout)

self.assertFalse(map.containsAdvancedEffects())
self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
result = map.containsAdvancedEffects()
self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)
self.assertTrue(result)

def testRasterization(self):
map_settings = QgsMapSettings()
map_settings.setLayers([self.vector_layer])
layout = QgsLayout(QgsProject.instance())
map = QgsLayoutItemMap(layout)

self.assertFalse(map.requiresRasterization())
self.vector_layer.setBlendMode(QPainter.CompositionMode_Darken)
self.assertFalse(map.requiresRasterization())
self.assertTrue(map.containsAdvancedEffects())

map.setBackgroundEnabled(False)
self.assertTrue(map.requiresRasterization())
map.setBackgroundEnabled(True)
map.setBackgroundColor(QColor(1, 1, 1, 1))
self.assertTrue(map.requiresRasterization())

self.vector_layer.setBlendMode(QPainter.CompositionMode_SourceOver)

def testWorldFileGeneration(self):
return
myRectangle = QgsRectangle(781662.375, 3339523.125, 793062.375, 3345223.125)

0 comments on commit d3aee95

Please sign in to comment.
You can’t perform that action at this time.