Skip to content

Commit

Permalink
highlight fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
blazek committed Mar 25, 2014
1 parent d8ad1d8 commit 776619f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 45 deletions.
4 changes: 2 additions & 2 deletions src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -1267,8 +1267,8 @@ void QgsIdentifyResultsDialog::highlightFeature( QTreeWidgetItem *item )
QSettings settings;
QColor color = QColor( settings.value( "/Map/identify/highlight/color", "#ff0000" ).toString() );
int alpha = settings.value( "/Map/identify/highlight/colorAlpha", "128" ).toInt();
double buffer = settings.value( "/Map/highlight/buffer", "0.5" ).toDouble();
double minWidth = settings.value( "/Map/highlight/minWidth", "1." ).toDouble();
double buffer = settings.value( "/Map/identify/highlight/buffer", "0.5" ).toDouble();
double minWidth = settings.value( "/Map/identify/highlight/minWidth", "1." ).toDouble();

highlight->setColor( color ); // sets also fill with default alpha
color.setAlpha( alpha );
Expand Down
8 changes: 4 additions & 4 deletions src/app/qgsoptions.cpp
Expand Up @@ -123,9 +123,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
int highlightAlpha = settings.value( "/Map/identify/highlight/colorAlpha", "63" ).toInt();
highlightColor.setAlpha( highlightAlpha );
mIdentifyHighlightColorButton->setColor( highlightColor );
double highlightBuffer = settings.value( "/Map/highlight/buffer", "0.5" ).toDouble();
double highlightBuffer = settings.value( "/Map/identify/highlight/buffer", "0.5" ).toDouble();
mIdentifyHighlightBufferSpinBox->setValue( highlightBuffer );
double highlightMinWidth = settings.value( "/Map/highlight/minWidth", "1." ).toDouble();
double highlightMinWidth = settings.value( "/Map/identify/highlight/minWidth", "1." ).toDouble();
mIdentifyHighlightMinWidthSpinBox->setValue( highlightMinWidth );

// custom environment variables
Expand Down Expand Up @@ -1048,8 +1048,8 @@ void QgsOptions::saveOptions()
settings.setValue( "/Map/identifyRadius", spinBoxIdentifyValue->value() );
settings.setValue( "/Map/identify/highlight/color", mIdentifyHighlightColorButton->color().name() );
settings.setValue( "/Map/identify/highlight/colorAlpha", mIdentifyHighlightColorButton->color().alpha() );
settings.setValue( "/Map/highlight/buffer", mIdentifyHighlightBufferSpinBox->value() );
settings.setValue( "/Map/highlight/minWidth", mIdentifyHighlightMinWidthSpinBox->value() );
settings.setValue( "/Map/identify/highlight/buffer", mIdentifyHighlightBufferSpinBox->value() );
settings.setValue( "/Map/identify/highlight/minWidth", mIdentifyHighlightMinWidthSpinBox->value() );

bool showLegendClassifiers = settings.value( "/qgis/showLegendClassifiers", false ).toBool();
settings.setValue( "/qgis/showLegendClassifiers", cbxLegendClassifiers->isChecked() );
Expand Down
60 changes: 24 additions & 36 deletions src/gui/qgshighlight.cpp
Expand Up @@ -131,7 +131,7 @@ void QgsHighlight::setFillColor( const QColor & fillColor )
mBrush.setStyle( Qt::SolidPattern );
}

QgsFeatureRendererV2 * QgsHighlight::getRenderer( const QgsRenderContext & context )
QgsFeatureRendererV2 * QgsHighlight::getRenderer( const QgsRenderContext & context, const QColor & color, const QColor & fillColor )
{
QgsFeatureRendererV2 *renderer = 0;
QgsVectorLayer *layer = vectorLayer();
Expand All @@ -144,30 +144,16 @@ QgsFeatureRendererV2 * QgsHighlight::getRenderer( const QgsRenderContext & conte
foreach ( QgsSymbolV2* symbol, renderer->symbols() )
{
if ( !symbol ) continue;
setSymbol( symbol, context, mPen.color() );
setSymbol( symbol, context, color, fillColor );
}
}
return renderer;
}

