Skip to content

Commit

Permalink
Merge pull request #485 from nyalldawson/blend_modes
Browse files Browse the repository at this point in the history
Blend modes pt 3 - blend modes for labels
  • Loading branch information
NathanW2 committed Mar 27, 2013
2 parents d1825ec + c9ef27c commit 2304350
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 100 deletions.
4 changes: 4 additions & 0 deletions src/app/qgslabelinggui.cpp
Expand Up @@ -250,6 +250,7 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
mBufferTranspSpinBox->setValue( lyr.bufferTransp );
mBufferJoinStyleComboBox->setPenJoinStyle( lyr.bufferJoinStyle );
mBufferTranspFillChbx->setChecked( !lyr.bufferNoFill );
comboBufferBlendMode->setBlendMode( lyr.bufferBlendMode );
}
else
{
Expand Down Expand Up @@ -290,6 +291,7 @@ QgsLabelingGui::QgsLabelingGui( QgsPalLabeling* lbl, QgsVectorLayer* layer, QgsM
mFontSizeSpinBox->setValue( lyr.textFont.pointSizeF() );
btnTextColor->setColor( lyr.textColor );
mFontTranspSpinBox->setValue( lyr.textTransp );
comboBlendMode->setBlendMode( lyr.blendMode );

mFontWordSpacingSpinBox->setValue( lyr.textFont.wordSpacing() );
mFontLetterSpacingSpinBox->setValue( lyr.textFont.letterSpacing() );
Expand Down Expand Up @@ -446,6 +448,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
lyr.textFont = mRefFont;
lyr.textNamedStyle = mFontStyleComboBox->currentText();
lyr.textTransp = mFontTranspSpinBox->value();
lyr.blendMode = ( QgsMapRenderer::BlendMode ) comboBlendMode->blendMode();
lyr.previewBkgrdColor = mPreviewBackgroundBtn->color();
lyr.enabled = chkEnableLabeling->isChecked();
lyr.priority = sliderPriority->value();
Expand All @@ -470,6 +473,7 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
lyr.bufferSizeInMapUnits = ( mBufferUnitComboBox->currentIndex() == 1 );
lyr.bufferJoinStyle = mBufferJoinStyleComboBox->penJoinStyle();
lyr.bufferNoFill = !mBufferTranspFillChbx->isChecked();
lyr.bufferBlendMode = ( QgsMapRenderer::BlendMode ) comboBufferBlendMode->blendMode();
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -825,7 +825,7 @@ void QgsRasterLayerProperties::apply()
}

//set the blend mode for the layer
mRasterLayer->setBlendMode(( QgsMapLayer::BlendMode ) mBlendModeComboBox->blendMode() );
mRasterLayer->setBlendMode(( QgsMapRenderer::BlendMode ) mBlendModeComboBox->blendMode() );

//get the thumbnail for the layer
pixmapThumbnail->setPixmap( mRasterLayer->previewAsPixmap( pixmapThumbnail->size() ) );
Expand Down
46 changes: 3 additions & 43 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -50,7 +50,7 @@ QgsMapLayer::QgsMapLayer( QgsMapLayer::LayerType type,
mLayerOrigName( lyrname ), // store the original name
mID( "" ),
mLayerType( type ),
mBlendMode( QgsMapLayer::BlendNormal ) // Default to normal blending
mBlendMode( QgsMapRenderer::BlendNormal ) // Default to normal blending
{
mCRS = new QgsCoordinateReferenceSystem();

Expand Down Expand Up @@ -135,57 +135,17 @@ QgsRectangle QgsMapLayer::extent()
}

/** Write blend mode for layer */
void QgsMapLayer::setBlendMode( const QgsMapLayer::BlendMode blendMode )
void QgsMapLayer::setBlendMode( const QgsMapRenderer::BlendMode blendMode )
{
mBlendMode = blendMode;
}

/** Read blend mode for layer */
QgsMapLayer::BlendMode QgsMapLayer::blendMode() const
QgsMapRenderer::BlendMode QgsMapLayer::blendMode() const
{
return mBlendMode;
}

/** Returns a QPainter::CompositionMode corresponding to the current
* blend mode for this layer
*/
QPainter::CompositionMode QgsMapLayer::getCompositionMode()
{
// Map QgsMapLayer::BlendNormal to QPainter::CompositionMode
switch ( mBlendMode )
{
case QgsMapLayer::BlendNormal:
return QPainter::CompositionMode_SourceOver;
case QgsMapLayer::BlendLighten:
return QPainter::CompositionMode_Lighten;
case QgsMapLayer::BlendScreen:
return QPainter::CompositionMode_Screen;
case QgsMapLayer::BlendDodge:
return QPainter::CompositionMode_ColorDodge;
case QgsMapLayer::BlendAddition:
return QPainter::CompositionMode_Plus;
case QgsMapLayer::BlendDarken:
return QPainter::CompositionMode_Darken;
case QgsMapLayer::BlendMultiply:
return QPainter::CompositionMode_Multiply;
case QgsMapLayer::BlendBurn:
return QPainter::CompositionMode_ColorBurn;
case QgsMapLayer::BlendOverlay:
return QPainter::CompositionMode_Overlay;
case QgsMapLayer::BlendSoftLight:
return QPainter::CompositionMode_SoftLight;
case QgsMapLayer::BlendHardLight:
return QPainter::CompositionMode_HardLight;
case QgsMapLayer::BlendDifference:
return QPainter::CompositionMode_Difference;
case QgsMapLayer::BlendSubtract:
return QPainter::CompositionMode_Exclusion;
default:
return QPainter::CompositionMode_SourceOver;
}
}


bool QgsMapLayer::draw( QgsRenderContext& rendererContext )
{
Q_UNUSED( rendererContext );
Expand Down
31 changes: 4 additions & 27 deletions src/core/qgsmaplayer.h
Expand Up @@ -29,6 +29,7 @@
#include "qgis.h"
#include "qgserror.h"
#include "qgsrectangle.h"
#include "qgsmaprenderer.h"

class QgsRenderContext;
class QgsCoordinateReferenceSystem;
Expand All @@ -54,26 +55,6 @@ class CORE_EXPORT QgsMapLayer : public QObject
PluginLayer // added in 1.5
};

/** Blending modes enum defining the available composition modes that can
* be used when rendering a layer
*/
enum BlendMode
{
BlendNormal,
BlendLighten,
BlendScreen,
BlendDodge,
BlendAddition,
BlendDarken,
BlendMultiply,
BlendBurn,
BlendOverlay,
BlendSoftLight,
BlendHardLight,
BlendDifference,
BlendSubtract
};

/** Constructor
* @param type Type of layer as defined in QgsMapLayer::LayerType enum
* @param lyrname Display Name of the layer
Expand Down Expand Up @@ -116,13 +97,9 @@ class CORE_EXPORT QgsMapLayer : public QObject
const QString& abstract() const { return mAbstract; }

/* Set the blending mode used for rendering a layer */
void setBlendMode( const QgsMapLayer::BlendMode blendMode );
void setBlendMode( const QgsMapRenderer::BlendMode blendMode );
/* Returns the current blending mode for a layer */
QgsMapLayer::BlendMode blendMode() const;
/** Returns a QPainter::CompositionMode corresponding to the
* current blending mode for the layer
*/
QPainter::CompositionMode getCompositionMode();
QgsMapRenderer::BlendMode blendMode() const;

/**Synchronises with changes in the datasource
@note added in version 1.6*/
Expand Down Expand Up @@ -494,7 +471,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
QgsMapLayer::LayerType mLayerType;

/** Blend mode for the layer */
QgsMapLayer::BlendMode mBlendMode;
QgsMapRenderer::BlendMode mBlendMode;

/** Tag for embedding additional information */
QString mTag;
Expand Down
40 changes: 39 additions & 1 deletion src/core/qgsmaprenderer.cpp
Expand Up @@ -388,7 +388,7 @@ void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale )

// Set the QPainter composition mode so that this layer is rendered using
// the desired blending mode
mypContextPainter->setCompositionMode( ml->getCompositionMode() );
mypContextPainter->setCompositionMode( getCompositionMode( ml->blendMode() ) );

if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview )
{
Expand Down Expand Up @@ -1152,4 +1152,42 @@ const QgsCoordinateTransform* QgsMapRenderer::tr( QgsMapLayer *layer )
return QgsCoordinateTransformCache::instance()->transform( layer->crs().authid(), mDestCRS->authid() );
}

