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 23, 2021
1 parent 757c69e commit 40279cb9963cacdd22711ae2343caf13e54a21ad
@@ -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();
}
@@ -2971,6 +2971,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() );

@@ -3489,6 +3490,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() );

@@ -3756,6 +3758,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 )
@@ -3839,6 +3844,8 @@ void QgsPointPatternFillSymbolLayer::renderPolygon( const QPolygonF &points, con
}
}
}

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

QVariantMap QgsPointPatternFillSymbolLayer::properties() const
@@ -4217,7 +4224,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 )
{
@@ -4850,13 +4861,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, Qgis::Ma
}
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, Qgis::Ma
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 40279cb

Please sign in to comment.