Skip to content
Permalink
Browse files
Set new Qgis::RenderContextFlag::RenderingSubSymbol flag on render co…
…ntexts

whenever a subsymbol component of a parent symbol is being rendered

This flag allows symbol layers to refine their behaviour based on whether
they are a subsymbol or not.
  • Loading branch information
nyalldawson committed Oct 24, 2021
1 parent 99fcbc9 commit 0175782b5a96a027737b9c2a8c8b604ddff44a0c
@@ -874,7 +874,10 @@
QgsRenderContext.ApplyClipAfterReprojection = Qgis.RenderContextFlag.ApplyClipAfterReprojection
QgsRenderContext.ApplyClipAfterReprojection.is_monkey_patched = True
QgsRenderContext.ApplyClipAfterReprojection.__doc__ = "Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using coordinateTransform(). Usually feature geometry clipping occurs using the extent() in the layer's CRS prior to geometry transformation, but in some cases when extent() could not be accurately calculated it is necessary to clip geometries to mapExtent() AFTER transforming them using coordinateTransform()."
Qgis.RenderContextFlag.__doc__ = 'Flags which affect rendering operations.\n\n.. versionadded:: 3.22\n\n' + '* ``DrawEditingInfo``: ' + Qgis.RenderContextFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.RenderContextFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.RenderContextFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.RenderContextFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.RenderContextFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.RenderContextFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.RenderContextFlag.RenderMapTile.__doc__ + '\n' + '* ``Antialiasing``: ' + Qgis.RenderContextFlag.Antialiasing.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.RenderContextFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.RenderContextFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.RenderContextFlag.RenderBlocking.__doc__ + '\n' + '* ``RenderSymbolPreview``: ' + Qgis.RenderContextFlag.RenderSymbolPreview.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.RenderContextFlag.LosslessImageRendering.__doc__ + '\n' + '* ``ApplyScalingWorkaroundForTextRendering``: ' + Qgis.RenderContextFlag.ApplyScalingWorkaroundForTextRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.RenderContextFlag.Render3DMap.__doc__ + '\n' + '* ``ApplyClipAfterReprojection``: ' + Qgis.RenderContextFlag.ApplyClipAfterReprojection.__doc__
QgsRenderContext.RenderingSubSymbol = Qgis.RenderContextFlag.RenderingSubSymbol
QgsRenderContext.RenderingSubSymbol.is_monkey_patched = True
QgsRenderContext.RenderingSubSymbol.__doc__ = "Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol and symbol layer rendering to determine whether the symbol being rendered is a subsymbol. (Since QGIS 3.24)"
Qgis.RenderContextFlag.__doc__ = 'Flags which affect rendering operations.\n\n.. versionadded:: 3.22\n\n' + '* ``DrawEditingInfo``: ' + Qgis.RenderContextFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.RenderContextFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.RenderContextFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.RenderContextFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.RenderContextFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.RenderContextFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.RenderContextFlag.RenderMapTile.__doc__ + '\n' + '* ``Antialiasing``: ' + Qgis.RenderContextFlag.Antialiasing.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.RenderContextFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.RenderContextFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.RenderContextFlag.RenderBlocking.__doc__ + '\n' + '* ``RenderSymbolPreview``: ' + Qgis.RenderContextFlag.RenderSymbolPreview.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.RenderContextFlag.LosslessImageRendering.__doc__ + '\n' + '* ``ApplyScalingWorkaroundForTextRendering``: ' + Qgis.RenderContextFlag.ApplyScalingWorkaroundForTextRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.RenderContextFlag.Render3DMap.__doc__ + '\n' + '* ``ApplyClipAfterReprojection``: ' + Qgis.RenderContextFlag.ApplyClipAfterReprojection.__doc__ + '\n' + '* ``RenderingSubSymbol``: ' + Qgis.RenderContextFlag.RenderingSubSymbol.__doc__
# --
QgsRenderContext.Flags = Qgis.RenderContextFlags
Qgis.RenderContextFlag.baseClass = Qgis
@@ -590,6 +590,7 @@ The development version
ApplyScalingWorkaroundForTextRendering,
Render3DMap,
ApplyClipAfterReprojection,
RenderingSubSymbol,
};
typedef QFlags<Qgis::RenderContextFlag> RenderContextFlags;

