Avoid storing and cloning paint effects for layers if they are just

the default stack unchanged

Speeds up cloning of symbol layers
This commit is contained in:
Nyall Dawson 2019-07-24 08:27:09 +10:00
parent 5981df7adb
commit fee239dbcc
5 changed files with 96 additions and 17 deletions

View File

@ -146,6 +146,8 @@ Returns the symbol layer property definitions.
virtual ~QgsSymbolLayer();
bool enabled() const;
%Docstring
Returns ``True`` if symbol layer is enabled and will be drawn.
@ -461,6 +463,8 @@ Copies paint effect of this layer to another symbol layer
.. versionadded:: 2.9
%End
private:
QgsSymbolLayer( const QgsSymbolLayer &other );
};
@ -489,8 +493,13 @@ Abstract base class for marker symbol layers.
Bottom,
};
virtual void startRender( QgsSymbolRenderContext &context );
%Docstring
QgsMarkerSymbolLayer cannot be copied
%End
virtual void stopRender( QgsSymbolRenderContext &context );
@ -834,6 +843,8 @@ Adjusts a marker offset to account for rotation.
%End
private:
QgsMarkerSymbolLayer( const QgsMarkerSymbolLayer &other );
};
class QgsLineSymbolLayer : QgsSymbolLayer
@ -851,8 +862,13 @@ class QgsLineSymbolLayer : QgsSymbolLayer
InteriorRingsOnly,
};
virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
QgsLineSymbolLayer cannot be copied
%End
virtual QgsUnitTypes::RenderUnit outputUnit() const;
virtual void setMapUnitScale( const QgsMapUnitScale &scale );
@ -1044,6 +1060,9 @@ for a polygon.
QgsLineSymbolLayer( bool locked = false );
private:
QgsLineSymbolLayer( const QgsLineSymbolLayer &other );
};
class QgsFillSymbolLayer : QgsSymbolLayer
@ -1053,7 +1072,13 @@ class QgsFillSymbolLayer : QgsSymbolLayer
#include "qgssymbollayer.h"
%End
public:
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
%Docstring
QgsFillSymbolLayer cannot be copied
%End
virtual void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size );
@ -1068,6 +1093,9 @@ class QgsFillSymbolLayer : QgsSymbolLayer
Default method to render polygon
%End
private:
QgsFillSymbolLayer( const QgsFillSymbolLayer &other );
};

View File

@ -26,6 +26,7 @@
#include "qgsproperty.h"
#include "qgsexpressioncontext.h"
#include "qgssymbollayerutils.h"
#include "qgsapplication.h"
#include <QSize>
#include <QPainter>
@ -163,23 +164,21 @@ Qt::BrushStyle QgsSymbolLayer::dxfBrushStyle() const
QgsPaintEffect *QgsSymbolLayer::paintEffect() const
{
return mPaintEffect;
return mPaintEffect.get();
}
void QgsSymbolLayer::setPaintEffect( QgsPaintEffect *effect )
{
delete mPaintEffect;
mPaintEffect = effect;
if ( effect == mPaintEffect.get() )
return;
mPaintEffect.reset( effect );
}
QgsSymbolLayer::QgsSymbolLayer( QgsSymbol::SymbolType type, bool locked )
: mType( type )
, mEnabled( true )
, mLocked( locked )
{
mPaintEffect = QgsPaintEffectRegistry::defaultStack();
mPaintEffect->setEnabled( false );
}
void QgsSymbolLayer::prepareExpressions( const QgsSymbolRenderContext &context )
@ -204,10 +203,7 @@ const QgsPropertiesDefinition &QgsSymbolLayer::propertyDefinitions()
return sPropertyDefinitions;
}
QgsSymbolLayer::~QgsSymbolLayer()
{
delete mPaintEffect;
}
QgsSymbolLayer::~QgsSymbolLayer() = default;
bool QgsSymbolLayer::isCompatibleWithSymbol( QgsSymbol *symbol ) const
{
@ -392,7 +388,10 @@ void QgsSymbolLayer::copyPaintEffect( QgsSymbolLayer *destLayer ) const
if ( !destLayer || !mPaintEffect )
return;
destLayer->setPaintEffect( mPaintEffect->clone() );
if ( !QgsPaintEffectRegistry::isDefaultStack( mPaintEffect.get() ) )
destLayer->setPaintEffect( mPaintEffect->clone() );
else
destLayer->setPaintEffect( nullptr );
}
QgsMarkerSymbolLayer::QgsMarkerSymbolLayer( bool locked )

View File

