Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[symbols] Fix marker symbol bounds incorrectly include bounds of
disabled symbol layers

(cherry picked from commit ca54e8f)
  • Loading branch information
nyalldawson committed Jun 21, 2021
1 parent 350d7c0 commit 7f91c00
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/core/symbology/qgssymbol.cpp
Expand Up @@ -1965,6 +1965,10 @@ QRectF QgsMarkerSymbol::bounds( QPointF point, QgsRenderContext &context, const
{
if ( layer->type() == QgsSymbol::Marker )
{
if ( !layer->enabled()
|| ( layer->dataDefinedProperties().hasActiveProperties() && !layer->dataDefinedProperties().valueAsBool( QgsSymbolLayer::PropertyLayerEnabled, context.expressionContext(), true ) ) )
continue;

QgsMarkerSymbolLayer *symbolLayer = static_cast< QgsMarkerSymbolLayer * >( layer );
if ( bound.isNull() )
bound = symbolLayer->bounds( point, symbolContext );
Expand Down
78 changes: 77 additions & 1 deletion tests/src/python/test_qgssymbol.py
Expand Up @@ -54,7 +54,10 @@
QgsReadWriteContext,
QgsSymbolLayerUtils,
QgsMarkerLineSymbolLayer,
QgsSymbol
QgsSymbol,
Qgis,
QgsSymbolLayer,
QgsProperty
)

from qgis.testing import unittest, start_app
Expand Down Expand Up @@ -820,6 +823,79 @@ def testSizeMapUnitScale(self):
self.assertEqual(markerSymbol.symbolLayer(1).sizeMapUnitScale(), QgsMapUnitScale(3000, 4000))
self.assertEqual(markerSymbol.symbolLayer(2).sizeMapUnitScale(), QgsMapUnitScale(3000, 4000))

def testBoundDisabledSymbolLayer(self):
# test calculating symbol bounds with a disabled symbol layer
s = QgsMarkerSymbol()
s.deleteSymbolLayer(0)
s.appendSymbolLayer(
QgsSimpleMarkerSymbolLayer(size=10, color=QColor(255, 255, 0)))
s[0].setStrokeStyle(Qt.NoPen)

# larger layer, but disabled. Should not be considered in the bounds
s.appendSymbolLayer(
QgsSimpleMarkerSymbolLayer(size=20, color=QColor(255, 255, 0)))
s[1].setStrokeStyle(Qt.NoPen)
s[1].setEnabled(False)

g = QgsGeometry.fromWkt('Point(1 1)')
rendered_image = self.renderGeometry(s, g, QgsMapSettings.DrawSymbolBounds)
self.assertTrue(self.imageCheck('marker_bounds_layer_disabled', 'marker_bounds_layer_disabled', rendered_image))

# with data defined visibility
s[1].setEnabled(True)
s[1].setDataDefinedProperty(QgsSymbolLayer.PropertyLayerEnabled, QgsProperty.fromExpression('false'))
rendered_image = self.renderGeometry(s, g, QgsMapSettings.DrawSymbolBounds)
self.assertTrue(self.imageCheck('marker_bounds_layer_disabled', 'marker_bounds_layer_disabled', rendered_image))

def renderGeometry(self, symbol, geom, flags=QgsMapSettings.Flags()):
f = QgsFeature()
f.setGeometry(geom)

image = QImage(200, 200, QImage.Format_RGB32)

painter = QPainter()
ms = QgsMapSettings()
if flags:
ms.setFlags(flags)
extent = geom.get().boundingBox()
# buffer extent by 10%
if extent.width() > 0:
extent = extent.buffered((extent.height() + extent.width()) / 20.0)
else:
extent = extent.buffered(10)

ms.setExtent(extent)
ms.setOutputSize(image.size())
context = QgsRenderContext.fromMapSettings(ms)
context.setPainter(painter)
context.setScaleFactor(96 / 25.4) # 96 DPI

painter.begin(image)
try:
image.fill(QColor(0, 0, 0))
symbol.startRender(context)
symbol.renderFeature(f, context)
symbol.stopRender(context)
finally:
painter.end()

return image

def imageCheck(self, name, reference_image, image):
self.report += "<h2>Render {}</h2>\n".format(name)
temp_dir = QDir.tempPath() + '/'
file_name = temp_dir + 'symbol_' + name + ".png"
image.save(file_name, "PNG")
checker = QgsRenderChecker()
checker.setControlPathPrefix("symbol")
checker.setControlName("expected_" + reference_image)
checker.setRenderedImage(file_name)
checker.setColorTolerance(2)
result = checker.compareImages(name, 20)
self.report += checker.report()
print((self.report))
return result


class TestQgsLineSymbol(unittest.TestCase):

Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 7f91c00

Please sign in to comment.