Skip to content

Commit

Permalink
Merge pull request #58122 from nyalldawson/painter_dpi_methods
Browse files Browse the repository at this point in the history
Cleanup QPicture dpi scaling workarounds
  • Loading branch information
troopa81 authored Jul 17, 2024
2 parents 9e47ca4 + f7237e2 commit 25c28d6
Show file tree
Hide file tree
Showing 20 changed files with 222 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,16 @@ effects.
.. seealso:: :py:func:`sourceAsImage`
%End

void fixQPictureDpi( QPainter *painter ) const;
void fixQPictureDpi( QPainter *painter ) const /Deprecated/;
%Docstring
Applies a workaround to a QPainter to avoid an issue with incorrect scaling
when drawing QPictures. This may need to be called by derived classes prior
to rendering results onto a painter.

:param painter: destination painter

.. deprecated::
QGIS 3.40, use :py:func:`QgsPainting.drawPicture()` or :py:func:`QgsPainting.applyScaleFixForQPictureDpi()` instead.
%End

};
Expand Down
51 changes: 51 additions & 0 deletions python/PyQt6/core/auto_generated/painting/qgspainting.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,57 @@ Returns ``True`` if the triangle could be rendered, or ``False`` if it could not
.. versionadded:: 3.34
%End

static int qtDefaultDpiX();
%Docstring
Returns the default Qt horizontal DPI.

.. note::

This method proxies the internal Qt :py:func:`~QgsPainting.qt_defaultDpiX` function.

.. seealso:: :py:func:`qtDefaultDpiY`

.. versionadded:: 3.40
%End

static int qtDefaultDpiY();
%Docstring
Returns the default Qt vertical DPI.

.. note::

This method proxies the internal Qt :py:func:`~QgsPainting.qt_defaultDpiY` function.

.. seealso:: :py:func:`qtDefaultDpiX`

.. versionadded:: 3.40
%End

static void applyScaleFixForQPictureDpi( QPainter *painter );
%Docstring
Applies a workaround to a ``painter`` to avoid an issue with incorrect scaling
when drawing QPictures.

.. note::

This is a low-level method, which alters the ``painter`` state and relies on the
caller saving/restoring painter state accordingly. Consider using
the high-level :py:func:`~QgsPainting.drawPicture` method instead.

.. seealso:: :py:func:`drawPicture`

.. versionadded:: 3.40
%End

static void drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture );
%Docstring
Draws a picture onto a ``painter``, correctly applying workarounds to avoid issues
with incorrect scaling.

.. seealso:: :py:func:`applyScaleFixForQPictureDpi`

.. versionadded:: 3.40
%End
};

