Skip to content

Commit

Permalink
Disable blend modes when printing or pdf exporting as vector, prevent…
Browse files Browse the repository at this point in the history
…s missing composer items in output
  • Loading branch information
nyalldawson committed May 10, 2013
1 parent 7f72d7f commit 2caf0e0
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 20 deletions.
34 changes: 34 additions & 0 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -637,6 +637,18 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
showBlendModePrintingWarning();
}

// If we are not printing as raster, temporarily disable advanced effects
// as QPrinter does not support composition modes and can result
// in items missing from the output
if ( mComposition->printAsRaster() )
{
mComposition->setUseAdvancedEffects( true );
}
else
{
mComposition->setUseAdvancedEffects( false );
}

bool hasAnAtlas = mComposition->atlasComposition().enabled();
bool atlasOnASingleFile = hasAnAtlas && mComposition->atlasComposition().singleFile();
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
Expand Down Expand Up @@ -795,6 +807,11 @@ void QgsComposer::on_mActionExportAsPDF_triggered()
mComposition->exportAsPDF( outputFileName );
}

if ( ! mComposition->useAdvancedEffects() )
{
//Switch advanced effects back on
mComposition->setUseAdvancedEffects( true );
}
mView->setPaintingEnabled( true );
QApplication::restoreOverrideCursor();
}
Expand All @@ -816,6 +833,18 @@ void QgsComposer::on_mActionPrint_triggered()
showBlendModePrintingWarning();
}

// If we are not printing as raster, temporarily disable advanced effects
// as QPrinter does not support composition modes and can result
// in items missing from the output
if ( mComposition->printAsRaster() )
{
mComposition->setUseAdvancedEffects( true );
}
else
{
mComposition->setUseAdvancedEffects( false );
}

//orientation and page size are already set to QPrinter in the page setup dialog
QPrintDialog printDialog( &mPrinter, 0 );
if ( printDialog.exec() != QDialog::Accepted )
Expand Down Expand Up @@ -887,6 +916,11 @@ void QgsComposer::on_mActionPrint_triggered()
painter.end();
}

if ( ! mComposition->useAdvancedEffects() )
{
//Switch advanced effects back on
mComposition->setUseAdvancedEffects( true );
}
mView->setPaintingEnabled( true );
QApplication::restoreOverrideCursor();
}
Expand Down
10 changes: 9 additions & 1 deletion src/core/composer/qgscomposeritem.cpp
Expand Up @@ -56,6 +56,7 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue
, mLastValidViewScaleFactor( -1 )
, mRotation( 0 )
, mBlendMode( QPainter::CompositionMode_SourceOver )
, mEffectsEnabled( true )
, mTransparency( 0 )
, mLastUsedPositionMode( UpperLeft )
, mId( "" )
Expand All @@ -78,6 +79,7 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q
, mLastValidViewScaleFactor( -1 )
, mRotation( 0 )
, mBlendMode( QPainter::CompositionMode_SourceOver )
, mEffectsEnabled( true )
, mTransparency( 0 )
, mLastUsedPositionMode( UpperLeft )
, mId( "" )
Expand Down Expand Up @@ -107,7 +109,6 @@ void QgsComposerItem::init( bool manageZValue )
// Setup composer effect
mEffect = new QgsComposerEffect();
setGraphicsEffect( mEffect );

}

QgsComposerItem::~QgsComposerItem()
Expand Down Expand Up @@ -906,6 +907,13 @@ void QgsComposerItem::setTransparency( int transparency )
setOpacity( 1. - ( transparency / 100. ) );
}

void QgsComposerItem::setEffectsEnabled( bool effectsEnabled )
{
//enable or disable the QgsComposerEffect applied to this item
mEffectsEnabled = effectsEnabled;
mEffect->setEnabled( effectsEnabled );
}