/** Returns a QPainter::CompositionMode corresponding to a QgsMapRenderer::BlendMode
*/
QPainter::CompositionMode QgsMapRenderer::getCompositionMode( const QgsMapRenderer::BlendMode blendMode )
{
// Map QgsMapRenderer::BlendNormal to QPainter::CompositionMode
switch ( blendMode )
{
case QgsMapRenderer::BlendNormal:
return QPainter::CompositionMode_SourceOver;
case QgsMapRenderer::BlendLighten:
return QPainter::CompositionMode_Lighten;
case QgsMapRenderer::BlendScreen:
return QPainter::CompositionMode_Screen;
case QgsMapRenderer::BlendDodge:
return QPainter::CompositionMode_ColorDodge;
case QgsMapRenderer::BlendAddition:
return QPainter::CompositionMode_Plus;
case QgsMapRenderer::BlendDarken:
return QPainter::CompositionMode_Darken;
case QgsMapRenderer::BlendMultiply:
return QPainter::CompositionMode_Multiply;
case QgsMapRenderer::BlendBurn:
return QPainter::CompositionMode_ColorBurn;
case QgsMapRenderer::BlendOverlay:
return QPainter::CompositionMode_Overlay;
case QgsMapRenderer::BlendSoftLight:
return QPainter::CompositionMode_SoftLight;
case QgsMapRenderer::BlendHardLight:
return QPainter::CompositionMode_HardLight;
case QgsMapRenderer::BlendDifference:
return QPainter::CompositionMode_Difference;
case QgsMapRenderer::BlendSubtract:
return QPainter::CompositionMode_Exclusion;
default:
return QPainter::CompositionMode_SourceOver;
}
}