/************************************************************************
Expand Down
5 changes: 4 additions & 1 deletion python/core/auto_generated/effects/qgspainteffect.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -305,13 +305,16 @@ effects.
.. seealso:: :py:func:`sourceAsImage`
%End

void fixQPictureDpi( QPainter *painter ) const;
void fixQPictureDpi( QPainter *painter ) const /Deprecated/;
%Docstring
Applies a workaround to a QPainter to avoid an issue with incorrect scaling
when drawing QPictures. This may need to be called by derived classes prior
to rendering results onto a painter.

:param painter: destination painter

.. deprecated::
QGIS 3.40, use :py:func:`QgsPainting.drawPicture()` or :py:func:`QgsPainting.applyScaleFixForQPictureDpi()` instead.
%End

};
Expand Down
51 changes: 51 additions & 0 deletions python/core/auto_generated/painting/qgspainting.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,57 @@ Returns ``True`` if the triangle could be rendered, or ``False`` if it could not
.. versionadded:: 3.34
%End

static int qtDefaultDpiX();
%Docstring
Returns the default Qt horizontal DPI.

.. note::

This method proxies the internal Qt :py:func:`~QgsPainting.qt_defaultDpiX` function.

.. seealso:: :py:func:`qtDefaultDpiY`

.. versionadded:: 3.40
%End

static int qtDefaultDpiY();
%Docstring
Returns the default Qt vertical DPI.

.. note::

This method proxies the internal Qt :py:func:`~QgsPainting.qt_defaultDpiY` function.

.. seealso:: :py:func:`qtDefaultDpiX`

.. versionadded:: 3.40
%End

static void applyScaleFixForQPictureDpi( QPainter *painter );
%Docstring
Applies a workaround to a ``painter`` to avoid an issue with incorrect scaling
when drawing QPictures.

.. note::

This is a low-level method, which alters the ``painter`` state and relies on the
caller saving/restoring painter state accordingly. Consider using
the high-level :py:func:`~QgsPainting.drawPicture` method instead.

.. seealso:: :py:func:`drawPicture`

.. versionadded:: 3.40
%End

static void drawPicture( QPainter *painter, const QPointF &point, const QPicture &picture );
%Docstring
Draws a picture onto a ``painter``, correctly applying workarounds to avoid issues
with incorrect scaling.

.. seealso:: :py:func:`applyScaleFixForQPictureDpi`

.. versionadded:: 3.40
%End
};

/************************************************************************
Expand Down
2 changes: 0 additions & 2 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,6 @@
#include <QNetworkProxy>
#include <QAuthenticator>

Q_GUI_EXPORT extern int qt_defaultDpiX();

//
// Mac OS X Includes
// Must include before GEOS 3 due to unqualified use of 'Point'
Expand Down
2 changes: 0 additions & 2 deletions src/app/qgsanimationexportdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
#include <QRegularExpression>
#include <QRegularExpressionValidator>

Q_GUI_EXPORT extern int qt_defaultDpiX();

QgsAnimationExportDialog::QgsAnimationExportDialog( QWidget *parent, QgsMapCanvas *mapCanvas, const QList< QgsMapDecoration * > &decorations )
: QDialog( parent )
, mMapCanvas( mapCanvas )
Expand Down
2 changes: 0 additions & 2 deletions src/app/qgsmapsavedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@
#include "qgsfileutils.h"
#include "qgsannotationlayer.h"

Q_GUI_EXPORT extern int qt_defaultDpiX();

QgsMapSaveDialog::QgsMapSaveDialog( QWidget *parent, QgsMapCanvas *mapCanvas, const QList<QgsMapDecoration *> &decorations, const QList< QgsAnnotation *> &annotations, DialogType type )
: QDialog( parent )
, mDialogType( type )
Expand Down
5 changes: 2 additions & 3 deletions src/core/annotations/qgsannotation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@
#include "qgssymbol.h"
#include "qgsmarkersymbol.h"
#include "qgsfillsymbol.h"
#include "qgspainting.h"

#include <QPen>
#include <QPainter>

Q_GUI_EXPORT extern int qt_defaultDpiX();

QgsAnnotation::QgsAnnotation( QObject *parent )
: QObject( parent )
, mMarkerSymbol( new QgsMarkerSymbol() )
Expand Down Expand Up @@ -329,7 +328,7 @@ void QgsAnnotation::_readXml( const QDomElement &annotationElem, const QgsReadWr
}

mContentsMargins = QgsMargins::fromString( annotationElem.attribute( QStringLiteral( "contentsMargin" ) ) );
const double dpiScale = 25.4 / qt_defaultDpiX();
const double dpiScale = 25.4 / QgsPainting::qtDefaultDpiX();
if ( annotationElem.hasAttribute( QStringLiteral( "frameWidthMM" ) ) )
mFrameSize.setWidth( annotationElem.attribute( QStringLiteral( "frameWidthMM" ), QStringLiteral( "5" ) ).toDouble() );
else
Expand Down
5 changes: 2 additions & 3 deletions src/core/effects/qgseffectstack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "qgspainteffectregistry.h"
#include "qgsrendercontext.h"
#include "qgsapplication.h"
#include "qgspainting.h"
#include <QPicture>

QgsEffectStack::QgsEffectStack( const QgsEffectStack &other )
Expand Down Expand Up @@ -136,9 +137,7 @@ void QgsEffectStack::draw( QgsRenderContext &context )
QPicture *pic = results.takeLast();
if ( mEffectList.at( i )->drawMode() != QgsPaintEffect::Modifier )
{
const QgsScopedQPainterState painterState( context.painter() );
fixQPictureDpi( context.painter() );
context.painter()->drawPicture( 0, 0, *pic );
QgsPainting::drawPicture( context.painter(), QPointF( 0, 0 ), *pic );
}
delete pic;
}
Expand Down
16 changes: 4 additions & 12 deletions src/core/effects/qgspainteffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,9 @@
#include "qgslogger.h"
#include "qgsrendercontext.h"
#include "qgssymbollayerutils.h"
#include <QPicture>
#include "qgspainting.h"

Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();
#include <QPicture>

QgsPaintEffect::QgsPaintEffect( const QgsPaintEffect &other )
: mEnabled( other.enabled() )
Expand Down Expand Up @@ -132,9 +131,7 @@ void QgsPaintEffect::drawSource( QPainter &painter )
{
if ( requiresQPainterDpiFix )
{
const QgsScopedQPainterState painterState( &painter );
fixQPictureDpi( &painter );
painter.drawPicture( 0, 0, *mPicture );
QgsPainting::drawPicture( &painter, QPointF( 0, 0 ), *mPicture );
}
else
{
Expand Down Expand Up @@ -180,12 +177,7 @@ QRectF QgsPaintEffect::boundingRect( const QRectF &rect, const QgsRenderContext

void QgsPaintEffect::fixQPictureDpi( QPainter *painter ) const
{
// QPicture makes an assumption that we drawing to it with system DPI.
// Then when being drawn, it scales the painter. The following call
// negates the effect. There is no way of setting QPicture's DPI.
// See QTBUG-20361
painter->scale( static_cast< double >( qt_defaultDpiX() ) / painter->device()->logicalDpiX(),
static_cast< double >( qt_defaultDpiY() ) / painter->device()->logicalDpiY() );
QgsPainting::applyScaleFixForQPictureDpi( painter );
}

QRectF QgsPaintEffect::imageBoundingRect( const QgsRenderContext &context ) const
Expand Down
4 changes: 3 additions & 1 deletion src/core/effects/qgspainteffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,10 @@ class CORE_EXPORT QgsPaintEffect SIP_NODEFAULTCTORS
* when drawing QPictures. This may need to be called by derived classes prior
* to rendering results onto a painter.
* \param painter destination painter
*
* \deprecated QGIS 3.40, use QgsPainting::drawPicture() or QgsPainting::applyScaleFixForQPictureDpi() instead.
*/
void fixQPictureDpi( QPainter *painter ) const;
Q_DECL_DEPRECATED void fixQPictureDpi( QPainter *painter ) const SIP_DEPRECATED;

