QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsmasksymbollayer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmasksymbollayer.cpp
3 ---------------------
4 begin : July 2019
5 copyright : (C) 2019 by Hugo Mercier
6 email : hugo dot mercier at oslandia dot com
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 "qgsmasksymbollayer.h"
17#include "qgspainteffect.h"
18#include "qgspainterswapper.h"
19#include "qgsmarkersymbol.h"
21
23{
24 mSymbol.reset( static_cast<QgsMarkerSymbol *>( QgsMarkerSymbol::createSimple( QVariantMap() ) ) );
25}
26
28
30{
31 return !mMaskedSymbolLayers.isEmpty();
32}
33
35{
36 if ( symbol && symbol->type() == Qgis::SymbolType::Marker )
37 {
38 mSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
39 return true;
40 }
41 delete symbol;
42 return false;
43}
44
46{
48
50
51 if ( props.contains( QStringLiteral( "mask_symbollayers" ) ) )
52 {
53 l->setMasks( stringToSymbolLayerReferenceList( props[QStringLiteral( "mask_symbollayers" )].toString() ) );
54 }
55 return l;
56}
57
59{
61 l->setSubSymbol( mSymbol->clone() );
62 l->setMasks( mMaskedSymbolLayers );
64 copyPaintEffect( l );
65 return l;
66}
67
69{
70 return mSymbol.get();
71}
72
74{
75 return QStringLiteral( "MaskMarker" );
76}
77
79{
80 QVariantMap props;
81 props[QStringLiteral( "mask_symbollayers" )] = symbolLayerReferenceListToString( masks() );
82 return props;
83}
84
86{
87 QSet<QString> attributes = QgsMarkerSymbolLayer::usedAttributes( context );
88
89 attributes.unite( mSymbol->usedAttributes( context ) );
90
91 return attributes;
92}
93
95{
97 return true;
98 if ( mSymbol && mSymbol->hasDataDefinedProperties() )
99 return true;
100 return false;
101}
102
104{
105 // since we need to swap the regular painter with the mask painter during rendering,
106 // effects won't work. So we cheat by handling effects ourselves in renderPoint
107 if ( auto *lPaintEffect = paintEffect() )
108 {
109 mEffect.reset( lPaintEffect->clone() );
110 setPaintEffect( nullptr );
111 }
112 mSymbol->startRender( context.renderContext() );
113}
114
116{
117 mSymbol->stopRender( context.renderContext() );
118 if ( mEffect )
119 {
120 setPaintEffect( mEffect.release() );
121 }
122}
123
125{
127}
128
129QList<QgsSymbolLayerReference> QgsMaskMarkerSymbolLayer::masks() const
130{
131 return mMaskedSymbolLayers;
132}
133
134void QgsMaskMarkerSymbolLayer::setMasks( const QList<QgsSymbolLayerReference> &maskedLayers )
135{
136 mMaskedSymbolLayers = maskedLayers;
137}
138
140{
141 return mSymbol->bounds( point, context.renderContext() );
142}
143
145{
147 || ( mSymbol && mSymbol->usesMapUnits() );
148}
149
151{
153 if ( mSymbol )
154 mSymbol->setOutputUnit( unit );
155}
156
158{
159 return QColor();
160}
161
163{
164 QgsRenderContext &renderContext = context.renderContext();
165 if ( !renderContext.painter() )
166 return;
167
168 if ( renderContext.isGuiPreview() )
169 {
170 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
171 return;
172 }
173
174 if ( !renderContext.maskPainter() )
175 return;
176
177 if ( mMaskedSymbolLayers.isEmpty() )
178 return;
179
180 // Otherwise switch to the mask painter before rendering
181 const QgsPainterSwapper swapper( renderContext, renderContext.maskPainter() );
182
183 // Special case when an effect is defined on this mask symbol layer
184 // (effects defined on sub symbol's layers do not need special handling)
185 if ( mEffect && mEffect->enabled() )
186 {
187 QgsEffectPainter p( renderContext );
188 // translate operates on the mask painter, which is what we want
189 p->translate( point );
190 p.setEffect( mEffect.get() );
191 mSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
192 // the translation will be canceled at the end of scope here
193 }
194 else
195 {
196 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
197 }
198}
RenderUnit
Rendering size units.
Definition: qgis.h:4255
@ MapUnits
Map units.
@ MetersInMapUnits
Meters value as Map units.
@ Marker
Marker symbol.
A class to manager painter saving and restoring required for effect drawing.
void setEffect(QgsPaintEffect *effect)
Sets the effect to be painted.
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
double size() const
Returns the symbol size.
Qgis::RenderUnit mSizeUnit
Marker size unit.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
A marker symbol type, for rendering Point and MultiPoint geometries.
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Special symbol layer that uses its sub symbol as a selective mask.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Create a new QgsMaskMarkerSymbolLayer.
void setMasks(const QList< QgsSymbolLayerReference > &maskedLayers)
Sets the symbol layers that will be masked by the sub symbol's shape.
QColor color() const override
Returns the "representative" color of the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QgsMaskMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QString layerType() const override
Returns a string that represents this layer type.
bool enabled() const
Whether some masked symbol layers are defined.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
~QgsMaskMarkerSymbolLayer() override
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
QList< QgsSymbolLayerReference > masks() const override
Returns a list of references to symbol layers that are masked by the sub symbol's shape.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
QgsMaskMarkerSymbolLayer()
Simple constructor.
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
A class to manage painter saving and restoring required for drawing on a different painter (mask pain...
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
bool isGuiPreview() const
Returns the Gui preview mode.
QPainter * maskPainter(int id=0)
Returns a mask QPainter for the render operation.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:94
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:156
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utilitary function to turn a QgsSymbolLayerReferenceList into a string.
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utilitary function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbo...