Skip to content

Commit 594eea5

Browse files
author
mhugent
committed
Added layer transparency to symbol classes (with the exception of svg marker, where I'm still looking for a solution with QPicture)
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12811 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent d059f32 commit 594eea5

10 files changed

+141
-33
lines changed

src/core/symbology-ng/qgsfillsymbollayerv2.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ QString QgsSimpleFillSymbolLayerV2::layerType() const
4343

4444
void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
4545
{
46+
mColor.setAlphaF( context.alpha() );
4647
mBrush = QBrush( mColor, mBrushStyle );
48+
mBorderColor.setAlphaF( context.alpha() );
4749
mPen = QPen( mBorderColor );
4850
mPen.setStyle( mBorderStyle );
4951
mPen.setWidthF( context.outputLineWidth( mBorderWidth ) );
@@ -162,10 +164,10 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
162164
}
163165

164166
//create QImage with appropriate dimensions
165-
int pixelWidth = context.outputPixelSize( mPatternWidth );//mPatternWidth.value( context, QgsOutputUnit::Pixel );
167+
int pixelWidth = context.outputPixelSize( mPatternWidth );
166168
int pixelHeight = pixelWidth / mSvgViewBox.width() * mSvgViewBox.height();
167169

168-
QImage textureImage( pixelWidth, pixelHeight, QImage::Format_ARGB32_Premultiplied );
170+
QImage textureImage( pixelWidth, pixelHeight, QImage::Format_ARGB32 );
169171
textureImage.fill( 0 ); // transparent background
170172

171173
//rasterise byte array to image
@@ -177,6 +179,11 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolV2RenderContext& context )
177179
}
178180
r.render( &p );
179181

182+
if ( context.alpha() < 1.0 )
183+
{
184+
QgsSymbolLayerV2Utils::multiplyImageOpacity( &textureImage, context.alpha() );
185+
}
186+
180187
QTransform brushTransform;
181188
brushTransform.scale( 1.0 / context.renderContext().rasterScaleFactor(), 1.0 / context.renderContext().rasterScaleFactor() );
182189
mBrush.setTextureImage( textureImage );

src/core/symbology-ng/qgslinesymbollayerv2.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ QString QgsSimpleLineSymbolLayerV2::layerType() const
5858

5959
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
6060
{
61-
mPen.setColor( mColor );
61+
QColor penColor = mColor;
62+
penColor.setAlphaF( context.alpha() );
63+
mPen.setColor( penColor );
6264
double scaledWidth = context.outputLineWidth( mWidth );
6365
mPen.setWidthF( scaledWidth );
6466
if ( mUseCustomDashPattern && scaledWidth != 0 )
@@ -242,6 +244,7 @@ void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
242244
// if being rotated, it gets initialized with every line segment
243245
if ( !mRotateMarker )
244246
{
247+
mMarker->setAlpha( context.alpha() );
245248
mMarker->startRender( context.renderContext() );
246249
}
247250
}
@@ -298,6 +301,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineNoOffset( const QPolygonF& points
298301
// rotate marker (if desired)
299302
if ( mRotateMarker )
300303
{
304+
mMarker->setAlpha( context.alpha() );
301305
mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
302306
mMarker->startRender( rc );
303307
}
@@ -394,7 +398,9 @@ QString QgsLineDecorationSymbolLayerV2::layerType() const
394398

395399
void QgsLineDecorationSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
396400
{
397-
mPen.setColor( mColor );
401+
QColor penColor = mColor;
402+
penColor.setAlphaF( context.alpha() );
403+
mPen.setColor( penColor );
398404
}
399405

400406
void QgsLineDecorationSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )

src/core/symbology-ng/qgsmarkersymbollayerv2.cpp

+14-4
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
164164

165165
double center = (( double ) imageSize / 2 ) + 0.5; // add 1/2 pixel for proper rounding when the figure's coordinates are added
166166

167-
mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
167+
mCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32 );
168168
mCache.fill( 0 );
169169

170170
QPainter p;
@@ -175,6 +175,12 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
175175
p.translate( QPointF( center, center ) );
176176
drawMarker( &p, context );
177177
p.end();
178+
179+
//opacity
180+
if ( context.alpha() < 1.0 )
181+
{
182+
QgsSymbolLayerV2Utils::multiplyImageOpacity( &mCache, context.alpha() );
183+
}
178184
}
179185

180186
void QgsSimpleMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -512,6 +518,8 @@ void QgsFontMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
512518
mFont = QFont( mFontFamily, MM2POINT( mSize ) );
513519
QFontMetrics fm( mFont );
514520
mChrOffset = QPointF( fm.width( mChr ) / 2, -fm.ascent() / 2 );
521+
522+
515523
}
516524

517525
void QgsFontMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -521,15 +529,17 @@ void QgsFontMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
521529
void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
522530
{
523531
QPainter* p = context.renderContext().painter();
524-
p->setPen( mColor );
532+
QColor penColor = mColor;
533+
penColor.setAlphaF( context.alpha() );
534+
p->setPen( penColor );
525535
p->setFont( mFont );
526536

527537
p->save();
528-
p->translate(point);
538+
p->translate( point );
529539
if ( mAngle != 0 )
530540
p->rotate( mAngle );
531541

532-
p->drawText(-mChrOffset, mChr );
542+
p->drawText( -mChrOffset, mChr );
533543
p->restore();
534544
}
535545

