Skip to content

Commit

Permalink
Simplify some painter related operations and make safer
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 4, 2020
1 parent 8319fd7 commit 61193fc
Show file tree
Hide file tree
Showing 69 changed files with 183 additions and 298 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_generated/qgsrendercontext.sip.in
Expand Up @@ -111,6 +111,17 @@ Returns the destination QPainter for the render operation.
%End


void setPainterFlagsUsingContext( QPainter *painter = 0 ) const;
%Docstring
Sets relevant flags on a destination ``painter``, using the flags and settings
currently defined for the render context.

If no ``painter`` is specified, then the flags will be applied to the render
context's :py:func:`~QgsRenderContext.painter`.

.. versionadded:: 3.16
%End

QPainter *maskPainter( int id = 0 );
%Docstring
Returns a mask QPainter for the render operation.
Expand Down
7 changes: 2 additions & 5 deletions src/app/decorations/qgsdecorationcopyright.cpp
Expand Up @@ -116,9 +116,8 @@ void QgsDecorationCopyright::render( const QgsMapSettings &mapSettings, QgsRende
if ( !enabled() )
return;

context.painter()->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
context.painter()->setRenderHint( QPainter::Antialiasing, true );
QgsScopedQPainterState painterState( context.painter() );
context.setPainterFlagsUsingContext();

QString displayString = QgsExpression::replaceExpressionText( mLabelText, &context.expressionContext() );
QStringList displayStringList = displayString.split( '\n' );
Expand Down Expand Up @@ -201,7 +200,5 @@ void QgsDecorationCopyright::render( const QgsMapSettings &mapSettings, QgsRende

//Paint label to canvas
QgsTextRenderer::drawText( QPointF( xOffset, yOffset ), 0.0, horizontalAlignment, displayStringList, context, mTextFormat );

context.painter()->restore();
}

4 changes: 1 addition & 3 deletions src/app/decorations/qgsdecorationimage.cpp
Expand Up @@ -199,7 +199,7 @@ void QgsDecorationImage::render( const QgsMapSettings &mapSettings, QgsRenderCon
return;
}

context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );

// need width/height of paint device
QPaintDevice *device = context.painter()->device();
Expand Down Expand Up @@ -276,6 +276,4 @@ void QgsDecorationImage::render( const QgsMapSettings &mapSettings, QgsRenderCon
// nothing happening here, function already returned in the first switch
break;
}

context.painter()->restore();
}
7 changes: 3 additions & 4 deletions src/app/decorations/qgsdecorationlayoutextent.cpp
Expand Up @@ -120,9 +120,9 @@ void QgsDecorationLayoutExtent::render( const QgsMapSettings &mapSettings, QgsRe
if ( !mSymbol )
return;

context.painter()->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
context.painter()->setRenderHint( QPainter::Antialiasing, true );
QgsScopedQPainterState painterState( context.painter() );
context.setPainterFlagsUsingContext();

mSymbol->startRender( context );

const QgsMapToPixel &m2p = mapSettings.mapToPixel();
Expand Down Expand Up @@ -172,7 +172,6 @@ void QgsDecorationLayoutExtent::render( const QgsMapSettings &mapSettings, QgsRe
}
}
mSymbol->stopRender( context );
context.painter()->restore();
}

bool QgsDecorationLayoutExtent::labelExtents() const
Expand Down
3 changes: 1 addition & 2 deletions src/app/decorations/qgsdecorationnortharrow.cpp
Expand Up @@ -140,7 +140,7 @@ void QgsDecorationNorthArrow::render( const QgsMapSettings &mapSettings, QgsRend
double centerYDouble = size.height() / 2.0;

//save the current canvas rotation
context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );
//
//work out how to shift the image so that it rotates
// properly about its center
Expand Down Expand Up @@ -239,6 +239,5 @@ void QgsDecorationNorthArrow::render( const QgsMapSettings &mapSettings, QgsRend
svg.render( context.painter(), QRectF( 0, 0, size.width(), size.height() ) );

//unrotate the canvas again
context.painter()->restore();
}
}
3 changes: 1 addition & 2 deletions src/app/decorations/qgsdecorationscalebar.cpp
Expand Up @@ -434,8 +434,7 @@ void QgsDecorationScaleBar::render( const QgsMapSettings &mapSettings, QgsRender
QgsDebugMsg( QStringLiteral( "Unsupported placement index of %1" ).arg( static_cast<int>( mPlacement ) ) );
}

