Skip to content

Commit 9809c1e

Browse files
nirvnnyalldawson
authored andcommittedMay 23, 2019
[effects] Fix blur radius not taking dpi into account (fixes #14885)
1 parent c1b9768 commit 9809c1e

File tree

21 files changed

+603
-92
lines changed

21 files changed

+603
-92
lines changed
 

‎python/core/auto_generated/effects/qgsblureffect.sip.in

Lines changed: 73 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,96 @@ Constructor for QgsBlurEffect.
5151
virtual QgsBlurEffect *clone() const /Factory/;
5252

5353

54-
void setBlurLevel( const int level );
54+
void setBlurLevel( const double level );
5555
%Docstring
56-
Sets blur level (strength)
56+
Sets blur level (radius)
5757

5858
:param level: blur level. Depending on the current blurMethod(), this parameter
5959
has different effects
6060

6161
.. seealso:: :py:func:`blurLevel`
6262

63-
.. seealso:: :py:func:`blurMethod`
63+
.. seealso:: :py:func:`setBlurUnit`
64+
65+
.. seealso:: :py:func:`setBlurMapUnitScale`
66+
67+
.. seealso:: :py:func:`setBlurMethod`
6468
%End
6569

66-
int blurLevel() const;
70+
double blurLevel() const;
6771
%Docstring
68-
Returns the blur level (strength)
72+
Returns the blur level (radius)
6973

7074
:return: blur level. Depending on the current blurMethod(), this parameter
7175
has different effects
7276

7377
.. seealso:: :py:func:`setBlurLevel`
7478

79+
.. seealso:: :py:func:`blurUnit`
80+
81+
.. seealso:: :py:func:`blurMapUnitScale`
82+
7583
.. seealso:: :py:func:`blurMethod`
84+
%End
85+
86+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit );
87+
%Docstring
88+
Sets the units used for the blur level (radius).
89+
90+
:param unit: units for blur level
91+
92+
.. seealso:: :py:func:`blurUnit`
93+
94+
.. seealso:: :py:func:`setBlurLevel`
95+
96+
.. seealso:: :py:func:`setBlurMapUnitScale`
97+
98+
.. versionadded:: 3.4.9
99+
%End
100+
101+
QgsUnitTypes::RenderUnit blurUnit() const;
102+
%Docstring
103+
Returns the units used for the blur level (radius).
104+
105+
:return: units for blur level
106+
107+
.. seealso:: :py:func:`setBlurUnit`
108+
109+
.. seealso:: :py:func:`blurLevel`
110+
111+
.. seealso:: :py:func:`blurMapUnitScale`
112+
113+
.. versionadded:: 3.4.9
114+
%End
115+
116+
void setBlurMapUnitScale( const QgsMapUnitScale &scale );
117+
%Docstring
118+
Sets the map unit scale used for the blur strength (radius).
119+
120+
:param scale: map unit scale for blur strength
121+
122+
.. seealso:: :py:func:`blurMapUnitScale`
123+
124+
.. seealso:: :py:func:`setBlurLevel`
125+
126+
.. seealso:: :py:func:`setBlurUnit`
127+
128+
.. versionadded:: 3.4.9
129+
%End
130+
131+
const QgsMapUnitScale &blurMapUnitScale() const;
132+
%Docstring
133+
Returns the map unit scale used for the blur strength (radius).
134+
135+
:return: map unit scale for blur strength
136+
137+
.. seealso:: :py:func:`setBlurMapUnitScale`
138+
139+
.. seealso:: :py:func:`blurLevel`
140+
141+
.. seealso:: :py:func:`blurUnit`
142+
143+
.. versionadded:: 3.4.9
76144
%End
77145

78146
void setBlurMethod( const BlurMethod method );

‎python/core/auto_generated/effects/qgsgloweffect.sip.in

Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,91 @@ Returns the map unit scale used for the spread distance.
118118
.. seealso:: :py:func:`spreadUnit`
119119
%End
120120

121-
void setBlurLevel( const int level );
121+
void setBlurLevel( const double level );
122122
%Docstring
123-
Sets blur level (strength) for the glow. This can be used to smooth the
123+
Sets blur level (radius) for the glow. This can be used to smooth the
124124
output from the glow effect.
125125

126-
:param level: blur level. Values between 0 and 16 are valid, with larger
127-
values indicating greater blur strength.
126+
:param level: blur level.
128127

129128
.. seealso:: :py:func:`blurLevel`
129+
130+
.. seealso:: :py:func:`setBlurUnit`
131+
132+
.. seealso:: :py:func:`setBlurMapUnitScale`
133+
%End
134+
135+
double blurLevel() const;
136+
%Docstring
137+
Returns the blur level (radius) for the glow.
138+
139+
:return: blur level.
140+
141+
.. seealso:: :py:func:`setBlurLevel`
142+
143+
.. seealso:: :py:func:`blurUnit`
144+
145+
.. seealso:: :py:func:`blurMapUnitScale`
146+
%End
147+
148+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit );
149+
%Docstring
150+
Sets the units used for the glow blur level (radius).
151+
152+
:param unit: units for blur level
153+
154+
.. seealso:: :py:func:`blurUnit`
155+
156+
.. seealso:: :py:func:`setBlurLevel`
157+
158+
.. seealso:: :py:func:`setBlurMapUnitScale`
159+
160+
.. versionadded:: 3.4.9
161+
%End
162+
163+
QgsUnitTypes::RenderUnit blurUnit() const;
164+
%Docstring
165+
Returns the units used for the glow blur level (radius).
166+
167+
:return: units for blur level
168+
169+
.. seealso:: :py:func:`setBlurUnit`
170+
171+
.. seealso:: :py:func:`blurLevel`
172+
173+
.. seealso:: :py:func:`blurMapUnitScale`
174+
175+
.. versionadded:: 3.4.9
130176
%End
131177

132-
int blurLevel() const;
178+
void setBlurMapUnitScale( const QgsMapUnitScale &scale );
133179
%Docstring
134-
Returns the blur level (strength) for the glow.
180+
Sets the map unit scale used for the glow blur strength (radius).
135181

136-
:return: blur level. Value will be between 0 and 16, with larger
137-
values indicating greater blur strength.
182+
:param scale: map unit scale for blur strength
183+
184+
.. seealso:: :py:func:`blurMapUnitScale`
138185

139186
.. seealso:: :py:func:`setBlurLevel`
187+
188+
.. seealso:: :py:func:`setBlurUnit`
189+
190+
.. versionadded:: 3.4.9
191+
%End
192+
193+
const QgsMapUnitScale &blurMapUnitScale() const;
194+
%Docstring
195+
Returns the map unit scale used for the glow blur strength (radius).
196+
197+
:return: map unit scale for blur strength
198+
199+
.. seealso:: :py:func:`setBlurMapUnitScale`
200+
201+
.. seealso:: :py:func:`blurLevel`
202+
203+
.. seealso:: :py:func:`blurUnit`
204+
205+
.. versionadded:: 3.4.9
140206
%End
141207

