Skip to content
Permalink
Browse files

Fix layout context flags not being respected when rendering items

  • Loading branch information
nyalldawson committed Jul 25, 2017
1 parent 0bffff0 commit 213064a8af1b695c2f362b8af51c77bd079f522f
@@ -67,6 +67,12 @@ class QgsLayoutContext
:rtype: bool
%End

QgsRenderContext::Flags renderContextFlags() const;
%Docstring
Returns the combination of render context flags matched to the layout context's settings.
:rtype: QgsRenderContext.Flags
%End

void setFeature( const QgsFeature &feature );
%Docstring
Sets the current ``feature`` for evaluating the layout. This feature may
@@ -33,17 +33,19 @@ class QgsLayoutUtils
%Docstring
Creates a render context suitable for the specified layout ``map`` and ``painter`` destination.
This method returns a new QgsRenderContext which matches the scale and settings of the
target map. If the ``dpi`` argument is not specified then the dpi will be taken from the destinatation
target map. If the ``dpi`` argument is not specified then the dpi will be taken from the destination
painter device.
.. seealso:: createRenderContextForLayout()
:rtype: QgsRenderContext
%End

static QgsRenderContext createRenderContextForLayout( QgsLayout *layout, QPainter *painter );
static QgsRenderContext createRenderContextForLayout( QgsLayout *layout, QPainter *painter, double dpi = -1 );
%Docstring
Creates a render context suitable for the specified ``layout`` and ``painter`` destination.
This method returns a new QgsRenderContext which matches the scale and settings from the layout's
QgsLayout.referenceMap().
If the ``dpi`` argument is not specified then the dpi will be taken from the destination
painter device.
.. seealso:: createRenderContextForMap()
:rtype: QgsRenderContext
%End
@@ -45,6 +45,19 @@ bool QgsLayoutContext::testFlag( const QgsLayoutContext::Flag flag ) const
return mFlags.testFlag( flag );
}

QgsRenderContext::Flags QgsLayoutContext::renderContextFlags() const
{
QgsRenderContext::Flags flags = 0;
if ( mFlags & FlagAntialiasing )
flags = flags | QgsRenderContext::Antialiasing;
if ( mFlags & FlagUseAdvancedEffects )
flags = flags | QgsRenderContext::UseAdvancedEffects;

// TODO - expose as layout context flag?
flags |= QgsRenderContext::ForceVectorOutput;
return flags;
}

QgsVectorLayer *QgsLayoutContext::layer() const
{
return mLayer;
@@ -81,6 +81,11 @@ class CORE_EXPORT QgsLayoutContext
*/
bool testFlag( const Flag flag ) const;

/**
* Returns the combination of render context flags matched to the layout context's settings.
*/
QgsRenderContext::Flags renderContextFlags() const;

/**
* Sets the current \a feature for evaluating the layout. This feature may
* be used for altering an item's content and appearance for a report
@@ -128,7 +128,7 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
QPainter p( &mItemCachedImage );

preparePainter( &p );
QgsRenderContext context = QgsLayoutUtils::createRenderContextForMap( nullptr, &p, destinationDpi );
QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( nullptr, &p, destinationDpi );
// painter is already scaled to dots
// need to translate so that item origin is at 0,0 in painter coordinates (not bounding rect origin)
p.translate( -boundingRect().x() * context.scaleFactor(), -boundingRect().y() * context.scaleFactor() );
@@ -147,7 +147,8 @@ void QgsLayoutItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *it
{
// no caching or flattening
painter->save();
QgsRenderContext context = QgsLayoutUtils::createRenderContextForMap( nullptr, painter, destinationDpi );
preparePainter( painter );
QgsRenderContext context = QgsLayoutUtils::createRenderContextForLayout( mLayout, painter, destinationDpi );
// scale painter from mm to dots
painter->scale( 1.0 / context.scaleFactor(), 1.0 / context.scaleFactor() );
draw( context, itemStyle );
@@ -74,12 +74,17 @@ QgsRenderContext QgsLayoutUtils::createRenderContextForMap( QgsLayoutItemMap *ma
QgsRenderContext context; // = QgsRenderContext::fromMapSettings( ms );
if ( painter )
context.setPainter( painter );

context.setFlags( map->layout()->context().renderContextFlags() );
return context;
}
}

QgsRenderContext QgsLayoutUtils::createRenderContextForLayout( QgsLayout *layout, QPainter *painter )
QgsRenderContext QgsLayoutUtils::createRenderContextForLayout( QgsLayout *layout, QPainter *painter, double dpi )
{
QgsLayoutItemMap *referenceMap = layout ? layout->referenceMap() : nullptr;
return createRenderContextForMap( referenceMap, painter );
QgsRenderContext context = createRenderContextForMap( referenceMap, painter, dpi );
if ( layout )
context.setFlags( layout->context().renderContextFlags() );
return context;
}
@@ -43,7 +43,7 @@ class CORE_EXPORT QgsLayoutUtils
/**
* Creates a render context suitable for the specified layout \a map and \a painter destination.
* This method returns a new QgsRenderContext which matches the scale and settings of the
* target map. If the \a dpi argument is not specified then the dpi will be taken from the destinatation
* target map. If the \a dpi argument is not specified then the dpi will be taken from the destination
* painter device.
* \see createRenderContextForLayout()
*/
@@ -53,9 +53,11 @@ class CORE_EXPORT QgsLayoutUtils
* Creates a render context suitable for the specified \a layout and \a painter destination.
* This method returns a new QgsRenderContext which matches the scale and settings from the layout's
* QgsLayout::referenceMap().
* If the \a dpi argument is not specified then the dpi will be taken from the destination
* painter device.
* \see createRenderContextForMap()
*/
static QgsRenderContext createRenderContextForLayout( QgsLayout *layout, QPainter *painter );
static QgsRenderContext createRenderContextForLayout( QgsLayout *layout, QPainter *painter, double dpi = -1 );

};

