QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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"
23 #include "qgsmarkersymbollayer.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 
90 QSet<QString> QgsMaskMarkerSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
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 
134 QList<QgsSymbolLayerReference> QgsMaskMarkerSymbolLayer::masks() const
135 {
136  return mMaskedSymbolLayers;
137 }
138 
139 void 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 }
QgsRenderContext::maskPainter
QPainter * maskPainter(int id=0)
Returns a mask QPainter for the render operation.
Definition: qgsrendercontext.h:144
QgsEffectPainter::setEffect
void setEffect(QgsPaintEffect *effect)
Sets the effect to be painted.
Definition: qgspainteffect.cpp:296
QgsMarkerSymbolLayer::size
double size() const
Returns the symbol size.
Definition: qgssymbollayer.h:785
QgsUnitTypes::RenderUnit
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
QgsEffectPainter
A class to manager painter saving and restoring required for effect drawing.
Definition: qgspainteffect.h:395
qgsmaskpaintdevice.h
QgsSymbolRenderContext::feature
const QgsFeature * feature() const
Returns the current feature being rendered.
Definition: qgssymbolrendercontext.h:143
QgsMaskMarkerSymbolLayer::setMasks
void setMasks(const QList< QgsSymbolLayerReference > &maskedLayers)
Sets the symbol layers that will be masked by the sub symbol's shape.
Definition: qgsmasksymbollayer.cpp:139
QgsMaskMarkerSymbolLayer::properties
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Definition: qgsmasksymbollayer.cpp:83
QgsMaskMarkerSymbolLayer::enabled
bool enabled() const
Whether some masked symbol layers are defined.
Definition: qgsmasksymbollayer.cpp:34
qgssymbollayerutils.h
QgsSymbolLayer::hasDataDefinedProperties
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
Definition: qgssymbollayer.cpp:287
qgsmarkersymbollayer.h
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:59
QgsMaskMarkerSymbolLayer::layerType
QString layerType() const override
Returns a string that represents this layer type.
Definition: qgsmasksymbollayer.cpp:78
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:92
QgsMarkerSymbolLayer::mSizeUnit
QgsUnitTypes::RenderUnit mSizeUnit
Marker size unit.
Definition: qgssymbollayer.h:995
qgspainteffect.h
QgsMarkerSymbolLayer::drawPreviewIcon
void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
Definition: qgssymbollayer.cpp:538
QgsMaskMarkerSymbolLayer::~QgsMaskMarkerSymbolLayer
~QgsMaskMarkerSymbolLayer() override
qgssymbollayerreference.h
QgsSymbolRenderContext
Definition: qgssymbolrendercontext.h:35
QgsMarkerSymbolLayer::setOutputUnit
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Definition: qgssymbollayer.cpp:691
QgsMaskMarkerSymbolLayer::QgsMaskMarkerSymbolLayer
QgsMaskMarkerSymbolLayer()
Simple constructor.
Definition: qgsmasksymbollayer.cpp:27
QgsSymbolLayer
Definition: qgssymbollayer.h:54
QgsMaskMarkerSymbolLayer::renderPoint
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
Definition: qgsmasksymbollayer.cpp:167
QgsMaskMarkerSymbolLayer::setSubSymbol
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Definition: qgsmasksymbollayer.cpp:39
QgsMaskMarkerSymbolLayer::hasDataDefinedProperties
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
Definition: qgsmasksymbollayer.cpp:99
QgsSymbol::type
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
QgsMaskMarkerSymbolLayer::startRender
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
Definition: qgsmasksymbollayer.cpp:108
QgsMarkerSymbol
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgsmarkersymbol.h:30
QgsMaskMarkerSymbolLayer::subSymbol
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
Definition: qgsmasksymbollayer.cpp:73
QgsSymbolLayer::copyPaintEffect
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
Definition: qgssymbollayer.cpp:491
QgsMaskMarkerSymbolLayer::bounds
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
Definition: qgsmasksymbollayer.cpp:144
qgsmasksymbollayer.h
QgsSymbolLayer::setPaintEffect
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
Definition: qgssymbollayer.cpp:228
stringToSymbolLayerReferenceList
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utilitary function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbo...
Definition: qgssymbollayerreference.cpp:40
QgsSymbolLayer::paintEffect
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
Definition: qgssymbollayer.cpp:223
QgsSymbolLayer::usedAttributes
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
Definition: qgssymbollayer.cpp:328
QgsMaskMarkerSymbolLayer::stopRender
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
Definition: qgsmasksymbollayer.cpp:120
QgsMaskMarkerSymbolLayer::setOutputUnit
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Definition: qgsmasksymbollayer.cpp:155
symbolLayerReferenceListToString
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utilitary function to turn a QgsSymbolLayerReferenceList into a string.
Definition: qgssymbollayerreference.cpp:20
qgsvectorlayer.h
QgsMaskMarkerSymbolLayer::usedAttributes
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
Definition: qgsmasksymbollayer.cpp:90
qgsmarkersymbol.h
QgsRenderContext::isGuiPreview
bool isGuiPreview() const
Returns the Gui preview mode.
Definition: qgsrendercontext.h:812
QgsUnitTypes::RenderMetersInMapUnits
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:176
QgsMaskMarkerSymbolLayer::color
QColor color() const override
Returns the "representative" color of the symbol layer.
Definition: qgsmasksymbollayer.cpp:162
QgsMaskMarkerSymbolLayer::drawPreviewIcon
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size) override
Definition: qgsmasksymbollayer.cpp:129
qgspainterswapper.h
QgsMaskMarkerSymbolLayer::clone
QgsMaskMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
Definition: qgsmasksymbollayer.cpp:63
QgsMaskMarkerSymbolLayer::masks
QList< QgsSymbolLayerReference > masks() const override
Returns a list of references to symbol layers that are masked by the sub symbol's shape.
Definition: qgsmasksymbollayer.cpp:134
QgsSymbolRenderContext::renderContext
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Definition: qgssymbolrendercontext.h:62
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:112
QgsMaskMarkerSymbolLayer
Special symbol layer that uses its sub symbol as a selective mask.
Definition: qgsmasksymbollayer.h:34
QgsMaskMarkerSymbolLayer::usesMapUnits
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
Definition: qgsmasksymbollayer.cpp:149
QgsMarkerSymbol::createSimple
static QgsMarkerSymbol * createSimple(const QVariantMap &properties)
Create a marker symbol with one symbol layer: SimpleMarker with specified properties.
Definition: qgsmarkersymbol.cpp:22
QgsSymbolLayer::copyDataDefinedProperties
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
Definition: qgssymbollayer.cpp:483
QgsUnitTypes::RenderMapUnits
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:170
QgsPainterSwapper
A class to manage painter saving and restoring required for drawing on a different painter (mask pain...
Definition: qgspainterswapper.h:34
qgsproject.h
Qgis::SymbolType::Marker
@ Marker
Marker symbol.
QgsMaskMarkerSymbolLayer::create
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Create a new QgsMaskMarkerSymbolLayer.
Definition: qgsmasksymbollayer.cpp:50