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
}

0 commit comments

Comments
 (0)