142208
void setOpacity( const double opacity );

‎python/core/auto_generated/effects/qgsshadoweffect.sip.in

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,92 @@ Base class for paint effects which offset, blurred shadows
2929
virtual void readProperties( const QgsStringMap &props );
3030

3131

32-
void setBlurLevel( const int level );
32+
void setBlurLevel( const double level );
3333
%Docstring
34-
Sets blur level (strength) for the shadow.
34+
Sets blur level (radius) for the shadow.
3535

36-
:param level: blur level. Values between 0 and 16 are valid, with larger
36+
:param level: blur level.
3737
values indicating greater blur strength.
3838

3939
.. seealso:: :py:func:`blurLevel`
40+
41+
.. seealso:: :py:func:`setBlurUnit`
42+
43+
.. seealso:: :py:func:`setBlurMapUnitScale`
4044
%End
4145

42-
int blurLevel() const;
46+
double blurLevel() const;
4347
%Docstring
44-
Returns the blur level (strength) for the shadow.
48+
Returns the blur level (radius) for the shadow.
4549

46-
:return: blur level. Value will be between 0 and 16, with larger
50+
:return: blur level.
4751
values indicating greater blur strength.
4852

4953
.. seealso:: :py:func:`setBlurLevel`
54+
55+
.. seealso:: :py:func:`blurUnit`
56+
57+
.. seealso:: :py:func:`blurMapUnitScale`
58+
%End
59+
60+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit );
61+
%Docstring
62+
Sets the units used for the shadow blur level (radius).
63+
64+
:param unit: units for blur level
65+
66+
.. seealso:: :py:func:`blurUnit`
67+
68+
.. seealso:: :py:func:`setBlurLevel`
69+
70+
.. seealso:: :py:func:`setBlurMapUnitScale`
71+
72+
.. versionadded:: 3.4.9
73+
%End
74+
75+
QgsUnitTypes::RenderUnit blurUnit() const;
76+
%Docstring
77+
Returns the units used for the shadow blur level (radius).
78+
79+
:return: units for blur level
80+
81+
.. seealso:: :py:func:`setBlurUnit`
82+
83+
.. seealso:: :py:func:`blurLevel`
84+
85+
.. seealso:: :py:func:`blurMapUnitScale`
86+
87+
.. versionadded:: 3.4.9
88+
%End
89+
90+
void setBlurMapUnitScale( const QgsMapUnitScale &scale );
91+
%Docstring
92+
Sets the map unit scale used for the shadow blur strength (radius).
93+
94+
:param scale: map unit scale for blur strength
95+
96+
.. seealso:: :py:func:`blurMapUnitScale`
97+
98+
.. seealso:: :py:func:`setBlurLevel`
99+
100+
.. seealso:: :py:func:`setBlurUnit`
101+
102+
.. versionadded:: 3.4.9
103+
%End
104+
105+
const QgsMapUnitScale &blurMapUnitScale() const;
106+
%Docstring
107+
Returns the map unit scale used for the shadow blur strength (radius).
108+
109+
:return: map unit scale for blur strength
110+
111+
.. seealso:: :py:func:`setBlurMapUnitScale`
112+
113+
.. seealso:: :py:func:`blurLevel`
114+
115+
.. seealso:: :py:func:`blurUnit`
116+
117+
.. versionadded:: 3.4.9
50118
%End
51119

52120
void setOffsetAngle( const int angle );

‎src/core/effects/qgsblureffect.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "qgsblureffect.h"
1919
#include "qgsimageoperation.h"
2020
#include "qgsrendercontext.h"
21+
#include "qgssymbollayerutils.h"
2122

2223
QgsPaintEffect *QgsBlurEffect::create( const QgsStringMap &map )
2324
{
@@ -44,14 +45,16 @@ void QgsBlurEffect::draw( QgsRenderContext &context )
4445

4546
void QgsBlurEffect::drawStackBlur( QgsRenderContext &context )
4647
{
48+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
4749
QImage im = sourceAsImage( context )->copy();
48-
QgsImageOperation::stackBlur( im, mBlurLevel );
50+
QgsImageOperation::stackBlur( im, blurLevel );
4951
drawBlurredImage( context, im );
5052
}
5153

5254
void QgsBlurEffect::drawGaussianBlur( QgsRenderContext &context )
5355
{
54-
QImage *im = QgsImageOperation::gaussianBlur( *sourceAsImage( context ), mBlurLevel );
56+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
57+
QImage *im = QgsImageOperation::gaussianBlur( *sourceAsImage( context ), blurLevel );
5558
drawBlurredImage( context, *im );
5659
delete im;
5760
}
@@ -76,6 +79,8 @@ QgsStringMap QgsBlurEffect::properties() const
7679
props.insert( QStringLiteral( "blend_mode" ), QString::number( static_cast< int >( mBlendMode ) ) );
7780
props.insert( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
7881
props.insert( QStringLiteral( "blur_level" ), QString::number( mBlurLevel ) );
82+
props.insert( QStringLiteral( "blur_unit" ), QgsUnitTypes::encodeUnit( mBlurUnit ) );
83+
props.insert( QStringLiteral( "blur_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mBlurMapUnitScale ) );
7984
props.insert( QStringLiteral( "blur_method" ), QString::number( static_cast< int >( mBlurMethod ) ) );
8085
return props;
8186
}
@@ -107,11 +112,18 @@ void QgsBlurEffect::readProperties( const QgsStringMap &props )
107112

108113
mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
109114
mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
110-
int level = props.value( QStringLiteral( "blur_level" ) ).toInt( &ok );
115+
double level = props.value( QStringLiteral( "blur_level" ) ).toDouble( &ok );
111116
if ( ok )
112117
{
113118
mBlurLevel = level;
119+
if ( !props.contains( QStringLiteral( "blur_unit" ) ) )
120+
{
121+
// deal with pre blur unit era by assuming 96 dpi and converting pixel values as millimeters
122+
mBlurLevel *= 0.2645;
123+
}
114124
}
125+
mBlurUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "blur_unit" ) ) );
126+
mBlurMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "blur_unit_scale" ) ) );
115127
QgsBlurEffect::BlurMethod method = static_cast< QgsBlurEffect::BlurMethod >( props.value( QStringLiteral( "blur_method" ) ).toInt( &ok ) );
116128
if ( ok )
117129
{
@@ -127,9 +139,8 @@ QgsBlurEffect *QgsBlurEffect::clone() const
127139

128140
QRectF QgsBlurEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
129141
{
130-
Q_UNUSED( context );
131-
142+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
132143
//plus possible extension due to blur, with a couple of extra pixels thrown in for safety
133-
double spread = mBlurLevel * 2.0 + 10;
144+
double spread = blurLevel * 2.0 + 10;
134145
return rect.adjusted( -spread, -spread, spread, spread );
135146
}

‎src/core/effects/qgsblureffect.h

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,22 +61,66 @@ class CORE_EXPORT QgsBlurEffect : public QgsPaintEffect
6161
QgsBlurEffect *clone() const override SIP_FACTORY;
6262

6363
/**
64-
* Sets blur level (strength)
64+
* Sets blur level (radius)
6565
* \param level blur level. Depending on the current blurMethod(), this parameter
6666
* has different effects
6767
* \see blurLevel
68-
* \see blurMethod
68+
* \see setBlurUnit
69+
* \see setBlurMapUnitScale
70+
* \see setBlurMethod
6971
*/
70-
void setBlurLevel( const int level ) { mBlurLevel = level; }
72+
void setBlurLevel( const double level ) { mBlurLevel = level; }
7173

7274
/**
73-
* Returns the blur level (strength)
75+
* Returns the blur level (radius)
7476
* \returns blur level. Depending on the current blurMethod(), this parameter
7577
* has different effects
7678
* \see setBlurLevel
79+
* \see blurUnit
80+
* \see blurMapUnitScale
7781
* \see blurMethod
7882
*/
79-
int blurLevel() const { return mBlurLevel; }
83+
double blurLevel() const { return mBlurLevel; }
84+
85+
/**
86+
* Sets the units used for the blur level (radius).
87+
* \param unit units for blur level
88+
* \see blurUnit
89+
* \see setBlurLevel
90+
* \see setBlurMapUnitScale
91+
* \since QGIS 3.4.9
92+
*/
93+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit ) { mBlurUnit = unit; }
94+
95+
/**
96+
* Returns the units used for the blur level (radius).
97+
* \returns units for blur level
98+
* \see setBlurUnit
99+
* \see blurLevel
100+
* \see blurMapUnitScale
101+
* \since QGIS 3.4.9
102+
*/
103+
QgsUnitTypes::RenderUnit blurUnit() const { return mBlurUnit; }
104+
105+
/**
106+
* Sets the map unit scale used for the blur strength (radius).
107+
* \param scale map unit scale for blur strength
108+
* \see blurMapUnitScale
109+
* \see setBlurLevel
110+
* \see setBlurUnit
111+
* \since QGIS 3.4.9
112+
*/
113+
void setBlurMapUnitScale( const QgsMapUnitScale &scale ) { mBlurMapUnitScale = scale; }
114+
115+
/**
116+
* Returns the map unit scale used for the blur strength (radius).
117+
* \returns map unit scale for blur strength
118+
* \see setBlurMapUnitScale
119+
* \see blurLevel
120+
* \see blurUnit
121+
* \since QGIS 3.4.9
122+
*/
123+
const QgsMapUnitScale &blurMapUnitScale() const { return mBlurMapUnitScale; }
80124

