Skip to content
Permalink
Browse files

Avoid texture jump when panning maps

We don't need the whole expense of the "Avoid artifacts when rendering as map tiles"
option, because that disables to default clipping of geometry parts which fall
outside the visible canvas extent and accordingly results in a lot of wasted rendering
calculations. Instead, we can just always use the upper left corner of the original
feature geometry before the optimisations like clipping to visible regions are applied,
and use this as the texture origin.

This means we can safely make this handling always applied and not an opt-in setting
  • Loading branch information
nyalldawson committed Jul 11, 2020
1 parent 81518f9 commit 28c8eefa6edf6dc4f66b77ea003cf6a56ba35db6
@@ -841,6 +841,26 @@ Sets a ``geometry`` to use to clip features at render time.

.. seealso:: :py:func:`featureClipGeometry`

.. versionadded:: 3.16
%End

QPointF textureOrigin() const;
%Docstring
Returns the texture origin, which should be used as a brush transform when
rendering using QBrush objects.

.. seealso:: :py:func:`setTextureOrigin`

.. versionadded:: 3.16
%End

void setTextureOrigin( const QPointF &origin );
%Docstring
Sets the texture ``origin``, which should be used as a brush transform when
rendering using QBrush objects.

.. seealso:: :py:func:`textureOrigin`

.. versionadded:: 3.16
%End

@@ -69,6 +69,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
, mDisabledSymbolLayers()
, mClippingRegions( rh.mClippingRegions )
, mFeatureClipGeometry( rh.mFeatureClipGeometry )
, mTextureOrigin( rh.mTextureOrigin )
#ifdef QGISDEBUG
, mHasTransformContext( rh.mHasTransformContext )
#endif
@@ -104,6 +105,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
mCustomRenderingFlags = rh.mCustomRenderingFlags;
mClippingRegions = rh.mClippingRegions;
mFeatureClipGeometry = rh.mFeatureClipGeometry;
mTextureOrigin = rh.mTextureOrigin;
setIsTemporal( rh.isTemporal() );
if ( isTemporal() )
setTemporalRange( rh.temporalRange() );
@@ -534,4 +536,14 @@ void QgsRenderContext::setFeatureClipGeometry( const QgsGeometry &geometry )
mFeatureClipGeometry = geometry;
}

QPointF QgsRenderContext::textureOrigin() const
{
return mTextureOrigin;
}

void QgsRenderContext::setTextureOrigin( const QPointF &origin )
{
mTextureOrigin = origin;
}


@@ -836,6 +836,24 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
*/
void setFeatureClipGeometry( const QgsGeometry &geometry );

/**
* Returns the texture origin, which should be used as a brush transform when
* rendering using QBrush objects.
*
* \see setTextureOrigin()
* \since QGIS 3.16
*/
QPointF textureOrigin() const;

/**
* Sets the texture \a origin, which should be used as a brush transform when
* rendering using QBrush objects.
*
* \see textureOrigin()
* \since QGIS 3.16
*/
void setTextureOrigin( const QPointF &origin );

private:

Flags mFlags;
@@ -930,6 +948,8 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
QList< QgsMapClippingRegion > mClippingRegions;
QgsGeometry mFeatureClipGeometry;

QPointF mTextureOrigin;

#ifdef QGISDEBUG
bool mHasTransformContext = false;
#endif
@@ -1597,7 +1597,14 @@ void QgsImageFillSymbolLayer::renderPolygon( const QPolygonF &points, const QVec
p->setPen( QPen( Qt::NoPen ) );

QTransform bkTransform = mBrush.transform();
if ( context.renderContext().testFlag( QgsRenderContext::RenderMapTile ) )
if ( !context.renderContext().textureOrigin().isNull() )
{
QPointF leftCorner = context.renderContext().textureOrigin();
QTransform t = mBrush.transform();
t.translate( leftCorner.x(), leftCorner.y() );
mBrush.setTransform( t );
}
else if ( context.renderContext().testFlag( QgsRenderContext::RenderMapTile ) )
{
//transform brush to upper left corner of geometry bbox
QPointF leftCorner = points.boundingRect().topLeft();
@@ -832,6 +832,12 @@ void QgsSymbol::renderFeature( const QgsFeature &feature, QgsRenderContext &cont
bool usingSegmentizedGeometry = false;
context.setGeometry( geom.constGet() );

if ( !geom.boundingBox().isNull() )
{
const QPointF boundsOrigin = _getPoint( context, QgsPoint( geom.boundingBox().xMinimum(), geom.boundingBox().yMinimum() ) );
context.setTextureOrigin( boundsOrigin );
}

bool tileMapRendering = context.testFlag( QgsRenderContext::RenderMapTile );

//convert curve types to normal point/line/polygon ones

0 comments on commit 28c8eef

Please sign in to comment.
You can’t perform that action at this time.