@ -187,6 +187,12 @@ class CORE_EXPORT QgsSymbolLayer
virtual ~QgsSymbolLayer();
//! QgsSymbolLayer cannot be copied
QgsSymbolLayer( const QgsSymbolLayer &other ) = delete;
//! QgsSymbolLayer cannot be copied
QgsSymbolLayer &operator=( const QgsSymbolLayer &other ) = delete;
/**
* Returns TRUE if symbol layer is enabled and will be drawn.
* \see setEnabled()
@ -427,15 +433,15 @@ class CORE_EXPORT QgsSymbolLayer
QgsSymbol::SymbolType mType;
//! True if layer is enabled and should be drawn
bool mEnabled;
bool mEnabled = true;
bool mLocked;
bool mLocked = false;
QColor mColor;
int mRenderingPass = 0;
QgsPropertyCollection mDataDefinedProperties;
QgsPaintEffect *mPaintEffect = nullptr;
std::unique_ptr< QgsPaintEffect > mPaintEffect;
QgsFields mFields;
// Configuration of selected symbology implementation
@ -471,6 +477,10 @@ class CORE_EXPORT QgsSymbolLayer
//! Property definitions
static QgsPropertiesDefinition sPropertyDefinitions;
#ifdef SIP_RUN
QgsSymbolLayer( const QgsSymbolLayer &other );
#endif
};
//////////////////////
@ -500,6 +510,12 @@ class CORE_EXPORT QgsMarkerSymbolLayer : public QgsSymbolLayer
Bottom, //!< Align to bottom of symbol
};
//! QgsMarkerSymbolLayer cannot be copied
QgsMarkerSymbolLayer( const QgsMarkerSymbolLayer &other ) = delete;
//! QgsMarkerSymbolLayer cannot be copied
QgsMarkerSymbolLayer &operator=( const QgsMarkerSymbolLayer &other ) = delete;
void startRender( QgsSymbolRenderContext &context ) override;
void stopRender( QgsSymbolRenderContext &context ) override;
@ -783,6 +799,10 @@ class CORE_EXPORT QgsMarkerSymbolLayer : public QgsSymbolLayer
private:
static QgsMarkerSymbolLayer::HorizontalAnchorPoint decodeHorizontalAnchorPoint( const QString &str );
static QgsMarkerSymbolLayer::VerticalAnchorPoint decodeVerticalAnchorPoint( const QString &str );
#ifdef SIP_RUN
QgsMarkerSymbolLayer( const QgsMarkerSymbolLayer &other );
#endif
};
/**
@ -801,6 +821,12 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
InteriorRingsOnly, //!< Render the interior rings only
};
//! QgsLineSymbolLayer cannot be copied
QgsLineSymbolLayer( const QgsLineSymbolLayer &other ) = delete;
//! QgsLineSymbolLayer cannot be copied
QgsLineSymbolLayer &operator=( const QgsLineSymbolLayer &other ) = delete;
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
QgsUnitTypes::RenderUnit outputUnit() const override;
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
@ -970,6 +996,11 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
QgsMapUnitScale mOffsetMapUnitScale;
RenderRingFilter mRingFilter = AllRings;
private:
#ifdef SIP_RUN
QgsLineSymbolLayer( const QgsLineSymbolLayer &other );
#endif
};
/**
@ -979,6 +1010,13 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
class CORE_EXPORT QgsFillSymbolLayer : public QgsSymbolLayer
{
public:
//! QgsFillSymbolLayer cannot be copied
QgsFillSymbolLayer( const QgsFillSymbolLayer &other ) = delete;
//! QgsFillSymbolLayer cannot be copied
QgsFillSymbolLayer &operator=( const QgsFillSymbolLayer &other ) = delete;
virtual void renderPolygon( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) = 0;
void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
@ -992,6 +1030,11 @@ class CORE_EXPORT QgsFillSymbolLayer : public QgsSymbolLayer
void _renderPolygon( QPainter *p, const QPolygonF &points, const QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
double mAngle = 0.0;
private:
#ifdef SIP_RUN
QgsFillSymbolLayer( const QgsFillSymbolLayer &other );
#endif
};
class QgsSymbolLayerWidget; // why does SIP fail, when this isn't here

View File

@ -32,6 +32,7 @@
#include "qgsrendercontext.h"
#include "qgsunittypes.h"
#include "qgsexpressioncontextutils.h"
#include "qgseffectstack.h"
#include <QColor>
#include <QFont>
@ -1029,7 +1030,9 @@ QgsSymbolLayer *QgsSymbolLayerUtils::loadSymbolLayer( QDomElement &element, cons
QDomElement effectElem = element.firstChildElement( QStringLiteral( "effect" ) );
if ( !effectElem.isNull() )
{
layer->setPaintEffect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
std::unique_ptr< QgsPaintEffect > effect( QgsApplication::paintEffectRegistry()->createEffect( effectElem ) );
if ( effect && !QgsPaintEffectRegistry::isDefaultStack( effect.get() ) )
layer->setPaintEffect( effect.release() );
}
// restore data defined properties
@ -1090,7 +1093,7 @@ QDomElement QgsSymbolLayerUtils::saveSymbol( const QString &name, QgsSymbol *sym
QgsApplication::symbolLayerRegistry()->resolvePaths( layer->layerType(), props, context.pathResolver(), true );
saveProperties( props, doc, layerEl );
if ( !QgsPaintEffectRegistry::isDefaultStack( layer->paintEffect() ) )
if ( layer->paintEffect() && !QgsPaintEffectRegistry::isDefaultStack( layer->paintEffect() ) )
layer->paintEffect()->saveProperties( doc, layerEl );
QDomElement ddProps = doc.createElement( QStringLiteral( "data_defined_properties" ) );

View File

@ -23,6 +23,7 @@
#include "qgssymbollayer.h"
#include "qgssymbollayerregistry.h"
#include "qgspainteffectregistry.h"
#include "qgsapplication.h"
#include "qgslogger.h"
@ -132,6 +133,11 @@ QgsLayerPropertiesWidget::QgsLayerPropertiesWidget( QgsSymbolLayer *layer, const
this->connectChildPanel( mEffectWidget );
if ( !mLayer->paintEffect() )
{
mLayer->setPaintEffect( QgsPaintEffectRegistry::defaultStack() );
mLayer->paintEffect()->setEnabled( false );
}
mEffectWidget->setPaintEffect( mLayer->paintEffect() );
registerDataDefinedButton( mEnabledDDBtn, QgsSymbolLayer::PropertyLayerEnabled );