Skip to content

Commit

Permalink
Add methods for retrieving extra parameters from symbol render
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Sep 8, 2015
1 parent b8ad58c commit fe9461b
Show file tree
Hide file tree
Showing 11 changed files with 231 additions and 7 deletions.
19 changes: 19 additions & 0 deletions python/core/symbology-ng/qgsrendererv2.sip
Expand Up @@ -263,6 +263,15 @@ class QgsFeatureRendererV2
*/
void setForceRasterRender( bool forceRaster );

/** Returns the result of the feature rendering operation. This should only be
* called immediately after a rendering operation (eg calling renderFeature).
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 renderFeature
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderFeature return a QgsRenderResult
const QgsRenderResult& renderResult() const;

protected:
QgsFeatureRendererV2( QString type );

Expand Down Expand Up @@ -291,6 +300,16 @@ class QgsFeatureRendererV2
*/
void copyPaintEffect( QgsFeatureRendererV2 *destRenderer ) const;

/** Sets the result of the symbol rendering operation. Subclasses should call
* this method after rendering a feature and update the render result to reflect
* to actual result of the feature render.
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the renderFeature method
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
void setRenderResult( const QgsRenderResult& result );

private:
QgsFeatureRendererV2( const QgsFeatureRendererV2 & );
QgsFeatureRendererV2 & operator=( const QgsFeatureRendererV2 & );
Expand Down
19 changes: 19 additions & 0 deletions python/core/symbology-ng/qgssymbollayerv2.sip
Expand Up @@ -260,6 +260,15 @@ class QgsSymbolLayerV2
*/
void setPaintEffect( QgsPaintEffect* effect /Transfer/);

/** Returns the result of the symbol rendering operation. This should only be
* called immediately after a rendering operation (eg calling renderPoint).
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the render methods
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
const QgsRenderResult& renderResult() const;

protected:
QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false );

Expand Down Expand Up @@ -306,6 +315,16 @@ class QgsSymbolLayerV2
*/
void copyPaintEffect( QgsSymbolLayerV2* destLayer ) const;

/** Sets the result of the symbol rendering operation. Subclasses should call
* this method after rendering a symbol and update the render result to reflect
* to actual result of the symbol render.
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the render methods
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
void setRenderResult( const QgsRenderResult& result );

};

//////////////////////
Expand Down
42 changes: 42 additions & 0 deletions python/core/symbology-ng/qgssymbolv2.sip
@@ -1,6 +1,39 @@

typedef QList<QgsSymbolLayerV2*> QgsSymbolLayerV2List;

/** \ingroup core
* \class QgsRenderResult
* \brief A simple container for the results of a rendering operation
* \note Added in version 2.12
*/

class QgsRenderResult
{
%TypeHeaderCode
#include <qgssymbolv2.h>
%End
public:

/** Constructor for QgsRenderResult
* @param symbolRendered initial value for symbolRendered member
*/
QgsRenderResult( bool symbolRendered );

/** Bounds of rendered symbol shape.
* @note only implemented for marker symbol types
*/
QRectF symbolBounds;

//! True if a symbol was rendered during the render operation
bool symbolRendered;

/** Unites the render result with another QgsRenderResult object
* @param other other render result
*/
void unite( const QgsRenderResult& other );
};


