Skip to content

Commit 2caf0e0

Browse files
committed
Disable blend modes when printing or pdf exporting as vector, prevents missing composer items in output
1 parent 7f72d7f commit 2caf0e0

10 files changed

+161
-20
lines changed

src/app/composer/qgscomposer.cpp

+34
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,18 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
637637
showBlendModePrintingWarning();
638638
}
639639

640+
// If we are not printing as raster, temporarily disable advanced effects
641+
// as QPrinter does not support composition modes and can result
642+
// in items missing from the output
643+
if ( mComposition->printAsRaster() )
644+
{
645+
mComposition->setUseAdvancedEffects( true );
646+
}
647+
else
648+
{
649+
mComposition->setUseAdvancedEffects( false );
650+
}
651+
640652
bool hasAnAtlas = mComposition->atlasComposition().enabled();
641653
bool atlasOnASingleFile = hasAnAtlas && mComposition->atlasComposition().singleFile();
642654
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
@@ -795,6 +807,11 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
795807
mComposition->exportAsPDF( outputFileName );
796808
}
797809

810+
if ( ! mComposition->useAdvancedEffects() )
811+
{
812+
//Switch advanced effects back on
813+
mComposition->setUseAdvancedEffects( true );
814+
}
798815
mView->setPaintingEnabled( true );
799816
QApplication::restoreOverrideCursor();
800817
}
@@ -816,6 +833,18 @@ void QgsComposer::on_mActionPrint_triggered()
816833
showBlendModePrintingWarning();
817834
}
818835

836+
// If we are not printing as raster, temporarily disable advanced effects
837+
// as QPrinter does not support composition modes and can result
838+
// in items missing from the output
839+
if ( mComposition->printAsRaster() )
840+
{
841+
mComposition->setUseAdvancedEffects( true );
842+
}
843+
else
844+
{
845+
mComposition->setUseAdvancedEffects( false );
846+
}
847+
819848
//orientation and page size are already set to QPrinter in the page setup dialog
820849
QPrintDialog printDialog( &mPrinter, 0 );
821850
if ( printDialog.exec() != QDialog::Accepted )
@@ -887,6 +916,11 @@ void QgsComposer::on_mActionPrint_triggered()
887916
painter.end();
888917
}
889918

919+
if ( ! mComposition->useAdvancedEffects() )
920+
{
921+
//Switch advanced effects back on
922+
mComposition->setUseAdvancedEffects( true );
923+
}
890924
mView->setPaintingEnabled( true );
891925
QApplication::restoreOverrideCursor();
892926
}

src/core/composer/qgscomposeritem.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue
5656
, mLastValidViewScaleFactor( -1 )
5757
, mRotation( 0 )
5858
, mBlendMode( QPainter::CompositionMode_SourceOver )
59+
, mEffectsEnabled( true )
5960
, mTransparency( 0 )
6061
, mLastUsedPositionMode( UpperLeft )
6162
, mId( "" )
@@ -78,6 +79,7 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q
7879
, mLastValidViewScaleFactor( -1 )
7980
, mRotation( 0 )
8081
, mBlendMode( QPainter::CompositionMode_SourceOver )
82+
, mEffectsEnabled( true )
8183
, mTransparency( 0 )
8284
, mLastUsedPositionMode( UpperLeft )
8385
, mId( "" )
@@ -107,7 +109,6 @@ void QgsComposerItem::init( bool manageZValue )
107109
// Setup composer effect
108110
mEffect = new QgsComposerEffect();
109111
setGraphicsEffect( mEffect );
110-
111112
}
112113

113114
QgsComposerItem::~QgsComposerItem()
@@ -906,6 +907,13 @@ void QgsComposerItem::setTransparency( int transparency )
906907
setOpacity( 1. - ( transparency / 100. ) );
907908
}
908909

