QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 "qgssymbollayerutils.h"
20 #include "qgsimageoperation.h"
21 #include "qgscolorramp.h"
22 #include "qgsunittypes.h"
23 
25  : mColor( Qt::white )
26 {
27 
28 }
29 
31  : QgsPaintEffect( other )
32 {
33  operator=( other );
34 }
35 
37 {
38  delete mRamp;
39 }
40 
42 {
43  if ( !source() || !enabled() || !context.painter() )
44  return;
45 
46  QImage im = sourceAsImage( context )->copy();
47 
48  QgsColorRamp *ramp = nullptr;
49  std::unique_ptr< QgsGradientColorRamp > tempRamp;
50  if ( mColorType == ColorRamp && mRamp )
51  {
52  ramp = mRamp;
53  }
54  else
55  {
56  //create a temporary ramp
57  QColor transparentColor = mColor;
58  transparentColor.setAlpha( 0 );
59  tempRamp.reset( new QgsGradientColorRamp( mColor, transparentColor ) );
60  ramp = tempRamp.get();
61  }
62 
65  dtProps.useMaxDistance = false;
66  dtProps.shadeExterior = shadeExterior();
67  dtProps.ramp = ramp;
69 
70  int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
71  if ( blurLevel <= 16 )
72  {
74  }
75  else
76  {
77  QImage *imb = QgsImageOperation::gaussianBlur( im, blurLevel );
78  im = QImage( *imb );
79  delete imb;
80  }
81 
83 
84  if ( !shadeExterior() )
85  {
86  //only keep interior portion
87  QPainter p( &im );
88  p.setRenderHint( QPainter::Antialiasing );
89  p.setCompositionMode( QPainter::CompositionMode_DestinationIn );
90  p.drawImage( 0, 0, *sourceAsImage( context ) );
91  p.end();
92  }
93 
94  QPainter *painter = context.painter();
95  painter->save();
96  painter->setCompositionMode( mBlendMode );
97  painter->drawImage( imageOffset( context ), im );
98  painter->restore();
99 }
100 
102 {
103  QgsStringMap props;
104  props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
105  props.insert( QStringLiteral( "draw_mode" ), QString::number( int( mDrawMode ) ) );
106  props.insert( QStringLiteral( "blend_mode" ), QString::number( int( mBlendMode ) ) );
107  props.insert( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
108  props.insert( QStringLiteral( "blur_level" ), QString::number( mBlurLevel ) );
109  props.insert( QStringLiteral( "blur_unit" ), QgsUnitTypes::encodeUnit( mBlurUnit ) );
110  props.insert( QStringLiteral( "blur_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mBlurMapUnitScale ) );
111  props.insert( QStringLiteral( "spread" ), QString::number( mSpread ) );
112  props.insert( QStringLiteral( "spread_unit" ), QgsUnitTypes::encodeUnit( mSpreadUnit ) );
113  props.insert( QStringLiteral( "spread_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpreadMapUnitScale ) );
114  props.insert( QStringLiteral( "color_type" ), QString::number( static_cast< int >( mColorType ) ) );
115  props.insert( QStringLiteral( "single_color" ), QgsSymbolLayerUtils::encodeColor( mColor ) );
116 
117  if ( mRamp )
118  {
119  props.unite( mRamp->properties() );
120  }
121 
122  return props;
123 }
124 
126 {
127  bool ok;
128  QPainter::CompositionMode mode = static_cast< QPainter::CompositionMode >( props.value( QStringLiteral( "blend_mode" ) ).toInt( &ok ) );
129  if ( ok )
130  {
131  mBlendMode = mode;
132  }
133  if ( props.contains( QStringLiteral( "transparency" ) ) )
134  {
135  double transparency = props.value( QStringLiteral( "transparency" ) ).toDouble( &ok );
136  if ( ok )
137  {
138  mOpacity = 1.0 - transparency;
139  }
140  }
141  else
142  {
143  double opacity = props.value( QStringLiteral( "opacity" ) ).toDouble( &ok );
144  if ( ok )
145  {
146  mOpacity = opacity;
147  }
148  }
149  mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
150  mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
151  double level = props.value( QStringLiteral( "blur_level" ) ).toDouble( &ok );
152  if ( ok )
153  {
154  mBlurLevel = level;
155  if ( !props.contains( QStringLiteral( "blur_unit" ) ) )
156  {
157  // deal with pre blur unit era by assuming 96 dpi and converting pixel values as millimeters
158  mBlurLevel *= 0.2645;
159  }
160  }
161  mBlurUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "blur_unit" ) ) );
162  mBlurMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "blur_unit_scale" ) ) );
163  double spread = props.value( QStringLiteral( "spread" ) ).toDouble( &ok );
164  if ( ok )
165  {
166  mSpread = spread;
167  }
168  mSpreadUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "spread_unit" ) ) );
169  mSpreadMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "spread_unit_scale" ) ) );
170  QgsGlowEffect::GlowColorType type = static_cast< QgsGlowEffect::GlowColorType >( props.value( QStringLiteral( "color_type" ) ).toInt( &ok ) );
171  if ( ok )
172  {
173  mColorType = type;
174  }
175  if ( props.contains( QStringLiteral( "single_color" ) ) )
176  {
177  mColor = QgsSymbolLayerUtils::decodeColor( props.value( QStringLiteral( "single_color" ) ) );
178  }
179 
180 //attempt to create color ramp from props
181  delete mRamp;
182  if ( props.contains( QStringLiteral( "rampType" ) ) && props[QStringLiteral( "rampType" )] == QStringLiteral( "cpt-city" ) )
183  {
185  }
186  else
187  {
189  }
190 }
191 
193 {
194  delete mRamp;
195  mRamp = ramp;
196 }
197 
199 {
200  if ( &rhs == this )
201  return *this;
202 
203  delete mRamp;
204 
205  mSpread = rhs.spread();
206  mSpreadUnit = rhs.spreadUnit();
208  mRamp = rhs.ramp() ? rhs.ramp()->clone() : nullptr;
209  mBlurLevel = rhs.blurLevel();
210  mBlurUnit = rhs.mBlurUnit;
212  mOpacity = rhs.opacity();
213  mColor = rhs.color();
214  mBlendMode = rhs.blendMode();
215  mColorType = rhs.colorType();
216 
217  return *this;
218 }
219 
220 QRectF QgsGlowEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
221 {
222  //blur radius and spread size
223  int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
225  //plus possible extension due to blur, with a couple of extra pixels thrown in for safety
226  spread += blurLevel * 2 + 10;
227  return rect.adjusted( -spread, -spread, spread, spread );
228 }
229 
230 
231 //
232 // QgsOuterGlowEffect
233 //
234 
236  : QgsGlowEffect()
237 {
238 
239 }
240 
242 {
243  QgsOuterGlowEffect *effect = new QgsOuterGlowEffect();
244  effect->readProperties( map );
245  return effect;
246 }
247 
249 {
250  QgsOuterGlowEffect *newEffect = new QgsOuterGlowEffect( *this );
251  return newEffect;
252 }
253 
254 
255 //
256 // QgsInnerGlowEffect
257 //
258 
260  : QgsGlowEffect()
261 {
262 
263 }
264 
266 {
267  QgsInnerGlowEffect *effect = new QgsInnerGlowEffect();
268  effect->readProperties( map );
269  return effect;
270 }
271 
273 {
274  QgsInnerGlowEffect *newEffect = new QgsInnerGlowEffect( *this );
275  return newEffect;
276 }
QgsColorRamp
Abstract base class for color ramps.
Definition: qgscolorramp.h:31
QgsPaintEffect::DrawMode
DrawMode
Drawing modes for effects.
Definition: qgspainteffect.h:104
QgsGlowEffect::blendMode
QPainter::CompositionMode blendMode() const
Returns the blend mode for the effect.
Definition: qgsgloweffect.h:238
QgsGlowEffect::mSpread
double mSpread
Definition: qgsgloweffect.h:276
QgsGlowEffect::mSpreadUnit
QgsUnitTypes::RenderUnit mSpreadUnit
Definition: qgsgloweffect.h:277
QgsSymbolLayerUtils::encodeColor
static QString encodeColor(const QColor &color)
Definition: qgssymbollayerutils.cpp:52
QgsRenderContext::convertToPainterUnits
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
Definition: qgsrendercontext.cpp:287
QgsImageOperation::DistanceTransformProperties::ramp
QgsColorRamp * ramp
Color ramp to use for shading the distance transform.
Definition: qgsimageoperation.h:141
QgsGradientColorRamp
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Definition: qgscolorramp.h:139
QgsCptCityColorRamp::create
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Definition: qgscolorramp.cpp:618
QgsGlowEffect::mBlurMapUnitScale
QgsMapUnitScale mBlurMapUnitScale
Definition: qgsgloweffect.h:282
QgsSymbolLayerUtils::encodeMapUnitScale
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Definition: qgssymbollayerutils.cpp:558
QgsGlowEffect::operator=
QgsGlowEffect & operator=(const QgsGlowEffect &rhs)
Definition: qgsgloweffect.cpp:198
QgsGlowEffect::color
QColor color() const
Returns the color for the glow.
Definition: qgsgloweffect.h:204
QgsGlowEffect::mBlurUnit
QgsUnitTypes::RenderUnit mBlurUnit
Definition: qgsgloweffect.h:281
QgsGlowEffect::setRamp
void setRamp(QgsColorRamp *ramp)
Sets the color ramp for the glow.
Definition: qgsgloweffect.cpp:192
qgssymbollayerutils.h
QgsImageOperation::multiplyOpacity
static void multiplyOpacity(QImage &image, double factor)
Multiplies opacity of image pixel values by a factor.
Definition: qgsimageoperation.cpp:322
QgsRenderContext
Definition: qgsrendercontext.h:57
QgsImageOperation::DistanceTransformProperties::useMaxDistance
bool useMaxDistance
Set to true to automatically calculate the maximum distance in the transform to use as the spread val...
Definition: qgsimageoperation.h:130
qgsunittypes.h
QgsGlowEffect::QgsGlowEffect
QgsGlowEffect()
Definition: qgsgloweffect.cpp:24
qgsimageoperation.h
QgsColorRamp::properties
virtual QgsStringMap properties() const =0
Returns a string map containing all the color ramp's properties.
QgsSymbolLayerUtils::decodeColor
static QColor decodeColor(const QString &str)
Definition: qgssymbollayerutils.cpp:57
QgsGlowEffect::mColorType
GlowColorType mColorType
Definition: qgsgloweffect.h:286
QgsPaintEffect::mEnabled
bool mEnabled
Definition: qgspainteffect.h:225
QgsGlowEffect::shadeExterior
virtual bool shadeExterior() const =0
Specifies whether the glow is drawn outside the picture or within the picture.
QgsUnitTypes::decodeRenderUnit
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
Definition: qgsunittypes.cpp:2900
QgsInnerGlowEffect::create
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsInnerGlowEffect effect from a properties string map.
Definition: qgsgloweffect.cpp:265
QgsUnitTypes::encodeUnit
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
Definition: qgsunittypes.cpp:122
QgsGlowEffect
Base class for paint effect which draw a glow inside or outside a picture.
Definition: qgsgloweffect.h:38
QgsGlowEffect::spreadMapUnitScale
const QgsMapUnitScale & spreadMapUnitScale() const
Returns the map unit scale used for the spread distance.
Definition: qgsgloweffect.h:109
QgsGlowEffect::boundingRect
QRectF boundingRect(const QRectF &rect, const QgsRenderContext &context) const override
Returns the bounding rect required for drawing the effect.
Definition: qgsgloweffect.cpp:220
QgsGlowEffect::ColorRamp
@ ColorRamp
Use colors from a color ramp.
Definition: qgsgloweffect.h:47
qgscolorramp.h
QgsOuterGlowEffect::QgsOuterGlowEffect
QgsOuterGlowEffect()
Definition: qgsgloweffect.cpp:235
qgsgloweffect.h
QgsGlowEffect::blurLevel
double blurLevel() const
Returns the blur level (radius) for the glow.
Definition: qgsgloweffect.h:128
QgsGlowEffect::mRamp
QgsColorRamp * mRamp
Definition: qgsgloweffect.h:279
QgsPaintEffect::imageOffset
QPointF imageOffset(const QgsRenderContext &context) const
Returns the offset which should be used when drawing the source image on to a destination render cont...
Definition: qgspainteffect.cpp:198
QgsGlowEffect::ramp
QgsColorRamp * ramp() const
Returns the color ramp used for the glow.
Definition: qgsgloweffect.h:222
QgsInnerGlowEffect::QgsInnerGlowEffect
QgsInnerGlowEffect()
Definition: qgsgloweffect.cpp:259
QgsInnerGlowEffect
A paint effect which draws a glow within a picture.
Definition: qgsgloweffect.h:331
QgsOuterGlowEffect::create
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsOuterGlowEffect effect from a properties string map.
Definition: qgsgloweffect.cpp:241
QgsColorRamp::clone
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
QgsImageOperation::DistanceTransformProperties::shadeExterior
bool shadeExterior
Set to true to perform the distance transform on transparent pixels in the source image,...
Definition: qgsimageoperation.h:124
QgsPaintEffect::mDrawMode
DrawMode mDrawMode
Definition: qgspainteffect.h:226
QgsGlowEffect::mBlendMode
QPainter::CompositionMode mBlendMode
Definition: qgsgloweffect.h:285
QgsGlowEffect::mColor
QColor mColor
Definition: qgsgloweffect.h:284
QgsImageOperation::distanceTransform
static void distanceTransform(QImage &image, const QgsImageOperation::DistanceTransformProperties &properties)
Performs a distance transform on the source image and shades the result using a color ramp.
Definition: qgsimageoperation.cpp:371
QgsStringMap
QMap< QString, QString > QgsStringMap
Definition: qgis.h:714
QgsImageOperation::gaussianBlur
static QImage * gaussianBlur(QImage &image, int radius)
Performs a gaussian blur on an image.
Definition: qgsimageoperation.cpp:603
QgsGlowEffect::~QgsGlowEffect
~QgsGlowEffect() override
Definition: qgsgloweffect.cpp:36
QgsPaintEffect::sourceAsImage
QImage * sourceAsImage(QgsRenderContext &context)
Returns the source QPicture rendered to a new QImage.
Definition: qgspainteffect.cpp:173
QgsGlowEffect::colorType
GlowColorType colorType() const
Returns the color mode used for the glow.
Definition: qgsgloweffect.h:259
QgsPaintEffect::source
const QPicture * source() const
Returns the source QPicture.
Definition: qgspainteffect.h:254
QgsImageOperation::DistanceTransformProperties::spread
double spread
Maximum distance (in pixels) for the distance transform shading to spread.
Definition: qgsimageoperation.h:136
QgsPaintEffect
Base class for visual effects which can be applied to QPicture drawings.
Definition: qgspainteffect.h:53
QgsOuterGlowEffect
A paint effect which draws a glow outside of a picture.
Definition: qgsgloweffect.h:299
QgsImageOperation::DistanceTransformProperties
Struct for storing properties of a distance transform operation.
Definition: qgsimageoperation.h:116
QgsGlowEffect::opacity
double opacity() const
Returns the opacity for the effect.
Definition: qgsgloweffect.h:184
QgsGlowEffect::readProperties
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...
Definition: qgsgloweffect.cpp:125
QgsGradientColorRamp::create
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
Definition: qgscolorramp.cpp:53
QgsGlowEffect::mSpreadMapUnitScale
QgsMapUnitScale mSpreadMapUnitScale
Definition: qgsgloweffect.h:278
QgsImageOperation::stackBlur
static void stackBlur(QImage &image, int radius, bool alphaOnly=false)
Performs a stack blur on an image.
Definition: qgsimageoperation.cpp:558
QgsGlowEffect::properties
QgsStringMap properties() const override
Returns the properties describing the paint effect encoded in a string format.
Definition: qgsgloweffect.cpp:101
QgsOuterGlowEffect::clone
QgsOuterGlowEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
Definition: qgsgloweffect.cpp:248
QgsGlowEffect::GlowColorType
GlowColorType
Color sources for the glow.
Definition: qgsgloweffect.h:44
QgsGlowEffect::mOpacity
double mOpacity
Definition: qgsgloweffect.h:283
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:174
QgsPaintEffect::enabled
bool enabled() const
Returns whether the effect is enabled.
Definition: qgspainteffect.h:198
QgsPaintEffect::type
virtual QString type() const =0
Returns the effect type.
QgsSymbolLayerUtils::decodeMapUnitScale
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Definition: qgssymbollayerutils.cpp:568
QgsInnerGlowEffect::clone
QgsInnerGlowEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
Definition: qgsgloweffect.cpp:272
QgsGlowEffect::spread
double spread() const
Returns the spread distance used for drawing the glow effect.
Definition: qgsgloweffect.h:73
QgsGlowEffect::spreadUnit
QgsUnitTypes::RenderUnit spreadUnit() const
Returns the units used for the glow spread distance.
Definition: qgsgloweffect.h:91
QgsGlowEffect::mBlurLevel
double mBlurLevel
Definition: qgsgloweffect.h:280
QgsGlowEffect::draw
void draw(QgsRenderContext &context) override
Handles drawing of the effect's result on to the specified render context.
Definition: qgsgloweffect.cpp:41