private:

Expand Down
24 changes: 3 additions & 21 deletions src/core/maprenderer/qgsmaprenderercustompainterjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,10 @@
#include "qgsmaplayerrenderer.h"
#include "qgsmaplayerlistutils_p.h"
#include "qgselevationmap.h"
#include "qgspainting.h"

#include <QtConcurrentRun>

Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();

static void _fixQPictureDPI( QPainter *p )
{
// QPicture makes an assumption that we drawing to it with system DPI.
// Then when being drawn, it scales the painter. The following call
// negates the effect. There is no way of setting QPicture's DPI.
// See QTBUG-20361
p->scale( static_cast< double >( qt_defaultDpiX() ) / p->device()->logicalDpiX(),
static_cast< double >( qt_defaultDpiY() ) / p->device()->logicalDpiY() );
}

//
// QgsMapRendererAbstractCustomPainterJob
//
Expand Down Expand Up @@ -480,21 +468,15 @@ void QgsMapRendererCustomPainterJob::doRender()
// if there is vector rendering we use it, else we use the raster rendering
if ( job.picture )
{
mPainter->save();
_fixQPictureDPI( mPainter );
mPainter->drawPicture( 0, 0, *job.picture );
mPainter->restore();
QgsPainting::drawPicture( mPainter, QPointF( 0, 0 ), *job.picture );
}
else
mPainter->drawImage( 0, 0, *job.img );
}

