1 /***************************************************************************
2  qgssymbollayer.h
3  ---------------------
4  begin                : November 2009
5  copyright            : (C) 2009 by Martin Dobias
6  email                : wonder dot sk at gmail 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 #ifndef QGSSYMBOLLAYER_H
16 #define QGSSYMBOLLAYER_H
17 
18 #define DEG2RAD(x)    ((x)*M_PI/180)
19 #define DEFAULT_SCALE_METHOD              Qgis::ScaleMethod::ScaleDiameter
20 
21 #include "qgis_core.h"
22 #include "qgis.h"
23 #include "qgsfields.h"
24 #include "qgspropertycollection.h"
25 #include "qgssymbolrendercontext.h"
26 
27 #include <QColor>
28 #include <QMap>
29 #include <QPointF>
30 #include <QSet>
31 #include <QDomDocument>
32 #include <QDomElement>
33 #include <QPainterPath>
34 
35 class QPainter;
36 class QSize;
37 class QPolygonF;
38 
39 class QgsDxfExport;
40 class QgsExpression;
41 class QgsRenderContext;
42 class QgsPaintEffect;
43 class QgsSymbolLayerReference;
44 
45 #ifndef SIP_RUN
46 typedef QMap<QString, QString> QgsStringMap;
47 #endif
48 
49 /**
50  * \ingroup core
51  * \class QgsSymbolLayer
52  */
53 class CORE_EXPORT QgsSymbolLayer
54 {
55 #ifdef SIP_RUN
56 #include <qgslinesymbollayer.h>
57 #endif
58 
59 
60 #ifdef SIP_RUN
61     SIP_CONVERT_TO_SUBCLASS_CODE
62     switch ( sipCpp->type() )
63     {
64       case Qgis::SymbolType::Marker:
65         if ( sipCpp->layerType() == "EllipseMarker" )
66           sipType = sipType_QgsEllipseSymbolLayer;
67         else if ( sipCpp->layerType() == "FontMarker" )
68           sipType = sipType_QgsFontMarkerSymbolLayer;
69         else if ( sipCpp->layerType() == "SimpleMarker" )
70           sipType = sipType_QgsSimpleMarkerSymbolLayer;
71         else if ( sipCpp->layerType() == "FilledMarker" )
72           sipType = sipType_QgsFilledMarkerSymbolLayer;
73         else if ( sipCpp->layerType() == "SvgMarker" )
74           sipType = sipType_QgsSvgMarkerSymbolLayer;
75         else if ( sipCpp->layerType() == "RasterMarker" )
76           sipType = sipType_QgsRasterMarkerSymbolLayer;
77         else if ( sipCpp->layerType() == "VectorField" )
78           sipType = sipType_QgsVectorFieldSymbolLayer;
79         else if ( sipCpp->layerType() == "MaskMarker" )
80           sipType = sipType_QgsMaskMarkerSymbolLayer;
81         else
82           sipType = sipType_QgsMarkerSymbolLayer;
83         break;
84 
85       case Qgis::SymbolType::Line:
86         if ( sipCpp->layerType() == "MarkerLine" )
87           sipType = sipType_QgsMarkerLineSymbolLayer;
88         else if ( sipCpp->layerType() == "SimpleLine" )
89           sipType = sipType_QgsSimpleLineSymbolLayer;
90         else if ( sipCpp->layerType() == "HashLine" )
91           sipType = sipType_QgsHashedLineSymbolLayer;
92         else if ( sipCpp->layerType() == "ArrowLine" )
93           sipType = sipType_QgsArrowSymbolLayer;
94         else if ( sipCpp->layerType() == "InterpolatedLine" )
95           sipType = sipType_QgsInterpolatedLineSymbolLayer;
96         else
97           sipType = sipType_QgsLineSymbolLayer;
98         break;
99 
100       case Qgis::SymbolType::Fill:
101         if ( sipCpp->layerType() == "SimpleFill" )
102           sipType = sipType_QgsSimpleFillSymbolLayer;
103         else if ( sipCpp->layerType() == "LinePatternFill" )
104           sipType = sipType_QgsLinePatternFillSymbolLayer;
105         else if ( sipCpp->layerType() == "PointPatternFill" )
106           sipType = sipType_QgsPointPatternFillSymbolLayer;
107         else if ( sipCpp->layerType() == "SVGFill" )
108           sipType = sipType_QgsSVGFillSymbolLayer;
109         else if ( sipCpp->layerType() == "RasterFill" )
110           sipType = sipType_QgsRasterFillSymbolLayer;
111         else if ( sipCpp->layerType() == "CentroidFill" )
112           sipType = sipType_QgsCentroidFillSymbolLayer;
113         else if ( sipCpp->layerType() == "GradientFill" )
114           sipType = sipType_QgsGradientFillSymbolLayer;
115         else if ( sipCpp->layerType() == "ShapeburstFill" )
116           sipType = sipType_QgsShapeburstFillSymbolLayer;
117         else if ( sipCpp->layerType() == "RandomMarkerFill" )
118           sipType = sipType_QgsRandomMarkerFillSymbolLayer;
119         else
120           sipType = sipType_QgsFillSymbolLayer;
121         break;
122 
123       case Qgis::SymbolType::Hybrid:
124         sipType = sipType_QgsGeometryGeneratorSymbolLayer;
125         break;
126     }
127     SIP_END
128 #endif
129   public:
130 
131     /**
132      * Data definable properties.
133      * \since QGIS 3.0
134      */
135     enum Property
136     {
137       PropertySize = 0, //!< Symbol size
138       PropertyAngle, //!< Symbol angle
139       PropertyName, //!< Name, eg shape name for simple markers
140       PropertyFillColor, //!< Fill color
141       PropertyStrokeColor, //!< Stroke color
142       PropertyStrokeWidth, //!< Stroke width
143       PropertyStrokeStyle, //!< Stroke style (eg solid, dashed)
144       PropertyOffset, //!< Symbol offset
145       PropertyCharacter, //!< Character, eg for font marker symbol layers
146       PropertyWidth, //!< Symbol width
147       PropertyHeight, //!< Symbol height
148       PropertyPreserveAspectRatio, //!< Preserve aspect ratio between width and height
149       PropertyFillStyle, //!< Fill style (eg solid, dots)
150       PropertyJoinStyle, //!< Line join style
151       PropertySecondaryColor, //!< Secondary color (eg for gradient fills)
152       PropertyLineAngle, //!< Line angle, or angle of hash lines for hash line symbols
153       PropertyLineDistance, //!< Distance between lines, or length of lines for hash line symbols
154       PropertyGradientType, //!< Gradient fill type
155       PropertyCoordinateMode, //!< Gradient coordinate mode
156       PropertyGradientSpread, //!< Gradient spread mode
157       PropertyGradientReference1X, //!< Gradient reference point 1 x
158       PropertyGradientReference1Y, //!< Gradient reference point 1 y
159       PropertyGradientReference2X, //!< Gradient reference point 2 x
160       PropertyGradientReference2Y, //!< Gradient reference point 2 y
161       PropertyGradientReference1IsCentroid, //!< Gradient reference point 1 is centroid
162       PropertyGradientReference2IsCentroid, //!< Gradient reference point 2 is centroid
163       PropertyBlurRadius, //!< Shapeburst blur radius
164       PropertyShapeburstUseWholeShape, //!< Shapeburst use whole shape
165       PropertyShapeburstMaxDistance, //!< Shapeburst fill from edge distance
166       PropertyShapeburstIgnoreRings, //!< Shapeburst ignore rings
167       PropertyFile, //!< Filename, eg for svg files
168       PropertyDistanceX, //!< Horizontal distance between points
169       PropertyDistanceY, //!< Vertical distance between points
170       PropertyDisplacementX, //!< Horizontal displacement
171       PropertyDisplacementY, //!< Vertical displacement
172       PropertyOpacity, //!< Opacity
173       PropertyCustomDash, //!< Custom dash pattern
174       PropertyCapStyle, //!< Line cap style
175       PropertyPlacement, //!< Line marker placement
176       PropertyInterval, //!< Line marker interval
177       PropertyOffsetAlongLine, //!< Offset along line
178       PropertyAverageAngleLength, //!< Length to average symbol angles over
179       PropertyHorizontalAnchor, //!< Horizontal anchor point
180       PropertyVerticalAnchor, //!< Vertical anchor point
181       PropertyLayerEnabled, //!< Whether symbol layer is enabled
182       PropertyArrowWidth, //!< Arrow tail width
183       PropertyArrowStartWidth, //!< Arrow tail start width
184       PropertyArrowHeadLength, //!< Arrow head length
185       PropertyArrowHeadThickness, //!< Arrow head thickness
186       PropertyArrowHeadType, //!< Arrow head type
187       PropertyArrowType, //!< Arrow type
188       PropertyOffsetX, //!< Horizontal offset
189       PropertyOffsetY, //!< Vertical offset
190       PropertyPointCount, //!< Point count
191       PropertyRandomSeed, //!< Random number seed
192       PropertyClipPoints, //!< Whether markers should be clipped to polygon boundaries
193       PropertyDensityArea, //!< Density area
194       PropertyFontFamily, //!< Font family
195       PropertyFontStyle, //!< Font style
196       PropertyDashPatternOffset, //!< Dash pattern offset,
197       PropertyTrimStart, //!< Trim distance from start of line (since QGIS 3.20)
198       PropertyTrimEnd, //!< Trim distance from end of line (since QGIS 3.20)
199       PropertyLineStartWidthValue, //!< Start line width for interpolated line renderer (since QGIS 3.22)
200       PropertyLineEndWidthValue, //!< End line width for interpolated line renderer (since QGIS 3.22)
201       PropertyLineStartColorValue, //!< Start line color for interpolated line renderer (since QGIS 3.22)
202       PropertyLineEndColorValue, //!< End line color for interpolated line renderer (since QGIS 3.22)
203     };
204 
205     /**
206      * Returns the symbol layer property definitions.
207      * \since QGIS 3.0
208      */
209     static const QgsPropertiesDefinition &propertyDefinitions();
210 
211     virtual ~QgsSymbolLayer();
212 
213     //! QgsSymbolLayer cannot be copied
214     QgsSymbolLayer( const QgsSymbolLayer &other ) = delete;
215 
216     //! QgsSymbolLayer cannot be copied
217     QgsSymbolLayer &operator=( const QgsSymbolLayer &other ) = delete;
218 
219     /**
220      * Returns flags which control the symbol layer's behavior.
221      *
222      * \since QGIS 3.22
223      */
224     virtual Qgis::SymbolLayerFlags flags() const;
225 
226     /**
227      * Returns TRUE if symbol layer is enabled and will be drawn.
228      * \see setEnabled()
229      * \since QGIS 3.0
230      */
enabled()231     bool enabled() const { return mEnabled; }
232 
233     /**
234      * Sets whether symbol layer is enabled and should be drawn. Disabled
235      * layers are not drawn, but remain part of the symbol and can be re-enabled
236      * when desired.
237      * \see enabled()
238      * \since QGIS 3.0
239      */
setEnabled(bool enabled)240     void setEnabled( bool enabled ) { mEnabled = enabled; }
241 
242     /**
243      * The fill color.
244      */
color()245     virtual QColor color() const { return mColor; }
246 
247     /**
248      * The fill color.
249      */
setColor(const QColor & color)250     virtual void setColor( const QColor &color ) { mColor = color; }
251 
252     /**
253      * Set stroke color. Supported by marker and fill layers.
254      * \since QGIS 2.1
255     */
setStrokeColor(const QColor & color)256     virtual void setStrokeColor( const QColor &color ) { Q_UNUSED( color ) }
257 
258     /**
259      * Gets stroke color. Supported by marker and fill layers.
260      * \since QGIS 2.1
261     */
strokeColor()262     virtual QColor strokeColor() const { return QColor(); }
263 
264     /**
265      * Set fill color. Supported by marker and fill layers.
266      * \since QGIS 2.1
267     */
setFillColor(const QColor & color)268     virtual void setFillColor( const QColor &color ) { Q_UNUSED( color ) }
269 
270     /**
271      * Gets fill color. Supported by marker and fill layers.
272      * \since QGIS 2.1
273     */
fillColor()274     virtual QColor fillColor() const { return QColor(); }
275 
276     /**
277      * Returns a string that represents this layer type. Used for serialization.
278      * Should match with the string used to register this symbol layer in the registry.
279      */
280     virtual QString layerType() const = 0;
281 
282     /**
283      * Called before a set of rendering operations commences on the supplied render \a context.
284      *
285      * This is always followed by a call to stopRender() after all rendering operations
286      * have been completed.
287      *
288      * Subclasses can use this method to prepare for a set of rendering operations, e.g. by
289      * pre-evaluating paths or images to render, and performing other one-time optimisations.
290      *
291      * \see startFeatureRender()
292      * \see stopRender()
293      */
294     virtual void startRender( QgsSymbolRenderContext &context ) = 0;
295 
296     /**
297      * Called after a set of rendering operations has finished on the supplied render \a context.
298      *
299      * This is always preceded by a call to startRender() before all rendering operations
300      * are commenced.
301      *
302      * Subclasses can use this method to cleanup after a set of rendering operations.
303      *
304      * \see startRender()
305      * \see stopFeatureRender()
306      */
307     virtual void stopRender( QgsSymbolRenderContext &context ) = 0;
308 
309     /**
310      * Called before the layer will be rendered for a particular \a feature.
311      *
312      * This is always followed by a call to stopFeatureRender() after the feature
313      * has been completely rendered (i.e. all parts have been rendered).
314      *
315      * The default implementation does nothing.
316      *
317      * \note In some circumstances, startFeatureRender() and stopFeatureRender() may not be called
318      * before a symbol layer is rendered. E.g., when a symbol layer is being rendered in isolation
319      * and not as a result of rendering a feature (for instance, when rendering a legend patch or other
320      * non-feature based shape).
321      *
322      * \see stopFeatureRender()
323      * \see startRender()
324      *
325      * \since QGIS 3.12
326      */
327     virtual void startFeatureRender( const QgsFeature &feature, QgsRenderContext &context );
328 
329     /**
330      * Called after the layer has been rendered for a particular \a feature.
331      *
332      * This is always preceded by a call to startFeatureRender() just before the feature
333      * will be rendered.
334      *
335      * The default implementation does nothing.
336      *
337      * \note In some circumstances, startFeatureRender() and stopFeatureRender() may not be called
338      * before a symbol layer is rendered. E.g., when a symbol layer is being rendered in isolation
339      * and not as a result of rendering a feature (for instance, when rendering a legend patch or other
340      * non-feature based shape).
341      *
342      * \see startFeatureRender()
343      * \see stopRender()
344      *
345      * \since QGIS 3.12
346      */
347     virtual void stopFeatureRender( const QgsFeature &feature, QgsRenderContext &context );
348 
349     /**
350      * Shall be reimplemented by subclasses to create a deep copy of the instance.
351      */
352     virtual QgsSymbolLayer *clone() const = 0 SIP_FACTORY;
353 
354     //! Saves the symbol layer as SLD
toSld(QDomDocument & doc,QDomElement & element,const QVariantMap & props)355     virtual void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
356     { Q_UNUSED( props ) element.appendChild( doc.createComment( QStringLiteral( "SymbolLayerV2 %1 not implemented yet" ).arg( layerType() ) ) ); }
357 
ogrFeatureStyle(double mmScaleFactor,double mapUnitScaleFactor)358     virtual QString ogrFeatureStyle( double mmScaleFactor, double mapUnitScaleFactor ) const { Q_UNUSED( mmScaleFactor ) Q_UNUSED( mapUnitScaleFactor ); return QString(); }
359 
360     /**
361      * Should be reimplemented by subclasses to return a string map that
362      * contains the configuration information for the symbol layer. This
363      * is used to serialize a symbol layer perstistently.
364      */
365     virtual QVariantMap properties() const = 0;
366 
367     virtual void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) = 0;
368 
369     /**
370      * Returns the symbol's sub symbol, if present.
371      */
372     virtual QgsSymbol *subSymbol();
373 
374     //! Sets layer's subsymbol. takes ownership of the passed symbol
375     virtual bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER );
376 
type()377     Qgis::SymbolType type() const { return mType; }
378 
379     //! Returns if the layer can be used below the specified symbol
380     virtual bool isCompatibleWithSymbol( QgsSymbol *symbol ) const;
381 
382     /**
383      * Returns TRUE if the symbol layer rendering can cause visible artifacts across a single feature
384      * when the feature is rendered as a series of adjacent map tiles each containing a portion of the feature's geometry.
385      *
386      * The default implementation returns FALSE.
387      *
388      * \since QGIS 3.18
389      */
390     virtual bool canCauseArtifactsBetweenAdjacentTiles() const;
391 
392     /**
393      * Sets whether the layer's colors are locked.
394      *
395      * If \a locked is TRUE then the symbol layer colors are locked and the layer will ignore any symbol-level color changes.
396      *
397      * \see isLocked()
398      */
setLocked(bool locked)399     void setLocked( bool locked ) { mLocked = locked; }
400 
401     /**
402      * Returns TRUE if the symbol layer colors are locked and the layer will ignore any symbol-level color changes.
403      *
404      * \see setLocked()
405      */
isLocked()406     bool isLocked() const { return mLocked; }
407 
408     /**
409      * Returns the estimated maximum distance which the layer style will bleed outside
410      * the drawn shape when drawn in the specified /a context. For example, polygons
411      * drawn with an stroke will draw half the width
412      * of the stroke outside of the polygon. This amount is estimated, since it may
413      * be affected by data defined symbology rules.
414     */
estimateMaxBleed(const QgsRenderContext & context)415     virtual double estimateMaxBleed( const QgsRenderContext &context ) const { Q_UNUSED( context ) return 0; }
416 
417     /**
418      * Sets the units to use for sizes and widths within the symbol layer. Individual
419      * symbol layer subclasses will interpret this in different ways, e.g., a marker symbol
420      * layer may use it to specify the units for the marker size, while a line symbol
421      * layer may use it to specify the units for the line width.
422      * \param unit output units
423      * \see outputUnit()
424      */
setOutputUnit(QgsUnitTypes::RenderUnit unit)425     virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit ) { Q_UNUSED( unit ) }
426 
427     /**
428      * Returns the units to use for sizes and widths within the symbol layer. Individual
429      * symbol layer subclasses will interpret this in different ways, e.g., a marker symbol
430      * layer may use it to specify the units for the marker size, while a line symbol
431      * layer may use it to specify the units for the line width.
432      * \returns output unit, or QgsUnitTypes::RenderUnknownUnit if the symbol layer contains mixed units
433      * \see setOutputUnit()
434      */
outputUnit()435     virtual QgsUnitTypes::RenderUnit outputUnit() const { return QgsUnitTypes::RenderUnknownUnit; }
436 
437     /**
438      * Returns TRUE if the symbol layer has any components which use map unit based sizes.
439      *
440      * \since QGIS 3.18
441      */
442     virtual bool usesMapUnits() const;
443 
setMapUnitScale(const QgsMapUnitScale & scale)444     virtual void setMapUnitScale( const QgsMapUnitScale &scale ) { Q_UNUSED( scale ) }
mapUnitScale()445     virtual QgsMapUnitScale mapUnitScale() const { return QgsMapUnitScale(); }
446 
447     /**
448      * Specifies the rendering pass in which this symbol layer should be rendered.
449      * The lower the number, the lower the symbol will be rendered.
450      * 0: first pass, 1: second pass, ...
451      * Defaults to 0
452      */
453     void setRenderingPass( int renderingPass );
454 
455     /**
456      * Specifies the rendering pass in which this symbol layer should be rendered.
457      * The lower the number, the lower the symbol will be rendered.
458      * 0: first pass, 1: second pass, ...
459      * Defaults to 0
460      */
461     int renderingPass() const;
462 
463     /**
464      * Returns the set of attributes referenced by the layer. This includes attributes
465      * required by any data defined properties associated with the layer.
466      */
467     virtual QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
468 
469     /**
470      * Sets a data defined property for the layer. Any existing property with the same key
471      * will be overwritten.
472      * \see dataDefinedProperties()
473      * \see Property
474      * \since QGIS 3.0
475      */
476     virtual void setDataDefinedProperty( Property key, const QgsProperty &property );
477 
478     //! write as DXF
479     virtual bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const;
480 
481     //! Gets line width
482     virtual double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const;
483 
484     //! Gets offset
485     virtual double dxfOffset( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const;
486 
487     //! Gets color
488     virtual QColor dxfColor( QgsSymbolRenderContext &context ) const;
489 
490     //! Gets angle
491     virtual double dxfAngle( QgsSymbolRenderContext &context ) const;
492 
493     //! Gets dash pattern
494     virtual QVector<qreal> dxfCustomDashPattern( QgsUnitTypes::RenderUnit &unit ) const;
495 
496     //! Gets pen style
497     virtual Qt::PenStyle dxfPenStyle() const;
498 
499     //! Gets brush/fill color
500     virtual QColor dxfBrushColor( QgsSymbolRenderContext &context ) const;
501 
502     //! Gets brush/fill style
503     virtual Qt::BrushStyle dxfBrushStyle() const;
504 
505     /**
506      * Returns the current paint effect for the layer.
507      * \returns paint effect
508      * \see setPaintEffect
509      * \since QGIS 2.9
510      */
511     QgsPaintEffect *paintEffect() const;
512 
513     /**
514      * Sets the current paint effect for the layer.
515      * \param effect paint effect. Ownership is transferred to the layer.
516      * \see paintEffect
517      * \since QGIS 2.9
518      */
519     void setPaintEffect( QgsPaintEffect *effect SIP_TRANSFER );
520 
521     /**
522      * Prepares all data defined property expressions for evaluation. This should
523      * be called prior to evaluating data defined properties.
524      * \param context symbol render context
525      * \since QGIS 2.12
526      */
527     virtual void prepareExpressions( const QgsSymbolRenderContext &context );
528 
529     /**
530      * Returns a reference to the symbol layer's property collection, used for data defined overrides.
531      * \see setDataDefinedProperties()
532      * \see Property
533      * \since QGIS 3.0
534      */
dataDefinedProperties()535     QgsPropertyCollection &dataDefinedProperties() { return mDataDefinedProperties; }
536 
537     /**
538      * Returns a reference to the symbol layer's property collection, used for data defined overrides.
539      * \see setDataDefinedProperties()
540      * \since QGIS 3.0
541      */
dataDefinedProperties()542     const QgsPropertyCollection &dataDefinedProperties() const { return mDataDefinedProperties; } SIP_SKIP
543 
544     /**
545      * Sets the symbol layer's property collection, used for data defined overrides.
546      * \param collection property collection. Existing properties will be replaced.
547      * \see dataDefinedProperties()
548      * \since QGIS 3.0
549      */
setDataDefinedProperties(const QgsPropertyCollection & collection)550     void setDataDefinedProperties( const QgsPropertyCollection &collection ) { mDataDefinedProperties = collection; }
551 
552     /**
553      * Returns TRUE if the symbol layer (or any of its sub-symbols) contains data defined properties.
554      *
555      * \since QGIS 3.4.5
556      */
557     virtual bool hasDataDefinedProperties() const;
558 
559     /**
560      * Returns masks defined by this symbol layer.
561      * This is a list of symbol layers of other layers that should be occluded.
562      * \since QGIS 3.12
563      */
564     virtual QList<QgsSymbolLayerReference> masks() const;
565 
566   protected:
567 
568     /**
569      * Constructor for QgsSymbolLayer.
570      * \param type specifies the associated symbol type
571      * \param locked if TRUE, then symbol layer colors will be locked and will ignore any symbol-level color changes.
572      */
573     QgsSymbolLayer( Qgis::SymbolType type, bool locked = false );
574 
575     Qgis::SymbolType mType;
576 
577     //! True if layer is enabled and should be drawn
578     bool mEnabled = true;
579 
580     bool mLocked = false;
581     QColor mColor;
582     int mRenderingPass = 0;
583 
584     QgsPropertyCollection mDataDefinedProperties;
585 
586     std::unique_ptr< QgsPaintEffect > mPaintEffect;
587     QgsFields mFields;
588 
589     // Configuration of selected symbology implementation
590     //! Whether styles for selected features ignore symbol alpha
591     static const bool SELECTION_IS_OPAQUE = true;
592     //! Whether fill styles for selected features also highlight symbol stroke
593     static const bool SELECT_FILL_BORDER = false;
594     //! Whether fill styles for selected features uses symbol layer style
595     static const bool SELECT_FILL_STYLE = false;
596 
597     /**
598      * Restores older data defined properties from string map.
599      * \since QGIS 3.0
600      */
601     void restoreOldDataDefinedProperties( const QVariantMap &stringMap );
602 
603     /**
604      * Copies all data defined properties of this layer to another symbol layer.
605      * \param destLayer destination layer
606      */
607     void copyDataDefinedProperties( QgsSymbolLayer *destLayer ) const;
608 
609     /**
610      * Copies paint effect of this layer to another symbol layer
611      * \param destLayer destination layer
612      * \since QGIS 2.9
613      */
614     void copyPaintEffect( QgsSymbolLayer *destLayer ) const;
615 
616   private:
617     static void initPropertyDefinitions();
618 
619     //! Property definitions
620     static QgsPropertiesDefinition sPropertyDefinitions;
621 
622 #ifdef SIP_RUN
623     QgsSymbolLayer( const QgsSymbolLayer &other );
624 #endif
625 
626 };
627 
628 //////////////////////
629 
630 /**
631  * \ingroup core
632  * \class QgsMarkerSymbolLayer
633  * \brief Abstract base class for marker symbol layers.
634  */
635 class CORE_EXPORT QgsMarkerSymbolLayer : public QgsSymbolLayer
636 {
637   public:
638 
639     //! Symbol horizontal anchor points
640     enum HorizontalAnchorPoint
641     {
642       Left, //!< Align to left side of symbol
643       HCenter, //!< Align to horizontal center of symbol
644       Right, //!< Align to right side of symbol
645     };
646 
647     //! Symbol vertical anchor points
648     enum VerticalAnchorPoint
649     {
650       Top, //!< Align to top of symbol
651       VCenter, //!< Align to vertical center of symbol
652       Bottom, //!< Align to bottom of symbol
653     };
654 
655     //! QgsMarkerSymbolLayer cannot be copied
656     QgsMarkerSymbolLayer( const QgsMarkerSymbolLayer &other ) = delete;
657 
658     //! QgsMarkerSymbolLayer cannot be copied
659     QgsMarkerSymbolLayer &operator=( const QgsMarkerSymbolLayer &other ) = delete;
660 
661     void startRender( QgsSymbolRenderContext &context ) override;
662 
663     void stopRender( QgsSymbolRenderContext &context ) override;
664 
665     /**
666      * Renders a marker at the specified point. Derived classes must implement this to
667      * handle drawing the point.
668      * \param point position at which to render point, in painter units
669      * \param context symbol render context
670      */
671     virtual void renderPoint( QPointF point, QgsSymbolRenderContext &context ) = 0;
672 
673     void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
674 
675     /**
676      * Sets the rotation angle for the marker.
677      * \param angle angle in degrees clockwise from north.
678      * \see angle()
679      * \see setLineAngle()
680      */
setAngle(double angle)681     void setAngle( double angle ) { mAngle = angle; }
682 
683     /**
684      * Returns the rotation angle for the marker, in degrees clockwise from north.
685      * \see setAngle()
686      */
angle()687     double angle() const { return mAngle; }
688 
689     /**
690      * Sets the line angle modification for the symbol's angle. This angle is added to
691      * the marker's rotation and data defined rotation before rendering the symbol, and
692      * is usually used for orienting symbols to match a line's angle.
693      * \param lineAngle Angle in degrees clockwise from north, valid values are between 0 and 360
694      * \see setAngle()
695      * \see angle()
696      * \since QGIS 2.9
697      */
setLineAngle(double lineAngle)698     void setLineAngle( double lineAngle ) { mLineAngle = lineAngle; }
699 
700     /**
701      * Sets the symbol size.
702      * \param size symbol size. Units are specified by sizeUnit().
703      * \see size()
704      * \see setSizeUnit()
705      * \see setSizeMapUnitScale()
706      */
setSize(double size)707     virtual void setSize( double size ) { mSize = size; }
708 
709     /**
710      * Returns the symbol size. Units are specified by sizeUnit().
711      * \see setSize()
712      * \see sizeUnit()
713      * \see sizeMapUnitScale()
714      */
size()715     double size() const { return mSize; }
716 
717     /**
718      * Sets the units for the symbol's size.
719      * \param unit size units
720      * \see sizeUnit()
721      * \see setSize()
722      * \see setSizeMapUnitScale()
723      */
setSizeUnit(QgsUnitTypes::RenderUnit unit)724     void setSizeUnit( QgsUnitTypes::RenderUnit unit ) { mSizeUnit = unit; }
725 
726     /**
727      * Returns the units for the symbol's size.
728      * \see setSizeUnit()
729      * \see size()
730      * \see sizeMapUnitScale()
731      */
sizeUnit()732     QgsUnitTypes::RenderUnit sizeUnit() const { return mSizeUnit; }
733 
734     /**
735      * Sets the map unit scale for the symbol's size.
736      * \param scale size map unit scale
737      * \see sizeMapUnitScale()
738      * \see setSize()
739      * \see setSizeUnit()
740      */
setSizeMapUnitScale(const QgsMapUnitScale & scale)741     void setSizeMapUnitScale( const QgsMapUnitScale &scale ) { mSizeMapUnitScale = scale; }
742 
743     /**
744      * Returns the map unit scale for the symbol's size.
745      * \see setSizeMapUnitScale()
746      * \see size()
747      * \see sizeUnit()
748      */
sizeMapUnitScale()749     const QgsMapUnitScale &sizeMapUnitScale() const { return mSizeMapUnitScale; }
750 
751     /**
752      * Sets the method to use for scaling the marker's size.
753      * \param scaleMethod scale method
754      * \see scaleMethod()
755      */
setScaleMethod(Qgis::ScaleMethod scaleMethod)756     void setScaleMethod( Qgis::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
757 
758     /**
759      * Returns the method to use for scaling the marker's size.
760      * \see setScaleMethod()
761      */
scaleMethod()762     Qgis::ScaleMethod scaleMethod() const { return mScaleMethod; }
763 
764     /**
765      * Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker
766      * should have from the original feature's geometry.
767      * \param offset marker offset. Units are specified by offsetUnit()
768      * \see offset()
769      * \see setOffsetUnit()
770      * \see setOffsetMapUnitScale()
771      */
setOffset(QPointF offset)772     void setOffset( QPointF offset ) { mOffset = offset; }
773 
774     /**
775      * Returns the marker's offset, which is the horizontal and vertical displacement which the rendered marker
776      * will have from the original feature's geometry. Units are specified by offsetUnit().
777      * \see setOffset()
778      * \see offsetUnit()
779      * \see offsetMapUnitScale()
780      */
offset()781     QPointF offset() const { return mOffset; }
782 
783     /**
784      * Sets the units for the symbol's offset.
785      * \param unit offset units
786      * \see offsetUnit()
787      * \see setOffset()
788      * \see setOffsetMapUnitScale()
789      */
setOffsetUnit(QgsUnitTypes::RenderUnit unit)790     void setOffsetUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetUnit = unit; }
791 
792     /**
793      * Returns the units for the symbol's offset.
794      * \see setOffsetUnit()
795      * \see offset()
796      * \see offsetMapUnitScale()
797      */
offsetUnit()798     QgsUnitTypes::RenderUnit offsetUnit() const { return mOffsetUnit; }
799 
800     /**
801      * Sets the map unit scale for the symbol's offset.
802      * \param scale offset map unit scale
803      * \see offsetMapUnitScale()
804      * \see setOffset()
805      * \see setOffsetUnit()
806      */
setOffsetMapUnitScale(const QgsMapUnitScale & scale)807     void setOffsetMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetMapUnitScale = scale; }
808 
809     /**
810      * Returns the map unit scale for the symbol's offset.
811      * \see setOffsetMapUnitScale()
812      * \see offset()
813      * \see offsetUnit()
814      */
offsetMapUnitScale()815     const QgsMapUnitScale &offsetMapUnitScale() const { return mOffsetMapUnitScale; }
816 
817     /**
818      * Sets the horizontal anchor point for positioning the symbol.
819      * \param h anchor point. Symbol will be drawn so that the horizontal anchor point is aligned with
820      * the marker's desired location.
821      * \see horizontalAnchorPoint()
822      * \see setVerticalAnchorPoint()
823      */
setHorizontalAnchorPoint(HorizontalAnchorPoint h)824     void setHorizontalAnchorPoint( HorizontalAnchorPoint h ) { mHorizontalAnchorPoint = h; }
825 
826     /**
827      * Returns the horizontal anchor point for positioning the symbol. The symbol will be drawn so that
828      * the horizontal anchor point is aligned with the marker's desired location.
829      * \see setHorizontalAnchorPoint()
830      * \see verticalAnchorPoint()
831      */
horizontalAnchorPoint()832     HorizontalAnchorPoint horizontalAnchorPoint() const { return mHorizontalAnchorPoint; }
833 
834     /**
835      * Sets the vertical anchor point for positioning the symbol.
836      * \param v anchor point. Symbol will be drawn so that the vertical anchor point is aligned with
837      * the marker's desired location.
838      * \see verticalAnchorPoint()
839      * \see setHorizontalAnchorPoint()
840      */
setVerticalAnchorPoint(VerticalAnchorPoint v)841     void setVerticalAnchorPoint( VerticalAnchorPoint v ) { mVerticalAnchorPoint = v; }
842 
843     /**
844      * Returns the vertical anchor point for positioning the symbol. The symbol will be drawn so that
845      * the vertical anchor point is aligned with the marker's desired location.
846      * \see setVerticalAnchorPoint()
847      * \see horizontalAnchorPoint()
848      */
verticalAnchorPoint()849     VerticalAnchorPoint verticalAnchorPoint() const { return mVerticalAnchorPoint; }
850 
851     void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const override;
852 
853     /**
854      * Writes the symbol layer definition as a SLD XML element.
855      * \param doc XML document
856      * \param element parent XML element
857      * \param props symbol layer definition (see properties())
858      */
writeSldMarker(QDomDocument & doc,QDomElement & element,const QVariantMap & props)859     virtual void writeSldMarker( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
860     { Q_UNUSED( props ) element.appendChild( doc.createComment( QStringLiteral( "QgsMarkerSymbolLayer %1 not implemented yet" ).arg( layerType() ) ) ); }
861 
862     void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
863     QgsUnitTypes::RenderUnit outputUnit() const override;
864     void setMapUnitScale( const QgsMapUnitScale &scale ) override;
865     QgsMapUnitScale mapUnitScale() const override;
866 
867     /**
868      * Returns the approximate bounding box of the marker symbol layer, taking into account
869      * any data defined overrides and offsets which are set for the marker layer.
870      * \returns approximate symbol bounds, in painter units
871      * \since QGIS 2.14
872      */
873     virtual QRectF bounds( QPointF point, QgsSymbolRenderContext &context ) = 0;
874 
875   protected:
876 
877     /**
878      * Constructor for QgsMarkerSymbolLayer.
879      * \param locked set to TRUE to lock symbol color
880      */
881     QgsMarkerSymbolLayer( bool locked = false );
882 
883     /**
884      * Calculates the required marker offset, including both the symbol offset
885      * and any displacement required to align with the marker's anchor point.
886      * \param context symbol render context
887      * \param offsetX will be set to required horizontal offset (in painter units)
888      * \param offsetY will be set to required vertical offset (in painter units)
889      */
890     void markerOffset( QgsSymbolRenderContext &context, double &offsetX, double &offsetY ) const;
891 
892     /**
893      * Calculates the required marker offset, including both the symbol offset
894      * and any displacement required to align with the marker's anchor point.
895      * \param context symbol render context
896      * \param width marker width
897      * \param height marker height
898      * \param offsetX will be set to required horizontal offset (in painter units)
899      * \param offsetY will be set to required vertical offset (in painter units)
900      * \note available in Python as markerOffsetWithWidthAndHeight
901      */
902     void markerOffset( QgsSymbolRenderContext &context, double width, double height, double &offsetX, double &offsetY ) const SIP_PYNAME( markerOffsetWithWidthAndHeight );
903 
904     //! \note available in Python bindings as markerOffset2
905     void markerOffset( QgsSymbolRenderContext &context, double width, double height,
906                        QgsUnitTypes::RenderUnit widthUnit, QgsUnitTypes::RenderUnit heightUnit,
907                        double &offsetX, double &offsetY,
908                        const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const SIP_PYNAME( markerOffset2 );
909 
910     /**
911      * Adjusts a marker offset to account for rotation.
912      * \param offset offset prior to rotation
913      * \param angle rotation angle in degrees clockwise from north
914      * \returns adjusted offset
915      */
916     static QPointF _rotatedOffset( QPointF offset, double angle );
917 
918     //! Marker rotation angle, in degrees clockwise from north
919     double mAngle = 0;
920     //! Line rotation angle (see setLineAngle() for details)
921     double mLineAngle = 0;
922     //! Marker size
923     double mSize = 2.0;
924     //! Marker size unit
925     QgsUnitTypes::RenderUnit mSizeUnit = QgsUnitTypes::RenderMillimeters;
926     //! Marker size map unit scale
927     QgsMapUnitScale mSizeMapUnitScale;
928     //! Marker offset
929     QPointF mOffset;
930     //! Offset units
931     QgsUnitTypes::RenderUnit mOffsetUnit = QgsUnitTypes::RenderMillimeters;
932     //! Offset map unit scale
933     QgsMapUnitScale mOffsetMapUnitScale;
934     //! Marker size scaling method
935     Qgis::ScaleMethod mScaleMethod = Qgis::ScaleMethod::ScaleDiameter;
936     //! Horizontal anchor point
937     HorizontalAnchorPoint mHorizontalAnchorPoint = HCenter;
938     //! Vertical anchor point
939     VerticalAnchorPoint mVerticalAnchorPoint = VCenter;
940 
941   private:
942     static QgsMarkerSymbolLayer::HorizontalAnchorPoint decodeHorizontalAnchorPoint( const QString &str );
943     static QgsMarkerSymbolLayer::VerticalAnchorPoint decodeVerticalAnchorPoint( const QString &str );
944 
945 #ifdef SIP_RUN
946     QgsMarkerSymbolLayer( const QgsMarkerSymbolLayer &other );
947 #endif
948 };
949 
950 /**
951  * \ingroup core
952  * \class QgsLineSymbolLayer
953  */
954 class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
955 {
956   public:
957 
958     //! Options for filtering rings when the line symbol layer is being used to render a polygon's rings.
959     enum RenderRingFilter
960     {
961       AllRings, //!< Render both exterior and interior rings
962       ExteriorRingOnly, //!< Render the exterior ring only
963       InteriorRingsOnly, //!< Render the interior rings only
964     };
965 
966     //! QgsLineSymbolLayer cannot be copied
967     QgsLineSymbolLayer( const QgsLineSymbolLayer &other ) = delete;
968 
969     //! QgsLineSymbolLayer cannot be copied
970     QgsLineSymbolLayer &operator=( const QgsLineSymbolLayer &other ) = delete;
971 
972     void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
973     QgsUnitTypes::RenderUnit outputUnit() const override;
974     void setMapUnitScale( const QgsMapUnitScale &scale ) override;
975     QgsMapUnitScale mapUnitScale() const override;
976     void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
977     double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const override;
978 
979     /**
980      * Renders the line symbol layer along the line joining \a points, using the given render \a context.
981      * \see renderPolygonStroke()
982      */
983     virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) = 0;
984 
985     /**
986      * Renders the line symbol layer along the outline of polygon, using the given render \a context.
987      *
988      * The exterior ring of the polygon is specified in \a points. Optionally, interior
989      * rings are set via the \a rings argument.
990      *
991      * \see renderPolyline()
992      */
993     virtual void renderPolygonStroke( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
994 
995     /**
996      * Sets the \a width of the line symbol layer.
997      *
998      * Calling this method updates the width of the line symbol layer, without
999      * changing the existing width units. It has different effects depending
1000      * on the line symbol layer subclass, e.g. for a simple line layer it
1001      * changes the stroke width of the line, for a marker line layer it
1002      * changes the size of the markers used to draw the line.
1003      *
1004      * \see width()
1005      * \warning Since the width units vary, this method is useful for changing the
1006      * relative width of a line symbol layer only.
1007      */
setWidth(double width)1008     virtual void setWidth( double width ) { mWidth = width; }
1009 
1010     /**
1011      * Returns the estimated width for the line symbol layer.
1012      *
1013      * \warning This returned value is inaccurate if the symbol layer has sub-symbols with
1014      * different width units. Use the overload accepting a QgsRenderContext
1015      * argument instead for accurate sizes in this case.
1016      *
1017      * \see setWidth()
1018      */
width()1019     virtual double width() const { return mWidth; }
1020 
1021     /**
1022      * Returns the line symbol layer width, in painter units.
1023      *
1024      * This method returns an accurate width by calculating the actual rendered
1025      * width of the symbol layer using the provided render \a context.
1026      *
1027      * \see setWidth()
1028      *
1029      * \since QGIS 3.4.5
1030      */
1031     virtual double width( const QgsRenderContext &context ) const;
1032 
1033     /**
1034      * Returns the line's offset.
1035      *
1036      * Offset units can be retrieved by calling offsetUnit().
1037      *
1038      * \see setOffset()
1039      * \see offsetUnit()
1040      * \see offsetMapUnitScale()
1041      */
offset()1042     double offset() const { return mOffset; }
1043 
1044     /**
1045      * Sets the line's \a offset.
1046      *
1047      * Offset units are set via setOffsetUnit().
1048      *
1049      * \see offset()
1050      * \see setOffsetUnit()
1051      * \see setOffsetMapUnitScale()
1052      */
setOffset(double offset)1053     void setOffset( double offset ) { mOffset = offset; }
1054 
1055     /**
1056      * Sets the \a unit for the line's offset.
1057      * \see offsetUnit()
1058      * \see setOffset()
1059      * \see setOffsetMapUnitScale()
1060     */
setOffsetUnit(QgsUnitTypes::RenderUnit unit)1061     void setOffsetUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetUnit = unit; }
1062 
1063     /**
1064      * Returns the units for the line's offset.
1065      * \see setOffsetUnit()
1066      * \see offset()
1067      * \see offsetMapUnitScale()
1068     */
offsetUnit()1069     QgsUnitTypes::RenderUnit offsetUnit() const { return mOffsetUnit; }
1070 
1071     /**
1072      * Sets the map unit \a scale for the line's offset.
1073      * \see offsetMapUnitScale()
1074      * \see setOffset()
1075      * \see setOffsetUnit()
1076     */
setOffsetMapUnitScale(const QgsMapUnitScale & scale)1077     void setOffsetMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetMapUnitScale = scale; }
1078 
1079     /**
1080      * Returns the map unit scale for the line's offset.
1081      * \see setOffsetMapUnitScale()
1082      * \see offset()
1083      * \see offsetUnit()
1084     */
offsetMapUnitScale()1085     const QgsMapUnitScale &offsetMapUnitScale() const { return mOffsetMapUnitScale; }
1086 
1087     // TODO QGIS 4.0 - setWidthUnit(), widthUnit(), setWidthUnitScale(), widthUnitScale()
1088     // only apply to simple line symbol layers and do not belong here.
1089 
1090     /**
1091      * Sets the units for the line's width.
1092      * \param unit width units
1093      * \see widthUnit()
1094     */
setWidthUnit(QgsUnitTypes::RenderUnit unit)1095     void setWidthUnit( QgsUnitTypes::RenderUnit unit ) { mWidthUnit = unit; }
1096 
1097     /**
1098      * Returns the units for the line's width.
1099      * \see setWidthUnit()
1100     */
widthUnit()1101     QgsUnitTypes::RenderUnit widthUnit() const { return mWidthUnit; }
1102 
setWidthMapUnitScale(const QgsMapUnitScale & scale)1103     void setWidthMapUnitScale( const QgsMapUnitScale &scale ) { mWidthMapUnitScale = scale; }
widthMapUnitScale()1104     const QgsMapUnitScale &widthMapUnitScale() const { return mWidthMapUnitScale; }
1105 
1106     /**
1107      * Returns the line symbol layer's ring filter, which controls which rings are
1108      * rendered when the line symbol is being used to draw a polygon's rings.
1109      *
1110      * This setting has no effect when the line symbol is not being rendered
1111      * for a polygon.
1112      *
1113      * \see setRingFilter()
1114      * \since QGIS 3.6
1115      */
1116     RenderRingFilter ringFilter() const;
1117 
1118     /**
1119      * Sets the line symbol layer's ring \a filter, which controls which rings are
1120      * rendered when the line symbol is being used to draw a polygon's rings.
1121      *
1122      * This setting has no effect when the line symbol is not being rendered
1123      * for a polygon.
1124      *
1125      * \see ringFilter()
1126      * \since QGIS 3.6
1127      */
1128     void setRingFilter( QgsLineSymbolLayer::RenderRingFilter filter );
1129 
1130   protected:
1131     QgsLineSymbolLayer( bool locked = false );
1132 
1133     double mWidth = 0;
1134     QgsUnitTypes::RenderUnit mWidthUnit = QgsUnitTypes::RenderMillimeters;
1135     QgsMapUnitScale mWidthMapUnitScale;
1136     double mOffset = 0;
1137     QgsUnitTypes::RenderUnit mOffsetUnit = QgsUnitTypes::RenderMillimeters;
1138     QgsMapUnitScale mOffsetMapUnitScale;
1139 
1140     RenderRingFilter mRingFilter = AllRings;
1141 
1142   private:
1143 #ifdef SIP_RUN
1144     QgsLineSymbolLayer( const QgsLineSymbolLayer &other );
1145 #endif
1146 };
1147 
1148 /**
1149  * \ingroup core
1150  * \class QgsFillSymbolLayer
1151  */
1152 class CORE_EXPORT QgsFillSymbolLayer : public QgsSymbolLayer
1153 {
1154   public:
1155 
1156     //! QgsFillSymbolLayer cannot be copied
1157     QgsFillSymbolLayer( const QgsFillSymbolLayer &other ) = delete;
1158 
1159     //! QgsFillSymbolLayer cannot be copied
1160     QgsFillSymbolLayer &operator=( const QgsFillSymbolLayer &other ) = delete;
1161 
1162     /**
1163      * Renders the fill symbol layer for the polygon whose outer ring is defined by \a points, using the given render \a context.
1164      *
1165      * The \a rings argument optionally specifies a list of polygon rings to render as holes.
1166      */
1167     virtual void renderPolygon( const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
1168 
1169     void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
1170 
setAngle(double angle)1171     void setAngle( double angle ) { mAngle = angle; }
angle()1172     double angle() const { return mAngle; }
1173 
1174   protected:
1175     QgsFillSymbolLayer( bool locked = false );
1176     //! Default method to render polygon
1177     void _renderPolygon( QPainter *p, const QPolygonF &points, const QVector<QPolygonF> *rings, QgsSymbolRenderContext &context );
1178 
1179     double mAngle = 0.0;
1180 
1181   private:
1182 #ifdef SIP_RUN
1183     QgsFillSymbolLayer( const QgsFillSymbolLayer &other );
1184 #endif
1185 };
1186 
1187 class QgsSymbolLayerWidget;  // why does SIP fail, when this isn't here
1188 
1189 #endif
1190 
1191 
1192