Skip to content

Commit 51e5894

Browse files
committed
Blend modes apply to whole layer, not individual objects (fix #7603)
1 parent 06abc4d commit 51e5894

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

‎src/core/qgsmaprenderer.cpp‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
364364
// Store the painter in case we need to swap it out for the
365365
// cache painter
366366
QPainter * mypContextPainter = mRenderContext.painter();
367+
// Flattened image for drawing when a blending mode is set
368+
QImage * mypFlattenedImage = 0;
367369

368370
QString layerId = li.previous();
369371

@@ -509,6 +511,26 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
509511
}
510512
}
511513

514+
// If we are drawing with an alternative blending mode then we need to render to a seperate image
515+
// before compositing this on the map. This effectively flattens the layer and prevents
516+
// blending occuring between objects on the layer
517+
// (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 ) &&
519+
( ml->type() != QgsMapLayer::RasterLayer ) &&
520+
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
521+
{
522+
mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
523+
mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
524+
mypFlattenedImage->fill( 0 );
525+
QPainter * mypPainter = new QPainter( mypFlattenedImage );
526+
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
527+
{
528+
mypPainter->setRenderHint( QPainter::Antialiasing );
529+
}
530+
mypPainter->scale( rasterScaleFactor, rasterScaleFactor );
531+
mRenderContext.setPainter( mypPainter );
532+
}
533+
512534
if ( scaleRaster )
513535
{
514536
bk_mapToPixel = mRenderContext.mapToPixel();
@@ -557,6 +579,22 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
557579
mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) );
558580
}
559581
}
582+
583+
// If we flattened this layer for alternate blend modes, composite it now
584+
if (( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
585+
( ml->type() != QgsMapLayer::RasterLayer ) &&
586+
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
587+
{
588+
delete mRenderContext.painter();
589+
mRenderContext.setPainter( mypContextPainter );
590+
mypContextPainter->save();
591+
mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
592+
mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) );
593+
mypContextPainter->restore();
594+
delete mypFlattenedImage;
595+
mypFlattenedImage = 0;
596+
}
597+
560598
disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) );
561599
}
562600
else // layer not visible due to scale

0 commit comments

Comments
 (0)