Skip to content

Commit

Permalink
Copy output image format and output size to QgsRenderContext
Browse files Browse the repository at this point in the history
These QgsMapSettings properties are useful to rendering operations
to use when they need to create temporary QImages during the
rendering
  • Loading branch information
nyalldawson committed Oct 1, 2021
1 parent 7a6d8ec commit b54001c
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 0 deletions.
77 changes: 77 additions & 0 deletions python/core/auto_generated/qgsrendercontext.sip.in
Expand Up @@ -949,6 +949,83 @@ Sets the ``range`` of z-values which should be rendered.
.. seealso:: :py:func:`zRange`

.. versionadded:: 3.18
%End

QSize outputSize() const;
%Docstring
Returns the size of the resulting rendered image, in pixels.

.. seealso:: :py:func:`deviceOutputSize`

.. seealso:: :py:func:`setOutputSize`

.. versionadded:: 3.22
%End

void setOutputSize( QSize size );
%Docstring
Sets the ``size`` of the resulting rendered image, in pixels.

.. seealso:: :py:func:`outputSize`

.. versionadded:: 3.22
%End

float devicePixelRatio() const;
%Docstring
Returns the device pixel ratio.

Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" displays.

.. seealso:: :py:func:`setDevicePixelRatio`

.. versionadded:: 3.22
%End

void setDevicePixelRatio( float ratio );
%Docstring
Sets the device pixel ``ratio``.

Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" displays.

.. seealso:: :py:func:`devicePixelRatio`

.. versionadded:: 3.22
%End

QSize deviceOutputSize() const;
%Docstring
Returns the device output size of the render.

This is equivalent to the output size multiplicated by the device pixel ratio.

.. seealso:: :py:func:`outputSize`

.. seealso:: :py:func:`devicePixelRatio`

.. seealso:: :py:func:`setOutputSize`

.. versionadded:: 3.22
%End

void setImageFormat( QImage::Format format );
%Docstring
Sets QImage ``format`` which should be used for QImages created
during rendering.

.. seealso:: :py:func:`imageFormat`

.. versionadded:: 3.22
%End

QImage::Format imageFormat() const;
%Docstring
Returns the QImage format which should be used for QImages created
during rendering.

.. seealso:: :py:func:`setImageFormat`

.. versionadded:: 3.22
%End

};
Expand Down
34 changes: 34 additions & 0 deletions src/core/qgsrendercontext.cpp
Expand Up @@ -74,6 +74,9 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
, mFeatureClipGeometry( rh.mFeatureClipGeometry )
, mTextureOrigin( rh.mTextureOrigin )
, mZRange( rh.mZRange )
, mSize( rh.mSize )
, mDevicePixelRatio( rh.mDevicePixelRatio )
, mImageFormat( rh.mImageFormat )
#ifdef QGISDEBUG
, mHasTransformContext( rh.mHasTransformContext )
#endif
Expand Down Expand Up @@ -114,6 +117,9 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
mFeatureClipGeometry = rh.mFeatureClipGeometry;
mTextureOrigin = rh.mTextureOrigin;
mZRange = rh.mZRange;
mSize = rh.mSize;
mDevicePixelRatio = rh.mDevicePixelRatio;
mImageFormat = rh.mImageFormat;
setIsTemporal( rh.isTemporal() );
if ( isTemporal() )
setTemporalRange( rh.temporalRange() );
Expand Down Expand Up @@ -258,6 +264,9 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
ctx.setTemporalRange( mapSettings.temporalRange() );

ctx.setZRange( mapSettings.zRange() );
ctx.setOutputSize( mapSettings.outputSize() );
ctx.setDevicePixelRatio( mapSettings.devicePixelRatio() );
ctx.setImageFormat( mapSettings.outputImageFormat() );

ctx.mClippingRegions = mapSettings.clippingRegions();

Expand Down Expand Up @@ -629,4 +638,29 @@ void QgsRenderContext::setZRange( const QgsDoubleRange &range )
mZRange = range;
}

QSize QgsRenderContext::outputSize() const
{
return mSize;
}

void QgsRenderContext::setOutputSize( QSize size )
{
mSize = size;
}

float QgsRenderContext::devicePixelRatio() const
{
return mDevicePixelRatio;
}

void QgsRenderContext::setDevicePixelRatio( float ratio )
{
mDevicePixelRatio = ratio;
}

QSize QgsRenderContext::deviceOutputSize() const
{
return outputSize() * mDevicePixelRatio;
}


73 changes: 73 additions & 0 deletions src/core/qgsrendercontext.h
Expand Up @@ -889,6 +889,75 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
*/
void setZRange( const QgsDoubleRange &range );

/**
* Returns the size of the resulting rendered image, in pixels.
*
* \see deviceOutputSize()
* \see setOutputSize()
*
* \since QGIS 3.22
*/
QSize outputSize() const;

/**
* Sets the \a size of the resulting rendered image, in pixels.
*
* \see outputSize()
* \since QGIS 3.22
*/
void setOutputSize( QSize size );