81125
/**
82126
* Sets the blur method (algorithm) to use for performing the blur.
@@ -131,7 +175,9 @@ class CORE_EXPORT QgsBlurEffect : public QgsPaintEffect
131175

132176
private:
133177

134-
int mBlurLevel = 10;
178+
double mBlurLevel = 2.645;
179+
QgsUnitTypes::RenderUnit mBlurUnit = QgsUnitTypes::RenderMillimeters;
180+
QgsMapUnitScale mBlurMapUnitScale;
135181
BlurMethod mBlurMethod = StackBlur;
136182
double mOpacity = 1.0;
137183
QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;

‎src/core/effects/qgsgloweffect.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,16 @@ void QgsGlowEffect::draw( QgsRenderContext &context )
7878
dtProps.ramp = ramp;
7979
QgsImageOperation::distanceTransform( im, dtProps );
8080

81-
if ( mBlurLevel > 0 )
81+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
82+
if ( blurLevel <= 16 )
8283
{
83-
QgsImageOperation::stackBlur( im, mBlurLevel );
84+
QgsImageOperation::stackBlur( im, blurLevel );
85+
}
86+
else
87+
{
88+
QImage *imb = QgsImageOperation::gaussianBlur( im, blurLevel );
89+
im = QImage( *imb );
90+
delete imb;
8491
}
8592

8693
QgsImageOperation::multiplyOpacity( im, mOpacity );
@@ -110,6 +117,8 @@ QgsStringMap QgsGlowEffect::properties() const
110117
props.insert( QStringLiteral( "blend_mode" ), QString::number( int( mBlendMode ) ) );
111118
props.insert( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
112119
props.insert( QStringLiteral( "blur_level" ), QString::number( mBlurLevel ) );
120+
props.insert( QStringLiteral( "blur_unit" ), QgsUnitTypes::encodeUnit( mBlurUnit ) );
121+
props.insert( QStringLiteral( "blur_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mBlurMapUnitScale ) );
113122
props.insert( QStringLiteral( "spread" ), QString::number( mSpread ) );
114123
props.insert( QStringLiteral( "spread_unit" ), QgsUnitTypes::encodeUnit( mSpreadUnit ) );
115124
props.insert( QStringLiteral( "spread_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mSpreadMapUnitScale ) );
@@ -150,11 +159,18 @@ void QgsGlowEffect::readProperties( const QgsStringMap &props )
150159
}
151160
mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
152161
mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
153-
int level = props.value( QStringLiteral( "blur_level" ) ).toInt( &ok );
162+
double level = props.value( QStringLiteral( "blur_level" ) ).toDouble( &ok );
154163
if ( ok )
155164
{
156165
mBlurLevel = level;
166+
if ( !props.contains( QStringLiteral( "blur_unit" ) ) )
167+
{
168+
// deal with pre blur unit era by assuming 96 dpi and converting pixel values as millimeters
169+
mBlurLevel *= 0.2645;
170+
}
157171
}
172+
mBlurUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "blur_unit" ) ) );
173+
mBlurMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "blur_unit_scale" ) ) );
158174
double spread = props.value( QStringLiteral( "spread" ) ).toDouble( &ok );
159175
if ( ok )
160176
{
@@ -210,10 +226,11 @@ QgsGlowEffect &QgsGlowEffect::operator=( const QgsGlowEffect &rhs )
210226

211227
QRectF QgsGlowEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
212228
{
213-
//spread size
229+
//blur radius and spread size
230+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
214231
double spread = context.convertToPainterUnits( mSpread, mSpreadUnit, mSpreadMapUnitScale );
215232
//plus possible extension due to blur, with a couple of extra pixels thrown in for safety
216-
spread += mBlurLevel * 2 + 10;
233+
spread += blurLevel * 2 + 10;
217234
return rect.adjusted( -spread, -spread, spread, spread );
218235
}
219236

‎src/core/effects/qgsgloweffect.h

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,63 @@ class CORE_EXPORT QgsGlowEffect : public QgsPaintEffect
109109
const QgsMapUnitScale &spreadMapUnitScale() const { return mSpreadMapUnitScale; }
110110

111111
/**
112-
* Sets blur level (strength) for the glow. This can be used to smooth the
112+
* Sets blur level (radius) for the glow. This can be used to smooth the
113113
* output from the glow effect.
114-
* \param level blur level. Values between 0 and 16 are valid, with larger
115-
* values indicating greater blur strength.
114+
* \param level blur level.
116115
* \see blurLevel
116+
* \see setBlurUnit
117+
* \see setBlurMapUnitScale
117118
*/
118-
void setBlurLevel( const int level ) { mBlurLevel = level; }
119+
void setBlurLevel( const double level ) { mBlurLevel = level; }
119120

