QGIS API Documentation 3.27.0-Master (1d7a28cfd2)
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 "qgssymbollayerutils.h"
18#include "qgsproject.h"
19#include "qgsvectorlayer.h"
20#include "qgspainteffect.h"
21#include "qgspainterswapper.h"
22#include "qgsmarkersymbol.h"
25#include "qgsmaskpaintdevice.h"
26
28{
29 mSymbol.reset( static_cast<QgsMarkerSymbol *>( QgsMarkerSymbol::createSimple( QVariantMap() ) ) );
30}
31
33
35{
36 return !mMaskedSymbolLayers.isEmpty();
37}
38
40{
41 if ( symbol && symbol->type() == Qgis::SymbolType::Marker )
42 {
43 mSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
44 return true;
45 }
46 delete symbol;
47 return false;
48}
49
51{
53
55
56 if ( props.contains( QStringLiteral( "mask_symbollayers" ) ) )
57 {
58 l->setMasks( stringToSymbolLayerReferenceList( props[QStringLiteral( "mask_symbollayers" )].toString() ) );
59 }
60 return l;
61}
62
64{
66 l->setSubSymbol( mSymbol->clone() );
67 l->setMasks( mMaskedSymbolLayers );
69 copyPaintEffect( l );
70 return l;
71}
72
74{
75 return mSymbol.get();
76}
77
79{
80 return QStringLiteral( "MaskMarker" );
81}
82
84{
85 QVariantMap props;
86 props[QStringLiteral( "mask_symbollayers" )] = symbolLayerReferenceListToString( masks() );
87 return props;
88}
89
91{
92 QSet<QString> attributes = QgsMarkerSymbolLayer::usedAttributes( context );
93
94 attributes.unite( mSymbol->usedAttributes( context ) );
95
96 return attributes;
97}
98
100{
102 return true;
103 if ( mSymbol && mSymbol->hasDataDefinedProperties() )
104 return true;
105 return false;
106}
107
109{
110 // since we need to swap the regular painter with the mask painter during rendering,
111 // effects won't work. So we cheat by handling effects ourselves in renderPoint
112 if ( auto *lPaintEffect = paintEffect() )
113 {
114 mEffect.reset( lPaintEffect->clone() );
115 setPaintEffect( nullptr );
116 }
117 mSymbol->startRender( context.renderContext() );
118}
119
121{
122 mSymbol->stopRender( context.renderContext() );
123 if ( mEffect )
124 {
125 setPaintEffect( mEffect.release() );
126 }
127}
128
130{
132}
133
134QList<QgsSymbolLayerReference> QgsMaskMarkerSymbolLayer::masks() const
135{
136 return mMaskedSymbolLayers;
137}
138
139void QgsMaskMarkerSymbolLayer::setMasks( const QList<QgsSymbolLayerReference> &maskedLayers )
140{
141 mMaskedSymbolLayers = maskedLayers;
142}
143
145{
146 return mSymbol->bounds( point, context.renderContext() );
147}
148
150{
152 || ( mSymbol && mSymbol->usesMapUnits() );
153}
154
156{
158 if ( mSymbol )
159 mSymbol->setOutputUnit( unit );
160}
161
163{
164 return QColor();
165}
166
168{
169 QgsRenderContext &renderContext = context.renderContext();
170 if ( !renderContext.painter() )
171 return;
172
173 if ( renderContext.isGuiPreview() )
174 {
175 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
176 return;
177 }
178
179 if ( !renderContext.maskPainter() )
180 return;
181
182 if ( mMaskedSymbolLayers.isEmpty() )
183 return;
184
185 // Otherwise switch to the mask painter before rendering
186 const QgsPainterSwapper swapper( renderContext, renderContext.maskPainter() );
187
188 // Special case when an effect is defined on this mask symbol layer
189 // (effects defined on sub symbol's layers do not need special handling)
190 if ( mEffect && mEffect->enabled() )
191 {
192 QgsEffectPainter p( renderContext );
193 // translate operates on the mask painter, which is what we want
194 p->translate( point );
195 p.setEffect( mEffect.get() );
196 mSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
197 // the translation will be canceled at the end of scope here
198 }
199 else
200 {
201 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
202 }
203}
@ 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
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
double size() const
Returns the symbol size.
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
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.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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.
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:93
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:168
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
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...