src/core/symbology-ng/qgssymbollayerv2utils.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ QgsSymbolV2* QgsSymbolLayerV2Utils::loadSymbol( QDomElement& element )
414414
}
415415

416416
symbol->setOutputUnit( decodeOutputUnit( element.attribute( "outputUnit" ) ) );
417+
symbol->setAlpha( element.attribute( "alpha", "1.0" ).toDouble() );
417418

418419
return symbol;
419420
}
@@ -459,6 +460,7 @@ QDomElement QgsSymbolLayerV2Utils::saveSymbol( QString name, QgsSymbolV2* symbol
459460
symEl.setAttribute( "type", _nameForSymbolType( symbol->type() ) );
460461
symEl.setAttribute( "name", name );
461462
symEl.setAttribute( "outputUnit", encodeOutputUnit( symbol->outputUnit() ) );
463+
symEl.setAttribute( "alpha", symbol->alpha() );
462464
QgsDebugMsg( "num layers " + QString::number( symbol->symbolLayerCount() ) );
463465
for ( int i = 0; i < symbol->symbolLayerCount(); i++ )
464466
{
@@ -712,3 +714,28 @@ QgsRenderContext QgsSymbolLayerV2Utils::createRenderContext( QPainter* p )
712714
}
713715
return context;
714716
}
717+
718+
void QgsSymbolLayerV2Utils::multiplyImageOpacity( QImage* image, qreal alpha )
719+
{
720+
if ( !image )
721+
{
722+
return;
723+
}
724+
725+
//change the alpha component of every pixel
726+
int widthIndex = 0;
727+
int heightIndex = 0;
728+
QRgb* scanLine = 0;
729+
QRgb myRgb;
730+
731+
for ( ; heightIndex < image->height(); ++heightIndex )
732+
{
733+
scanLine = ( QRgb* )image->scanLine( heightIndex );
734+
widthIndex = 0;
735+
for ( ; widthIndex < image->width(); ++widthIndex )
736+
{
737+
myRgb = image->pixel( widthIndex, heightIndex );
738+
scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), qAlpha( myRgb ) * alpha );
739+
}
740+
}
741+
}

src/core/symbology-ng/qgssymbollayerv2utils.h

+3
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
8080
static QgsRenderContext createRenderContext( QPainter* p );
8181

8282
static QString iconPath( QString iconFile );
83+
84+
/**Multiplies opacity of image pixel values with a (global) transparency value*/
85+
static void multiplyImageOpacity( QImage* image, qreal alpha );
8386
};
8487

8588
class QPolygonF;

src/core/symbology-ng/qgssymbolv2.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#include <cmath>
1818

1919
QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
20-
: mType( type ), mLayers( layers ), mOutputUnit( MM )
20+
: mType( type ), mLayers( layers ), mOutputUnit( MM ), mAlpha( 1.0 )
2121
{
2222

2323
// check they're all correct symbol layers
@@ -126,14 +126,14 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
126126

127127
void QgsSymbolV2::startRender( QgsRenderContext& context )
128128
{
129-
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit );
129+
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
130130
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
131131
( *it )->startRender( symbolContext );
132132
}
133133

134134
void QgsSymbolV2::stopRender( QgsRenderContext& context )
135135
{
136-
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit );
136+
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
137137
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
138138
( *it )->stopRender( symbolContext );
139139
}
@@ -244,8 +244,8 @@ QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
244244

245245
////////////////////
246246

247-
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u )
248-
: mRenderContext( c ), mOutputUnit( u )
247+
QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha )
248+
: mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha )
249249
{
250250

251251
}
@@ -331,7 +331,7 @@ double QgsMarkerSymbolV2::size()
331331

332332
void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer )
333333
{
334-
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit );
334+
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
335335
if ( layer != -1 )
336336
{
337337
if ( layer >= 0 && layer < mLayers.count() )
@@ -350,6 +350,7 @@ QgsSymbolV2* QgsMarkerSymbolV2::clone() const
350350
{
351351
QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() );
352352
cloneSymbol->setOutputUnit( mOutputUnit );
353+
cloneSymbol->setAlpha( mAlpha );
353354
return cloneSymbol;
354355
}
355356

@@ -399,7 +400,7 @@ double QgsLineSymbolV2::width()
399400

400401
void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer )
401402
{
402-
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit );
403+
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
403404
if ( layer != -1 )
404405
{
405406
if ( layer >= 0 && layer < mLayers.count() )
@@ -419,6 +420,7 @@ QgsSymbolV2* QgsLineSymbolV2::clone() const
419420
{
420421
QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() );
421422
cloneSymbol->setOutputUnit( mOutputUnit );
423+
cloneSymbol->setAlpha( mAlpha );
422424
return cloneSymbol;
423425
}
424426

@@ -434,7 +436,7 @@ QgsFillSymbolV2::QgsFillSymbolV2( QgsSymbolLayerV2List layers )
434436