/**
* Returns the device pixel ratio.
*
* Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" displays.
*
* \see setDevicePixelRatio()
* \since QGIS 3.22
*/
float devicePixelRatio() const;

/**
* Sets the device pixel \a ratio.
*
* Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" displays.
*
* \see devicePixelRatio()
* \since QGIS 3.22
*/
void setDevicePixelRatio( float ratio );

/**
* Returns the device output size of the render.
*
* This is equivalent to the output size multiplicated by the device pixel ratio.
*
* \see outputSize()
* \see devicePixelRatio()
* \see setOutputSize()
*
* \since QGIS 3.22
*/
QSize deviceOutputSize() const;

/**
* Sets QImage \a format which should be used for QImages created
* during rendering.
*
* \see imageFormat()
* \since QGIS 3.22
*/
void setImageFormat( QImage::Format format ) { mImageFormat = format; }

/**
* Returns the QImage format which should be used for QImages created
* during rendering.
*
* \see setImageFormat
* \since QGIS 3.22
*/
QImage::Format imageFormat() const { return mImageFormat; }

private:

Qgis::RenderContextFlags mFlags;
Expand Down Expand Up @@ -995,6 +1064,10 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject

QgsDoubleRange mZRange;

QSize mSize;
float mDevicePixelRatio = 1.0;
QImage::Format mImageFormat = QImage::Format_ARGB32_Premultiplied;

#ifdef QGISDEBUG
bool mHasTransformContext = false;
#endif
Expand Down
26 changes: 26 additions & 0 deletions tests/src/python/test_qgsrendercontext.py
Expand Up @@ -68,6 +68,18 @@ def testGettersSetters(self):
c.setSymbologyReferenceScale(1000)
self.assertEqual(c.symbologyReferenceScale(), 1000)

self.assertTrue(c.outputSize().isEmpty())
c.setOutputSize(QSize(100, 200))
self.assertEqual(c.outputSize(), QSize(100, 200))

self.assertEqual(c.devicePixelRatio(), 1)
c.setDevicePixelRatio(2)
self.assertEqual(c.devicePixelRatio(), 2)
self.assertEqual(c.deviceOutputSize(), QSize(200, 400))

c.setImageFormat(QImage.Format_Alpha8)
self.assertEqual(c.imageFormat(), QImage.Format_Alpha8)

# should have an invalid mapToPixel by default
self.assertFalse(c.mapToPixel().isValid())

Expand All @@ -81,12 +93,19 @@ def testCopyConstructor(self):
c1.setMapExtent(QgsRectangle(1, 2, 3, 4))
c1.setZRange(QgsDoubleRange(1, 10))
c1.setSymbologyReferenceScale(1000)
c1.setOutputSize(QSize(100, 200))
c1.setImageFormat(QImage.Format_Alpha8)
c1.setDevicePixelRatio(2)

c2 = QgsRenderContext(c1)
self.assertEqual(c2.textRenderFormat(), QgsRenderContext.TextFormatAlwaysText)
self.assertEqual(c2.mapExtent(), QgsRectangle(1, 2, 3, 4))
self.assertEqual(c2.zRange(), QgsDoubleRange(1, 10))
self.assertEqual(c2.symbologyReferenceScale(), 1000)
self.assertEqual(c2.outputSize(), QSize(100, 200))
self.assertEqual(c2.imageFormat(), QImage.Format_Alpha8)
self.assertEqual(c2.devicePixelRatio(), 2)
self.assertEqual(c2.deviceOutputSize(), QSize(200, 400))

c1.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysOutlines)
c2 = QgsRenderContext(c1)
Expand Down Expand Up @@ -150,6 +169,9 @@ def testFromMapSettings(self):
ms.setFlag(QgsMapSettings.LosslessImageRendering, True)
ms.setFlag(QgsMapSettings.Render3DMap, True)
ms.setZRange(QgsDoubleRange(1, 10))
ms.setOutputSize(QSize(100, 100))
ms.setDevicePixelRatio(2)
ms.setOutputImageFormat(QImage.Format_Alpha8)

ms.setTextRenderFormat(QgsRenderContext.TextFormatAlwaysText)
rc = QgsRenderContext.fromMapSettings(ms)
Expand All @@ -159,6 +181,10 @@ def testFromMapSettings(self):
self.assertTrue(rc.testFlag(QgsRenderContext.Render3DMap))
self.assertEqual(ms.zRange(), QgsDoubleRange(1, 10))
self.assertEqual(rc.symbologyReferenceScale(), -1)
self.assertEqual(rc.outputSize(), QSize(100, 100))
self.assertEqual(rc.devicePixelRatio(), 2)
self.assertEqual(rc.deviceOutputSize(), QSize(200, 200))
self.assertEqual(rc.imageFormat(), QImage.Format_Alpha8)

# should have an valid mapToPixel
self.assertTrue(rc.mapToPixel().isValid())
Expand Down

0 comments on commit b54001c

Please sign in to comment.