void QgsHighlight::setSymbol( QgsSymbolV2* symbol, const QgsRenderContext & context, const QColor & color )
void QgsHighlight::setSymbol( QgsSymbolV2* symbol, const QgsRenderContext & context, const QColor & color, const QColor & fillColor )
{
if ( !symbol ) return;

// Temporary fill color must be similar to outline color (antialiasing between
// outline and temporary fill) but also different enough to be distinguishable
// so that it can be replaced by transparent fill.
// Unfortunately the result of the transparent fill rendered over the original
// (not highlighted) feature color may be either lighter or darker.
if ( color.lightness() < 200 )
{
mTemporaryFillColor = color.lighter( 120 );
}
else
{
mTemporaryFillColor = color.darker( 120 );
}
mTemporaryFillColor.setAlpha( 255 );

for ( int i = symbol->symbolLayerCount() - 1; i >= 0; i-- )
{
Expand All @@ -176,13 +162,13 @@ void QgsHighlight::setSymbol( QgsSymbolV2* symbol, const QgsRenderContext & cont

if ( symbolLayer->subSymbol() )
{
setSymbol( symbolLayer->subSymbol(), context, color );
setSymbol( symbolLayer->subSymbol(), context, color, fillColor );
}
else
{
symbolLayer->setColor( color ); // line symbology layers
symbolLayer->setOutlineColor( color ); // marker and fill symbology layers
symbolLayer->setFillColor( mTemporaryFillColor ); // marker and fill symbology layers
symbolLayer->setFillColor( fillColor ); // marker and fill symbology layers

// Data defined widths overwrite what we set here (widths do not work with data defined)
QgsSimpleMarkerSymbolLayerV2 * simpleMarker = dynamic_cast<QgsSimpleMarkerSymbolLayerV2*>( symbolLayer );
Expand Down Expand Up @@ -214,9 +200,8 @@ double QgsHighlight::getSymbolWidth( const QgsRenderContext & context, double wi
{
scale = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, QgsSymbolV2::MM ) / QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, QgsSymbolV2::MapUnit );
}
return qMax( width + 2*mBuffer*scale, mMinWidth*scale );


width = qMax( width + 2 * mBuffer * scale, mMinWidth * scale );
return width;
}

/*!
Expand Down Expand Up @@ -364,7 +349,13 @@ void QgsHighlight::paint( QPainter* p )
QgsMapSettings mapSettings = mMapCanvas->mapSettings();
QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings );

QgsFeatureRendererV2 *renderer = getRenderer( context );
// Because lower level outlines must be covered by upper level fill color
// we render first with temporary opaque color, which is then replaced
// by final transparent fill color.
QColor tmpColor( 255, 0, 0, 255 );
QColor tmpFillColor( 0, 255, 0, 255 );

QgsFeatureRendererV2 *renderer = getRenderer( context, tmpColor, tmpFillColor );
if ( layer && renderer )
{
QgsRectangle extent = mMapCanvas->extent();
Expand All @@ -374,10 +365,6 @@ void QgsHighlight::paint( QPainter* p )
return; // it will be repainted after updateRect()
}

// Because lower level outlines must be covered by upper level fill color
// we render first with temporary opaque color, which is then replaced
// by final transparent fill color.
//QImage image = QImage(( int )width, ( int )height, QImage::Format_ARGB32 );
QSize imageSize( mMapCanvas->mapSettings().outputSize() );
QImage image = QImage( imageSize.width(), imageSize.height(), QImage::Format_ARGB32 );
image.fill( 0 );
Expand All @@ -392,20 +379,21 @@ void QgsHighlight::paint( QPainter* p )

imagePainter->end();

// overwrite temporary fill color
QRgb temporaryRgb = mTemporaryFillColor.rgba();
QColor color = QColor( mBrush.color() );
color.setAlpha( 63 );
QRgb colorRgb = color.rgba();

QColor color( mPen.color() ); // true output color
// coeficient to subtract alpha using green (temporary fill)
double k = ( 255. - mBrush.color().alpha() ) / 255.;
for ( int r = 0; r < image.height(); r++ )
{
QRgb *line = ( QRgb * ) image.scanLine( r );
for ( int c = 0; c < image.width(); c++ )
{
if ( line[c] == temporaryRgb )
QRgb rgba = image.pixel( c, r );
int alpha = qAlpha( rgba );
if ( alpha > 0 )
{
line[c] = colorRgb;
int green = qGreen( rgba );
color.setAlpha( alpha - ( green * k ) );

image.setPixel( c, r, color.rgba() );
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/gui/qgshighlight.h
Expand Up @@ -74,10 +74,10 @@ class GUI_EXPORT QgsHighlight: public QgsMapCanvasItem

private:
void init();
void setSymbol( QgsSymbolV2* symbol, const QgsRenderContext & context, const QColor & color );
void setSymbol( QgsSymbolV2* symbol, const QgsRenderContext & context, const QColor & color, const QColor & fillColor );
double getSymbolWidth( const QgsRenderContext & context, double width, QgsSymbolV2::OutputUnit unit );
/** Get renderer for current color mode and colors. The renderer should be freed by caller. */
QgsFeatureRendererV2 * getRenderer( const QgsRenderContext & context );
QgsFeatureRendererV2 * getRenderer( const QgsRenderContext & context, const QColor & color, const QColor & fillColor );
void paintPoint( QPainter *p, QgsPoint point );
void paintLine( QPainter *p, QgsPolyline line );
void paintPolygon( QPainter *p, QgsPolygon polygon );
Expand All @@ -91,7 +91,6 @@ class GUI_EXPORT QgsHighlight: public QgsMapCanvasItem
QgsGeometry *mGeometry;
QgsMapLayer *mLayer;
QgsFeature mFeature;
QColor mTemporaryFillColor;
double mBuffer; // line / outline buffer in pixels
double mMinWidth; // line / outline minimum width in pixels
};
Expand Down

0 comments on commit 776619f

Please sign in to comment.