Skip to content
Permalink
Browse files

Applied patch from #2640: improved rendering of selected features (sy…

…mbology-ng).

+ fixed font marker scaling for printing
Contributed by Chris Crook. Thanks!


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@13322 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder
wonder committed Apr 18, 2010
1 parent 9f3dcf4 commit e58f83762357bc986f67a86198a87dd196ca0e52
@@ -79,7 +79,7 @@ public:

virtual QgsSymbolV2List symbols()=0;

virtual void renderFeature(QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool drawVertexMarker = false );
virtual void renderFeature(QgsFeature& feature, QgsRenderContext& context, int layer = -1, bool selected = false, bool drawVertexMarker = false );

bool usingSymbolLevels() const;
void setUsingSymbolLevels(bool usingSymbolLevels);
@@ -453,7 +453,7 @@ class QgsSymbolV2RenderContext
%End

public:
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0 );
QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u , qreal alpha = 1.0, bool selected = false );
~QgsSymbolV2RenderContext();

QgsRenderContext& renderContext();
@@ -465,6 +465,11 @@ class QgsSymbolV2RenderContext
qreal alpha() const;
void setAlpha( qreal alpha );

bool selected() const;
void setSelected( bool selected ) const;

static QColor selectionColor();

double outputLineWidth(double width) const;
double outputPixelSize(double size) const;
};
@@ -574,7 +579,7 @@ public:
void setSize(double size);
double size();

void renderPoint(const QPointF& point, QgsRenderContext& context, int layer = -1);
void renderPoint(const QPointF& point, QgsRenderContext& context, int layer = -1, bool selected = false );

virtual QgsSymbolV2* clone() const /Factory/;
};
@@ -593,7 +598,7 @@ public:
void setWidth(double width);
double width();

void renderPolyline(const QPolygonF& points, QgsRenderContext& context, int layer = -1);
void renderPolyline(const QPolygonF& points, QgsRenderContext& context, int layer = -1, bool selected = false );

virtual QgsSymbolV2* clone() const /Factory/;
};
@@ -609,7 +614,7 @@ class QgsFillSymbolV2 : QgsSymbolV2
public:
QgsFillSymbolV2(QgsSymbolLayerV2List layers /Transfer/ = QgsSymbolLayerV2List());

void renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer = -1);
void renderPolygon(const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer = -1, bool selected = false );

virtual QgsSymbolV2* clone() const /Factory/;
};
@@ -705,15 +705,6 @@ void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool lab

mRendererV2->startRender( rendererContext, this );

QgsSingleSymbolRendererV2* selRenderer = NULL;
if ( !mSelectedFeatureIds.isEmpty() )
{
selRenderer = new QgsSingleSymbolRendererV2( QgsSymbolV2::defaultSymbol( geometryType() ) );
selRenderer->symbol()->setColor( QgsRenderer::selectionColor() );
selRenderer->setVertexMarkerAppearance( currentVertexMarkerType(), currentVertexMarkerSize() );
selRenderer->startRender( rendererContext, this );
}

#ifndef Q_WS_MAC
int totalFeatures = pendingFeatureCount();
int featureCount = 0;
@@ -747,10 +738,7 @@ void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool lab
bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) );

// render feature
if ( sel )
selRenderer->renderFeature( fet, rendererContext, -1, drawMarker );
else
mRendererV2->renderFeature( fet, rendererContext, -1, drawMarker );
mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker );

// labeling - register feature
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
@@ -771,8 +759,6 @@ void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool lab
++featureCount;
#endif //Q_WS_MAC
}

stopRendererV2( rendererContext, selRenderer );
}

void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling )
@@ -885,10 +871,7 @@ void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bo