910+
void QgsComposerItem::setEffectsEnabled( bool effectsEnabled )
911+
{
912+
//enable or disable the QgsComposerEffect applied to this item
913+
mEffectsEnabled = effectsEnabled;
914+
mEffect->setEnabled( effectsEnabled );
915+
}
916+
909917
void QgsComposerItem::hoverMoveEvent( QGraphicsSceneHoverEvent * event )
910918
{
911919
if ( isSelected() )

src/core/composer/qgscomposeritem.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,15 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
221221
/** Sets the item's transparency */
222222
void setTransparency( int transparency );
223223

224+
/** Returns true if effects (eg blend modes) are enabled for the item
225+
* @note introduced in 2.0
226+
*/
227+
bool effectsEnabled() const {return mEffectsEnabled;}
228+
/** Sets whether effects (eg blend modes) are enabled for the item
229+
* @note introduced in 2.0
230+
*/
231+
void setEffectsEnabled( bool effectsEnabled );
232+
224233
/**Composite operations for item groups do nothing per default*/
225234
virtual void addItem( QgsComposerItem* item ) { Q_UNUSED( item ); }
226235
virtual void removeItems() {}
@@ -337,7 +346,7 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
337346

338347
/**Composition blend mode for item*/
339348
QPainter::CompositionMode mBlendMode;
340-
349+
bool mEffectsEnabled;
341350
QgsComposerEffect *mEffect;
342351

343352
/**Item transparency*/

src/core/composer/qgscomposermap.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
168168
// force vector output (no caching of marker images etc.)
169169
theRendererContext->setForceVectorOutput( true );
170170

171+
// make the renderer respect the composition's useAdvancedEffects flag
172+
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );
173+
171174
//force composer map scale for scale dependent visibility
172175
double bk_scale = theMapRenderer.scale();
173176
theMapRenderer.setScale( scale() );

src/core/composer/qgscomposition.cpp

+56-8
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,25 @@
4747
#include <QDir>
4848

4949

50-
QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
51-
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
52-
mSnapToGrid( false ), mSnapGridResolution( 10.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mAlignmentSnap( true ), mAlignmentSnapTolerance( 2 ),
53-
mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ), mAtlasComposition( this )
50+
QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer )
51+
: QGraphicsScene( 0 ),
52+
mMapRenderer( mapRenderer ),
53+
mPlotStyle( QgsComposition::Preview ),
54+
mPageWidth( 297 ),
55+
mPageHeight( 210 ),
56+
mSpaceBetweenPages( 10 ),
57+
mPrintAsRaster( false ),
58+
mUseAdvancedEffects( true ),
59+
mSelectionTolerance( 0.0 ),
60+
mSnapToGrid( false ),
61+
mSnapGridResolution( 10.0 ),
62+
mSnapGridOffsetX( 0.0 ),
63+
mSnapGridOffsetY( 0.0 ),
64+
mAlignmentSnap( true ),
65+
mAlignmentSnapTolerance( 2 ),
66+
mActiveItemCommand( 0 ),
67+
mActiveMultiFrameCommand( 0 ),
68+
mAtlasComposition( this )
5469
{
5570
setBackgroundBrush( Qt::gray );
5671
addPaperItem();
@@ -59,10 +74,25 @@ QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
5974
loadSettings();
6075
}
6176

62-
QgsComposition::QgsComposition():
63-
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
64-
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 10.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mAlignmentSnap( true ),
65-
mAlignmentSnapTolerance( 2 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ), mAtlasComposition( this )
77+
QgsComposition::QgsComposition()
78+
: QGraphicsScene( 0 ),
79+
mMapRenderer( 0 ),
80+
mPlotStyle( QgsComposition::Preview ),
81+
mPageWidth( 297 ),
82+
mPageHeight( 210 ),
83+
mSpaceBetweenPages( 10 ),
84+
mPrintAsRaster( false ),
85+
mUseAdvancedEffects( true ),
86+
mSelectionTolerance( 0.0 ),
87+
mSnapToGrid( false ),
88+
mSnapGridResolution( 10.0 ),
89+
mSnapGridOffsetX( 0.0 ),
90+
mSnapGridOffsetY( 0.0 ),
91+
mAlignmentSnap( true ),
92+
mAlignmentSnapTolerance( 2 ),
93+
mActiveItemCommand( 0 ),
94+
mActiveMultiFrameCommand( 0 ),
95+
mAtlasComposition( this )
6696
{
6797
loadSettings();
6898

@@ -318,6 +348,24 @@ const QgsComposerItem* QgsComposition::getComposerItemByUuid( QString theUuid )
318348
return 0;
319349
}
320350