@@ -36,6 +36,7 @@ class TestQgsLayoutContext: public QObject
void feature();
void layer();
void dpi();
void renderContextFlags();

private:
QString mReport;
@@ -135,5 +136,27 @@ void TestQgsLayoutContext::dpi()
QCOMPARE( context.measurementConverter().dpi(), 600.0 );
}

void TestQgsLayoutContext::renderContextFlags()
{
QgsLayoutContext context;
context.setFlags( 0 );
QgsRenderContext::Flags flags = context.renderContextFlags();
QVERIFY( !( flags & QgsRenderContext::Antialiasing ) );
QVERIFY( !( flags & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( flags & QgsRenderContext::ForceVectorOutput ) );

context.setFlag( QgsLayoutContext::FlagAntialiasing );
flags = context.renderContextFlags();
QVERIFY( ( flags & QgsRenderContext::Antialiasing ) );
QVERIFY( !( flags & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( flags & QgsRenderContext::ForceVectorOutput ) );

context.setFlag( QgsLayoutContext::FlagUseAdvancedEffects );
flags = context.renderContextFlags();
QVERIFY( ( flags & QgsRenderContext::Antialiasing ) );
QVERIFY( ( flags & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( flags & QgsRenderContext::ForceVectorOutput ) );
}

QGSTEST_MAIN( TestQgsLayoutContext )
#include "testqgslayoutcontext.moc"
@@ -124,17 +124,17 @@ void TestQgsLayoutUtils::createRenderContextFromLayout()
testImage.setDotsPerMeterY( 150 / 25.4 * 1000 );
QPainter p( &testImage );

// no composition
// no layout
QgsRenderContext rc = QgsLayoutUtils::createRenderContextForLayout( nullptr, &p );
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
QCOMPARE( rc.painter(), &p );

// no composition, no painter
// no layout, no painter
rc = QgsLayoutUtils::createRenderContextForLayout( nullptr, nullptr );
QGSCOMPARENEAR( rc.scaleFactor(), 88 / 25.4, 0.001 );
QVERIFY( !rc.painter() );

//create composition with no reference map
//create layout with no reference map
QgsRectangle extent( 2000, 2800, 2500, 2900 );
QgsProject project;
QgsLayout l( &project );
@@ -167,6 +167,25 @@ void TestQgsLayoutUtils::createRenderContextFromLayout()
QGSCOMPARENEAR( rc.rendererScale(), map->scale(), 1000000 );
QVERIFY( !rc.painter() );

// check render context flags are correctly set
l.context().setFlags( 0 );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( !( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );

l.context().setFlag( QgsLayoutContext::FlagAntialiasing );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );

l.context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( ( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );

p.end();
}

@@ -224,6 +243,25 @@ void TestQgsLayoutUtils::createRenderContextFromMap()
QGSCOMPARENEAR( rc.scaleFactor(), 150 / 25.4, 0.001 );
QGSCOMPARENEAR( rc.rendererScale(), map2->scale(), 1000000 );
QVERIFY( rc.painter() );

// check render context flags are correctly set
l.context().setFlags( 0 );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( !( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );

l.context().setFlag( QgsLayoutContext::FlagAntialiasing );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( !( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );

l.context().setFlag( QgsLayoutContext::FlagUseAdvancedEffects );
rc = QgsLayoutUtils::createRenderContextForLayout( &l, nullptr );
QVERIFY( ( rc.flags() & QgsRenderContext::Antialiasing ) );
QVERIFY( ( rc.flags() & QgsRenderContext::UseAdvancedEffects ) );
QVERIFY( ( rc.flags() & QgsRenderContext::ForceVectorOutput ) );
#endif
p.end();
}

0 comments on commit 213064a

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