bool QgsMapRenderer::mDrawing = false;
24 changes: 24 additions & 0 deletions src/core/qgsmaprenderer.h
Expand Up @@ -20,6 +20,7 @@
#include <QSize>
#include <QStringList>
#include <QVector>
#include <QPainter>

#include "qgis.h"
#include "qgsrectangle.h"
Expand Down Expand Up @@ -123,6 +124,26 @@ class CORE_EXPORT QgsMapRenderer : public QObject
//MAP_UNITS probably supported in future versions
};

/** Blending modes enum defining the available composition modes that can
* be used when rendering a layer
*/
enum BlendMode
{
BlendNormal,
BlendLighten,
BlendScreen,
BlendDodge,
BlendAddition,
BlendDarken,
BlendMultiply,
BlendBurn,
BlendOverlay,
BlendSoftLight,
BlendHardLight,
BlendDifference,
BlendSubtract
};

//! constructor
QgsMapRenderer();

Expand Down Expand Up @@ -230,6 +251,9 @@ class CORE_EXPORT QgsMapRenderer : public QObject
//! Added in QGIS v1.4
void setLabelingEngine( QgsLabelingEngineInterface* iface );

//! Returns a QPainter::CompositionMode corresponding to a BlendMode
QPainter::CompositionMode getCompositionMode( const QgsMapRenderer::BlendMode blendMode );

signals:

void drawingProgress( int current, int total );
Expand Down
21 changes: 20 additions & 1 deletion src/core/qgspallabeling.cpp
Expand Up @@ -202,6 +202,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
textNamedStyle = QString( "" );
textColor = Qt::black;
textTransp = 0;
blendMode = QgsMapRenderer::BlendNormal;
previewBkgrdColor = Qt::white;
enabled = false;
priority = 5;
Expand All @@ -212,6 +213,7 @@ QgsPalLayerSettings::QgsPalLayerSettings()
bufferSize = 1;
bufferColor = Qt::white;
bufferTransp = 0;
bufferBlendMode = QgsMapRenderer::BlendNormal;
bufferNoFill = false;
bufferJoinStyle = Qt::BevelJoin;
formatNumbers = false;
Expand Down Expand Up @@ -286,6 +288,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
textNamedStyle = s.textNamedStyle;
textColor = s.textColor;
textTransp = s.textTransp;
blendMode = s.blendMode;
previewBkgrdColor = s.previewBkgrdColor;
enabled = s.enabled;
priority = s.priority;
Expand All @@ -296,6 +299,7 @@ QgsPalLayerSettings::QgsPalLayerSettings( const QgsPalLayerSettings& s )
bufferSize = s.bufferSize;
bufferColor = s.bufferColor;
bufferTransp = s.bufferTransp;
bufferBlendMode = s.bufferBlendMode;
bufferJoinStyle = s.bufferJoinStyle;
bufferNoFill = s.bufferNoFill;
formatNumbers = s.formatNumbers;
Expand Down Expand Up @@ -524,6 +528,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
textFont.setWordSpacing( layer->customProperty( "labeling/fontWordSpacing", QVariant( 0.0 ) ).toDouble() );
textColor = _readColor( layer, "labeling/textColor" );
textTransp = layer->customProperty( "labeling/textTransp" ).toInt();
blendMode = ( QgsMapRenderer::BlendMode ) layer->customProperty( "labeling/blendMode" ).toInt();
previewBkgrdColor = QColor( layer->customProperty( "labeling/previewBkgrdColor", QVariant( "#ffffff" ) ).toString() );
enabled = layer->customProperty( "labeling/enabled" ).toBool();
priority = layer->customProperty( "labeling/priority" ).toInt();
Expand All @@ -534,6 +539,7 @@ void QgsPalLayerSettings::readFromLayer( QgsVectorLayer* layer )
bufferSize = layer->customProperty( "labeling/bufferSize" ).toDouble();
bufferColor = _readColor( layer, "labeling/bufferColor" );
bufferTransp = layer->customProperty( "labeling/bufferTransp" ).toInt();
bufferBlendMode = ( QgsMapRenderer::BlendMode ) layer->customProperty( "labeling/bufferBlendMode" ).toInt();
bufferJoinStyle = ( Qt::PenJoinStyle ) layer->customProperty( "labeling/bufferJoinStyle", QVariant( Qt::BevelJoin ) ).toUInt();
bufferNoFill = layer->customProperty( "labeling/bufferNoFill", QVariant( false ) ).toBool();
formatNumbers = layer->customProperty( "labeling/formatNumbers" ).toBool();
Expand Down Expand Up @@ -596,6 +602,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )

