From 776619fa3d48317e85d4133f41944f8cf0b8aa45 Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Tue, 25 Mar 2014 21:50:23 +0100 Subject: [PATCH] highlight fixes --- src/app/qgsidentifyresultsdialog.cpp | 4 +- src/app/qgsoptions.cpp | 8 ++-- src/gui/qgshighlight.cpp | 60 +++++++++++----------------- src/gui/qgshighlight.h | 5 +-- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp index fe660508b36b..5908ef0fbc89 100644 --- a/src/app/qgsidentifyresultsdialog.cpp +++ b/src/app/qgsidentifyresultsdialog.cpp @@ -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 ); diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index 6ed910d985d1..d59df4b647d0 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -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 @@ -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() ); diff --git a/src/gui/qgshighlight.cpp b/src/gui/qgshighlight.cpp index ada0b42630e0..e97a6ac15d11 100644 --- a/src/gui/qgshighlight.cpp +++ b/src/gui/qgshighlight.cpp @@ -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(); @@ -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-- ) { @@ -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( symbolLayer ); @@ -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; } /*! @@ -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(); @@ -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 ); @@ -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() ); } } } diff --git a/src/gui/qgshighlight.h b/src/gui/qgshighlight.h index 8759998faf08..37ff7e8adae7 100644 --- a/src/gui/qgshighlight.h +++ b/src/gui/qgshighlight.h @@ -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 ); @@ -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 };