Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[FEATURE] Allow the line symbol layers to be used for outline of poly…
…gon (fill) symbols

git-svn-id: http://svn.osgeo.org/qgis/trunk@14855 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Dec 6, 2010
1 parent 8af3dd1 commit 7e5d546
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 8 deletions.
3 changes: 3 additions & 0 deletions python/core/symbology-ng-core.sip
Expand Up @@ -565,6 +565,9 @@ class QgsLineSymbolLayerV2 : QgsSymbolLayerV2
public:
virtual void renderPolyline(const QPolygonF& points, QgsSymbolV2RenderContext& context) = 0;

//! @note added in v1.7
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );

void setWidth(double width);
double width() const;

Expand Down
11 changes: 11 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.cpp
Expand Up @@ -45,6 +45,17 @@ void QgsLineSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, Q
stopRender( context );
}

void QgsLineSymbolLayerV2::renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
{
renderPolyline( points, context );
if ( rings )
{
foreach( const QPolygonF& ring, *rings )
renderPolyline( ring, context );
}
}


void QgsFillSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size )
{
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
Expand Down
3 changes: 3 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.h
Expand Up @@ -99,6 +99,9 @@ class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2
public:
virtual void renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context ) = 0;

//! @note added in v1.7
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );

virtual void setWidth( double width ) { mWidth = width; }
virtual double width() const { return mWidth; }

Expand Down
53 changes: 45 additions & 8 deletions src/core/symbology-ng/qgssymbolv2.cpp
Expand Up @@ -28,7 +28,7 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
{
mLayers.removeAt( i-- );
}
else if ( mLayers[i]->type() != mType )
else if ( !isSymbolLayerCompatible( mLayers[i]->type() ) )
{
delete mLayers[i];
mLayers.removeAt( i-- );
Expand Down Expand Up @@ -69,12 +69,21 @@ QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
}


bool QgsSymbolV2::isSymbolLayerCompatible( SymbolType t )
{
// fill symbol can contain also line symbol layers for drawing of outlines
if ( mType == Fill && t == Line )
return true;

return mType == t;
}


bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
{
if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
return false;
if ( layer == NULL || layer->type() != mType )
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
return false;

mLayers.insert( index, layer );
Expand All @@ -84,7 +93,7 @@ bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )

bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
{
if ( layer == NULL || layer->type() != mType )
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
return false;

mLayers.append( layer );
Expand Down Expand Up @@ -116,7 +125,7 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
{
if ( index < 0 || index >= mLayers.count() )
return false;
if ( layer == NULL || layer->type() != mType )
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
return false;

delete mLayers[index]; // first delete the original layer
Expand Down Expand Up @@ -165,7 +174,20 @@ void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
{
( *it )->drawPreviewIcon( symbolContext, size );
if ( mType == Fill && ( *it )->type() == Line )
{
// line symbol layer would normally draw just a line
// so we override this case to force it to draw a polygon outline
QgsLineSymbolLayerV2* lsl = ( QgsLineSymbolLayerV2* ) * it;

// from QgsFillSymbolLayerV2::drawPreviewIcon()
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
lsl->startRender( symbolContext );
lsl->renderPolygonOutline( poly, NULL, symbolContext );
lsl->stopRender( symbolContext );
}
else
( *it )->drawPreviewIcon( symbolContext, size );
}
}

Expand Down Expand Up @@ -456,14 +478,29 @@ void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>*
if ( layer != -1 )
{
if ( layer >= 0 && layer < mLayers.count() )
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
{
QgsSymbolV2::SymbolType layertype = mLayers.at( layer )->type();
if ( layertype == QgsSymbolV2::Fill )
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
else if ( layertype == QgsSymbolV2::Line )
(( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolygonOutline( points, rings, symbolContext );
}
return;
}

for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
{
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
layer->renderPolygon( points, rings, symbolContext );
QgsSymbolV2::SymbolType layertype = ( *it )->type();
if ( layertype == QgsSymbolV2::Fill )
{
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
layer->renderPolygon( points, rings, symbolContext );
}
else if ( layertype == QgsSymbolV2::Line )
{
QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
layer->renderPolygonOutline( points, rings, symbolContext );
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/core/symbology-ng/qgssymbolv2.h
Expand Up @@ -101,6 +101,11 @@ class CORE_EXPORT QgsSymbolV2

QgsSymbolLayerV2List cloneLayers() const;

//! check whether a symbol layer type can be used within the symbol
//! (marker-marker, line-line, fill-fill/line)
//! @note added in 1.7
bool isSymbolLayerCompatible( SymbolType t );

SymbolType mType;
QgsSymbolLayerV2List mLayers;

Expand Down
15 changes: 15 additions & 0 deletions src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp
Expand Up @@ -164,6 +164,17 @@ void QgsSymbolV2PropertiesDialog::populateLayerTypes()
cboLayerType->clear();
for ( int i = 0; i < types.count(); i++ )
cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( types[i] )->visibleName(), types[i] );

if ( mSymbol->type() == QgsSymbolV2::Fill )
{
QStringList typesLine = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( QgsSymbolV2::Line );
for ( int i = 0; i < typesLine.count(); i++ )
{
QString visibleName = QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( typesLine[i] )->visibleName();
QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
cboLayerType->addItem( name, typesLine[i] );
}
}
}


Expand Down Expand Up @@ -223,6 +234,10 @@ void QgsSymbolV2PropertiesDialog::loadPropertyWidgets()

QStringList layerTypes = pReg->symbolLayersForType( mSymbol->type() );

// also load line symbol layers for fill symbols
if ( mSymbol->type() == QgsSymbolV2::Fill )
layerTypes += pReg->symbolLayersForType( QgsSymbolV2::Line );

for ( int i = 0; i < layerTypes.count(); i++ )
{
QString layerType = layerTypes[i];
Expand Down

0 comments on commit 7e5d546

Please sign in to comment.