Skip to content

Commit 85619da

Browse files
committed
Some optimisations to gradient ramps and shapeburst fills
Leads to up to 25% improvement in render speed.
1 parent 8b5587f commit 85619da

File tree

3 files changed

+38
-20
lines changed

3 files changed

+38
-20
lines changed

src/core/symbology-ng/qgsfillsymbollayerv2.cpp

+24-12
Original file line numberDiff line numberDiff line change
@@ -1287,10 +1287,11 @@ void QgsShapeburstFillSymbolLayerV2::distanceTransform1d( double *f, int n, int
12871287
/* distance transform of 2d function using squared distance */
12881288
void QgsShapeburstFillSymbolLayerV2::distanceTransform2d( double * im, int width, int height )
12891289
{
1290-
double *f = new double[ qMax( width,height )];
1291-
int *v = new int[ qMax( width,height )];
1292-
double *z = new double[ qMax( width,height ) + 1 ];
1293-
double *d = new double[ qMax( width,height )];
1290+
int maxDimension = qMax( width, height );
1291+
double *f = new double[ maxDimension ];
1292+
int *v = new int[ maxDimension ];
1293+
double *z = new double[ maxDimension + 1 ];
1294+
double *d = new double[ maxDimension ];
12941295

12951296
// transform along columns
12961297
for ( int x = 0; x < width; x++ )
@@ -1365,16 +1366,22 @@ double * QgsShapeburstFillSymbolLayerV2::distanceTransform( QImage *im )
13651366

13661367
void QgsShapeburstFillSymbolLayerV2::dtArrayToQImage( double * array, QImage *im, QgsVectorColorRampV2* ramp, double layerAlpha, bool useWholeShape, int maxPixelDistance )
13671368
{
1369+
int width = im->width();
1370+
int height = im->height();
1371+
13681372
//find maximum distance value
13691373
double maxDistanceValue;
13701374

13711375
if ( useWholeShape )
13721376
{
13731377
//no max distance specified in symbol properties, so calculate from maximum value in distance transform results
13741378
double dtMaxValue = array[0];
1375-
for ( int i = 1; i < ( im->width() * im->height() ); ++i )
1379+
for ( int i = 1; i < ( width * height ); ++i )
13761380
{
1377-
dtMaxValue = qMax( dtMaxValue, array[i] );
1381+
if ( array[i] > dtMaxValue )
1382+
{
1383+
dtMaxValue = array[i];
1384+
}
13781385
}
13791386

13801387
//values in distance transform are squared
@@ -1391,11 +1398,12 @@ void QgsShapeburstFillSymbolLayerV2::dtArrayToQImage( double * array, QImage *im
13911398
double squaredVal = 0;
13921399
double pixVal = 0;
13931400
QColor pixColor;
1401+
bool layerHasAlpha = layerAlpha < 1.0;
13941402

1395-
for ( int heightIndex = 0; heightIndex < im->height(); ++heightIndex )
1403+
for ( int heightIndex = 0; heightIndex < height; ++heightIndex )
13961404
{
13971405
QRgb* scanLine = ( QRgb* )im->scanLine( heightIndex );
1398-
for ( int widthIndex = 0; widthIndex < im->width(); ++widthIndex )
1406+
for ( int widthIndex = 0; widthIndex < width; ++widthIndex )
13991407
{
14001408
//result of distance transform
14011409
squaredVal = array[idx];
@@ -1406,11 +1414,15 @@ void QgsShapeburstFillSymbolLayerV2::dtArrayToQImage( double * array, QImage *im
14061414
//convert value to color from ramp
14071415
pixColor = ramp->color( pixVal );
14081416

1409-
//apply layer's transparency to alpha value
1410-
double alpha = pixColor.alpha() * layerAlpha;
1417+
int pixAlpha = pixColor.alpha();
1418+
if (( layerHasAlpha ) || ( pixAlpha != 255 ) )
1419+
{
1420+
//apply layer's transparency to alpha value
1421+
double alpha = pixAlpha * layerAlpha;
1422+
//premultiply ramp color since we are storing this in a ARGB32_Premultiplied QImage
1423+
QgsSymbolLayerV2Utils::premultiplyColor( pixColor, alpha );
1424+
}
14111425

1412-
//premultiply ramp color since we are storing this in a ARGB32_Premultiplied QImage
1413-
QgsSymbolLayerV2Utils::premultiplyColor( pixColor, alpha );
14141426
scanLine[widthIndex] = pixColor.rgba();
14151427
idx++;
14161428
}

src/core/symbology-ng/qgssymbollayerv2utils.cpp

+2-5
Original file line numberDiff line numberDiff line change
@@ -3409,17 +3409,14 @@ void QgsSymbolLayerV2Utils::blurImageInPlace( QImage& image, const QRect& rect,
34093409

34103410
void QgsSymbolLayerV2Utils::premultiplyColor( QColor &rgb, int alpha )
34113411
{
3412-
int r = 0, g = 0, b = 0;
3413-
double alphaFactor = 1.0;
3414-
34153412
if ( alpha != 255 && alpha > 0 )
34163413
{
34173414
// Semi-transparent pixel. We need to adjust the colors for ARGB32_Premultiplied images
34183415
// where color values have to be premultiplied by alpha
3419-
3416+
double alphaFactor = alpha / 255.;
3417+
int r = 0, g = 0, b = 0;
34203418
rgb.getRgb( &r, &g, &b );
34213419

3422-
alphaFactor = alpha / 255.;
34233420
r *= alphaFactor;
34243421
g *= alphaFactor;
34253422
b *= alphaFactor;

src/core/symbology-ng/qgsvectorcolorrampv2.cpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828

2929
//////////////
3030

31-
static QColor _interpolate( QColor c1, QColor c2, double value )
31+
static QColor _interpolate( const QColor& c1, const QColor& c2, const double value )
3232
{
33-
if ( qIsNaN( value ) ) value = 1;
33+
if ( qIsNaN( value ) ) return c2;
3434
int r = ( int )( c1.red() + value * ( c2.red() - c1.red() ) );
3535
int g = ( int )( c1.green() + value * ( c2.green() - c1.green() ) );
3636
int b = ( int )( c1.blue() + value * ( c2.blue() - c1.blue() ) );
@@ -112,10 +112,19 @@ double QgsVectorGradientColorRampV2::value( int index ) const
112112

113113
QColor QgsVectorGradientColorRampV2::color( double value ) const
114114
{
115-
if ( mStops.isEmpty() )
115+
if ( qgsDoubleNear( value, 0.0 ) || value < 0.0 )
116+
{
117+
return mColor1;
118+
}
119+
else if ( qgsDoubleNear( value, 1.0 ) || value > 1.0 )
120+
{
121+
return mColor2;
122+
}
123+
else if ( mStops.isEmpty() )
116124
{
117125
if ( mDiscrete )
118126
return mColor1;
127+
119128
return _interpolate( mColor1, mColor2, value );
120129
}
121130
else

0 commit comments

Comments
 (0)