@@ -948,6 +948,7 @@ class CORE_EXPORT Qgis
ApplyScalingWorkaroundForTextRendering = 0x2000, //!< Whether a scaling workaround designed to stablise the rendering of small font sizes (or for painters scaled out by a large amount) when rendering text. Generally this is recommended, but it may incur some performance cost.
Render3DMap = 0x4000, //!< Render is for a 3D map
ApplyClipAfterReprojection = 0x8000, //!< Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using coordinateTransform(). Usually feature geometry clipping occurs using the extent() in the layer's CRS prior to geometry transformation, but in some cases when extent() could not be accurately calculated it is necessary to clip geometries to mapExtent() AFTER transforming them using coordinateTransform().
RenderingSubSymbol = 0x10000, //!< Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol and symbol layer rendering to determine whether the symbol being rendered is a subsymbol. (Since QGIS 3.24)
};
//! Render context flags
Q_DECLARE_FLAGS( RenderContextFlags, RenderContextFlag ) SIP_MONKEYPATCH_FLAGS_UNNEST( QgsRenderContext, Flags )
@@ -731,6 +731,9 @@ void QgsArrowSymbolLayer::renderPolyline( const QPolygonF &points, QgsSymbolRend
mExpressionScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT, points.size() + 1, true ) );
mExpressionScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, 1, true ) );

const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

const double prevOpacity = mSymbol->opacity();
mSymbol->setOpacity( prevOpacity * context.opacity() );

@@ -840,6 +843,8 @@ void QgsArrowSymbolLayer::renderPolyline( const QPolygonF &points, QgsSymbolRend
}
}

context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );

mSymbol->setOpacity( prevOpacity );
context.renderContext().expressionContext().popScope();
}
@@ -2939,6 +2939,7 @@ void QgsLinePatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext &
lineRenderContext.setMapToPixel( mtp );
lineRenderContext.setForceVectorOutput( false );
lineRenderContext.setExpressionContext( context.renderContext().expressionContext() );
lineRenderContext.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

fillLineSymbol->startRender( lineRenderContext, context.fields() );

@@ -3402,6 +3403,7 @@ void QgsPointPatternFillSymbolLayer::applyPattern( const QgsSymbolRenderContext
pointRenderContext.setMapToPixel( mtp );
pointRenderContext.setForceVectorOutput( false );
pointRenderContext.setExpressionContext( context.renderContext().expressionContext() );
pointRenderContext.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

mMarkerSymbol->startRender( pointRenderContext, context.fields() );

@@ -3585,6 +3587,9 @@ void QgsPointPatternFillSymbolLayer::renderPolygon( const QPolygonF &points, con
int pointNum = 0;
const bool needsExpressionContext = hasDataDefinedProperties();

const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

bool alternateColumn = false;
int currentCol = -3; // because we actually render a few rows/cols outside the bounds, try to align the col/row numbers to start at 1 for the first visible row/col
for ( double currentX = left; currentX <= right; currentX += width, alternateColumn = !alternateColumn )
@@ -3628,6 +3633,8 @@ void QgsPointPatternFillSymbolLayer::renderPolygon( const QPolygonF &points, con
}
}
}

context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );
}

QVariantMap QgsPointPatternFillSymbolLayer::properties() const
@@ -3998,7 +4005,11 @@ void QgsCentroidFillSymbolLayer::render( QgsRenderContext &context, const QVecto
}