if ( mLabelJob.picture )
{
mPainter->save();
_fixQPictureDPI( mPainter );
mPainter->drawPicture( 0, 0, *mLabelJob.picture );
mPainter->restore();
QgsPainting::drawPicture( mPainter, QPointF( 0, 0 ), *mLabelJob.picture );
}
}
}
Expand Down
12 changes: 5 additions & 7 deletions src/core/painting/qgsgeometrypaintdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@
#include "qgsgeos.h"
#include "qgsmultipolygon.h"
#include "qgsmultilinestring.h"

Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();
#include "qgspainting.h"

//
// QgsGeometryPaintEngine
Expand Down Expand Up @@ -652,18 +650,18 @@ int QgsGeometryPaintDevice::metric( PaintDeviceMetric m ) const
val = static_cast< int >( mPaintEngine->geometry().boundingBox().height() );
break;
case PdmWidthMM:
val = static_cast< int >( 25.4 / qt_defaultDpiX() * mPaintEngine->geometry().boundingBox().width() );
val = static_cast< int >( 25.4 / QgsPainting::qtDefaultDpiX() * mPaintEngine->geometry().boundingBox().width() );
break;
case PdmHeightMM:
val = static_cast< int >( 25.4 / qt_defaultDpiY() * mPaintEngine->geometry().boundingBox().height() );
val = static_cast< int >( 25.4 / QgsPainting::qtDefaultDpiY() * mPaintEngine->geometry().boundingBox().height() );
break;
case PdmDpiX:
case PdmPhysicalDpiX:
val = qt_defaultDpiX();
val = QgsPainting::qtDefaultDpiX();
break;
case PdmDpiY:
case PdmPhysicalDpiY:
val = qt_defaultDpiY();
val = QgsPainting::qtDefaultDpiY();
break;
case PdmNumColors:
val = 16777216;
Expand Down
13 changes: 5 additions & 8 deletions src/core/painting/qgsmaskpaintdevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@
***************************************************************************/

#include "qgsmaskpaintdevice.h"


Q_GUI_EXPORT extern int qt_defaultDpiX();
Q_GUI_EXPORT extern int qt_defaultDpiY();
#include "qgspainting.h"

///@cond PRIVATE

Expand Down Expand Up @@ -85,18 +82,18 @@ int QgsMaskPaintDevice::metric( PaintDeviceMetric m ) const
val = static_cast< int >( mPaintEngine->maskPainterPath().boundingRect().height() );
break;
case PdmWidthMM:
val = static_cast< int >( 25.4 / qt_defaultDpiX() * mPaintEngine->maskPainterPath().boundingRect().width() );
val = static_cast< int >( 25.4 / QgsPainting::qtDefaultDpiX() * mPaintEngine->maskPainterPath().boundingRect().width() );
break;
case PdmHeightMM:
val = static_cast< int >( 25.4 / qt_defaultDpiY() * mPaintEngine->maskPainterPath().boundingRect().height() );
val = static_cast< int >( 25.4 / QgsPainting::qtDefaultDpiY() * mPaintEngine->maskPainterPath().boundingRect().height() );
break;
case PdmDpiX:
case PdmPhysicalDpiX:
val = qt_defaultDpiX();
val = QgsPainting::qtDefaultDpiX();
break;
case PdmDpiY:
case PdmPhysicalDpiY:
val = qt_defaultDpiY();
val = QgsPainting::qtDefaultDpiY();
break;
case PdmNumColors:
val = 16777216;
Expand Down
Loading

0 comments on commit 25c28d6

Please sign in to comment.