120121
/**
121-
* Returns the blur level (strength) for the glow.
122-
* \returns blur level. Value will be between 0 and 16, with larger
123-
* values indicating greater blur strength.
122+
* Returns the blur level (radius) for the glow.
123+
* \returns blur level.
124124
* \see setBlurLevel
125+
* \see blurUnit
126+
* \see blurMapUnitScale
125127
*/
126-
int blurLevel() const { return mBlurLevel; }
128+
double blurLevel() const { return mBlurLevel; }
129+
130+
/**
131+
* Sets the units used for the glow blur level (radius).
132+
* \param unit units for blur level
133+
* \see blurUnit
134+
* \see setBlurLevel
135+
* \see setBlurMapUnitScale
136+
* \since QGIS 3.4.9
137+
*/
138+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit ) { mBlurUnit = unit; }
139+
140+
/**
141+
* Returns the units used for the glow blur level (radius).
142+
* \returns units for blur level
143+
* \see setBlurUnit
144+
* \see blurLevel
145+
* \see blurMapUnitScale
146+
* \since QGIS 3.4.9
147+
*/
148+
QgsUnitTypes::RenderUnit blurUnit() const { return mBlurUnit; }
149+
150+
/**
151+
* Sets the map unit scale used for the glow blur strength (radius).
152+
* \param scale map unit scale for blur strength
153+
* \see blurMapUnitScale
154+
* \see setBlurLevel
155+
* \see setBlurUnit
156+
* \since QGIS 3.4.9
157+
*/
158+
void setBlurMapUnitScale( const QgsMapUnitScale &scale ) { mBlurMapUnitScale = scale; }
159+
160+
/**
161+
* Returns the map unit scale used for the glow blur strength (radius).
162+
* \returns map unit scale for blur strength
163+
* \see setBlurMapUnitScale
164+
* \see blurLevel
165+
* \see blurUnit
166+
* \since QGIS 3.4.9
167+
*/
168+
const QgsMapUnitScale &blurMapUnitScale() const { return mBlurMapUnitScale; }
127169

128170
/**
129171
* Sets the \a opacity for the effect.
@@ -235,7 +277,9 @@ class CORE_EXPORT QgsGlowEffect : public QgsPaintEffect
235277
QgsUnitTypes::RenderUnit mSpreadUnit = QgsUnitTypes::RenderMillimeters;
236278
QgsMapUnitScale mSpreadMapUnitScale;
237279
QgsColorRamp *mRamp = nullptr;
238-
int mBlurLevel = 3;
280+
double mBlurLevel = 2.645;
281+
QgsUnitTypes::RenderUnit mBlurUnit = QgsUnitTypes::RenderMillimeters;
282+
QgsMapUnitScale mBlurMapUnitScale;
239283
double mOpacity = 0.5;
240284
QColor mColor;
241285
QPainter::CompositionMode mBlendMode = QPainter::CompositionMode_SourceOver;

‎src/core/effects/qgsshadoweffect.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,18 @@ void QgsShadowEffect::draw( QgsRenderContext &context )
4545
}
4646

4747
QgsImageOperation::overlayColor( colorisedIm, mColor );
48-
QgsImageOperation::stackBlur( colorisedIm, mBlurLevel );
48+
49+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
50+
if ( blurLevel <= 16 )
51+
{
52+
QgsImageOperation::stackBlur( colorisedIm, blurLevel );
53+
}
54+
else
55+
{
56+
QImage *imb = QgsImageOperation::gaussianBlur( colorisedIm, blurLevel );
57+
colorisedIm = QImage( *imb );
58+
delete imb;
59+
}
4960

5061
double offsetDist = context.convertToPainterUnits( mOffsetDist, mOffsetUnit, mOffsetMapUnitScale );
5162

@@ -88,6 +99,8 @@ QgsStringMap QgsShadowEffect::properties() const
8899
props.insert( QStringLiteral( "blend_mode" ), QString::number( int( mBlendMode ) ) );
89100
props.insert( QStringLiteral( "opacity" ), QString::number( mOpacity ) );
90101
props.insert( QStringLiteral( "blur_level" ), QString::number( mBlurLevel ) );
102+
props.insert( QStringLiteral( "blur_unit" ), QgsUnitTypes::encodeUnit( mBlurUnit ) );
103+
props.insert( QStringLiteral( "blur_unit_scale" ), QgsSymbolLayerUtils::encodeMapUnitScale( mBlurMapUnitScale ) );
91104
props.insert( QStringLiteral( "offset_angle" ), QString::number( mOffsetAngle ) );
92105
props.insert( QStringLiteral( "offset_distance" ), QString::number( mOffsetDist ) );
93106
props.insert( QStringLiteral( "offset_unit" ), QgsUnitTypes::encodeUnit( mOffsetUnit ) );
@@ -122,11 +135,18 @@ void QgsShadowEffect::readProperties( const QgsStringMap &props )
122135
}
123136
mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
124137
mDrawMode = static_cast< QgsPaintEffect::DrawMode >( props.value( QStringLiteral( "draw_mode" ), QStringLiteral( "2" ) ).toInt() );
125-
int level = props.value( QStringLiteral( "blur_level" ) ).toInt( &ok );
138+
double level = props.value( QStringLiteral( "blur_level" ) ).toDouble( &ok );
126139
if ( ok )
127140
{
128141
mBlurLevel = level;
142+
if ( !props.contains( QStringLiteral( "blur_unit" ) ) )
143+
{
144+
// deal with pre blur unit era by assuming 96 dpi and converting pixel values as millimeters
145+
mBlurLevel *= 0.2645;
146+
}
129147
}
148+
mBlurUnit = QgsUnitTypes::decodeRenderUnit( props.value( QStringLiteral( "blur_unit" ) ) );
149+
mBlurMapUnitScale = QgsSymbolLayerUtils::decodeMapUnitScale( props.value( QStringLiteral( "blur_unit_scale" ) ) );
130150
int angle = props.value( QStringLiteral( "offset_angle" ) ).toInt( &ok );
131151
if ( ok )
132152
{
@@ -147,10 +167,11 @@ void QgsShadowEffect::readProperties( const QgsStringMap &props )
147167

148168
QRectF QgsShadowEffect::boundingRect( const QRectF &rect, const QgsRenderContext &context ) const
149169
{
150-
//offset distance
170+
//blur radius and offset distance
171+
int blurLevel = std::round( context.convertToPainterUnits( mBlurLevel, mBlurUnit, mBlurMapUnitScale ) );
151172
double spread = context.convertToPainterUnits( mOffsetDist, mOffsetUnit, mOffsetMapUnitScale );
152173
//plus possible extension due to blur, with a couple of extra pixels thrown in for safety
153-
spread += mBlurLevel * 2 + 10;
174+
spread += blurLevel * 2 + 10;
154175
return rect.adjusted( -spread, -spread, spread, spread );
155176
}
156177

‎src/core/effects/qgsshadoweffect.h

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,64 @@ class CORE_EXPORT QgsShadowEffect : public QgsPaintEffect
4242
void readProperties( const QgsStringMap &props ) override;
4343

4444
/**
45-
* Sets blur level (strength) for the shadow.
46-
* \param level blur level. Values between 0 and 16 are valid, with larger
45+
* Sets blur level (radius) for the shadow.
46+
* \param level blur level.
4747
* values indicating greater blur strength.
4848
* \see blurLevel
49+
* \see setBlurUnit
50+
* \see setBlurMapUnitScale
4951
*/
50-
void setBlurLevel( const int level ) { mBlurLevel = level; }
52+
void setBlurLevel( const double level ) { mBlurLevel = level; }
5153