context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );
context.painter()->translate( originX, originY );
mStyle->draw( context, mSettings, scaleContext );
context.painter()->restore();
}
7 changes: 2 additions & 5 deletions src/app/decorations/qgsdecorationtitle.cpp
Expand Up @@ -105,9 +105,8 @@ void QgsDecorationTitle::render( const QgsMapSettings &mapSettings, QgsRenderCon
if ( !enabled() )
return;

context.painter()->save();
if ( context.flags() & QgsRenderContext::Antialiasing )
context.painter()->setRenderHint( QPainter::Antialiasing, true );
QgsScopedQPainterState painterState( context.painter() );
context.setPainterFlagsUsingContext();

QString displayString = QgsExpression::replaceExpressionText( mLabelText, &context.expressionContext() );
QStringList displayStringList = displayString.split( '\n' );
Expand Down Expand Up @@ -221,7 +220,5 @@ void QgsDecorationTitle::render( const QgsMapSettings &mapSettings, QgsRenderCon

// Paint label to canvas
QgsTextRenderer::drawText( QPointF( xOffset, yOffset ), 0.0, horizontalAlignment, displayStringList, context, mTextFormat );

context.painter()->restore();
}

7 changes: 2 additions & 5 deletions src/app/georeferencer/qgsresidualplotitem.cpp
Expand Up @@ -146,12 +146,11 @@ void QgsResidualPlotItem::paint( QPainter *painter, const QStyleOptionGraphicsIt

if ( frameEnabled() )
{
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setPen( pen() );
painter->setBrush( Qt::NoBrush );
painter->setRenderHint( QPainter::Antialiasing, true );
painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
painter->restore();
}
}

Expand Down Expand Up @@ -252,7 +251,7 @@ void QgsResidualPlotItem::drawArrowHead( QPainter *p, const double x, const doub
arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );

p->save();
QgsScopedQPainterState painterState( p );

QPen arrowPen = p->pen();
arrowPen.setJoinStyle( Qt::RoundJoin );
Expand All @@ -262,8 +261,6 @@ void QgsResidualPlotItem::drawArrowHead( QPainter *p, const double x, const doub
p->setBrush( arrowBrush );
arrowBrush.setStyle( Qt::SolidPattern );
p->drawPolygon( arrowHeadPoly );

p->restore();
}

double QgsResidualPlotItem::angle( QPointF p1, QPointF p2 )
Expand Down
5 changes: 2 additions & 3 deletions src/app/pluginmanager/qgspluginitemdelegate.cpp
Expand Up @@ -16,6 +16,7 @@
***************************************************************************/

#include "qgspluginitemdelegate.h"
#include "qgsrendercontext.h"
#include <QPainter>
#include <QFont>
#include <QStyleOptionViewItem>
Expand All @@ -39,7 +40,7 @@ QSize QgsPluginItemDelegate::sizeHint( const QStyleOptionViewItem &option, const

void QgsPluginItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setRenderHint( QPainter::SmoothPixmapTransform );
QStyle *style = QApplication::style();
int pixelsHigh = QApplication::fontMetrics().height();
Expand Down Expand Up @@ -100,6 +101,4 @@ void QgsPluginItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem
painter->setFont( font );
}
painter->drawText( option.rect.left() + pixelsHigh * 2.4, option.rect.bottom() - pixelsHigh * 0.4, index.data( Qt::DisplayRole ).toString() );

painter->restore();
}
9 changes: 3 additions & 6 deletions src/app/qgsprojectlistitemdelegate.cpp
Expand Up @@ -18,6 +18,7 @@
#include "qgsnewsfeedmodel.h"
#include "qgswebframe.h"
#include "qgsapplication.h"
#include "qgsrendercontext.h"

#include <QApplication>
#include <QPainter>
Expand All @@ -33,7 +34,7 @@ QgsProjectListItemDelegate::QgsProjectListItemDelegate( QObject *parent )

void QgsProjectListItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
painter->save();
QgsScopedQPainterState painterState( painter );