QPointF centroid = pointOnSurface ? QgsSymbolLayerUtils::polygonPointOnSurface( part.exterior, &part.rings ) : QgsSymbolLayerUtils::polygonCentroid( part.exterior );

const bool prevIsSubsymbol = context.flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );
mMarker->renderPoint( centroid, feature.isValid() ? &feature : nullptr, context, -1, selected );
context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );

if ( clipPoints )
{
@@ -4630,13 +4641,18 @@ void QgsRandomMarkerFillSymbolLayer::render( QgsRenderContext &context, const QV
int pointNum = 0;
const bool needsExpressionContext = hasDataDefinedProperties();

const bool prevIsSubsymbol = context.flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

for ( const QgsPointXY &p : std::as_const( randomPoints ) )
{
if ( needsExpressionContext )
scope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum, true ) );
mMarker->renderPoint( QPointF( p.x(), p.y() ), feature.isValid() ? &feature : nullptr, context, -1, selected );
}

context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );

if ( clipPoints )
{
context.painter()->restore();
@@ -446,8 +446,13 @@ void QgsGeometryGeneratorSymbolLayer::render( QgsSymbolRenderContext &context, Q

subSymbolExpressionContextScope->setFeature( f );

const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

mSymbol->renderFeature( f, context.renderContext(), -1, context.selected() );

context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );

if ( mRenderingFeature )
mHasRenderedFeature = true;
}
@@ -2518,7 +2518,12 @@ void QgsMarkerLineSymbolLayer::setSymbolAngle( double angle )

void QgsMarkerLineSymbolLayer::renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer, bool selected )
{
const bool prevIsSubsymbol = context.flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

mMarker->renderPoint( point, feature, context, layer, selected );

context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );
}

double QgsMarkerLineSymbolLayer::width() const
@@ -2795,8 +2800,12 @@ void QgsHashedLineSymbolLayer::renderSymbol( const QPointF &point, const QgsFeat
QPolygonF points;
points << QPointF( start.x(), start.y() ) << QPointF( end.x(), end.y() );

const bool prevIsSubsymbol = context.flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

mHashSymbol->renderPolyline( points, feature, context, layer, selected );

context.setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );
}

double QgsHashedLineSymbolLayer::hashAngle() const
@@ -1913,6 +1913,9 @@ void QgsFilledMarkerSymbolLayer::draw( QgsSymbolRenderContext &context, QgsSimpl
}
p->setPen( Qt::black );

const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

if ( !polygon.isEmpty() )
{
mFill->renderPolygon( polygon, /* rings */ nullptr, context.feature(), context.renderContext(), -1, context.selected() );
@@ -1923,6 +1926,8 @@ void QgsFilledMarkerSymbolLayer::draw( QgsSymbolRenderContext &context, QgsSimpl
mFill->renderPolygon( poly, /* rings */ nullptr, context.feature(), context.renderContext(), -1, context.selected() );
}

context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );

mFill->setOpacity( prevOpacity );
}

@@ -144,13 +144,17 @@ void QgsVectorFieldSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderConte

const QgsRenderContext &ctx = context.renderContext();

const bool prevIsSubsymbol = context.renderContext().flags() & Qgis::RenderContextFlag::RenderingSubSymbol;
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol );

if ( !context.feature() )
{
//preview
QPolygonF line;
line << QPointF( 0, 50 );
line << QPointF( 100, 50 );
mLineSymbol->renderPolyline( line, nullptr, context.renderContext() );
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );
return;
}

@@ -209,7 +213,9 @@ void QgsVectorFieldSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderConte
}

line << destPoint;

mLineSymbol->renderPolyline( line, &f, context.renderContext() );
context.renderContext().setFlag( Qgis::RenderContextFlag::RenderingSubSymbol, prevIsSubsymbol );
}

void QgsVectorFieldSymbolLayer::startRender( QgsSymbolRenderContext &context )

0 comments on commit 0175782

Please sign in to comment.