5254
/**
53-
* Returns the blur level (strength) for the shadow.
54-
* \returns blur level. Value will be between 0 and 16, with larger
55+
* Returns the blur level (radius) for the shadow.
56+
* \returns blur level.
5557
* values indicating greater blur strength.
5658
* \see setBlurLevel
59+
* \see blurUnit
60+
* \see blurMapUnitScale
5761
*/
58-
int blurLevel() const { return mBlurLevel; }
62+
double blurLevel() const { return mBlurLevel; }
63+
64+
/**
65+
* Sets the units used for the shadow blur level (radius).
66+
* \param unit units for blur level
67+
* \see blurUnit
68+
* \see setBlurLevel
69+
* \see setBlurMapUnitScale
70+
* \since QGIS 3.4.9
71+
*/
72+
void setBlurUnit( const QgsUnitTypes::RenderUnit unit ) { mBlurUnit = unit; }
73+
74+
/**
75+
* Returns the units used for the shadow blur level (radius).
76+
* \returns units for blur level
77+
* \see setBlurUnit
78+
* \see blurLevel
79+
* \see blurMapUnitScale
80+
* \since QGIS 3.4.9
81+
*/
82+
QgsUnitTypes::RenderUnit blurUnit() const { return mBlurUnit; }
83+
84+
/**
85+
* Sets the map unit scale used for the shadow blur strength (radius).
86+
* \param scale map unit scale for blur strength
87+
* \see blurMapUnitScale
88+
* \see setBlurLevel
89+
* \see setBlurUnit
90+
* \since QGIS 3.4.9
91+
*/
92+
void setBlurMapUnitScale( const QgsMapUnitScale &scale ) { mBlurMapUnitScale = scale; }
93+
94+
/**
95+
* Returns the map unit scale used for the shadow blur strength (radius).
96+
* \returns map unit scale for blur strength
97+
* \see setBlurMapUnitScale
98+
* \see blurLevel
99+
* \see blurUnit
100+
* \since QGIS 3.4.9
101+
*/
102+
const QgsMapUnitScale &blurMapUnitScale() const { return mBlurMapUnitScale; }
59103

60104
/**
61105
* Sets the angle for offsetting the shadow.
@@ -186,7 +230,9 @@ class CORE_EXPORT QgsShadowEffect : public QgsPaintEffect
186230
*/
187231
virtual bool exteriorShadow() const = 0;
188232

189-
int mBlurLevel = 10;
233+
double mBlurLevel = 2.645;
234+
QgsUnitTypes::RenderUnit mBlurUnit = QgsUnitTypes::RenderMillimeters;
235+
QgsMapUnitScale mBlurMapUnitScale;
190236
int mOffsetAngle = 135;
191237
double mOffsetDist = 2.0;
192238
QgsUnitTypes::RenderUnit mOffsetUnit = QgsUnitTypes::RenderMillimeters;

‎src/gui/effects/qgspainteffectwidget.cpp

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,16 @@ QgsBlurWidget::QgsBlurWidget( QWidget *parent )
117117
{
118118
setupUi( this );
119119
connect( mBlurTypeCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsBlurWidget::mBlurTypeCombo_currentIndexChanged );
120-
connect( mBlurStrengthSpnBx, static_cast< void ( QSpinBox::* )( int ) >( &QSpinBox::valueChanged ), this, &QgsBlurWidget::mBlurStrengthSpnBx_valueChanged );
120+
connect( mBlurStrengthSpnBx, static_cast< void ( QDoubleSpinBox::* )( double ) >( &QDoubleSpinBox::valueChanged ), this, &QgsBlurWidget::mBlurStrengthSpnBx_valueChanged );
121+
connect( mBlurUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsBlurWidget::mBlurUnitWidget_changed );
121122
connect( mDrawModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsBlurWidget::mDrawModeComboBox_currentIndexChanged );
122123
connect( mBlendCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsBlurWidget::mBlendCmbBx_currentIndexChanged );
123124

124-
mBlurTypeCombo->addItem( tr( "Stack blur (fast)" ), QgsBlurEffect::StackBlur );
125-
mBlurTypeCombo->addItem( tr( "Gaussian blur (quality)" ), QgsBlurEffect::GaussianBlur );
125+
mBlurTypeCombo->addItem( tr( "Stack blur (fast, doesn't support high dpi)" ), QgsBlurEffect::StackBlur );
126+
mBlurTypeCombo->addItem( tr( "Gaussian blur (quality, supports high dpi)" ), QgsBlurEffect::GaussianBlur );
127+
128+
mBlurUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderMapUnits
129+
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
126130

127131
initGui();
128132
connect( mOpacityWidget, &QgsOpacityWidget::opacityChanged, this, &QgsBlurWidget::opacityChanged );
@@ -187,7 +191,7 @@ void QgsBlurWidget::mBlurTypeCombo_currentIndexChanged( int index )
187191
emit changed();
188192
}
189193

190-
void QgsBlurWidget::mBlurStrengthSpnBx_valueChanged( int value )
194+
void QgsBlurWidget::mBlurStrengthSpnBx_valueChanged( double value )
191195
{
192196
if ( !mEffect )
193197
return;
@@ -196,6 +200,18 @@ void QgsBlurWidget::mBlurStrengthSpnBx_valueChanged( int value )
196200
emit changed();
197201
}
198202