void QgsComposerItem::hoverMoveEvent( QGraphicsSceneHoverEvent * event )
{
if ( isSelected() )
Expand Down
11 changes: 10 additions & 1 deletion src/core/composer/qgscomposeritem.h
Expand Up @@ -221,6 +221,15 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem
/** Sets the item's transparency */
void setTransparency( int transparency );

/** Returns true if effects (eg blend modes) are enabled for the item
* @note introduced in 2.0
*/
bool effectsEnabled() const {return mEffectsEnabled;}
/** Sets whether effects (eg blend modes) are enabled for the item
* @note introduced in 2.0
*/
void setEffectsEnabled( bool effectsEnabled );

/**Composite operations for item groups do nothing per default*/
virtual void addItem( QgsComposerItem* item ) { Q_UNUSED( item ); }
virtual void removeItems() {}
Expand Down Expand Up @@ -337,7 +346,7 @@ class CORE_EXPORT QgsComposerItem: public QObject, public QGraphicsRectItem

/**Composition blend mode for item*/
QPainter::CompositionMode mBlendMode;

bool mEffectsEnabled;
QgsComposerEffect *mEffect;

/**Item transparency*/
Expand Down
3 changes: 3 additions & 0 deletions src/core/composer/qgscomposermap.cpp
Expand Up @@ -168,6 +168,9 @@ void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const
// force vector output (no caching of marker images etc.)
theRendererContext->setForceVectorOutput( true );

// make the renderer respect the composition's useAdvancedEffects flag
theRendererContext->setUseAdvancedEffects( mComposition->useAdvancedEffects() );

//force composer map scale for scale dependent visibility
double bk_scale = theMapRenderer.scale();
theMapRenderer.setScale( scale() );
Expand Down
64 changes: 56 additions & 8 deletions src/core/composer/qgscomposition.cpp
Expand Up @@ -47,10 +47,25 @@
#include <QDir>


QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
mSnapToGrid( false ), mSnapGridResolution( 10.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mAlignmentSnap( true ), mAlignmentSnapTolerance( 2 ),
mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ), mAtlasComposition( this )
QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer )
: QGraphicsScene( 0 ),
mMapRenderer( mapRenderer ),
mPlotStyle( QgsComposition::Preview ),
mPageWidth( 297 ),
mPageHeight( 210 ),
mSpaceBetweenPages( 10 ),
mPrintAsRaster( false ),
mUseAdvancedEffects( true ),
mSelectionTolerance( 0.0 ),
mSnapToGrid( false ),
mSnapGridResolution( 10.0 ),
mSnapGridOffsetX( 0.0 ),
mSnapGridOffsetY( 0.0 ),
mAlignmentSnap( true ),
mAlignmentSnapTolerance( 2 ),
mActiveItemCommand( 0 ),
mActiveMultiFrameCommand( 0 ),
mAtlasComposition( this )
{
setBackgroundBrush( Qt::gray );
addPaperItem();
Expand All @@ -59,10 +74,25 @@ QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
loadSettings();
}

QgsComposition::QgsComposition():
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 10.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mAlignmentSnap( true ),
mAlignmentSnapTolerance( 2 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ), mAtlasComposition( this )
QgsComposition::QgsComposition()
: QGraphicsScene( 0 ),
mMapRenderer( 0 ),
mPlotStyle( QgsComposition::Preview ),
mPageWidth( 297 ),
mPageHeight( 210 ),
mSpaceBetweenPages( 10 ),
mPrintAsRaster( false ),
mUseAdvancedEffects( true ),
mSelectionTolerance( 0.0 ),
mSnapToGrid( false ),
mSnapGridResolution( 10.0 ),
mSnapGridOffsetX( 0.0 ),
mSnapGridOffsetY( 0.0 ),
mAlignmentSnap( true ),
mAlignmentSnapTolerance( 2 ),
mActiveItemCommand( 0 ),
mActiveMultiFrameCommand( 0 ),
mAtlasComposition( this )
{
loadSettings();

Expand Down Expand Up @@ -318,6 +348,24 @@ const QgsComposerItem* QgsComposition::getComposerItemByUuid( QString theUuid )
return 0;
}


void QgsComposition::setUseAdvancedEffects( bool effectsEnabled )
{
mUseAdvancedEffects = effectsEnabled;

//toggle effects for all composer items
QList<QGraphicsItem*> itemList = items();
QList<QGraphicsItem*>::const_iterator itemIt = itemList.constBegin();
for ( ; itemIt != itemList.constEnd(); ++itemIt )
{
QgsComposerItem* composerItem = dynamic_cast<QgsComposerItem*>( *itemIt );
if ( composerItem )
{
composerItem->setEffectsEnabled( effectsEnabled );
}
}
}

int QgsComposition::pixelFontSize( double pointSize ) const
{
//in QgsComposition, one unit = one mm
Expand Down
10 changes: 10 additions & 0 deletions src/core/composer/qgscomposition.h
Expand Up @@ -182,6 +182,13 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
bool printAsRaster() const {return mPrintAsRaster;}
void setPrintAsRaster( bool enabled ) { mPrintAsRaster = enabled; }

/**Returns true if a composition should use advanced effects such as blend modes
@note added in 1.9*/
bool useAdvancedEffects() const {return mUseAdvancedEffects;}
/**Used to enable or disable advanced effects such as blend modes in a composition
@note: added in version 1.9*/
void setUseAdvancedEffects( bool effectsEnabled );

double selectionTolerance() const { return mSelectionTolerance; }
void setSelectionTolerance( double tol );

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

/**Flag if advanced visual effects such as blend modes should be used. True by default*/
bool mUseAdvancedEffects;

/**Distance tolerance for item selection (in mm)*/
double mSelectionTolerance;

Expand Down
13 changes: 8 additions & 5 deletions src/core/qgsmaprenderer.cpp
Expand Up @@ -397,9 +397,12 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
.arg( ml->blendMode() )
);

