QGIS API Documentation  2.12.0-Lyon
qgsgloweffect.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgloweffect.cpp
3  -----------------
4  begin : December 2014
5  copyright : (C) 2014 Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgsgloweffect.h"
19 #include "qgssymbollayerv2utils.h"
20 #include "qgsimageoperation.h"
21 #include "qgsvectorcolorrampv2.h"
22 
24  : QgsPaintEffect()
25  , mSpread( 2.0 )
26  , mSpreadUnit( QgsSymbolV2::MM )
27  , mRamp( NULL )
28  , mBlurLevel( 3 )
29  , mTransparency( 0.5 )
30  , mColor( Qt::white )
31  , mBlendMode( QPainter::CompositionMode_SourceOver )
32  , mColorType( SingleColor )
33 {
34 
35 }
36 
38  : QgsPaintEffect( other )
39  , mSpread( other.spread() )
40  , mSpreadUnit( other.spreadUnit() )
41  , mSpreadMapUnitScale( other.spreadMapUnitScale() )
42  , mRamp( NULL )
43  , mBlurLevel( other.blurLevel() )
44  , mTransparency( other.transparency() )
45  , mColor( other.color() )
46  , mBlendMode( other.blendMode() )
47  , mColorType( other.colorType() )
48 {
49  if ( other.ramp() )
50  {
51  mRamp = other.ramp()->clone();
52  }
53 }
54 
56 {
57  delete mRamp;
58 }
59 
61 {
62  if ( !source() || !enabled() || !context.painter() )
63  return;
64 
65  QImage im = sourceAsImage( context )->copy();
66 
68  if ( mColorType == ColorRamp && mRamp )
69  {
70  ramp = mRamp;
71  }
72  else
73  {
74  //create a temporary ramp
75  QColor transparentColor = mColor;
76  transparentColor.setAlpha( 0 );
77  ramp = new QgsVectorGradientColorRampV2( mColor, transparentColor );
78  }
79 
82  dtProps.useMaxDistance = false;
83  dtProps.shadeExterior = shadeExterior();
84  dtProps.ramp = ramp;
86 
87  if ( mBlurLevel > 0 )
88  {
90  }
91 
93 
94  if ( !shadeExterior() )
95  {
96  //only keep interior portion
97  QPainter p( &im );
98  p.setRenderHint( QPainter::Antialiasing );
99  p.setCompositionMode( QPainter::CompositionMode_DestinationIn );
100  p.drawImage( 0, 0, *sourceAsImage( context ) );
101  p.end();
102  }
103 
104  QPainter* painter = context.painter();
105  painter->save();
106  painter->setCompositionMode( mBlendMode );
107  painter->drawImage( imageOffset( context ), im );
108  painter->restore();
109 
110  if ( !mRamp )
111  {
112  //delete temporary ramp
113  delete ramp;
114  }
115 }
116 
118 {
119  QgsStringMap props;
120  props.insert( "enabled", mEnabled ? "1" : "0" );
121  props.insert( "draw_mode", QString::number( int( mDrawMode ) ) );
122  props.insert( "blend_mode", QString::number( int( mBlendMode ) ) );
123  props.insert( "transparency", QString::number( mTransparency ) );
124  props.insert( "blur_level", QString::number( mBlurLevel ) );
125  props.insert( "spread", QString::number( mSpread ) );
128  props.insert( "color_type", QString::number(( int )mColorType ) );
129  props.insert( "single_color", QgsSymbolLayerV2Utils::encodeColor( mColor ) );
130 
131  if ( mRamp )
132  {
133  props.unite( mRamp->properties() );
134  }
135 
136  return props;
137 }
138 
140 {
141  bool ok;
142  QPainter::CompositionMode mode = ( QPainter::CompositionMode )props.value( "blend_mode" ).toInt( &ok );
143  if ( ok )
144  {
145  mBlendMode = mode;
146  }
147  double transparency = props.value( "transparency" ).toDouble( &ok );
148  if ( ok )
149  {
151  }
152  mEnabled = props.value( "enabled", "1" ).toInt();
153  mDrawMode = ( QgsPaintEffect::DrawMode )props.value( "draw_mode", "2" ).toInt();
154  int level = props.value( "blur_level" ).toInt( &ok );
155  if ( ok )
156  {
157  mBlurLevel = level;
158  }
159  double spread = props.value( "spread" ).toDouble( &ok );
160  if ( ok )
161  {
162  mSpread = spread;
163  }
164  mSpreadUnit = QgsSymbolLayerV2Utils::decodeOutputUnit( props.value( "spread_unit" ) );
165  mSpreadMapUnitScale = QgsSymbolLayerV2Utils::decodeMapUnitScale( props.value( "spread_unit_scale" ) );
166  QgsGlowEffect::GlowColorType type = ( QgsGlowEffect::GlowColorType )props.value( "color_type" ).toInt( &ok );
167  if ( ok )
168  {
169  mColorType = type;
170  }
171  if ( props.contains( "single_color" ) )
172  {
173  mColor = QgsSymbolLayerV2Utils::decodeColor( props.value( "single_color" ) );
174  }
175 
176  //attempt to create color ramp from props
177  delete mRamp;
179 }
180 
182 {
183  delete mRamp;
184  mRamp = ramp;
185 }
186 
188 {
189  if ( &rhs == this )
190  return *this;
191 
192  delete mRamp;
193 
194  mSpread = rhs.spread();
195  mRamp = rhs.ramp() ? rhs.ramp()->clone() : NULL;
196  mBlurLevel = rhs.blurLevel();
197  mTransparency = rhs.transparency();
198  mColor = rhs.color();
199  mBlendMode = rhs.blendMode();
200  mColorType = rhs.colorType();
201 
202  return *this;
203 }
204 
205 QRectF QgsGlowEffect::boundingRect( const QRectF &rect, const QgsRenderContext& context ) const
206 {
207  //spread size
209  //plus possible extension due to blur, with a couple of extra pixels thrown in for safety
210  spread += mBlurLevel * 2 + 10;
211  return rect.adjusted( -spread, -spread, spread, spread );
212 }
213 
214 
215 //
216 // QgsOuterGlowEffect
217 //
218 
220  : QgsGlowEffect()
221 {
222 
223 }
224 
226 {
227 
228 }
229 
231 {
232  QgsOuterGlowEffect* effect = new QgsOuterGlowEffect();
233  effect->readProperties( map );
234  return effect;
235 }
236 
238 {
239  QgsOuterGlowEffect* newEffect = new QgsOuterGlowEffect( *this );
240  return newEffect;
241 }
242 
243 
244 //
245 // QgsInnerGlowEffect
246 //
247 
249  : QgsGlowEffect()
250 {
251 
252 }
253 
255 {
256 
257 }
258 
260 {
261  QgsInnerGlowEffect* effect = new QgsInnerGlowEffect();
262  effect->readProperties( map );
263  return effect;
264 }
265 
267 {
268  QgsInnerGlowEffect* newEffect = new QgsInnerGlowEffect( *this );
269  return newEffect;
270 }
static QString encodeOutputUnit(QgsSymbolV2::OutputUnit unit)
QgsVectorColorRampV2 * ramp() const
Returns the color ramp used for the glow.
QgsSymbolV2::OutputUnit mSpreadUnit
virtual QgsPaintEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
bool end()
bool contains(const Key &key) const
void setCompositionMode(CompositionMode mode)
virtual ~QgsOuterGlowEffect()
DrawMode mDrawMode
static void multiplyOpacity(QImage &image, const double factor)
Multiplies opacity of image pixel values by a factor.
void setRenderHint(RenderHint hint, bool on)
QMap< Key, T > & unite(const QMap< Key, T > &other)
static QString encodeColor(const QColor &color)
static void distanceTransform(QImage &image, const DistanceTransformProperties &properties)
Performs a distance transform on the source image and shades the result using a color ramp...
double transparency() const
Returns the transparency for the effect.
QPainter::CompositionMode mBlendMode
QgsGlowEffect & operator=(const QgsGlowEffect &rhs)
double spread
Maximum distance (in pixels) for the distance transform shading to spread.
bool enabled() const
Returns whether the effect is enabled.
Base class for visual effects which can be applied to QPicture drawings.
virtual void draw(QgsRenderContext &context) override
Handles drawing of the effect's result on to the specified render context.
void save()
void setAlpha(int alpha)
virtual QgsStringMap properties() const =0
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
QImage copy(const QRect &rectangle) const
bool shadeExterior
Set to true to perform the distance transform on transparent pixels in the source image...
virtual bool shadeExterior() const =0
Specifies whether the glow is drawn outside the picture or within the picture.
Base class for paint effect which draw a glow inside or outside a picture.
Definition: qgsgloweffect.h:34
static double pixelSizeScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns scale factor painter units -> pixel dimensions.
QImage * sourceAsImage(QgsRenderContext &context)
Returns the source QPicture rendered to a new QImage.
static QgsSymbolV2::OutputUnit decodeOutputUnit(const QString &str)
double mTransparency
QString number(int n, int base)
double spread() const
Returns the spread distance used for drawing the glow effect.
Definition: qgsgloweffect.h:67
GlowColorType mColorType
virtual QString type() const =0
Returns the effect type.
virtual QgsVectorColorRampV2 * clone() const =0
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsOuterGlowEffect effect from a properties string map.
QgsVectorColorRampV2 * mRamp
GlowColorType
Color sources for the glow.
Definition: qgsgloweffect.h:40
QPointF imageOffset(const QgsRenderContext &context) const
Returns the offset which should be used when drawing the source image on to a destination render cont...
bool useMaxDistance
Set to true to automatically calculate the maximum distance in the transform to use as the spread val...
A paint effect which draws a glow outside of a picture.
DrawMode
Drawing modes for effects.
virtual ~QgsInnerGlowEffect()
static QgsVectorColorRampV2 * create(const QgsStringMap &properties=QgsStringMap())
QgsVectorColorRampV2 * ramp
Color ramp to use for shading the distance transform.
void restore()
void setRamp(QgsVectorColorRampV2 *ramp)
Sets the color ramp for the glow.
Contains information about the context of a rendering operation.
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
QPainter * painter()
int blurLevel() const
Returns the blur level (strength) for the glow.
static void stackBlur(QImage &image, const int radius, const bool alphaOnly=false)
Performs a stack blur on an image.
QgsMapUnitScale mSpreadMapUnitScale
virtual void readProperties(const QgsStringMap &props) override
Reads a string map of an effect's properties and restores the effect to the state described by the pr...
QColor color() const
Returns the color for the glow.
GlowColorType colorType() const
Returns the color mode used for the glow.
virtual QgsStringMap properties() const override
Returns the properties describing the paint effect encoded in a string format.
virtual QgsPaintEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const
virtual ~QgsGlowEffect()
static QColor decodeColor(const QString &str)
iterator insert(const Key &key, const T &value)
const QPicture * source() const
Returns the source QPicture.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
A paint effect which draws a glow within a picture.
virtual QRectF boundingRect(const QRectF &rect, const QgsRenderContext &context) const override
Returns the bounding rect required for drawing the effect.
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsInnerGlowEffect effect from a properties string map.
QPainter::CompositionMode blendMode() const
Returns the blend mode for the effect.
Struct for storing properties of a distance transform operation.
const T value(const Key &key) const