203+
void QgsBlurWidget::mBlurUnitWidget_changed()
204+
{
205+
if ( !mEffect )
206+
{
207+
return;
208+
}
209+
210+
mEffect->setBlurUnit( mBlurUnitWidget->unit() );
211+
mEffect->setBlurMapUnitScale( mBlurUnitWidget->getMapUnitScale() );
212+
emit changed();
213+
}
214+
199215
void QgsBlurWidget::opacityChanged( double value )
200216
{
201217
if ( !mEffect )
@@ -244,7 +260,8 @@ QgsShadowEffectWidget::QgsShadowEffectWidget( QWidget *parent )
244260
connect( mShadowColorBtn, &QgsColorButton::colorChanged, this, &QgsShadowEffectWidget::mShadowColorBtn_colorChanged );
245261
connect( mDrawModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsShadowEffectWidget::mDrawModeComboBox_currentIndexChanged );
246262
connect( mShadowBlendCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsShadowEffectWidget::mShadowBlendCmbBx_currentIndexChanged );
247-
connect( mShadowRadiuSpnBx, static_cast< void ( QSpinBox::* )( int ) >( &QSpinBox::valueChanged ), this, &QgsShadowEffectWidget::mShadowRadiuSpnBx_valueChanged );
263+
connect( mShadowRadiuSpnBx, static_cast< void ( QDoubleSpinBox::* )( double ) >( &QDoubleSpinBox::valueChanged ), this, &QgsShadowEffectWidget::mShadowRadiuSpnBx_valueChanged );
264+
connect( mBlurUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsShadowEffectWidget::mBlurUnitWidget_changed );
248265

249266
mShadowColorBtn->setAllowOpacity( false );
250267
mShadowColorBtn->setColorDialogTitle( tr( "Select Shadow Color" ) );
@@ -253,6 +270,8 @@ QgsShadowEffectWidget::QgsShadowEffectWidget( QWidget *parent )
253270

254271
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderMapUnits
255272
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
273+
mBlurUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderMapUnits
274+
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
256275

257276
initGui();
258277

@@ -283,6 +302,8 @@ void QgsShadowEffectWidget::initGui()
283302
mOffsetUnitWidget->setUnit( mEffect->offsetUnit() );
284303
mOffsetUnitWidget->setMapUnitScale( mEffect->offsetMapUnitScale() );
285304
mShadowRadiuSpnBx->setValue( mEffect->blurLevel() );
305+
mBlurUnitWidget->setUnit( mEffect->blurUnit() );
306+
mBlurUnitWidget->setMapUnitScale( mEffect->blurMapUnitScale() );
286307
mOpacityWidget->setOpacity( mEffect->opacity() );
287308
mShadowColorBtn->setColor( mEffect->color() );
288309
mShadowBlendCmbBx->setBlendMode( mEffect->blendMode() );
@@ -298,6 +319,7 @@ void QgsShadowEffectWidget::blockSignals( const bool block )
298319
mShadowOffsetSpnBx->blockSignals( block );
299320
mOffsetUnitWidget->blockSignals( block );
300321
mShadowRadiuSpnBx->blockSignals( block );
322+
mBlurUnitWidget->blockSignals( block );
301323
mOpacityWidget->blockSignals( block );
302324
mShadowColorBtn->blockSignals( block );
303325
mShadowBlendCmbBx->blockSignals( block );
@@ -361,7 +383,7 @@ void QgsShadowEffectWidget::mShadowColorBtn_colorChanged( const QColor &color )
361383
emit changed();
362384
}
363385

364-
void QgsShadowEffectWidget::mShadowRadiuSpnBx_valueChanged( int value )
386+
void QgsShadowEffectWidget::mShadowRadiuSpnBx_valueChanged( double value )
365387
{
366388
if ( !mEffect )
367389
return;
@@ -370,6 +392,18 @@ void QgsShadowEffectWidget::mShadowRadiuSpnBx_valueChanged( int value )
370392
emit changed();
371393
}
372394

395+
void QgsShadowEffectWidget::mBlurUnitWidget_changed()
396+
{
397+
if ( !mEffect )
398+
{
399+
return;
400+
}
401+
402+
mEffect->setBlurUnit( mBlurUnitWidget->unit() );
403+
mEffect->setBlurMapUnitScale( mBlurUnitWidget->getMapUnitScale() );
404+
emit changed();
405+
}
406+
373407
void QgsShadowEffectWidget::mDrawModeComboBox_currentIndexChanged( int index )
374408
{
375409
Q_UNUSED( index );
@@ -408,14 +442,17 @@ QgsGlowWidget::QgsGlowWidget( QWidget *parent )
408442
connect( mColorBtn, &QgsColorButton::colorChanged, this, &QgsGlowWidget::mColorBtn_colorChanged );
409443
connect( mBlendCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGlowWidget::mBlendCmbBx_currentIndexChanged );
410444
connect( mDrawModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsGlowWidget::mDrawModeComboBox_currentIndexChanged );
411-
connect( mBlurRadiusSpnBx, static_cast< void ( QSpinBox::* )( int ) >( &QSpinBox::valueChanged ), this, &QgsGlowWidget::mBlurRadiusSpnBx_valueChanged );
445+
connect( mBlurRadiusSpnBx, static_cast< void ( QDoubleSpinBox::* )( double ) >( &QDoubleSpinBox::valueChanged ), this, &QgsGlowWidget::mBlurRadiusSpnBx_valueChanged );
446+
connect( mBlurUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGlowWidget::mBlurUnitWidget_changed );
412447

413448
mColorBtn->setAllowOpacity( false );
414449
mColorBtn->setColorDialogTitle( tr( "Select Glow Color" ) );
415450
mColorBtn->setContext( QStringLiteral( "symbology" ) );
416451

417452
mSpreadUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderMapUnits
418453
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
454+
mBlurUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderPixels << QgsUnitTypes::RenderMapUnits
455+
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
419456

420457
btnColorRamp->setShowGradientOnly( true );
421458

@@ -538,7 +575,7 @@ void QgsGlowWidget::mColorBtn_colorChanged( const QColor &color )
538575
emit changed();
539576
}
540577

541-
void QgsGlowWidget::mBlurRadiusSpnBx_valueChanged( int value )
578+
void QgsGlowWidget::mBlurRadiusSpnBx_valueChanged( double value )
542579
{
543580
if ( !mEffect )
544581
return;
@@ -547,6 +584,18 @@ void QgsGlowWidget::mBlurRadiusSpnBx_valueChanged( int value )
547584
emit changed();
548585
}
549586