// Set the QPainter composition mode so that this layer is rendered using
// the desired blending mode
mypContextPainter->setCompositionMode( ml->blendMode() );
if ( mRenderContext.useAdvancedEffects() )
{
// Set the QPainter composition mode so that this layer is rendered using
// the desired blending mode
mypContextPainter->setCompositionMode( ml->blendMode() );
}

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

// If we flattened this layer for alternate blend modes, composite it now
if (( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
if (( mRenderContext.useAdvancedEffects() ) && ( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
( ml->type() != QgsMapLayer::RasterLayer ) &&
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
{
Expand Down
25 changes: 20 additions & 5 deletions src/core/qgspallabeling.cpp
Expand Up @@ -2286,7 +2286,10 @@ void QgsPalLabeling::drawLabel( pal::LabelPosition* label, QgsRenderContext& con
}

// paint the text
painter->setCompositionMode( tmpLyr.blendMode );
if ( context.useAdvancedEffects() )
{
painter->setCompositionMode( tmpLyr.blendMode );
}
// painter->setPen( Qt::NoPen );
// painter->setBrush( tmpLyr.textColor );
// painter->drawPath( path );
Expand Down Expand Up @@ -2350,7 +2353,10 @@ void QgsPalLabeling::drawLabelBuffer( QgsRenderContext& context,
}

p->save();
p->setCompositionMode( tmpLyr.bufferBlendMode );
if ( context.useAdvancedEffects() )
{
p->setCompositionMode( tmpLyr.bufferBlendMode );
}
// p->setPen( pen );
// p->setBrush( tmpColor );
// p->drawPath( path );
Expand Down Expand Up @@ -2512,7 +2518,10 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,
( 100.0 - ( double )( tmpLyr.shapeTransparency ) ) / 100.0 );

p->save();
p->setCompositionMode( tmpLyr.shapeBlendMode );
if ( context.useAdvancedEffects() )
{
p->setCompositionMode( tmpLyr.shapeBlendMode );
}
p->translate( component.center().x(), component.center().y() );
p->rotate( component.rotation() );
double xoff = tmpLyr.scaleToPixelContext( tmpLyr.shapeOffset.x(), context, tmpLyr.shapeOffsetUnits );
Expand Down Expand Up @@ -2642,7 +2651,10 @@ void QgsPalLabeling::drawLabelBackground( QgsRenderContext& context,
}

p->setOpacity(( 100.0 - ( double )( tmpLyr.shapeTransparency ) ) / 100.0 );
p->setCompositionMode( tmpLyr.shapeBlendMode );
if ( context.useAdvancedEffects() )
{
p->setCompositionMode( tmpLyr.shapeBlendMode );
}

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

p->save();
p->setRenderHints( QPainter::Antialiasing | QPainter::SmoothPixmapTransform );
p->setCompositionMode( tmpLyr.shadowBlendMode );
if ( context.useAdvancedEffects() )
{
p->setCompositionMode( tmpLyr.shadowBlendMode );
}
p->setOpacity(( 100.0 - ( double )( tmpLyr.shadowTransparency ) ) / 100.0 );

double scale = ( double )tmpLyr.shadowScale / 100.0;
Expand Down
1 change: 1 addition & 0 deletions src/core/qgsrendercontext.cpp
Expand Up @@ -23,6 +23,7 @@ QgsRenderContext::QgsRenderContext()
mCoordTransform( 0 ),
mDrawEditingInformation( true ),
mForceVectorOutput( false ),
mUseAdvancedEffects( true ),
mRenderingStopped( false ),
mScaleFactor( 1.0 ),
mRasterScaleFactor( 1.0 ),
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsrendercontext.h
Expand Up @@ -59,6 +59,13 @@ class CORE_EXPORT QgsRenderContext

bool forceVectorOutput() const {return mForceVectorOutput;}

/**Returns true if advanced effects such as blend modes such be used
@note added in 1.9*/
bool useAdvancedEffects() const {return mUseAdvancedEffects;}
/**Used to enable or disable advanced effects such as blend modes
@note: added in version 1.9*/
void setUseAdvancedEffects( bool enabled ) { mUseAdvancedEffects = enabled; }

bool drawEditingInformation() const {return mDrawEditingInformation;}

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

/**Flag if advanced visual effects such as blend modes should be used. True by default*/
bool mUseAdvancedEffects;

QgsMapToPixel mMapToPixel;

/**True if the rendering has been canceled*/
Expand Down

0 comments on commit 2caf0e0

Please sign in to comment.