QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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  QgsScopedQPainterState painterState( painter );
96  painter->setCompositionMode( mBlendMode );
97  painter->drawImage( imageOffset( context ), im );
98 }
99 
101 {
102  QgsStringMap props;
103  props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
104  props.insert( QStringLiteral( "draw_mode" ), QString::number( int( mDrawMode ) ) );
105  props.insert( QStringLiteral( "blend_mode" ), QString::number( int( mBlendMode ) ) );
106  props.insert( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
107  props.insert( QStringLiteral( "blur_level" ), QString::number( mBlurLevel ) );
108  props.insert( QStringLiteral( "blur_unit" ), QgsUnitTypes::encodeUnit( mBlurUnit ) );
109  props.insert( QStringLiteral( "blur_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mBlurMapUnitScale ) );
110  props.insert( QStringLiteral( "spread" ), QString::number( mSpread ) );
111  props.insert( QStringLiteral( "spread_unit" ), QgsUnitTypes::encodeUnit( mSpreadUnit ) );
112  props.insert( QStringLiteral( "spread_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpreadMapUnitScale ) );
113  props.insert( QStringLiteral( "color_type" ), QString::number( static_cast< int >( mColorType ) ) );
114  props.insert( QStringLiteral( "single_color" ), QgsSymbolLayerUtils::encodeColor( mColor ) );
115 
116  if ( mRamp )
117  {
118 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
119  props.unite( mRamp->properties() );
120 #else
121  props.insert( mRamp->properties() );
122 #endif
123  }
124 
125  return props;
126 }
127 
129 {
130  bool ok;
131  QPainter::CompositionMode mode = static_cast< QPainter::CompositionMode >( props.value( QStringLiteral( "blend_mode" ) ).toInt( &ok ) );
132  if ( ok )
133  {
134  mBlendMode = mode;
135  }
136  if ( props.contains( QStringLiteral( "transparency" ) ) )
137  {
138  double transparency = props.value( QStringLiteral( "transparency" ) ).toDouble( &ok );
139  if ( ok )
140  {
141  mOpacity = 1.0 - transparency;
142  }
143  }
144  else
145  {
146  double opacity = props.value( QStringLiteral( "opacity" ) ).toDouble( &ok );
147  if ( ok )
148  {
149  mOpacity = opacity;
150  }
151  }
152  mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
153  mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
154  double level = props.value( QStringLiteral( "blur_level" ) ).toDouble( &ok );
155  if ( ok )
156  {
157  mBlurLevel = level;
158  if ( !props.contains( QStringLiteral( "blur_unit" ) ) )
159  {
160  // deal with pre blur unit era by assuming 96 dpi and converting pixel values as millimeters
161  mBlurLevel *= 0.2645;
162  }
163  }
164  mBlurUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "blur_unit" ) ) );
165  mBlurMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "blur_unit_scale" ) ) );
166  double spread = props.value( QStringLiteral( "spread" ) ).toDouble( &ok );
167  if ( ok )
168  {
169  mSpread = spread;
170  }
171  mSpreadUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "spread_unit" ) ) );
172  mSpreadMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "spread_unit_scale" ) ) );
173  QgsGlowEffect::GlowColorType type = static_cast< QgsGlowEffect::GlowColorType >( props.value( QStringLiteral( "color_type" ) ).toInt( &ok ) );
174  if ( ok )
175  {
176  mColorType = type;
177  }
178  if ( props.contains( QStringLiteral( "single_color" ) ) )
179  {
180  mColor = QgsSymbolLayerUtils::decodeColor( props.value( QStringLiteral( "single_color" ) ) );
181  }
182 
183  //attempt to create color ramp from props
184  delete mRamp;
185  if ( props.contains( QStringLiteral( "rampType" ) ) && props[QStringLiteral( "rampType" )] == QgsCptCityColorRamp::typeString() )
186  {
188  }
189  else
190  {
192  }
193 }
194 
196 {
197  delete mRamp;
198  mRamp = ramp;
199 }
200 
202 {
203  if ( &rhs == this )
204  return *this;
205 
206  delete mRamp;
207 
208  mSpread = rhs.spread();
209  mSpreadUnit = rhs.spreadUnit();
211  mRamp = rhs.ramp() ? rhs.ramp()->clone() : nullptr;
212  mBlurLevel = rhs.blurLevel();
213  mBlurUnit = rhs.mBlurUnit;
215  mOpacity = rhs.opacity();
216  mColor = rhs.color();
217  mBlendMode = rhs.blendMode();
218  mColorType = rhs.colorType();
219 
220  return *this;
221 }
222 
223 QRectF QgsGlowEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
224 {
225  //blur radius and spread size
226  int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
228  //plus possible extension due to blur, with a couple of extra pixels thrown in for safety
229  spread += blurLevel * 2 + 10;
230  return rect.adjusted( -spread, -spread, spread, spread );
231 }
232 
233 
234 //
235 // QgsOuterGlowEffect
236 //
237 
239  : QgsGlowEffect()
240 {
241 
242 }
243 
245 {
246  QgsOuterGlowEffect *effect = new QgsOuterGlowEffect();
247  effect->readProperties( map );
248  return effect;
249 }
250 
252 {
253  QgsOuterGlowEffect *newEffect = new QgsOuterGlowEffect( *this );
254  return newEffect;
255 }
256 
257 
258 //
259 // QgsInnerGlowEffect
260 //
261 
263  : QgsGlowEffect()
264 {
265 
266 }
267 
269 {
270  QgsInnerGlowEffect *effect = new QgsInnerGlowEffect();
271  effect->readProperties( map );
272  return effect;
273 }
274 
276 {
277  QgsInnerGlowEffect *newEffect = new QgsInnerGlowEffect( *this );
278  return newEffect;
279 }
QgsColorRamp
Abstract base class for color ramps.
Definition: qgscolorramp.h:32
QgsPaintEffect::DrawMode
DrawMode
Drawing modes for effects.
Definition: qgspainteffect.h:105
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:318
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:151
QgsCptCityColorRamp::create
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Definition: qgscolorramp.cpp:628
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:201
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:195
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
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
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
QgsCptCityColorRamp::typeString
static QString typeString()
Returns the string identifier for QgsCptCityColorRamp.
Definition: qgscolorramp.h:711
QgsInnerGlowEffect::create
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsInnerGlowEffect effect from a properties string map.
Definition: qgsgloweffect.cpp:268
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:39
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:223
QgsGlowEffect::ColorRamp
@ ColorRamp
Use colors from a color ramp.
Definition: qgsgloweffect.h:47
qgscolorramp.h
QgsOuterGlowEffect::QgsOuterGlowEffect
QgsOuterGlowEffect()
Definition: qgsgloweffect.cpp:238
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
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1120
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:197
QgsGlowEffect::ramp
QgsColorRamp * ramp() const
Returns the color ramp used for the glow.
Definition: qgsgloweffect.h:222
QgsInnerGlowEffect::QgsInnerGlowEffect
QgsInnerGlowEffect()
Definition: qgsgloweffect.cpp:262
QgsInnerGlowEffect
A paint effect which draws a glow within a picture.
Definition: qgsgloweffect.h:332
QgsOuterGlowEffect::create
static QgsPaintEffect * create(const QgsStringMap &map)
Creates a new QgsOuterGlowEffect effect from a properties string map.
Definition: qgsgloweffect.cpp:244
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:758
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:172
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:54
QgsOuterGlowEffect
A paint effect which draws a glow outside of a picture.
Definition: qgsgloweffect.h:300
QgsImageOperation::DistanceTransformProperties
Struct for storing properties of a distance transform operation.
Definition: qgsimageoperation.h:117
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:128
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:100
QgsOuterGlowEffect::clone
QgsOuterGlowEffect * clone() const override
Duplicates an effect by creating a deep copy of the effect.
Definition: qgsgloweffect.cpp:251
QgsGlowEffect::GlowColorType
GlowColorType
Color sources for the glow.
Definition: qgsgloweffect.h:45
QgsGlowEffect::mOpacity
double mOpacity
Definition: qgsgloweffect.h:283
QgsRenderContext::painter
QPainter * painter()
Returns the destination QPainter for the render operation.
Definition: qgsrendercontext.h:179
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:275
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