class QgsSymbolV2
{
%TypeHeaderCode
Expand Down Expand Up @@ -163,6 +196,15 @@ class QgsSymbolV2
void setLayer( const QgsVectorLayer* layer );
const QgsVectorLayer* layer() const;

/** Returns the result of the symbol rendering operation. This should only be
* called immediately after a rendering operation (eg calling renderPoint).
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the render methods
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
const QgsRenderResult& renderResult() const;

protected:
QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers /Transfer/ ); // can't be instantiated

Expand Down
27 changes: 22 additions & 5 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Expand Up @@ -541,15 +541,18 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
}
}

QgsRenderResult result( true );
if ( mUsingCache )
{
//QgsDebugMsg( QString("XXX using cache") );
// we will use cached image
QImage &img = context.selected() ? mSelCache : mCache;
double s = img.width() / context.renderContext().rasterScaleFactor();
p->drawImage( QRectF( point.x() - s / 2.0 + off.x(),
point.y() - s / 2.0 + off.y(),
s, s ), img );
QRectF imgRect( point.x() - s / 2.0 + off.x(),
point.y() - s / 2.0 + off.y(),
s, s );
p->drawImage( imgRect, img );
result.symbolBounds = imgRect;
}
else
{
Expand Down Expand Up @@ -606,11 +609,25 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
p->setBrush( context.selected() ? mSelBrush : mBrush );
p->setPen( context.selected() ? mSelPen : mPen );

QRectF boundingRect;
if ( !mPolygon.isEmpty() )
p->drawPolygon( transform.map( mPolygon ) );
{
QPolygonF transformed = transform.map( mPolygon );
boundingRect = transformed.boundingRect();
p->drawPolygon( transformed );

}
else
p->drawPath( transform.map( mPath ) );
{
QPainterPath transformed = transform.map( mPath );
boundingRect = transformed.boundingRect();
p->drawPath( transformed );
}
//adjust bounding rect for pen width
result.symbolBounds = boundingRect.adjusted( -mPen.widthF() / 2.0, -mPen.widthF() / 2.0,
mPen.widthF() / 2.0, mPen.widthF() / 2.0 );
}
setRenderResult( result );
}


Expand Down
10 changes: 10 additions & 0 deletions src/core/symbology-ng/qgsrendererv2.cpp
Expand Up @@ -218,6 +218,7 @@ QgsFeatureRendererV2::QgsFeatureRendererV2( QString type )
, mCurrentVertexMarkerSize( 3 )
, mPaintEffect( 0 )
, mForceRaster( false )
, mRenderResult( QgsRenderResult( true ) )
{
mPaintEffect = QgsPaintEffectRegistry::defaultStack();
mPaintEffect->setEnabled( false );
Expand Down Expand Up @@ -270,9 +271,13 @@ bool QgsFeatureRendererV2::renderFeature( QgsFeature& feature, QgsRenderContext&
{
QgsSymbolV2* symbol = symbolForFeature( feature, context );
if ( symbol == NULL )
{
setRenderResult( QgsRenderResult( false ) );
return false;
}

renderFeatureWithSymbol( feature, symbol, context, layer, selected, drawVertexMarker );
setRenderResult( symbol->renderResult() );
return true;
}

Expand Down Expand Up @@ -810,3 +815,8 @@ void QgsFeatureRendererV2::convertSymbolRotation( QgsSymbolV2 * symbol, const QS
s->setDataDefinedAngle( dd );
}
}

void QgsFeatureRendererV2::setRenderResult( const QgsRenderResult& result )
{
mRenderResult = result;
}
21 changes: 21 additions & 0 deletions src/core/symbology-ng/qgsrendererv2.h
Expand Up @@ -311,6 +311,15 @@ class CORE_EXPORT QgsFeatureRendererV2
*/
void setForceRasterRender( bool forceRaster ) { mForceRaster = forceRaster; }

/** Returns the result of the feature rendering operation. This should only be
* called immediately after a rendering operation (eg calling renderFeature).
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 renderFeature
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderFeature return a QgsRenderResult
const QgsRenderResult& renderResult() const { return mRenderResult; }

protected:
QgsFeatureRendererV2( QString type );

Expand Down Expand Up @@ -361,8 +370,20 @@ class CORE_EXPORT QgsFeatureRendererV2
*/
static void convertSymbolRotation( QgsSymbolV2 * symbol, const QString & field );

/** Sets the result of the symbol rendering operation. Subclasses should call
* this method after rendering a feature and update the render result to reflect
* to actual result of the feature render.
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the renderFeature method
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
void setRenderResult( const QgsRenderResult& result );

private:
Q_DISABLE_COPY( QgsFeatureRendererV2 )

QgsRenderResult mRenderResult;
};

// for some reason SIP compilation fails if these lines are not included:
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgsrulebasedrendererv2.cpp
Expand Up @@ -815,6 +815,8 @@ bool QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
{
Q_UNUSED( layer );

setRenderResult( QgsRenderResult( false ) );

int flags = ( selected ? FeatIsSelected : 0 ) | ( drawVertexMarker ? FeatDrawMarkers : 0 );
mCurrentFeatures.append( FeatureToRender( feature, flags ) );

Expand Down Expand Up @@ -873,6 +875,10 @@ void QgsRuleBasedRendererV2::stopRender( QgsRenderContext& context )
{
int flags = job->ftr.flags;
renderFeatureWithSymbol( job->ftr.feat, job->symbol, context, i, flags & FeatIsSelected, flags & FeatDrawMarkers );

QgsRenderResult newRenderResult = job->symbol->renderResult();
newRenderResult.unite( renderResult() );
setRenderResult( newRenderResult );
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.cpp
Expand Up @@ -334,6 +334,7 @@ QgsSymbolLayerV2::QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked )
, mLocked( locked )
, mRenderingPass( 0 )
, mPaintEffect( 0 )
, mRenderResult( QgsRenderResult( true ) )
{
mPaintEffect = QgsPaintEffectRegistry::defaultStack();
mPaintEffect->setEnabled( false );
Expand Down Expand Up @@ -482,6 +483,11 @@ void QgsSymbolLayerV2::copyPaintEffect( QgsSymbolLayerV2 *destLayer ) const
destLayer->setPaintEffect( mPaintEffect->clone() );
}

void QgsSymbolLayerV2::setRenderResult( const QgsRenderResult& result )
{
mRenderResult = result;
}

QgsMarkerSymbolLayerV2::QgsMarkerSymbolLayerV2( bool locked )
: QgsSymbolLayerV2( QgsSymbolV2::Marker, locked )
, mAngle( 0 )
Expand Down
23 changes: 23 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.h
Expand Up @@ -247,6 +247,15 @@ class CORE_EXPORT QgsSymbolLayerV2
*/
void setPaintEffect( QgsPaintEffect* effect );

/** Returns the result of the symbol rendering operation. This should only be
* called immediately after a rendering operation (eg calling renderPoint).
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the render methods
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
const QgsRenderResult& renderResult() const { return mRenderResult; }

protected:
QgsSymbolLayerV2( QgsSymbolV2::SymbolType type, bool locked = false );

Expand Down Expand Up @@ -307,6 +316,16 @@ class CORE_EXPORT QgsSymbolLayerV2
*/
void copyPaintEffect( QgsSymbolLayerV2* destLayer ) const;

/** Sets the result of the symbol rendering operation. Subclasses should call
* this method after rendering a symbol and update the render result to reflect
* to actual result of the symbol render.
* @note added in QGIS 2.12
* @note this is a temporary method until QGIS 3.0. For QGIS 3.0 the render methods
* will return a QgsRenderResult object
*/
// TODO - QGIS 3.0. Remove and make renderPoint, etc return a QgsRenderResult
void setRenderResult( const QgsRenderResult& result );

static const QString EXPR_SIZE;
static const QString EXPR_ANGLE;
static const QString EXPR_NAME;
Expand Down Expand Up @@ -365,6 +384,10 @@ class CORE_EXPORT QgsSymbolLayerV2
static const QString EXPR_OFFSET_ALONG_LINE;
static const QString EXPR_HORIZONTAL_ANCHOR_POINT;
static const QString EXPR_VERTICAL_ANCHOR_POINT;

private:

QgsRenderResult mRenderResult;
};

