@@ -83,7 +83,6 @@ QgsSymbol::QgsSymbol( SymbolType type, const QgsSymbolLayerList &layers )
83
83
, mRenderHints( 0 )
84
84
, mClipFeaturesToExtent( true )
85
85
, mLayer( nullptr )
86
- , mSymbolRenderContext( nullptr )
87
86
{
88
87
89
88
// check they're all correct symbol layers
@@ -188,7 +187,6 @@ void QgsSymbol::_getPolygon( QPolygonF &pts, QList<QPolygonF> &holes, QgsRenderC
188
187
189
188
QgsSymbol::~QgsSymbol ()
190
189
{
191
- delete mSymbolRenderContext ;
192
190
// delete all symbol layers (we own them, so it's okay)
193
191
qDeleteAll ( mLayers );
194
192
}
@@ -377,14 +375,12 @@ bool QgsSymbol::changeSymbolLayer( int index, QgsSymbolLayer *layer )
377
375
378
376
void QgsSymbol::startRender ( QgsRenderContext &context, const QgsFields &fields )
379
377
{
380
- delete mSymbolRenderContext ;
381
- mSymbolRenderContext = new QgsSymbolRenderContext ( context, outputUnit (), mAlpha , false , mRenderHints , nullptr , fields, mapUnitScale () );
378
+ mSymbolRenderContext .reset ( new QgsSymbolRenderContext ( context, outputUnit (), mAlpha , false , mRenderHints , nullptr , fields, mapUnitScale () ) );
382
379
383
380
QgsSymbolRenderContext symbolContext ( context, outputUnit (), mAlpha , false , mRenderHints , nullptr , fields, mapUnitScale () );
384
381
385
- QgsExpressionContextScope *scope = QgsExpressionContextUtils::updateSymbolScope ( this , new QgsExpressionContextScope () );
386
-
387
- mSymbolRenderContext ->setExpressionContextScope ( scope );
382
+ std::unique_ptr< QgsExpressionContextScope > scope ( QgsExpressionContextUtils::updateSymbolScope ( this , new QgsExpressionContextScope () ) );
383
+ mSymbolRenderContext ->setExpressionContextScope ( scope.release () );
388
384
389
385
Q_FOREACH ( QgsSymbolLayer *layer, mLayers )
390
386
{
@@ -410,8 +406,7 @@ void QgsSymbol::stopRender( QgsRenderContext &context )
410
406
}
411
407
}
412
408
413
- delete mSymbolRenderContext ;
414
- mSymbolRenderContext = nullptr ;
409
+ mSymbolRenderContext .reset ( nullptr );
415
410
416
411
mLayer = nullptr ;
417
412
}
@@ -643,6 +638,27 @@ bool QgsSymbol::hasDataDefinedProperties() const
643
638
return false ;
644
639
}
645
640
641
+ // /@cond PRIVATE
642
+
643
+ /* *
644
+ * RAII class to pop scope from an expression context on destruction
645
+ */
646
+ class ExpressionContextScopePopper
647
+ {
648
+ public:
649
+
650
+ ExpressionContextScopePopper () = default ;
651
+
652
+ ~ExpressionContextScopePopper ()
653
+ {
654
+ if ( context )
655
+ context->popScope ();
656
+ }
657
+
658
+ QgsExpressionContext *context = nullptr ;
659
+ };
660
+ // /@endcond PRIVATE
661
+
646
662
void QgsSymbol::renderFeature ( const QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker, int currentVertexMarkerType, int currentVertexMarkerSize )
647
663
{
648
664
QgsGeometry geom = feature.geometry ();
@@ -672,9 +688,17 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
672
688
mSymbolRenderContext ->setGeometryPartCount ( segmentizedGeometry.geometry ()->partCount () );
673
689
mSymbolRenderContext ->setGeometryPartNum ( 1 );
674
690
691
+ ExpressionContextScopePopper scopePopper;
675
692
if ( mSymbolRenderContext ->expressionContextScope () )
676
693
{
694
+ // this is somewhat nasty - by appending this scope here it's now owned
695
+ // by both mSymbolRenderContext AND context.expressionContext()
696
+ // the RAII scopePopper is required to make sure it always has ownership transferred back
697
+ // from context.expressionContext(), even if exceptions of other early exits occur in this
698
+ // function
677
699
context.expressionContext ().appendScope ( mSymbolRenderContext ->expressionContextScope () );
700
+ scopePopper.context = &context.expressionContext ();
701
+
678
702
QgsExpressionContextUtils::updateSymbolScope ( this , mSymbolRenderContext ->expressionContextScope () );
679
703
mSymbolRenderContext ->expressionContextScope ()->addVariable ( QgsExpressionContextScope::StaticVariable ( QgsExpressionContext::EXPR_GEOMETRY_PART_COUNT, mSymbolRenderContext ->geometryPartCount (), true ) );
680
704
mSymbolRenderContext ->expressionContextScope ()->addVariable ( QgsExpressionContextScope::StaticVariable ( QgsExpressionContext::EXPR_GEOMETRY_PART_NUM, 1 , true ) );
@@ -952,14 +976,11 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
952
976
}
953
977
}
954
978
}
955
-
956
- if ( mSymbolRenderContext ->expressionContextScope () )
957
- context.expressionContext ().popScope ();
958
979
}
959
980
960
981
QgsSymbolRenderContext *QgsSymbol::symbolRenderContext ()
961
982
{
962
- return mSymbolRenderContext ;
983
+ return mSymbolRenderContext . get () ;
963
984
}
964
985
965
986
void QgsSymbol::renderVertexMarker ( QPointF pt, QgsRenderContext &context, int currentVertexMarkerType, int currentVertexMarkerSize )
@@ -972,7 +993,6 @@ void QgsSymbol::renderVertexMarker( QPointF pt, QgsRenderContext &context, int c
972
993
973
994
QgsSymbolRenderContext::QgsSymbolRenderContext ( QgsRenderContext &c, QgsUnitTypes::RenderUnit u, qreal alpha, bool selected, QgsSymbol::RenderHints renderHints, const QgsFeature *f, const QgsFields &fields, const QgsMapUnitScale &mapUnitScale )
974
995
: mRenderContext( c )
975
- , mExpressionContextScope( nullptr )
976
996
, mOutputUnit( u )
977
997
, mMapUnitScale( mapUnitScale )
978
998
, mAlpha( alpha )
@@ -985,11 +1005,6 @@ QgsSymbolRenderContext::QgsSymbolRenderContext( QgsRenderContext &c, QgsUnitType
985
1005
{
986
1006
}
987
1007
988
- QgsSymbolRenderContext::~QgsSymbolRenderContext ()
989
- {
990
- delete mExpressionContextScope ;
991
- }
992
-
993
1008
void QgsSymbolRenderContext::setOriginalValueVariable ( const QVariant &value )
994
1009
{
995
1010
mRenderContext .expressionContext ().setOriginalValueVariable ( value );
@@ -1017,12 +1032,12 @@ QgsSymbolRenderContext &QgsSymbolRenderContext::operator=( const QgsSymbolRender
1017
1032
1018
1033
QgsExpressionContextScope *QgsSymbolRenderContext::expressionContextScope ()
1019
1034
{
1020
- return mExpressionContextScope ;
1035
+ return mExpressionContextScope . get () ;
1021
1036
}
1022
1037
1023
1038
void QgsSymbolRenderContext::setExpressionContextScope ( QgsExpressionContextScope *contextScope )
1024
1039
{
1025
- mExpressionContextScope = contextScope;
1040
+ mExpressionContextScope . reset ( contextScope ) ;
1026
1041
}
1027
1042
1028
1043
// /////////////////
0 commit comments