QTextDocument doc;
QPixmap icon = qvariant_cast<QPixmap>( index.data( Qt::DecorationRole ) );
Expand Down Expand Up @@ -90,8 +91,6 @@ void QgsProjectListItemDelegate::paint( QPainter *painter, const QStyleOptionVie
painter->translate( option.rect.left() + ( !icon.isNull() ? icon.width() + 3.125 * mRoundedRectSizePixels : 1.875 * mRoundedRectSizePixels ), option.rect.top() + 1.875 * mRoundedRectSizePixels );
ctx.clip = QRect( 0, 0, option.rect.width() - ( !icon.isNull() ? icon.width() - 4.375 * mRoundedRectSizePixels : 3.125 * mRoundedRectSizePixels ), option.rect.height() - 3.125 * mRoundedRectSizePixels );
doc.documentLayout()->draw( painter, ctx );

painter->restore();
}

QSize QgsProjectListItemDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
Expand Down Expand Up @@ -189,7 +188,7 @@ QgsNewsItemListItemDelegate::QgsNewsItemListItemDelegate( QObject *parent )

void QgsNewsItemListItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{
painter->save();
QgsScopedQPainterState painterState( painter );

QTextDocument doc;
QPixmap icon = qvariant_cast<QPixmap>( index.data( Qt::DecorationRole ) );
Expand Down Expand Up @@ -253,8 +252,6 @@ void QgsNewsItemListItemDelegate::paint( QPainter *painter, const QStyleOptionVi
painter->translate( option.rect.left() + ( !icon.isNull() ? icon.width() + 3.125 * mRoundedRectSizePixels : 1.875 * mRoundedRectSizePixels ), option.rect.top() + 1.875 * mRoundedRectSizePixels );
ctx.clip = QRect( 0, 0, option.rect.width() - ( !icon.isNull() ? icon.width() - 4.375 * mRoundedRectSizePixels : 3.125 * mRoundedRectSizePixels ), option.rect.height() - 3.125 * mRoundedRectSizePixels );
doc.documentLayout()->draw( painter, ctx );

painter->restore();
}

QSize QgsNewsItemListItemDelegate::sizeHint( const QStyleOptionViewItem &option, const QModelIndex &index ) const
Expand Down
7 changes: 3 additions & 4 deletions src/core/annotations/qgsannotation.cpp
Expand Up @@ -138,7 +138,9 @@ void QgsAnnotation::render( QgsRenderContext &context ) const
return;
}

painter->save();
QgsScopedQPainterState painterState( context.painter() );
context.setPainterFlagsUsingContext();

drawFrame( context );
if ( mHasFixedMapPosition )
{
Expand All @@ -162,7 +164,6 @@ void QgsAnnotation::render( QgsRenderContext &context ) const
// context.painter()->scale( dotsPerMM, dotsPerMM );

renderAnnotation( context, size );
painter->restore();
}

void QgsAnnotation::setMarkerSymbol( QgsMarkerSymbol *symbol )
Expand Down Expand Up @@ -354,8 +355,6 @@ void QgsAnnotation::drawFrame( QgsRenderContext &context ) const
if ( !mFillSymbol )
return;

context.painter()->setRenderHint( QPainter::Antialiasing, context.flags() & QgsRenderContext::Antialiasing );

QPolygonF poly;
poly.reserve( 9 + ( mHasFixedMapPosition ? 3 : 0 ) );
QVector<QPolygonF> rings; //empty list
Expand Down
4 changes: 1 addition & 3 deletions src/core/annotations/qgshtmlannotation.cpp
Expand Up @@ -84,15 +84,13 @@ void QgsHtmlAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size
}

// scale painter back to 96 dpi, so layout prints match screen rendering
context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );
const double scaleFactor = context.painter()->device()->logicalDpiX() / 96.0;
context.painter()->scale( scaleFactor, scaleFactor );
size /= scaleFactor;

mWebPage->setViewportSize( size.toSize() );
mWebPage->mainFrame()->render( context.painter() );

context.painter()->restore();
}

QSizeF QgsHtmlAnnotation::minimumFrameSize() const
Expand Down
4 changes: 1 addition & 3 deletions src/core/annotations/qgstextannotation.cpp
Expand Up @@ -57,7 +57,7 @@ void QgsTextAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size
}

// scale painter back to 96 dpi, so layout prints match screen rendering
context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );
const double scaleFactor = context.painter()->device()->logicalDpiX() / 96.0;
context.painter()->scale( scaleFactor, scaleFactor );
size /= scaleFactor;
Expand All @@ -74,8 +74,6 @@ void QgsTextAnnotation::renderAnnotation( QgsRenderContext &context, QSizeF size
}
//draw text document
mDocument->drawContents( painter, clipRect );