351+
352+
void QgsComposition::setUseAdvancedEffects( bool effectsEnabled )
353+
{
354+
mUseAdvancedEffects = effectsEnabled;
355+
356+
//toggle effects for all composer items
357+
QList<QGraphicsItem*> itemList = items();
358+
QList<QGraphicsItem*>::const_iterator itemIt = itemList.constBegin();
359+
for ( ; itemIt != itemList.constEnd(); ++itemIt )
360+
{
361+
QgsComposerItem* composerItem = dynamic_cast<QgsComposerItem*>( *itemIt );
362+
if ( composerItem )
363+
{
364+
composerItem->setEffectsEnabled( effectsEnabled );
365+
}
366+
}
367+
}
368+
321369
int QgsComposition::pixelFontSize( double pointSize ) const
322370
{
323371
//in QgsComposition, one unit = one mm

src/core/composer/qgscomposition.h

+10
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
182182
bool printAsRaster() const {return mPrintAsRaster;}
183183
void setPrintAsRaster( bool enabled ) { mPrintAsRaster = enabled; }
184184

185+
/**Returns true if a composition should use advanced effects such as blend modes
186+
@note added in 1.9*/
187+
bool useAdvancedEffects() const {return mUseAdvancedEffects;}
188+
/**Used to enable or disable advanced effects such as blend modes in a composition
189+
@note: added in version 1.9*/
190+
void setUseAdvancedEffects( bool effectsEnabled );
191+
185192
double selectionTolerance() const { return mSelectionTolerance; }
186193
void setSelectionTolerance( double tol );
187194

@@ -375,6 +382,9 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
375382
/**Flag if map should be printed as a raster (via QImage). False by default*/
376383
bool mPrintAsRaster;
377384

385+
/**Flag if advanced visual effects such as blend modes should be used. True by default*/
386+
bool mUseAdvancedEffects;
387+
378388
/**Distance tolerance for item selection (in mm)*/
379389
double mSelectionTolerance;
380390

src/core/qgsmaprenderer.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,12 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
397397
.arg( ml->blendMode() )
398398
);
399399

400-
// Set the QPainter composition mode so that this layer is rendered using
401-
// the desired blending mode
402-
mypContextPainter->setCompositionMode( ml->blendMode() );
400+
if ( mRenderContext.useAdvancedEffects() )
401+
{
402+
// Set the QPainter composition mode so that this layer is rendered using
403+
// the desired blending mode
404+
mypContextPainter->setCompositionMode( ml->blendMode() );
405+
}
403406