435437
void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer )
436438
{
437-
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit );
439+
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha );
438440
if ( layer != -1 )
439441
{
440442
if ( layer >= 0 && layer < mLayers.count() )
@@ -454,5 +456,6 @@ QgsSymbolV2* QgsFillSymbolV2::clone() const
454456
{
455457
QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() );
456458
cloneSymbol->setOutputUnit( mOutputUnit );
459+
cloneSymbol->setAlpha( mAlpha );
457460
return cloneSymbol;
458461
}

src/core/symbology-ng/qgssymbolv2.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ class CORE_EXPORT QgsSymbolV2
8181
OutputUnit outputUnit() const { return mOutputUnit; }
8282
void setOutputUnit( OutputUnit u ) { mOutputUnit = u; }
8383

84+
qreal alpha() const { return mAlpha; }
85+
void setAlpha( qreal alpha ) { mAlpha = alpha; }
86+
8487
protected:
8588
QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers ); // can't be instantiated
8689

@@ -90,14 +93,17 @@ class CORE_EXPORT QgsSymbolV2
9093
QgsSymbolLayerV2List mLayers;
9194

9295
OutputUnit mOutputUnit;
96+
97+
/**Symbol opacity (in the range 0 - 1)*/
98+
qreal mAlpha;
9399
};
94100

95101
///////////////////////
96102

97103
class CORE_EXPORT QgsSymbolV2RenderContext
98104
{
99105
public:
100-
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
106+
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0 );
101107
~QgsSymbolV2RenderContext();
102108

103109
QgsRenderContext& renderContext() { return mRenderContext; }
@@ -106,12 +112,16 @@ class CORE_EXPORT QgsSymbolV2RenderContext
106112
QgsSymbolV2::OutputUnit outputUnit() const { return mOutputUnit; }
107113
void setOutputUnit( QgsSymbolV2::OutputUnit u ) { mOutputUnit = u; }
108114

109-
double outputLineWidth(double width) const;
110-
double outputPixelSize(double size) const;
115+
qreal alpha() const { return mAlpha; }
116+
void setAlpha( qreal alpha ) { mAlpha = alpha; }
117+
118+
double outputLineWidth( double width ) const;
119+
double outputPixelSize( double size ) const;
111120

112121
private:
113122
QgsRenderContext& mRenderContext;
114123
QgsSymbolV2::OutputUnit mOutputUnit;
124+
qreal mAlpha;
115125
};
116126

117127

src/gui/symbology-ng/qgssymbolv2selectordialog.cpp

+27-7
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,17 @@ QgsSymbolV2SelectorDialog::QgsSymbolV2SelectorDialog( QgsSymbolV2* symbol, QgsSt
4141
updateSymbolPreview();
4242
updateSymbolInfo();
4343

44-
// output unit
45-
mSymbolUnitComboBox->blockSignals( true );
46-
mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() );
47-
mSymbolUnitComboBox->blockSignals( false );
44+
if ( mSymbol )
45+
{
46+
// output unit
47+
mSymbolUnitComboBox->blockSignals( true );
48+
mSymbolUnitComboBox->setCurrentIndex( mSymbol->outputUnit() );
49+
mSymbolUnitComboBox->blockSignals( false );
50+
51+
mOpacitySlider->blockSignals( true );
52+
mOpacitySlider->setValue( symbol->alpha() * 255 );
53+
mOpacitySlider->blockSignals( false );
54+
}
4855

4956
// select correct page in stacked widget
5057
// there's a correspondence between symbol type number and page numbering => exploit it!
@@ -232,8 +239,21 @@ void QgsSymbolV2SelectorDialog::keyPressEvent( QKeyEvent * e )
232239

233240
void QgsSymbolV2SelectorDialog::on_mSymbolUnitComboBox_currentIndexChanged( const QString & text )
234241
{
235-
mSymbol->setOutputUnit( (QgsSymbolV2::OutputUnit) mSymbolUnitComboBox->currentIndex() );
242+
if ( mSymbol )
243+
{
244+
mSymbol->setOutputUnit(( QgsSymbolV2::OutputUnit ) mSymbolUnitComboBox->currentIndex() );
236245

237-
updateSymbolPreview();
238-
emit symbolModified();
246+
updateSymbolPreview();
247+
emit symbolModified();
248+
}
249+
}
250+
251+
void QgsSymbolV2SelectorDialog::on_mOpacitySlider_valueChanged( int value )
252+
{
253+
if ( mSymbol )
254+
{
255+
mSymbol->setAlpha( value / 255.0 );
256+
updateSymbolPreview();
257+
emit symbolModified();
258+
}
239259
}

src/gui/symbology-ng/qgssymbolv2selectordialog.h

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class GUI_EXPORT QgsSymbolV2SelectorDialog : public QDialog, private Ui::QgsSymb
3434
void setLineWidth( double width );
3535
void addSymbolToStyle();
3636
void on_mSymbolUnitComboBox_currentIndexChanged( const QString & text );
37+
void on_mOpacitySlider_valueChanged( int value );
3738

3839
signals:
3940
void symbolModified();

0 commit comments

Comments
 (0)