try
{
if ( sel )
selRenderer->renderFeature( *fit, rendererContext, -1, drawMarker );
else
mRendererV2->renderFeature( *fit, rendererContext, layer, drawMarker );
mRendererV2->renderFeature( *fit, rendererContext, layer, sel, drawMarker );
}
catch ( const QgsCsException &cse )
{
@@ -47,6 +47,10 @@ void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
{
mColor.setAlphaF( context.alpha() );
mBrush = QBrush( mColor, mBrushStyle );
QColor selColor = context.selectionColor();
// selColor.setAlphaF( context.alpha() );
mSelBrush = QBrush( selColor );
if ( selectFillStyle ) mSelBrush.setStyle( mBrushStyle );
mBorderColor.setAlphaF( context.alpha() );
mPen = QPen( mBorderColor );
mPen.setStyle( mBorderStyle );
@@ -65,7 +69,7 @@ void QgsSimpleFillSymbolLayerV2::renderPolygon( const QPolygonF& points, QList<Q
return;
}

p->setBrush( mBrush );
p->setBrush( context.selected() ? mSelBrush : mBrush );
p->setPen( mPen );

_renderPolygon( p, points, rings );
@@ -209,18 +213,25 @@ void QgsSVGFillSymbolLayer::renderPolygon( const QPolygonF& points, QList<QPolyg
{
return;
}
p->setBrush( mBrush );
p->setPen( QPen( Qt::NoPen ) );
if ( context.selected() )
{
QColor selColor = context.selectionColor();
if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() );
p->setBrush( QBrush( selColor ) );
_renderPolygon( p, points, rings );
}
p->setBrush( mBrush );
_renderPolygon( p, points, rings );
if ( mOutline )
{
mOutline->renderPolyline( points, context.renderContext() );
mOutline->renderPolyline( points, context.renderContext(), -1, selectFillBorder && context.selected() );
if ( rings )
{
QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
for ( ; ringIt != rings->constEnd(); ++ringIt )
{
mOutline->renderPolyline( *ringIt, context.renderContext() );
mOutline->renderPolyline( *ringIt, context.renderContext(), -1, selectFillBorder && context.selected() );
}
}
}
@@ -54,6 +54,7 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2

protected:
QBrush mBrush;
QBrush mSelBrush;
Qt::BrushStyle mBrushStyle;
QColor mBorderColor;
Qt::PenStyle mBorderStyle;
@@ -83,6 +83,11 @@ void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
}
mPen.setJoinStyle( mPenJoinStyle );
mPen.setCapStyle( mPenCapStyle );

mSelPen = mPen;
QColor selColor = context.selectionColor();
if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() );
mSelPen.setColor( selColor );
}

void QgsSimpleLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -97,7 +102,7 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
return;
}

p->setPen( mPen );
p->setPen( context.selected() ? mSelPen : mPen );
if ( mOffset == 0 )
{
p->drawPolyline( points );
@@ -309,7 +314,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineNoOffset( const QPolygonF& points
// draw first marker
if ( first )
{
mMarker->renderPoint( lastPt, rc );
mMarker->renderPoint( lastPt, rc, -1, context.selected() );
first = false;
}

@@ -319,7 +324,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineNoOffset( const QPolygonF& points
// "c" is 1 for regular point or in interval (0,1] for begin of line segment
lastPt += c * diff;
lengthLeft -= painterUnitInterval;
mMarker->renderPoint( lastPt, rc );
mMarker->renderPoint( lastPt, rc, -1, context.selected() );
c = 1; // reset c (if wasn't 1 already)
}

@@ -401,6 +406,9 @@ void QgsLineDecorationSymbolLayerV2::startRender( QgsSymbolV2RenderContext& cont
QColor penColor = mColor;
penColor.setAlphaF( context.alpha() );
mPen.setColor( penColor );
QColor selColor = context.selectionColor();
if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() );
mSelPen.setColor( selColor );
}

void QgsLineDecorationSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -442,7 +450,7 @@ void QgsLineDecorationSymbolLayerV2::renderPolyline( const QPolygonF& points, Qg
QPointF p2_1 = p2 - QPointF( size * cos( angle1 ), size * sin( angle1 ) );
QPointF p2_2 = p2 - QPointF( size * cos( angle2 ), size * sin( angle2 ) );

p->setPen( mPen );
p->setPen( context.selected() ? mSelPen : mPen );
p->drawLine( p2, p2_1 );
p->drawLine( p2, p2_2 );
}
@@ -64,6 +64,7 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
Qt::PenJoinStyle mPenJoinStyle;
Qt::PenCapStyle mPenCapStyle;
QPen mPen;
QPen mSelPen;
double mOffset;
//use a custom dash dot pattern instead of the predefined ones
bool mUseCustomDashPattern;
@@ -159,6 +160,7 @@ class CORE_EXPORT QgsLineDecorationSymbolLayerV2 : public QgsLineSymbolLayerV2

protected:
QPen mPen;
QPen mSelPen;

};

@@ -68,6 +68,10 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
mBrush = QBrush( mColor );
mPen = QPen( mBorderColor );
mPen.setWidthF( context.outputLineWidth( mPen.widthF() ) );
QColor selColor = context.selectionColor();
mSelBrush = QBrush( selColor );
mSelPen = QPen( selColor == mColor ? selColor : mBorderColor );
mSelPen.setWidthF( mPen.widthF() );

