14
14
***************************************************************************/
15
15
16
16
#include < typeinfo>
17
+
18
+ #include < QImage>
19
+
17
20
#include " qgsmarkersymbollayerv2.h"
18
21
#include " qgslinesymbollayerv2.h"
19
22
@@ -120,7 +123,20 @@ void QgsHighlight::setSymbolColor( QgsSymbolV2* symbol, const QColor & color )
120
123
{
121
124
if ( !symbol ) return ;
122
125
123
- QColor fillColor ( color.red (), color.green (), color.blue (), 63 );
126
+ // Temporary fill color must be similar to outline color (antialiasing between
127
+ // outline and temporary fill) but also different enough to be distinguishable
128
+ // so that it can be replaced by transparent fill.
129
+ // Unfortunately the result of the transparent fill rendered over the original
130
+ // (not highlighted) feature color may be either lighter or darker.
131
+ if ( color.lightness () < 200 )
132
+ {
133
+ mTemporaryFillColor = color.lighter ( 120 );
134
+ }
135
+ else
136
+ {
137
+ mTemporaryFillColor = color.darker ( 120 );
138
+ }
139
+ mTemporaryFillColor .setAlpha ( 255 );
124
140
125
141
for ( int i = symbol->symbolLayerCount () - 1 ; i >= 0 ; i-- )
126
142
{
@@ -133,14 +149,9 @@ void QgsHighlight::setSymbolColor( QgsSymbolV2* symbol, const QColor & color )
133
149
}
134
150
else
135
151
{
136
- // We must insert additional highlight symbol layer above each original layer
137
- // otherwise lower layers would become visible through transparent fill color.
138
- QgsSymbolLayerV2* highlightLayer = symbolLayer->clone ();
139
-
140
- highlightLayer->setColor ( color ); // line symbology layers
141
- highlightLayer->setOutlineColor ( color ); // marker and fill symbology layers
142
- highlightLayer->setFillColor ( fillColor ); // marker and fill symbology layers
143
- symbol->insertSymbolLayer ( i + 1 , highlightLayer );
152
+ symbolLayer->setColor ( color ); // line symbology layers
153
+ symbolLayer->setOutlineColor ( color ); // marker and fill symbology layers
154
+ symbolLayer->setFillColor ( mTemporaryFillColor ); // marker and fill symbology layers
144
155
}
145
156
}
146
157
}
@@ -300,17 +311,54 @@ void QgsHighlight::paint( QPainter* p )
300
311
updateRect ();
301
312
return ; // it will be repainted after updateRect()
302
313
}
303
- double height = toCanvasCoordinates ( QgsPoint ( extent.xMinimum (), extent.yMinimum () ) ).y () - toCanvasCoordinates ( QgsPoint ( extent.xMinimum (), extent.yMaximum () ) ).y ();
314
+
315
+
316
+ QPointF ll = toCanvasCoordinates ( QgsPoint ( extent.xMinimum (), extent.yMinimum () ) );
317
+ QPointF ur = toCanvasCoordinates ( QgsPoint ( extent.xMaximum (), extent.yMaximum () ) );
318
+ double height = ll.y () - ur.y ();
319
+ double width = ur.x () - ll.x ();
320
+
321
+ // Because lower level outlines must be covered by upper level fill color
322
+ // we render first with temporary opaque color, which is then replaced
323
+ // by final transparent fill color.
324
+ QImage image = QImage (( int )width, ( int )height, QImage::Format_ARGB32 );
325
+ image.fill ( 0 );
326
+ QPainter *imagePainter = new QPainter ( &image );
327
+ imagePainter->setRenderHint ( QPainter::Antialiasing, true );
304
328
305
329
QgsMapToPixel mapToPixel = QgsMapToPixel ( mMapCanvas ->mapUnitsPerPixel (),
306
330
height, extent.yMinimum (), extent.xMinimum () );
307
331
context.setMapToPixel ( mapToPixel );
308
332
context.setExtent ( extent );
309
333
context.setCoordinateTransform ( 0 ); // we reprojected geometry in init()
310
- context.setPainter ( p );
334
+ context.setPainter ( imagePainter );
335
+
311
336
mRenderer ->startRender ( context, layer );
312
337
mRenderer ->renderFeature ( mFeature , context );
313
338
mRenderer ->stopRender ( context );
339
+
340
+ imagePainter->end ();
341
+
342
+ QRgb temporaryRgb = mTemporaryFillColor .rgba ();
343
+ QColor color = QColor ( mBrush .color () );
344
+ color.setAlpha ( 63 );
345
+ QRgb colorRgb = color.rgba ();
346
+
347
+ for ( int r = 0 ; r < image.height (); r++ )
348
+ {
349
+ QRgb *line = ( QRgb * ) image.scanLine ( r );
350
+ for ( int c = 0 ; c < image.width (); c++ )
351
+ {
352
+ if ( line[c] == temporaryRgb )
353
+ {
354
+ line[c] = colorRgb;
355
+ }
356
+ }
357
+ }
358
+
359
+ p->drawImage ( 0 , 0 , image );
360
+
361
+ delete imagePainter;
314
362
}
315
363
}
316
364
}
0 commit comments