404407
if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
405408
{
@@ -515,7 +518,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
515518
// before compositing this on the map. This effectively flattens the layer and prevents
516519
// blending occuring between objects on the layer
517520
// (this is not required for raster layers or when layer caching is enabled, since that has the same effect)
518-
if (( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
521+
if (( mRenderContext.useAdvancedEffects() ) && ( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
519522
( ml->type() != QgsMapLayer::RasterLayer ) &&
520523
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
521524
{
@@ -581,7 +584,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
581584
}
582585

583586
// If we flattened this layer for alternate blend modes, composite it now
584-
if (( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
587+
if (( mRenderContext.useAdvancedEffects() ) && ( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
585588
( ml->type() != QgsMapLayer::RasterLayer ) &&
586589
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
587590
{

src/core/qgspallabeling.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -2286,7 +2286,10 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
22862286
}
22872287

22882288
// paint the text
2289-
painter->setCompositionMode( tmpLyr.blendMode );
2289+
if ( context.useAdvancedEffects() )
2290+
{
2291+
painter->setCompositionMode( tmpLyr.blendMode );
2292+
}
22902293
// painter->setPen( Qt::NoPen );
22912294
// painter->setBrush( tmpLyr.textColor );
22922295
// painter->drawPath( path );
@@ -2350,7 +2353,10 @@ void QgsPalLabeling::drawLabelBuffer( QgsRenderContext& context,
23502353
}
23512354

23522355
p->save();
2353-
p->setCompositionMode( tmpLyr.bufferBlendMode );
2356+
if ( context.useAdvancedEffects() )
2357+
{
2358+
p->setCompositionMode( tmpLyr.bufferBlendMode );
2359+
}
23542360
// p->setPen( pen );
23552361
// p->setBrush( tmpColor );
23562362
// p->drawPath( path );
@@ -2512,7 +2518,10 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,
25122518
( 100.0 - ( double )( tmpLyr.shapeTransparency ) ) / 100.0 );
25132519

25142520
p->save();
2515-
p->setCompositionMode( tmpLyr.shapeBlendMode );
2521+
if ( context.useAdvancedEffects() )
2522+
{
2523+
p->setCompositionMode( tmpLyr.shapeBlendMode );
2524+
}
25162525
p->translate( component.center().x(), component.center().y() );
25172526
p->rotate( component.rotation() );
25182527
double xoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.x(), context, tmpLyr.shapeOffsetUnits );
@@ -2642,7 +2651,10 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,
26422651
}
26432652

26442653
p->setOpacity(( 100.0 - ( double )( tmpLyr.shapeTransparency ) ) / 100.0 );
2645-
p->setCompositionMode( tmpLyr.shapeBlendMode );
2654+
if ( context.useAdvancedEffects() )
2655+
{
2656+
p->setCompositionMode( tmpLyr.shapeBlendMode );
2657+
}
26462658

26472659
// scale for any print output or image saving @ specific dpi
26482660
p->scale( component.dpiRatio(), component.dpiRatio() );
@@ -2744,7 +2756,10 @@ void QgsPalLabeling::drawLabelShadow( QgsRenderContext& context,
27442756

27452757
p->save();
27462758
p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
2747-
p->setCompositionMode( tmpLyr.shadowBlendMode );
2759+
if ( context.useAdvancedEffects() )
2760+
{
2761+
p->setCompositionMode( tmpLyr.shadowBlendMode );
2762+
}
27482763
p->setOpacity(( 100.0 - ( double )( tmpLyr.shadowTransparency ) ) / 100.0 );
27492764

27502765
double scale = ( double )tmpLyr.shadowScale / 100.0;

src/core/qgsrendercontext.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ QgsRenderContext::QgsRenderContext()
2323
mCoordTransform( 0 ),
2424
mDrawEditingInformation( true ),
2525
mForceVectorOutput( false ),
26+
mUseAdvancedEffects( true ),
2627
mRenderingStopped( false ),
2728
mScaleFactor( 1.0 ),
2829
mRasterScaleFactor( 1.0 ),

src/core/qgsrendercontext.h

+10
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ class CORE_EXPORT QgsRenderContext
5959

6060
bool forceVectorOutput() const {return mForceVectorOutput;}
6161

62+
/**Returns true if advanced effects such as blend modes such be used
63+
@note added in 1.9*/
64+
bool useAdvancedEffects() const {return mUseAdvancedEffects;}
65+
/**Used to enable or disable advanced effects such as blend modes
66+
@note: added in version 1.9*/
67+
void setUseAdvancedEffects( bool enabled ) { mUseAdvancedEffects = enabled; }
68+
6269
bool drawEditingInformation() const {return mDrawEditingInformation;}
6370

6471
double rendererScale() const {return mRendererScale;}
@@ -104,6 +111,9 @@ class CORE_EXPORT QgsRenderContext
104111
/**If true then no rendered vector elements should be cached as image*/
105112
bool mForceVectorOutput;
106113

114+
/**Flag if advanced visual effects such as blend modes should be used. True by default*/
115+
bool mUseAdvancedEffects;
116+
107117
QgsMapToPixel mMapToPixel;
108118

109119
/**True if the rendering has been canceled*/

0 commit comments

Comments
 (0)