587+
void QgsGlowWidget::mBlurUnitWidget_changed()
588+
{
589+
if ( !mEffect )
590+
{
591+
return;
592+
}
593+
594+
mEffect->setBlurUnit( mBlurUnitWidget->unit() );
595+
mEffect->setBlurMapUnitScale( mBlurUnitWidget->getMapUnitScale() );
596+
emit changed();
597+
}
598+
550599
void QgsGlowWidget::mBlendCmbBx_currentIndexChanged( int index )
551600
{
552601
Q_UNUSED( index );

‎src/gui/effects/qgspainteffectwidget.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ class GUI_EXPORT QgsBlurWidget : public QgsPaintEffectWidget, private Ui::Widget
120120
private slots:
121121

122122
void mBlurTypeCombo_currentIndexChanged( int index );
123-
void mBlurStrengthSpnBx_valueChanged( int value );
123+
void mBlurStrengthSpnBx_valueChanged( double value );
124+
void mBlurUnitWidget_changed();
124125
void opacityChanged( double value );
125126
void mDrawModeComboBox_currentIndexChanged( int index );
126127
void mBlendCmbBx_currentIndexChanged( int index );
@@ -161,7 +162,8 @@ class GUI_EXPORT QgsShadowEffectWidget : public QgsPaintEffectWidget, private Ui
161162
void mShadowColorBtn_colorChanged( const QColor &color );
162163
void mDrawModeComboBox_currentIndexChanged( int index );
163164
void mShadowBlendCmbBx_currentIndexChanged( int index );
164-
void mShadowRadiuSpnBx_valueChanged( int value );
165+
void mShadowRadiuSpnBx_valueChanged( double value );
166+
void mBlurUnitWidget_changed();
165167
};
166168

167169

@@ -196,7 +198,8 @@ class GUI_EXPORT QgsGlowWidget : public QgsPaintEffectWidget, private Ui::Widget
196198
void mColorBtn_colorChanged( const QColor &color );
197199
void mBlendCmbBx_currentIndexChanged( int index );
198200
void mDrawModeComboBox_currentIndexChanged( int index );
199-
void mBlurRadiusSpnBx_valueChanged( int value );
201+
void mBlurRadiusSpnBx_valueChanged( double value );
202+
void mBlurUnitWidget_changed();
200203
void applyColorRamp();
201204

202205
};

‎src/ui/effects/widget_blur.ui

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
<property name="bottomMargin">
3232
<number>0</number>
3333
</property>
34-
<item row="0" column="1">
34+
<item row="0" column="1" colspan="2">
3535
<widget class="QComboBox" name="mBlurTypeCombo"/>
3636
</item>
3737
<item row="2" column="0">
@@ -48,19 +48,41 @@
4848
</property>
4949
</widget>
5050
</item>
51-
<item row="3" column="1">
51+
<item row="3" column="1" colspan="2">
5252
<widget class="QgsBlendModeComboBox" name="mBlendCmbBx"/>
5353
</item>
5454
<item row="1" column="1">
55-
<widget class="QgsSpinBox" name="mBlurStrengthSpnBx">
55+
<widget class="QgsDoubleSpinBox" name="mBlurStrengthSpnBx">
56+
<property name="decimals">
57+
<number>4</number>
58+
</property>
59+
<property name="minimum">
60+
<double>0.000000000000000</double>
61+
</property>
5662
<property name="maximum">
57-
<number>16</number>
63+
<double>9999999.000000000000000</double>
64+
</property>
65+
<property name="singleStep">
66+
<double>0.200000000000000</double>
5867
</property>
5968
<property name="showClearButton" stdset="0">
6069
<bool>false</bool>
6170
</property>
6271
</widget>
6372
</item>
73+
<item row="1" column="2">
74+
<widget class="QgsUnitSelectionWidget" name="mBlurUnitWidget" native="true">
75+
<property name="minimumSize">
76+
<size>
77+
<width>0</width>
78+
<height>0</height>
79+
</size>
80+
</property>
81+
<property name="focusPolicy">
82+
<enum>Qt::StrongFocus</enum>
83+
</property>
84+
</widget>
85+
</item>
6486
<item row="0" column="0">
6587
<widget class="QLabel" name="label">
6688
<property name="text">
@@ -75,7 +97,7 @@
7597
</property>
7698
</widget>
7799
</item>
78-
<item row="4" column="1">
100+
<item row="4" column="1" colspan="2">
79101
<widget class="QgsEffectDrawModeComboBox" name="mDrawModeComboBox"/>
80102
</item>
81103
<item row="4" column="0">
@@ -85,7 +107,7 @@
85107
</property>
86108
</widget>
87109
</item>
88-
<item row="2" column="1">
110+
<item row="2" column="1" colspan="2">
89111
<widget class="QgsOpacityWidget" name="mOpacityWidget" native="true">
90112
<property name="focusPolicy">
91113
<enum>Qt::StrongFocus</enum>
@@ -114,9 +136,9 @@
114136
</widget>
115137
<customwidgets>
116138
<customwidget>
117-
<class>QgsSpinBox</class>
118-
<extends>QSpinBox</extends>
119-
<header>qgsspinbox.h</header>
139+
<class>QgsDoubleSpinBox</class>
140+
<extends>QDoubleSpinBox</extends>
141+
<header>qgsdoublespinbox.h</header>
120142
</customwidget>
121143
<customwidget>
122144
<class>QgsBlendModeComboBox</class>

‎src/ui/effects/widget_glow.ui

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@
8484
<property name="maximum">
8585
<double>9999999.000000000000000</double>
8686
</property>
87+
<property name="singleStep">
88+
<double>0.200000000000000</double>
89+
</property>
8790
<property name="showClearButton" stdset="0">
8891
<bool>false</bool>
8992
</property>
@@ -102,16 +105,38 @@
102105
</property>
103106
</widget>
104107
</item>
105-
<item row="1" column="1" colspan="2">
106-
<widget class="QgsSpinBox" name="mBlurRadiusSpnBx">
108+
<item row="1" column="1">
109+
<widget class="QgsDoubleSpinBox" name="mBlurRadiusSpnBx">
110+
<property name="decimals">
111+
<number>4</number>
112+
</property>
113+
<property name="minimum">
114+
<double>0.000000000000000</double>
115+
</property>
107116
<property name="maximum">
108-
<number>16</number>
117+
<double>9999999.000000000000000</double>
118+
</property>
119+
<property name="singleStep">
120+
<double>0.200000000000000</double>
109121
</property>
110122
<property name="showClearButton" stdset="0">
111123
<bool>false</bool>
112124
</property>
113125
</widget>
114126
</item>
127+
<item row="1" column="2">
128+
<widget class="QgsUnitSelectionWidget" name="mBlurUnitWidget" native="true">
129+
<property name="minimumSize">
130+
<size>
131+
<width>0</width>
132+
<height>0</height>
133+
</size>
134+
</property>
135+
<property name="focusPolicy">
136+
<enum>Qt::StrongFocus</enum>
137+
</property>
138+
</widget>
139+
</item>
115140
<item row="4" column="1" colspan="2">
116141
<widget class="QgsColorRampButton" name="btnColorRamp">
117142
<property name="sizePolicy">

