QGIS API Documentation 3.99.0-Master (21b3aa880ba)
Loading...
Searching...
No Matches
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
18#include "qgsmarkersymbol.h"
19#include "qgspainteffect.h"
20#include "qgspainterswapper.h"
22
27
29
30bool QgsMaskMarkerSymbolLayer::enabled() const // cppcheck-suppress duplInheritedMember
31{
32 return !mMaskedSymbolLayers.isEmpty();
33}
34
36{
37 if ( symbol && symbol->type() == Qgis::SymbolType::Marker )
38 {
39 mSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
40 return true;
41 }
42 delete symbol;
43 return false;
44}
45
47{
49
50 l->setSubSymbol( QgsMarkerSymbol::createSimple( props ).release() );
51
52 if ( props.contains( QStringLiteral( "mask_symbollayers" ) ) )
53 {
54 l->setMasks( stringToSymbolLayerReferenceList( props[QStringLiteral( "mask_symbollayers" )].toString() ) );
55 }
56 return l;
57}
58
60{
62 l->setSubSymbol( mSymbol->clone() );
63 l->setMasks( mMaskedSymbolLayers );
65 copyPaintEffect( l );
66 return l;
67}
68
70{
71 return mSymbol.get();
72}
73
75{
76 return QStringLiteral( "MaskMarker" );
77}
78
80{
81 QVariantMap props;
82 props[QStringLiteral( "mask_symbollayers" )] = symbolLayerReferenceListToString( masks() );
83 return props;
84}
85
87{
88 QSet<QString> attributes = QgsMarkerSymbolLayer::usedAttributes( context );
89
90 attributes.unite( mSymbol->usedAttributes( context ) );
91
92 return attributes;
93}
94
96{
98 return true;
99 if ( mSymbol && mSymbol->hasDataDefinedProperties() )
100 return true;
101 return false;
102}
103
105{
106 // since we need to swap the regular painter with the mask painter during rendering,
107 // effects won't work. So we cheat by handling effects ourselves in renderPoint
108 if ( auto *lPaintEffect = paintEffect() )
109 {
110 mEffect.reset( lPaintEffect->clone() );
111 setPaintEffect( nullptr );
112 }
113 mSymbol->startRender( context.renderContext() );
114}
115
117{
118 mSymbol->stopRender( context.renderContext() );
119 if ( mEffect )
120 {
121 setPaintEffect( mEffect.release() );
122 }
123}
124
129
130QList<QgsSymbolLayerReference> QgsMaskMarkerSymbolLayer::masks() const
131{
132 return mMaskedSymbolLayers;
133}
134
135void QgsMaskMarkerSymbolLayer::setMasks( const QList<QgsSymbolLayerReference> &maskedLayers )
136{
137 mMaskedSymbolLayers = maskedLayers;
138}
139
141{
142 mMaskedSymbolLayers.clear();
143}
144
146{
147 return mSymbol->bounds( point, context.renderContext() );
148}
149
151{
153 || ( mSymbol && mSymbol->usesMapUnits() );
154}
155
157{
159 if ( mSymbol )
160 mSymbol->setOutputUnit( unit );
161}
162
164{
165 return QColor();
166}
167
169{
170 QgsRenderContext &renderContext = context.renderContext();
171 if ( !renderContext.painter() )
172 return;
173
174 if ( renderContext.isGuiPreview() )
175 {
176 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
177 return;
178 }
179
180 if ( !renderContext.maskPainter() )
181 return;
182
183 if ( mMaskedSymbolLayers.isEmpty() )
184 return;
185
186 // Otherwise switch to the mask painter before rendering
187 const QgsPainterSwapper swapper( renderContext, renderContext.maskPainter() );
188
189 // Special case when an effect is defined on this mask symbol layer
190 // (effects defined on sub symbol's layers do not need special handling)
191 if ( mEffect && mEffect->enabled() )
192 {
193 QgsEffectPainter p( renderContext );
194 // translate operates on the mask painter, which is what we want
195 p->translate( point );
196 p.setEffect( mEffect.get() );
197 mSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
198 // the translation will be canceled at the end of scope here
199 }
200 else
201 {
202 mSymbol->renderPoint( point, context.feature(), renderContext, /* layer = */ -1, /* selected = */ false );
203 }
204}
RenderUnit
Rendering size units.
Definition qgis.h:5183
@ MapUnits
Map units.
Definition qgis.h:5185
@ MetersInMapUnits
Meters value as Map units.
Definition qgis.h:5191
@ Marker
Marker symbol.
Definition qgis.h:611
Manages 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 std::unique_ptr< QgsMarkerSymbol > createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
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.
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.
void clearMasks()
Remove masks defined by this symbol layer.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
Manages painter saving and restoring required for drawing on a different painter (mask painter for ex...
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.
QgsSymbolLayer(const QgsSymbolLayer &other)
Encapsulates the context in which a symbol is being rendered.
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:231
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:294
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utility function to turn a QgsSymbolLayerReferenceList into a string.
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utility function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbolL...