2
#include "qgssymbolv2.h"
3
#include "qgssymbollayerv2.h"
5
#include "qgslinesymbollayerv2.h"
6
#include "qgsmarkersymbollayerv2.h"
7
#include "qgsfillsymbollayerv2.h"
10
#include "qgsrendercontext.h" // for bigSymbolPreview
19
QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
20
: mType( type ), mLayers( layers )
23
// check they're all correct symbol layers
24
for ( int i = 0; i < mLayers.count(); i++ )
26
if ( mLayers[i] == NULL )
28
mLayers.removeAt( i-- );
30
else if ( mLayers[i]->type() != mType )
33
mLayers.removeAt( i-- );
39
QgsSymbolV2::~QgsSymbolV2()
41
// delete all symbol layers (we own them, so it's okay)
42
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
46
QgsSymbolV2* QgsSymbolV2::defaultSymbol( QGis::GeometryType geomType )
51
case QGis::Point: s = new QgsMarkerSymbolV2(); break;
52
case QGis::Line: s = new QgsLineSymbolV2(); break;
53
case QGis::Polygon: s = new QgsFillSymbolV2(); break;
54
default: QgsDebugMsg( "unknown layer's geometry type" ); return NULL;
57
s->setColor( QColor::fromHsv( rand() % 360, 64 + rand() % 192, 128 + rand() % 128 ) );
62
QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
64
if ( layer < 0 || layer >= mLayers.count() )
67
return mLayers[layer];
72
bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
74
if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
76
if ( layer == NULL || layer->type() != mType )
79
mLayers.insert( index, layer );
84
bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
86
if ( layer == NULL || layer->type() != mType )
89
mLayers.append( layer );
94
bool QgsSymbolV2::deleteSymbolLayer( int index )
96
if ( index < 0 || index >= mLayers.count() )
99
delete mLayers[index];
100
mLayers.removeAt( index );
105
QgsSymbolLayerV2* QgsSymbolV2::takeSymbolLayer( int index )
107
if ( index < 0 || index >= mLayers.count() )
110
return mLayers.takeAt( index );
114
bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
116
if ( index < 0 || index >= mLayers.count() )
118
if ( layer == NULL || layer->type() != mType )
121
delete mLayers[index]; // first delete the original layer
122
mLayers[index] = layer; // set new layer
127
void QgsSymbolV2::startRender( QgsRenderContext& context )
129
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
130
( *it )->startRender( context );
133
void QgsSymbolV2::stopRender( QgsRenderContext& context )
135
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
136
( *it )->stopRender( context );
139
void QgsSymbolV2::setColor( const QColor& color )
141
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
143
if ( !( *it )->isLocked() )
144
( *it )->setColor( color );
148
QColor QgsSymbolV2::color()
150
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
152
// return color of the first unlocked layer
153
if ( !( *it )->isLocked() )
154
return ( *it )->color();
156
return QColor( 0, 0, 0 );
159
void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
161
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
163
( *it )->drawPreviewIcon( painter, size );
168
QImage QgsSymbolV2::bigSymbolPreviewImage()
170
QImage preview( QSize( 100, 100 ), QImage::Format_ARGB32_Premultiplied );
173
QPainter p( &preview );
174
p.setRenderHint( QPainter::Antialiasing );
175
p.translate( 0.5, 0.5 ); // shift by half a pixel to avoid blurring due antialising
177
if ( mType == QgsSymbolV2::Marker )
179
p.setPen( QPen( QColor( 230, 230, 230 ) ) );
180
p.drawLine( 0, 50, 100, 50 );
181
p.drawLine( 50, 0, 50, 100 );
184
QgsRenderContext context;
185
context.setPainter( &p );
187
startRender( context );
189
if ( mType == QgsSymbolV2::Line )
192
poly << QPointF( 0, 50 ) << QPointF( 99, 50 );
193
static_cast<QgsLineSymbolV2*>( this )->renderPolyline( poly, context );
195
else if ( mType == QgsSymbolV2::Fill )
198
polygon << QPointF( 20, 20 ) << QPointF( 80, 20 ) << QPointF( 80, 80 ) << QPointF( 20, 80 ) << QPointF( 20, 20 );
199
static_cast<QgsFillSymbolV2*>( this )->renderPolygon( polygon, NULL, context );
203
static_cast<QgsMarkerSymbolV2*>( this )->renderPoint( QPointF( 50, 50 ), context );
206
stopRender( context );
211
QString QgsSymbolV2::dump()
216
case QgsSymbolV2::Marker: t = "MARKER"; break;
217
case QgsSymbolV2::Line: t = "LINE"; break;
218
case QgsSymbolV2::Fill: t = "FILL"; break;
219
default: Q_ASSERT( 0 && "unknown symbol type" );
221
QString s = QString( "%1 SYMBOL (%2 layers) color %3" ).arg( t ).arg( mLayers.count() ).arg( QgsSymbolLayerV2Utils::encodeColor( color() ) );
223
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
230
QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
232
QgsSymbolLayerV2List lst;
233
for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
235
QgsSymbolLayerV2* layer = ( *it )->clone();
236
layer->setLocked(( *it )->isLocked() );
237
layer->setRenderingPass(( *it )->renderingPass() );
247
QgsMarkerSymbolV2::QgsMarkerSymbolV2( QgsSymbolLayerV2List layers )
248
: QgsSymbolV2( Marker, layers )
250
if ( mLayers.count() == 0 )
251
mLayers.append( new QgsSimpleMarkerSymbolLayerV2() );
254
void QgsMarkerSymbolV2::setAngle( double angle )
256
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
258
QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
259
layer->setAngle( angle );
263
double QgsMarkerSymbolV2::angle()
265
QgsSymbolLayerV2List::const_iterator it = mLayers.begin();
267
if ( it == mLayers.end() )
270
// return angle of the first symbol layer
271
const QgsMarkerSymbolLayerV2 *layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
272
return layer->angle();
275
void QgsMarkerSymbolV2::setSize( double s )
277
double origSize = size();
279
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
281
QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
282
if ( layer->size() == origSize )
286
// proportionally scale size
288
layer->setSize( layer->size() * s / origSize );
293
double QgsMarkerSymbolV2::size()
295
// return size of the largest symbol
297
for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
299
const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
300
double lsize = layer->size();
301
if ( lsize > maxSize )
307
void QgsMarkerSymbolV2::renderPoint( const QPointF& point, QgsRenderContext& context, int layer )
311
if ( layer >= 0 && layer < mLayers.count() )
312
(( QgsMarkerSymbolLayerV2* ) mLayers[layer] )->renderPoint( point, context );
316
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
318
QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
319
layer->renderPoint( point, context );
323
QgsSymbolV2* QgsMarkerSymbolV2::clone() const
325
return new QgsMarkerSymbolV2( cloneLayers() );
332
QgsLineSymbolV2::QgsLineSymbolV2( QgsSymbolLayerV2List layers )
333
: QgsSymbolV2( Line, layers )
335
if ( mLayers.count() == 0 )
336
mLayers.append( new QgsSimpleLineSymbolLayerV2() );
339
void QgsLineSymbolV2::setWidth( double w )
341
double origWidth = width();
343
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
345
QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
346
if ( layer->width() == origWidth )
348
layer->setWidth( w );
352
// proportionally scale the width
353
if ( origWidth != 0 )
354
layer->setWidth( layer->width() * w / origWidth );
359
double QgsLineSymbolV2::width()
362
for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
364
const QgsLineSymbolLayerV2* layer = ( const QgsLineSymbolLayerV2* ) * it;
365
double width = layer->width();
366
if ( width > maxWidth )
372
void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, QgsRenderContext& context, int layer )
376
if ( layer >= 0 && layer < mLayers.count() )
377
(( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolyline( points, context );
381
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
383
QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
384
layer->renderPolyline( points, context );
389
QgsSymbolV2* QgsLineSymbolV2::clone() const
391
return new QgsLineSymbolV2( cloneLayers() );
397
QgsFillSymbolV2::QgsFillSymbolV2( QgsSymbolLayerV2List layers )
398
: QgsSymbolV2( Fill, layers )
400
if ( mLayers.count() == 0 )
401
mLayers.append( new QgsSimpleFillSymbolLayerV2() );
404
void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsRenderContext& context, int layer )
408
if ( layer >= 0 && layer < mLayers.count() )
409
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, context );
413
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
415
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
416
layer->renderPolygon( points, rings, context );
421
QgsSymbolV2* QgsFillSymbolV2::clone() const
423
return new QgsFillSymbolV2( cloneLayers() );