mPolygon.clear();

@@ -148,6 +152,9 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
else
{
// some markers can't be drawn as a polygon (circle, cross)
// For these set the selected border color to the selected color

if ( mName != "circle" ) mSelPen.setColor( selColor );
}

// rotate if needed
@@ -176,10 +183,40 @@ void QgsSimpleMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& contex
drawMarker( &p, context );
p.end();

// Construct the selected version of the Cache

mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
mSelCache.fill( 0 );

p.begin( &mSelCache );
p.setRenderHint( QPainter::Antialiasing );
p.setBrush( mSelBrush );
p.setPen( mSelPen );
p.translate( QPointF( center, center ) );
drawMarker( &p, context );
p.end();

// Check that the selected version is different. If not, then re-render,
// filling the background with the selection colour and using the normal
// colours for the symbol .. could be ugly!

if ( mSelCache == mCache )
{
p.begin( &mSelCache );
p.setRenderHint( QPainter::Antialiasing );
p.fillRect( 0, 0, imageSize, imageSize, selColor );
p.setBrush( mBrush );
p.setPen( mPen );
p.translate( QPointF( center, center ) );
drawMarker( &p, context );
p.end();
}

//opacity
if ( context.alpha() < 1.0 )
{
QgsSymbolLayerV2Utils::multiplyImageOpacity( &mCache, context.alpha() );
if ( ! selectionIsOpaque ) QgsSymbolLayerV2Utils::multiplyImageOpacity( &mSelCache, context.alpha() );
}
}

@@ -203,11 +240,12 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
//p->translate(point);

//drawMarker(p);
//mCache.save("/home/marco/tmp/marker.png", "PNG");
double s = mCache.width() / context.renderContext().rasterScaleFactor();
//mCache.save("/home/marco/tmp/marker.png","PNG");
QImage &img = context.selected() ? mSelCache : mCache;
double s = img.width() / context.renderContext().rasterScaleFactor();
p->drawImage( QRectF( point.x() - s / 2.0 + context.outputLineWidth( mOffset.x() ),
point.y() - s / 2.0 + context.outputLineWidth( mOffset.y() ),
s, s ), mCache );
s, s ), img );
//p->restore();
}

@@ -328,6 +366,13 @@ void QgsSvgMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
QSvgRenderer renderer( mPath );
QPainter painter( &mPicture );
renderer.render( &painter, rect );
double selPictureSize = pictureSize * 1.2;
QPainter selPainter( &mSelPicture );
selPainter.setRenderHint( QPainter::Antialiasing );
selPainter.setBrush( QBrush( context.selectionColor() ) );
selPainter.setPen( Qt::NoPen );
selPainter.drawEllipse( QPointF( 0, 0 ), pictureSize*0.6, pictureSize*0.6 );
renderer.render( &selPainter, rect );
}

void QgsSvgMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -350,7 +395,8 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
if ( mAngle != 0 )
p->rotate( mAngle );

p->drawPicture( 0, 0, mPicture );
QPicture &pct = context.selected() ? mSelPicture : mPicture;
p->drawPicture( 0, 0, pct );

if ( mAngle != 0 )
p->rotate( -mAngle );
@@ -515,7 +561,7 @@ QString QgsFontMarkerSymbolLayerV2::layerType() const

void QgsFontMarkerSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
{
mFont = QFont( mFontFamily, MM2POINT( mSize ) );
mFont = QFont( mFontFamily, MM2POINT( mSize ) / context.renderContext().rasterScaleFactor() );
QFontMetrics fm( mFont );
mChrOffset = QPointF( fm.width( mChr ) / 2, -fm.ascent() / 2 );

@@ -529,7 +575,7 @@ void QgsFontMarkerSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
void QgsFontMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
{
QPainter* p = context.renderContext().painter();
QColor penColor = mColor;
QColor penColor = context.selected() ? context.selectionColor() : mColor;
penColor.setAlphaF( context.alpha() );
p->setPen( penColor );
p->setFont( mFont );
@@ -59,6 +59,9 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QPolygonF mPolygon;
QString mName;
QImage mCache;
QPen mSelPen;
QBrush mSelBrush;
QImage mSelCache;
};

//////////
@@ -110,6 +113,7 @@ class CORE_EXPORT QgsSvgMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2

QString mPath;
QPicture mPicture;
QPicture mSelPicture;
};


0 comments on commit e58f837

Please sign in to comment.
You can’t perform that action at this time.