QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
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 
24 {
25  mSymbol.reset( static_cast<QgsMarkerSymbol *>( QgsMarkerSymbol::createSimple( QgsStringMap() ) ) );
26 }
27 
29 {
30  if ( symbol && symbol->type() == QgsSymbol::Marker )
31  {
32  mSymbol.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
33  return true;
34  }
35  delete symbol;
36  return false;
37 }
38 
40 {
42 
44 
45  if ( props.contains( QStringLiteral( "mask_symbollayers" ) ) )
46  {
47  l->setMasks( stringToSymbolLayerReferenceList( props[QStringLiteral( "mask_symbollayers" )] ) );
48  }
49  return l;
50 }
51 
53 {
55  l->setSubSymbol( mSymbol->clone() );
56  l->setMasks( mMaskedSymbolLayers );
58  copyPaintEffect( l );
59  return l;
60 }
61 
63 {
64  return QStringLiteral( "MaskMarker" );
65 }
66 
68 {
69  QgsStringMap props;
70  props[QStringLiteral( "mask_symbollayers" )] = symbolLayerReferenceListToString( masks() );
71  return props;
72 }
73 
74 QSet<QString> QgsMaskMarkerSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
75 {
76  QSet<QString> attributes = QgsMarkerSymbolLayer::usedAttributes( context );
77 
78  attributes.unite( mSymbol->usedAttributes( context ) );
79 
80  return attributes;
81 }
82 
84 {
86  return true;
87  if ( mSymbol && mSymbol->hasDataDefinedProperties() )
88  return true;
89  return false;
90 }
91 
93 {
94  // since we need to swap the regular painter with the mask painter during rendering,
95  // effects won't work. So we cheat by handling effects ourselves in renderPoint
96  if ( paintEffect() )
97  {
98  mEffect.reset( paintEffect()->clone() );
99  setPaintEffect( nullptr );
100  }
101  mSymbol->startRender( context.renderContext() );
102 }
103 
105 {
106  mSymbol->stopRender( context.renderContext() );
107  if ( mEffect )
108  {
109  setPaintEffect( mEffect.release() );
110  }
111 }
112 
114 {
115  QgsMarkerSymbolLayer::drawPreviewIcon( context, size );
116 }
117 
119 {
120  return mSymbol->bounds( point, context.renderContext() );
121 }
122 
124 {
125  if ( !context.renderContext().painter() )
126  return;
127 
128  if ( context.renderContext().isGuiPreview() )
129  {
130  mSymbol->renderPoint( point, context.feature(), context.renderContext(), /* layer = */ -1, /* selected = */ false );
131  return;
132  }
133 
134  if ( ! context.renderContext().maskPainter() )
135  return;
136 
137  if ( mMaskedSymbolLayers.isEmpty() )
138  return;
139 
140  {
141  // Otherwise switch to the mask painter before rendering
142  QgsPainterSwapper swapper( context.renderContext(), context.renderContext().maskPainter() );
143 
144  // Special case when an effect is defined on this mask symbol layer
145  // (effects defined on sub symbol's layers do not need special handling)
146  if ( mEffect && mEffect->enabled() )
147  {
148  QgsEffectPainter p( context.renderContext() );
149  // translate operates on the mask painter, which is what we want
150  p->translate( point );
151  p.setEffect( mEffect.get() );
152  mSymbol->renderPoint( QPointF( 0, 0 ), context.feature(), context.renderContext(), /* layer = */ -1, /* selected = */ false );
153  // the translation will be canceled at the end of scope here
154  }
155  else
156  {
157  mSymbol->renderPoint( point, context.feature(), context.renderContext(), /* layer = */ -1, /* selected = */ false );
158  }
159  }
160 }
161 
162 
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:62
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer&#39;s subsymbol. takes ownership of the passed symbol.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:694
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
Special symbol layer that uses its sub symbol as a selective mask.
bool isGuiPreview() const
Returns the Gui preview mode.
double size() const
Returns the symbol size.
void setMasks(QgsSymbolLayerReferenceList maskedLayers)
Sets the symbol layers that will be masked by the sub symbol&#39;s shape.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Create a new QgsMaskMarkerSymbolLayer.
QString layerType() const override
Returns a string that represents this layer type.
QgsMaskMarkerSymbolLayer()
Simple constructor.
QgsSymbolLayerReferenceList masks() const override
Returns a list of references to symbol layers that are masked by the sub symbol&#39;s shape...
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
QPainter * maskPainter(int id=0)
Returns a mask QPainter for the render operation.
QgsRenderContext & renderContext()
Returns a reference to the context&#39;s render context.
Definition: qgssymbol.h:703
void setEffect(QgsPaintEffect *effect)
Sets the effect to be painted.
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utilitary function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbo...
Marker symbol.
Definition: qgssymbol.h:86
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
Contains information about the context of a rendering operation.
QPainter * painter()
Returns the destination QPainter for the render operation.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
SymbolType type() const
Returns the symbol&#39;s type.
Definition: qgssymbol.h:121
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
const QgsFeature * feature() const
Returns the current feature being rendered.
Definition: qgssymbol.h:784
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utilitary function to turn a QgsSymbolLayerReferenceList into a string.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
static QgsMarkerSymbol * createSimple(const QgsStringMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgssymbol.cpp:1288
A class to manage painter saving and restoring required for drawing on a different painter (mask pain...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
A class to manager painter saving and restoring required for effect drawing.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
QgsMaskMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.