_writeColor( layer, "labeling/textColor", textColor );
layer->setCustomProperty( "labeling/textTransp", textTransp );
layer->setCustomProperty( "labeling/blendMode", ( unsigned int )blendMode );
layer->setCustomProperty( "labeling/previewBkgrdColor", previewBkgrdColor.name() );
layer->setCustomProperty( "labeling/enabled", enabled );
layer->setCustomProperty( "labeling/priority", priority );
Expand All @@ -606,6 +613,7 @@ void QgsPalLayerSettings::writeToLayer( QgsVectorLayer* layer )
layer->setCustomProperty( "labeling/bufferSize", bufferSize );
_writeColor( layer, "labeling/bufferColor", bufferColor );
layer->setCustomProperty( "labeling/bufferTransp", bufferTransp );
layer->setCustomProperty( "labeling/bufferBlendMode", ( unsigned int )bufferBlendMode );
layer->setCustomProperty( "labeling/bufferJoinStyle", ( unsigned int )bufferJoinStyle );
layer->setCustomProperty( "labeling/bufferNoFill", bufferNoFill );
layer->setCustomProperty( "labeling/formatNumbers", formatNumbers );
Expand Down Expand Up @@ -1645,9 +1653,11 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
QFont fontForLabel = lyr.textFont;
QColor fontColor = lyr.textColor;
int fontTransp = lyr.textTransp;
QgsMapRenderer::BlendMode blendMode = lyr.blendMode;
double bufferSize = lyr.bufferSize;
QColor bufferColor = lyr.bufferColor;
int bufferTransp = lyr.bufferTransp;
QgsMapRenderer::BlendMode bufferBlendMode = lyr.bufferBlendMode;

//apply data defined settings for the label
//font size
Expand Down Expand Up @@ -1741,10 +1751,16 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )

if ( lyr.bufferSize != 0 )
{
// Set the painter composition mode for the buffer
painter->setCompositionMode( mMapRenderer->getCompositionMode( bufferBlendMode ) );

int bufferPixelSize = lyr.sizeToPixel( bufferSize, context, true );
drawLabel( *it, painter, fontForLabel, fontColor, xform, bufferPixelSize, bufferColor, true );
}


// Set the painter composition mode before rendering the label
painter->setCompositionMode( mMapRenderer->getCompositionMode( blendMode ) );

drawLabel( *it, painter, fontForLabel, fontColor, xform );

if ( mLabelSearchTree )
Expand All @@ -1754,6 +1770,9 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
}
}

// Reset composition mode for further drawing operations
painter->setCompositionMode( QPainter::CompositionMode_SourceOver );

QgsDebugMsg( QString( "LABELING draw: %1 ms" ).arg( t.elapsed() ) );

delete problem;
Expand Down
2 changes: 2 additions & 0 deletions src/core/qgspallabeling.h
Expand Up @@ -154,6 +154,7 @@ class CORE_EXPORT QgsPalLayerSettings
QString textNamedStyle;
QColor textColor;
int textTransp;
QgsMapRenderer::BlendMode blendMode;
QColor previewBkgrdColor;
bool enabled;
int priority; // 0 = low, 10 = high
Expand All @@ -168,6 +169,7 @@ class CORE_EXPORT QgsPalLayerSettings
double bufferSize; //buffer size (in mm)
QColor bufferColor;
int bufferTransp;
QgsMapRenderer::BlendMode bufferBlendMode;
Qt::PenJoinStyle bufferJoinStyle;
bool bufferNoFill; //set interior of buffer to 100% transparent
bool formatNumbers;
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsvectorlayer.cpp
Expand Up @@ -2264,7 +2264,7 @@ bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage
if ( !blendModeNode.isNull() )
{
QDomElement e = blendModeNode.toElement();
setBlendMode(( QgsMapLayer::BlendMode ) e.text().toInt() );
setBlendMode(( QgsMapRenderer::BlendMode ) e.text().toInt() );
}

// use scale dependent visibility flag
Expand Down

0 comments on commit 2304350

Please sign in to comment.