painter->restore();
}

void QgsTextAnnotation::writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const
Expand Down
3 changes: 1 addition & 2 deletions src/core/effects/qgsblureffect.cpp
Expand Up @@ -65,10 +65,9 @@ void QgsBlurEffect::drawBlurredImage( QgsRenderContext &context, QImage &image )
QgsImageOperation::multiplyOpacity( image, mOpacity );

QPainter *painter = context.painter();
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setCompositionMode( mBlendMode );
painter->drawImage( imageOffset( context ), image );
painter->restore();
}

QgsStringMap QgsBlurEffect::properties() const
Expand Down
3 changes: 1 addition & 2 deletions src/core/effects/qgscoloreffect.cpp
Expand Up @@ -50,10 +50,9 @@ void QgsColorEffect::draw( QgsRenderContext &context )
QgsImageOperation::adjustHueSaturation( image, mSaturation, mColorizeOn ? mColorizeColor : QColor(), mColorizeStrength / 100.0 );

QgsImageOperation::multiplyOpacity( image, mOpacity );
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setCompositionMode( mBlendMode );
painter->drawImage( imageOffset( context ), image );
painter->restore();
}


Expand Down
4 changes: 1 addition & 3 deletions src/core/effects/qgseffectstack.cpp
Expand Up @@ -136,11 +136,9 @@ void QgsEffectStack::draw( QgsRenderContext &context )
QPicture *pic = results.takeLast();
if ( mEffectList.at( i )->drawMode() != QgsPaintEffect::Modifier )
{
context.painter()->save();
QgsScopedQPainterState painterState( context.painter() );
fixQPictureDpi( context.painter() );
context.painter()->drawPicture( 0, 0, *pic );
context.painter()->restore();

}
delete pic;
}
Expand Down
3 changes: 1 addition & 2 deletions src/core/effects/qgsgloweffect.cpp
Expand Up @@ -92,10 +92,9 @@ void QgsGlowEffect::draw( QgsRenderContext &context )
}

QPainter *painter = context.painter();
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setCompositionMode( mBlendMode );
painter->drawImage( imageOffset( context ), im );
painter->restore();
}

QgsStringMap QgsGlowEffect::properties() const
Expand Down
6 changes: 2 additions & 4 deletions src/core/effects/qgspainteffect.cpp
Expand Up @@ -159,10 +159,9 @@ void QgsPaintEffect::drawSource( QPainter &painter )
{
if ( requiresQPainterDpiFix )
{
painter.save();
QgsScopedQPainterState painterState( &painter );
fixQPictureDpi( &painter );
painter.drawPicture( 0, 0, *mPicture );
painter.restore();
}
else
{
Expand Down Expand Up @@ -250,10 +249,9 @@ void QgsDrawSourceEffect::draw( QgsRenderContext &context )
//rasterize source and apply modifications
QImage image = sourceAsImage( context )->copy();
QgsImageOperation::multiplyOpacity( image, mOpacity );
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setCompositionMode( mBlendMode );
painter->drawImage( imageOffset( context ), image );
painter->restore();
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/core/effects/qgsshadoweffect.cpp
Expand Up @@ -34,7 +34,7 @@ void QgsShadowEffect::draw( QgsRenderContext &context )
QImage colorisedIm = sourceAsImage( context )->copy();

QPainter *painter = context.painter();
painter->save();
QgsScopedQPainterState painterState( painter );
painter->setCompositionMode( mBlendMode );

if ( !exteriorShadow() )
Expand Down Expand Up @@ -88,7 +88,6 @@ void QgsShadowEffect::draw( QgsRenderContext &context )
{
painter->drawImage( imageOffset( context ) + transPt, colorisedIm );
}
painter->restore();
}

QgsStringMap QgsShadowEffect::properties() const
Expand Down
4 changes: 1 addition & 3 deletions src/core/effects/qgstransformeffect.cpp
Expand Up @@ -36,13 +36,11 @@ void QgsTransformEffect::draw( QgsRenderContext &context )
QPainter *painter = context.painter();

//apply transformations
painter->save();
QgsScopedQPainterState painterState( painter );

QTransform t = createTransform( context );
painter->setTransform( t, true );
drawSource( *painter );

painter->restore();
}

QgsStringMap QgsTransformEffect::properties() const
Expand Down

0 comments on commit 61193fc

Please sign in to comment.