‎src/ui/effects/widget_shadoweffect.ui

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
<property name="maximum">
4343
<double>9999999.000000000000000</double>
4444
</property>
45+
<property name="singleStep">
46+
<double>0.200000000000000</double>
47+
</property>
4548
<property name="showClearButton" stdset="0">
4649
<bool>false</bool>
4750
</property>
@@ -107,16 +110,38 @@
107110
<item row="5" column="1" colspan="2">
108111
<widget class="QgsBlendModeComboBox" name="mShadowBlendCmbBx"/>
109112
</item>
110-
<item row="2" column="1" colspan="2">
111-
<widget class="QgsSpinBox" name="mShadowRadiuSpnBx">
113+
<item row="2" column="1">
114+
<widget class="QgsDoubleSpinBox" name="mShadowRadiuSpnBx">
115+
<property name="decimals">
116+
<number>4</number>
117+
</property>
118+
<property name="minimum">
119+
<double>0.000000000000000</double>
120+
</property>
112121
<property name="maximum">
113-
<number>16</number>
122+
<double>9999999.000000000000000</double>
123+
</property>
124+
<property name="singleStep">
125+
<double>0.200000000000000</double>
114126
</property>
115127
<property name="showClearButton" stdset="0">
116128
<bool>false</bool>
117129
</property>
118130
</widget>
119131
</item>
132+
<item row="2" column="2">
133+
<widget class="QgsUnitSelectionWidget" name="mBlurUnitWidget" native="true">
134+
<property name="minimumSize">
135+
<size>
136+
<width>0</width>
137+
<height>0</height>
138+
</size>
139+
</property>
140+
<property name="focusPolicy">
141+
<enum>Qt::StrongFocus</enum>
142+
</property>
143+
</widget>
144+
</item>
120145
<item row="0" column="1" colspan="2">
121146
<layout class="QHBoxLayout" name="horizontalLayout_24">
122147
<item>

‎tests/src/core/testqgspainteffect.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ void TestQgsPaintEffect::blur()
360360
QCOMPARE( effect->opacity(), 0.5 );
361361
effect->setEnabled( false );
362362
QCOMPARE( effect->enabled(), false );
363-
effect->setBlurLevel( 6 );
364-
QCOMPARE( effect->blurLevel(), 6 );
363+
effect->setBlurLevel( 6.0 );
364+
QCOMPARE( effect->blurLevel(), 6.0 );
365365
effect->setBlurMethod( QgsBlurEffect::GaussianBlur );
366366
QCOMPARE( effect->blurMethod(), QgsBlurEffect::GaussianBlur );
367367
effect->setDrawMode( QgsPaintEffect::Modifier );
@@ -434,8 +434,8 @@ void TestQgsPaintEffect::dropShadow()
434434
QCOMPARE( effect->opacity(), 0.5 );
435435
effect->setEnabled( false );
436436
QCOMPARE( effect->enabled(), false );
437-
effect->setBlurLevel( 6 );
438-
QCOMPARE( effect->blurLevel(), 6 );
437+
effect->setBlurLevel( 6.0 );
438+
QCOMPARE( effect->blurLevel(), 6.0 );
439439
effect->setOffsetAngle( 77 );
440440
QCOMPARE( effect->offsetAngle(), 77 );
441441
effect->setOffsetDistance( 9.7 );
@@ -531,8 +531,8 @@ void TestQgsPaintEffect::glow()
531531
QCOMPARE( effect->opacity(), 0.5 );
532532
effect->setEnabled( false );
533533
QCOMPARE( effect->enabled(), false );
534-
effect->setBlurLevel( 6 );
535-
QCOMPARE( effect->blurLevel(), 6 );
534+
effect->setBlurLevel( 6.0 );
535+
QCOMPARE( effect->blurLevel(), 6.0 );
536536
effect->setSpread( 7.8 );
537537
QCOMPARE( effect->spread(), 7.8 );
538538
effect->setSpreadUnit( QgsUnitTypes::RenderMapUnits );

‎tests/src/python/test_qgstextformatwidget.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def createBufferSettings(self):
4343
s.setOpacity(0.5)
4444
s.setJoinStyle(Qt.RoundJoin)
4545
s.setBlendMode(QPainter.CompositionMode_Difference)
46-
s.setPaintEffect(QgsBlurEffect.create({'blur_level': '10', 'enabled': '1'}))
46+
s.setPaintEffect(QgsBlurEffect.create({'blur_level': '2.0', 'blur_unit': QgsUnitTypes.encodeUnit(QgsUnitTypes.RenderMillimeters), 'enabled': '1'}))
4747
return s
4848

4949
def checkBufferSettings(self, s):
@@ -58,7 +58,7 @@ def checkBufferSettings(self, s):
5858
self.assertEqual(s.joinStyle(), Qt.RoundJoin)
5959
self.assertEqual(s.blendMode(), QPainter.CompositionMode_Difference)
6060
self.assertTrue(s.paintEffect())
61-
self.assertEqual(s.paintEffect().blurLevel(), 10)
61+
self.assertEqual(s.paintEffect().blurLevel(), 2.0)
6262

6363
def createBackgroundSettings(self):
6464
s = QgsTextBackgroundSettings()
@@ -85,7 +85,7 @@ def createBackgroundSettings(self):
8585
s.setStrokeWidth(7)
8686
s.setStrokeWidthUnit(QgsUnitTypes.RenderMapUnits)
8787
s.setStrokeWidthMapUnitScale(QgsMapUnitScale(QgsMapUnitScale(25, 26)))
88-
s.setPaintEffect(QgsBlurEffect.create({'blur_level': '6', 'enabled': '1'}))
88+
s.setPaintEffect(QgsBlurEffect.create({'blur_level': '6.0', 'blur_unit': QgsUnitTypes.encodeUnit(QgsUnitTypes.RenderMillimeters), 'enabled': '1'}))
8989
return s
9090

9191
def checkBackgroundSettings(self, s):
@@ -114,7 +114,7 @@ def checkBackgroundSettings(self, s):
114114
self.assertEqual(s.strokeWidthUnit(), QgsUnitTypes.RenderMapUnits)
115115
self.assertEqual(s.strokeWidthMapUnitScale(), QgsMapUnitScale(25, 26))
116116
self.assertTrue(s.paintEffect())
117-
self.assertEqual(s.paintEffect().blurLevel(), 6)
117+
self.assertEqual(s.paintEffect().blurLevel(), 6.0)
118118

119119
def createShadowSettings(self):
120120
s = QgsTextShadowSettings()
Loading
Loading

0 commit comments

Comments
 (0)
Please sign in to comment.