//////////////////////
Expand Down
10 changes: 10 additions & 0 deletions src/core/symbology-ng/qgssymbolv2.cpp
Expand Up @@ -81,6 +81,7 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
, mRenderHints( 0 )
, mClipFeaturesToExtent( true )
, mLayer( 0 )
, mRenderResult( QgsRenderResult( true ) )
{

// check they're all correct symbol layers
Expand Down Expand Up @@ -831,6 +832,8 @@ void QgsMarkerSymbolV2::renderPointUsingLayer( QgsMarkerSymbolLayerV2* layer, co
{
layer->renderPoint( point, context );
}

mRenderResult = layer->renderResult();
}

void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
Expand All @@ -846,10 +849,13 @@ void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f,
return;
}

QgsRenderResult combinedResult( false );
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
{
renderPointUsingLayer(( QgsMarkerSymbolLayerV2* ) * it, point, symbolContext );
combinedResult.unite(( *it )->renderResult() );
}
mRenderResult = combinedResult;
}

QgsSymbolV2* QgsMarkerSymbolV2::clone() const
Expand Down Expand Up @@ -1032,6 +1038,8 @@ void QgsLineSymbolV2::renderPolylineUsingLayer( QgsLineSymbolLayerV2 *layer, con
{
layer->renderPolyline( points, context );
}

mRenderResult = layer->renderResult();
}


Expand Down Expand Up @@ -1112,6 +1120,8 @@ void QgsFillSymbolV2::renderPolygonUsingLayer( QgsSymbolLayerV2* layer, const QP
(( QgsLineSymbolLayerV2* )layer )->renderPolygonOutline( points, rings, context );
}
}

mRenderResult = layer->renderResult();
}

QRectF QgsFillSymbolV2::polygonBounds( const QPolygonF& points, const QList<QPolygonF>* rings ) const
Expand Down

0 comments on commit fe9461b

Please sign in to comment.