Skip to content

Commit

Permalink
Some optimisations to gradient ramps and shapeburst fills
Browse files Browse the repository at this point in the history
Leads to up to 25% improvement in render speed.
  • Loading branch information
nyalldawson committed Jan 9, 2015
1 parent 8b5587f commit 85619da
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 20 deletions.
36 changes: 24 additions & 12 deletions src/core/symbology-ng/qgsfillsymbollayerv2.cpp
Expand Up @@ -1287,10 +1287,11 @@ void QgsShapeburstFillSymbolLayerV2::distanceTransform1d( double *f, int n, int
/* distance transform of 2d function using squared distance */
void QgsShapeburstFillSymbolLayerV2::distanceTransform2d( double * im, int width, int height )
{
double *f = new double[ qMax( width,height )];
int *v = new int[ qMax( width,height )];
double *z = new double[ qMax( width,height ) + 1 ];
double *d = new double[ qMax( width,height )];
int maxDimension = qMax( width, height );
double *f = new double[ maxDimension ];
int *v = new int[ maxDimension ];
double *z = new double[ maxDimension + 1 ];
double *d = new double[ maxDimension ];

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

void QgsShapeburstFillSymbolLayerV2::dtArrayToQImage( double * array, QImage *im, QgsVectorColorRampV2* ramp, double layerAlpha, bool useWholeShape, int maxPixelDistance )
{
int width = im->width();
int height = im->height();

//find maximum distance value
double maxDistanceValue;

if ( useWholeShape )
{
//no max distance specified in symbol properties, so calculate from maximum value in distance transform results
double dtMaxValue = array[0];
for ( int i = 1; i < ( im->width() * im->height() ); ++i )
for ( int i = 1; i < ( width * height ); ++i )
{
dtMaxValue = qMax( dtMaxValue, array[i] );
if ( array[i] > dtMaxValue )
{
dtMaxValue = array[i];
}
}

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

for ( int heightIndex = 0; heightIndex < im->height(); ++heightIndex )
for ( int heightIndex = 0; heightIndex < height; ++heightIndex )
{
QRgb* scanLine = ( QRgb* )im->scanLine( heightIndex );
for ( int widthIndex = 0; widthIndex < im->width(); ++widthIndex )
for ( int widthIndex = 0; widthIndex < width; ++widthIndex )
{
//result of distance transform
squaredVal = array[idx];
Expand All @@ -1406,11 +1414,15 @@ void QgsShapeburstFillSymbolLayerV2::dtArrayToQImage( double * array, QImage *im
//convert value to color from ramp
pixColor = ramp->color( pixVal );

//apply layer's transparency to alpha value
double alpha = pixColor.alpha() * layerAlpha;
int pixAlpha = pixColor.alpha();
if (( layerHasAlpha ) || ( pixAlpha != 255 ) )
{
//apply layer's transparency to alpha value
double alpha = pixAlpha * layerAlpha;
//premultiply ramp color since we are storing this in a ARGB32_Premultiplied QImage
QgsSymbolLayerV2Utils::premultiplyColor( pixColor, alpha );
}

//premultiply ramp color since we are storing this in a ARGB32_Premultiplied QImage
QgsSymbolLayerV2Utils::premultiplyColor( pixColor, alpha );
scanLine[widthIndex] = pixColor.rgba();
idx++;
}
Expand Down
7 changes: 2 additions & 5 deletions src/core/symbology-ng/qgssymbollayerv2utils.cpp
Expand Up @@ -3409,17 +3409,14 @@ void QgsSymbolLayerV2Utils::blurImageInPlace( QImage& image, const QRect& rect,

void QgsSymbolLayerV2Utils::premultiplyColor( QColor &rgb, int alpha )
{
int r = 0, g = 0, b = 0;
double alphaFactor = 1.0;

if ( alpha != 255 && alpha > 0 )
{
// Semi-transparent pixel. We need to adjust the colors for ARGB32_Premultiplied images
// where color values have to be premultiplied by alpha

double alphaFactor = alpha / 255.;
int r = 0, g = 0, b = 0;
rgb.getRgb( &r, &g, &b );

alphaFactor = alpha / 255.;
r *= alphaFactor;
g *= alphaFactor;
b *= alphaFactor;
Expand Down
15 changes: 12 additions & 3 deletions src/core/symbology-ng/qgsvectorcolorrampv2.cpp
Expand Up @@ -28,9 +28,9 @@

//////////////

static QColor _interpolate( QColor c1, QColor c2, double value )
static QColor _interpolate( const QColor& c1, const QColor& c2, const double value )
{
if ( qIsNaN( value ) ) value = 1;
if ( qIsNaN( value ) ) return c2;
int r = ( int )( c1.red() + value * ( c2.red() - c1.red() ) );
int g = ( int )( c1.green() + value * ( c2.green() - c1.green() ) );
int b = ( int )( c1.blue() + value * ( c2.blue() - c1.blue() ) );
Expand Down Expand Up @@ -112,10 +112,19 @@ double QgsVectorGradientColorRampV2::value( int index ) const

QColor QgsVectorGradientColorRampV2::color( double value ) const
{
if ( mStops.isEmpty() )
if ( qgsDoubleNear( value, 0.0 ) || value < 0.0 )
{
return mColor1;
}
else if ( qgsDoubleNear( value, 1.0 ) || value > 1.0 )
{
return mColor2;
}
else if ( mStops.isEmpty() )
{
if ( mDiscrete )
return mColor1;

return _interpolate( mColor1, mColor2, value );
}
else
Expand Down

0 comments on commit 85619da

Please sign in to comment.