Skip to content

Commit

Permalink
Add blend mode option for features, allows blending to be used betwee…
Browse files Browse the repository at this point in the history
…n features in a layer
  • Loading branch information
nyalldawson committed May 13, 2013
1 parent 226c524 commit 63ee006
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 19 deletions.
7 changes: 6 additions & 1 deletion src/core/composer/qgscomposermap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,10 +655,15 @@ bool QgsComposerMap::containsBlendModes() const
{
return true;
}
// if vector layer and has labels, check label blend modes
// if vector layer, check labels and feature blend mode
QgsVectorLayer* currentVectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
if ( currentVectorLayer )
{
if ( currentVectorLayer->featureBlendMode() != QPainter::CompositionMode_SourceOver )
{
return true;
}
// check label blend modes
if ( lbl->willUseLayer( currentVectorLayer ) )
{
// Check all label blending properties
Expand Down
35 changes: 21 additions & 14 deletions src/core/qgsmaprenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,20 +518,29 @@ 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 (( mRenderContext.useAdvancedEffects() ) && ( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
( ml->type() != QgsMapLayer::RasterLayer ) &&
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
bool flattenedLayer = false;
if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) )
{
mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
mypFlattenedImage->fill( 0 );
QPainter * mypPainter = new QPainter( mypFlattenedImage );
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml );
if (( vl->blendMode() != QPainter::CompositionMode_SourceOver && ( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
|| ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver ) )

{
mypPainter->setRenderHint( QPainter::Antialiasing );
flattenedLayer = true;
mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(),
mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 );
mypFlattenedImage->fill( 0 );
QPainter * mypPainter = new QPainter( mypFlattenedImage );
if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() )
{
mypPainter->setRenderHint( QPainter::Antialiasing );
}
mypPainter->scale( rasterScaleFactor, rasterScaleFactor );
mRenderContext.setPainter( mypPainter );

// set the painter to the feature blend mode
mypPainter->setCompositionMode( vl->featureBlendMode() );
}
mypPainter->scale( rasterScaleFactor, rasterScaleFactor );
mRenderContext.setPainter( mypPainter );
}

if ( scaleRaster )
Expand Down Expand Up @@ -584,9 +593,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )
}

// If we flattened this layer for alternate blend modes, composite it now
if (( mRenderContext.useAdvancedEffects() ) && ( ml->blendMode() != QPainter::CompositionMode_SourceOver ) &&
( ml->type() != QgsMapLayer::RasterLayer ) &&
( split || !mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) )
if ( flattenedLayer )
{
delete mRenderContext.painter();
mRenderContext.setPainter( mypContextPainter );
Expand Down
27 changes: 27 additions & 0 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
, mRendererV2( NULL )
, mLabel( 0 )
, mLabelOn( false )
, mFeatureBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal feature blending
, mVertexMarkerOnlyForSelection( false )
, mCache( new QgsGeometryCache( this ) )
, mEditBuffer( 0 )
Expand Down Expand Up @@ -1759,6 +1760,14 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) e.text().toInt() ) );
}

// get and set the feature blend mode if it exists
QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
if ( !featureBlendModeNode.isNull() )
{
QDomElement e = featureBlendModeNode.toElement();
setFeatureBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) e.text().toInt() ) );
}

// use scale dependent visibility flag
QDomElement e = node.toElement();
mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
Expand Down Expand Up @@ -2084,6 +2093,12 @@ bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString&
blendModeElem.appendChild( blendModeText );
node.appendChild( blendModeElem );

// add the feature blend mode field
QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
QDomText featureBlendModeText = doc.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( featureBlendMode() ) ) );
featureBlendModeElem.appendChild( featureBlendModeText );
node.appendChild( featureBlendModeElem );

// add the display field
QDomElement dField = doc.createElement( "displayfield" );
QDomText dFieldText = doc.createTextNode( displayField() );
Expand Down Expand Up @@ -3340,6 +3355,18 @@ QVariant QgsVectorLayer::maximumValue( int index )
return QVariant();
}

/** Write blend mode for features */
void QgsVectorLayer::setFeatureBlendMode( const QPainter::CompositionMode featureBlendMode )
{
mFeatureBlendMode = featureBlendMode;
}

/** Read blend mode for layer */
QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
{
return mFeatureBlendMode;
}

void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
{
mRendererV2->stopRender( rendererContext );
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
@note added in 1.7*/
QVariant maximumValue( int index );

/* Set the blending mode used for rendering each feature
* @note added in 2.0
*/
void setFeatureBlendMode( const QPainter::CompositionMode blendMode );
/* Returns the current blending mode for features
* @note added in 2.0
*/
QPainter::CompositionMode featureBlendMode() const;

public slots:
/**
* Select feature by its ID
Expand Down Expand Up @@ -1480,6 +1489,9 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Display labels */
bool mLabelOn;

/** Blend mode for features */
QPainter::CompositionMode mFeatureBlendMode;

/**The current type of editing marker*/
QgsVectorLayer::VertexMarkerType mCurrentVertexMarkerType;

Expand Down
6 changes: 5 additions & 1 deletion src/gui/symbology-ng/qgsrendererv2propertiesdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ QgsRendererV2PropertiesDialog::QgsRendererV2PropertiesDialog( QgsVectorLayer* la
// Blend mode
mBlendModeComboBox->setBlendMode( mLayer->blendMode() );

// Feature blend mode
mFeatureBlendComboBox->setBlendMode( mLayer->featureBlendMode() );

QPixmap pix;
QgsRendererV2Registry* reg = QgsRendererV2Registry::instance();
QStringList renderers = reg->renderersList();
Expand Down Expand Up @@ -173,8 +176,9 @@ void QgsRendererV2PropertiesDialog::apply()
mLayer->setRendererV2( renderer->clone() );
}

// set the blend mode for the layer
// set the blend modes for the layer
mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
mLayer->setFeatureBlendMode( mFeatureBlendComboBox->blendMode() );
}

void QgsRendererV2PropertiesDialog::onOK()
Expand Down
37 changes: 34 additions & 3 deletions src/ui/qgsrendererv2propsdialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@
<string>Renderer settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QgsCollapsibleGroupBox" name="groupBox">
<property name="title">
<string>Layer rendering</string>
</property>
<property name="collapsed" stdset="0">
<bool>false</bool>
</property>
<property name="saveCollapsedState" stdset="0">
<bool>true</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblLayerBlend">
<property name="text">
<string>Layer blending mode</string>
</property>
</widget>
</item>
<item>
<widget class="QgsBlendModeComboBox" name="mBlendModeComboBox"/>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
Expand All @@ -33,14 +58,14 @@
</spacer>
</item>
<item>
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="lblFeatureBlend">
<property name="text">
<string>Blending mode</string>
<string>Feature blending mode</string>
</property>
</widget>
</item>
<item>
<widget class="QgsBlendModeComboBox" name="mBlendModeComboBox"/>
<widget class="QgsBlendModeComboBox" name="mFeatureBlendComboBox"/>
</item>
</layout>
</item>
Expand Down Expand Up @@ -89,6 +114,12 @@
<extends>QComboBox</extends>
<header>qgsblendmodecombobox.h</header>
</customwidget>
<customwidget>
<class>QgsCollapsibleGroupBox</class>
<extends>QGroupBox</extends>
<header>qgscollapsiblegroupbox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>cboRenderers</tabstop>
Expand Down

0 comments on commit 63ee006

Please sign in to comment.