Quantum GIS API Documentation  master-693a1fe
src/core/symbology-ng/qgssymbolv2.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002     qgssymbolv2.cpp
00003     ---------------------
00004     begin                : November 2009
00005     copyright            : (C) 2009 by Martin Dobias
00006     email                : wonder dot sk at gmail dot com
00007  ***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include "qgssymbolv2.h"
00017 #include "qgssymbollayerv2.h"
00018 
00019 #include "qgslinesymbollayerv2.h"
00020 #include "qgsmarkersymbollayerv2.h"
00021 #include "qgsfillsymbollayerv2.h"
00022 
00023 #include "qgslogger.h"
00024 #include "qgsrendercontext.h" // for bigSymbolPreview
00025 
00026 #include "qgsproject.h"
00027 #include "qgsstylev2.h"
00028 
00029 #include <QColor>
00030 #include <QImage>
00031 #include <QPainter>
00032 #include <QSize>
00033 
00034 #include <cmath>
00035 
00036 QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
00037     : mType( type ), mLayers( layers ), mAlpha( 1.0 ), mRenderHints( 0 )
00038 {
00039 
00040   // check they're all correct symbol layers
00041   for ( int i = 0; i < mLayers.count(); i++ )
00042   {
00043     if ( mLayers[i] == NULL )
00044     {
00045       mLayers.removeAt( i-- );
00046     }
00047     else if ( !isSymbolLayerCompatible( mLayers[i]->type() ) )
00048     {
00049       delete mLayers[i];
00050       mLayers.removeAt( i-- );
00051     }
00052   }
00053 
00054 }
00055 
00056 QgsSymbolV2::~QgsSymbolV2()
00057 {
00058   // delete all symbol layers (we own them, so it's okay)
00059   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00060     delete *it;
00061 }
00062 
00063 QgsSymbolV2::OutputUnit QgsSymbolV2::outputUnit() const
00064 {
00065   QgsSymbolV2::OutputUnit unit( QgsSymbolV2::Mixed );
00066 
00067   QgsSymbolLayerV2List::const_iterator it = mLayers.constBegin();
00068   for ( ; it != mLayers.constEnd(); ++it )
00069   {
00070     if ( it == mLayers.constBegin() )
00071     {
00072       unit = ( *it )->outputUnit();
00073     }
00074     else
00075     {
00076       if (( *it )->outputUnit() != unit )
00077       {
00078         return QgsSymbolV2::Mixed;
00079       }
00080     }
00081   }
00082 
00083   return unit;
00084 }
00085 
00086 void QgsSymbolV2::setOutputUnit( QgsSymbolV2::OutputUnit u )
00087 {
00088   QgsSymbolLayerV2List::iterator it = mLayers.begin();
00089   for ( ; it != mLayers.end(); ++it )
00090   {
00091     ( *it )->setOutputUnit( u );
00092   }
00093 }
00094 
00095 QgsSymbolV2* QgsSymbolV2::defaultSymbol( QGis::GeometryType geomType )
00096 {
00097   QgsSymbolV2* s = 0;
00098 
00099   // override global default if project has a default for this type
00100   QString defaultSymbol;
00101   switch ( geomType )
00102   {
00103     case QGis::Point :
00104       defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Marker", "" );
00105       break;
00106     case QGis::Line :
00107       defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Line", "" );
00108       break;
00109     case QGis::Polygon :
00110       defaultSymbol = QgsProject::instance()->readEntry( "DefaultStyles", "/Fill", "" );
00111       break;
00112     default: defaultSymbol = ""; break;
00113   }
00114   if ( defaultSymbol != "" )
00115     s = QgsStyleV2::defaultStyle()->symbol( defaultSymbol );
00116 
00117   // if no default found for this type, get global default (as previously)
00118   if ( ! s )
00119   {
00120     switch ( geomType )
00121     {
00122       case QGis::Point: s = new QgsMarkerSymbolV2(); break;
00123       case QGis::Line:  s = new QgsLineSymbolV2(); break;
00124       case QGis::Polygon: s = new QgsFillSymbolV2(); break;
00125       default: QgsDebugMsg( "unknown layer's geometry type" ); return NULL;
00126     }
00127   }
00128 
00129   // set alpha transparency
00130   s->setAlpha( QgsProject::instance()->readDoubleEntry( "DefaultStyles", "/AlphaInt", 255 ) / 255.0 );
00131 
00132   // set random color, it project prefs allow
00133   if ( defaultSymbol == "" ||
00134        QgsProject::instance()->readBoolEntry( "DefaultStyles", "/RandomColors", true ) )
00135   {
00136     s->setColor( QColor::fromHsv( rand() % 360, 64 + rand() % 192, 128 + rand() % 128 ) );
00137   }
00138 
00139   return s;
00140 }
00141 
00142 QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
00143 {
00144   if ( layer < 0 || layer >= mLayers.count() )
00145     return NULL;
00146 
00147   return mLayers[layer];
00148 }
00149 
00150 
00151 bool QgsSymbolV2::isSymbolLayerCompatible( SymbolType t )
00152 {
00153   // fill symbol can contain also line symbol layers for drawing of outlines
00154   if ( mType == Fill && t == Line )
00155     return true;
00156 
00157   return mType == t;
00158 }
00159 
00160 
00161 bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
00162 {
00163   if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
00164     return false;
00165   if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
00166     return false;
00167 
00168   mLayers.insert( index, layer );
00169   return true;
00170 }
00171 
00172 
00173 bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
00174 {
00175   if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
00176     return false;
00177 
00178   mLayers.append( layer );
00179   return true;
00180 }
00181 
00182 
00183 bool QgsSymbolV2::deleteSymbolLayer( int index )
00184 {
00185   if ( index < 0 || index >= mLayers.count() )
00186     return false;
00187 
00188   delete mLayers[index];
00189   mLayers.removeAt( index );
00190   return true;
00191 }
00192 
00193 
00194 QgsSymbolLayerV2* QgsSymbolV2::takeSymbolLayer( int index )
00195 {
00196   if ( index < 0 || index >= mLayers.count() )
00197     return NULL;
00198 
00199   return mLayers.takeAt( index );
00200 }
00201 
00202 
00203 bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
00204 {
00205   if ( index < 0 || index >= mLayers.count() )
00206     return false;
00207   if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
00208     return false;
00209 
00210   delete mLayers[index]; // first delete the original layer
00211   mLayers[index] = layer; // set new layer
00212   return true;
00213 }
00214 
00215 
00216 void QgsSymbolV2::startRender( QgsRenderContext& context, const QgsVectorLayer* layer )
00217 {
00218   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints );
00219   symbolContext.setLayer( layer );
00220   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00221     ( *it )->startRender( symbolContext );
00222 }
00223 
00224 void QgsSymbolV2::stopRender( QgsRenderContext& context )
00225 {
00226   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints );
00227   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00228     ( *it )->stopRender( symbolContext );
00229 }
00230 
00231 void QgsSymbolV2::setColor( const QColor& color )
00232 {
00233   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00234   {
00235     if ( !( *it )->isLocked() )
00236       ( *it )->setColor( color );
00237   }
00238 }
00239 
00240 QColor QgsSymbolV2::color()
00241 {
00242   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00243   {
00244     // return color of the first unlocked layer
00245     if ( !( *it )->isLocked() )
00246       return ( *it )->color();
00247   }
00248   return QColor( 0, 0, 0 );
00249 }
00250 
00251 void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
00252 {
00253   QgsRenderContext context = QgsSymbolLayerV2Utils::createRenderContext( painter );
00254   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, false, mRenderHints );
00255   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00256   {
00257     if ( mType == Fill && ( *it )->type() == Line )
00258     {
00259       // line symbol layer would normally draw just a line
00260       // so we override this case to force it to draw a polygon outline
00261       QgsLineSymbolLayerV2* lsl = ( QgsLineSymbolLayerV2* ) * it;
00262 
00263       // from QgsFillSymbolLayerV2::drawPreviewIcon()
00264       QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
00265       lsl->startRender( symbolContext );
00266       lsl->renderPolygonOutline( poly, NULL, symbolContext );
00267       lsl->stopRender( symbolContext );
00268     }
00269     else
00270       ( *it )->drawPreviewIcon( symbolContext, size );
00271   }
00272 }
00273 
00274 
00275 QImage QgsSymbolV2::bigSymbolPreviewImage()
00276 {
00277   QImage preview( QSize( 100, 100 ), QImage::Format_ARGB32_Premultiplied );
00278   preview.fill( 0 );
00279 
00280   QPainter p( &preview );
00281   p.setRenderHint( QPainter::Antialiasing );
00282   p.translate( 0.5, 0.5 ); // shift by half a pixel to avoid blurring due antialising
00283 
00284   if ( mType == QgsSymbolV2::Marker )
00285   {
00286     p.setPen( QPen( Qt::gray ) );
00287     p.drawLine( 0, 50, 100, 50 );
00288     p.drawLine( 50, 0, 50, 100 );
00289   }
00290 
00291   QgsRenderContext context = QgsSymbolLayerV2Utils::createRenderContext( &p );
00292   startRender( context );
00293 
00294   if ( mType == QgsSymbolV2::Line )
00295   {
00296     QPolygonF poly;
00297     poly << QPointF( 0, 50 ) << QPointF( 99, 50 );
00298     static_cast<QgsLineSymbolV2*>( this )->renderPolyline( poly, 0, context );
00299   }
00300   else if ( mType == QgsSymbolV2::Fill )
00301   {
00302     QPolygonF polygon;
00303     polygon << QPointF( 20, 20 ) << QPointF( 80, 20 ) << QPointF( 80, 80 ) << QPointF( 20, 80 ) << QPointF( 20, 20 );
00304     static_cast<QgsFillSymbolV2*>( this )->renderPolygon( polygon, NULL, 0, context );
00305   }
00306   else // marker
00307   {
00308     static_cast<QgsMarkerSymbolV2*>( this )->renderPoint( QPointF( 50, 50 ), 0, context );
00309   }
00310 
00311   stopRender( context );
00312   return preview;
00313 }
00314 
00315 
00316 QString QgsSymbolV2::dump()
00317 {
00318   QString t;
00319   switch ( type() )
00320   {
00321     case QgsSymbolV2::Marker: t = "MARKER"; break;
00322     case QgsSymbolV2::Line: t = "LINE"; break;
00323     case QgsSymbolV2::Fill: t = "FILL"; break;
00324     default: Q_ASSERT( 0 && "unknown symbol type" );
00325   }
00326   QString s = QString( "%1 SYMBOL (%2 layers) color %3" ).arg( t ).arg( mLayers.count() ).arg( QgsSymbolLayerV2Utils::encodeColor( color() ) );
00327 
00328   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00329   {
00330     // TODO:
00331   }
00332   return s;
00333 }
00334 
00335 void QgsSymbolV2::toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const
00336 {
00337   props[ "alpha" ] = QString::number( alpha() );
00338   double scaleFactor = 1.0;
00339   props[ "uom" ] = QgsSymbolLayerV2Utils::encodeSldUom( outputUnit(), &scaleFactor );
00340   props[ "uomScale" ] = scaleFactor != 1 ? QString::number( scaleFactor ) : "";
00341 
00342   for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00343   {
00344     ( *it )->toSld( doc, element, props );
00345   }
00346 }
00347 
00348 QgsSymbolLayerV2List QgsSymbolV2::cloneLayers() const
00349 {
00350   QgsSymbolLayerV2List lst;
00351   for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00352   {
00353     QgsSymbolLayerV2* layer = ( *it )->clone();
00354     layer->setLocked(( *it )->isLocked() );
00355     layer->setRenderingPass(( *it )->renderingPass() );
00356     lst.append( layer );
00357   }
00358   return lst;
00359 }
00360 
00361 QSet<QString> QgsSymbolV2::usedAttributes() const
00362 {
00363   QSet<QString> attributes;
00364   QgsSymbolLayerV2List::const_iterator sIt = mLayers.constBegin();
00365   for ( ; sIt != mLayers.constEnd(); ++sIt )
00366   {
00367     if ( *sIt )
00368     {
00369       attributes.unite(( *sIt )->usedAttributes() );
00370     }
00371   }
00372   return attributes;
00373 }
00374 
00376 
00377 
00378 QgsSymbolV2RenderContext::QgsSymbolV2RenderContext( QgsRenderContext& c, QgsSymbolV2::OutputUnit u, qreal alpha, bool selected, int renderHints, const QgsFeature* f )
00379     : mRenderContext( c ), mOutputUnit( u ), mAlpha( alpha ), mSelected( selected ), mRenderHints( renderHints ), mFeature( f ), mLayer( 0 )
00380 {
00381 
00382 }
00383 
00384 QgsSymbolV2RenderContext::~QgsSymbolV2RenderContext()
00385 {
00386 
00387 }
00388 
00389 
00390 double QgsSymbolV2RenderContext::outputLineWidth( double width ) const
00391 {
00392   return width * QgsSymbolLayerV2Utils::lineWidthScaleFactor( mRenderContext, mOutputUnit );
00393 }
00394 
00395 double QgsSymbolV2RenderContext::outputPixelSize( double size ) const
00396 {
00397   return size * QgsSymbolLayerV2Utils::pixelSizeScaleFactor( mRenderContext, mOutputUnit );
00398 }
00399 
00400 QgsSymbolV2RenderContext& QgsSymbolV2RenderContext::operator=( const QgsSymbolV2RenderContext& )
00401 {
00402   // This is just a dummy implementation of assignment.
00403   // sip 4.7 generates a piece of code that needs this function to exist.
00404   // It's not generated automatically by the compiler because of
00405   // mRenderContext member which is a reference (and thus can't be changed).
00406   Q_ASSERT( false );
00407   return *this;
00408 }
00409 
00411 
00412 QgsMarkerSymbolV2* QgsMarkerSymbolV2::createSimple( const QgsStringMap& properties )
00413 {
00414   QgsSymbolLayerV2* sl = QgsSimpleMarkerSymbolLayerV2::create( properties );
00415   if ( sl == NULL )
00416     return NULL;
00417 
00418   QgsSymbolLayerV2List layers;
00419   layers.append( sl );
00420   return new QgsMarkerSymbolV2( layers );
00421 }
00422 
00423 QgsLineSymbolV2* QgsLineSymbolV2::createSimple( const QgsStringMap& properties )
00424 {
00425   QgsSymbolLayerV2* sl = QgsSimpleLineSymbolLayerV2::create( properties );
00426   if ( sl == NULL )
00427     return NULL;
00428 
00429   QgsSymbolLayerV2List layers;
00430   layers.append( sl );
00431   return new QgsLineSymbolV2( layers );
00432 }
00433 
00434 QgsFillSymbolV2* QgsFillSymbolV2::createSimple( const QgsStringMap& properties )
00435 {
00436   QgsSymbolLayerV2* sl = QgsSimpleFillSymbolLayerV2::create( properties );
00437   if ( sl == NULL )
00438     return NULL;
00439 
00440   QgsSymbolLayerV2List layers;
00441   layers.append( sl );
00442   return new QgsFillSymbolV2( layers );
00443 }
00444 
00446 
00447 
00448 QgsMarkerSymbolV2::QgsMarkerSymbolV2( QgsSymbolLayerV2List layers )
00449     : QgsSymbolV2( Marker, layers )
00450 {
00451   if ( mLayers.count() == 0 )
00452     mLayers.append( new QgsSimpleMarkerSymbolLayerV2() );
00453 }
00454 
00455 void QgsMarkerSymbolV2::setAngle( double ang )
00456 {
00457   double origAngle = angle();
00458   double angleDiff = ang - origAngle;
00459   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00460   {
00461     QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
00462     layer->setAngle( layer->angle() + angleDiff );
00463   }
00464 }
00465 
00466 double QgsMarkerSymbolV2::angle()
00467 {
00468   QgsSymbolLayerV2List::const_iterator it = mLayers.begin();
00469 
00470   if ( it == mLayers.end() )
00471     return 0;
00472 
00473   // return angle of the first symbol layer
00474   const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
00475   return layer->angle();
00476 }
00477 
00478 void QgsMarkerSymbolV2::setSize( double s )
00479 {
00480   double origSize = size();
00481 
00482   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00483   {
00484     QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
00485     if ( layer->size() == origSize )
00486       layer->setSize( s );
00487     else
00488     {
00489       // proportionally scale size
00490       if ( origSize != 0 )
00491         layer->setSize( layer->size() * s / origSize );
00492     }
00493   }
00494 }
00495 
00496 double QgsMarkerSymbolV2::size()
00497 {
00498   // return size of the largest symbol
00499   double maxSize = 0;
00500   for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00501   {
00502     const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
00503     double lsize = layer->size();
00504     if ( lsize > maxSize )
00505       maxSize = lsize;
00506   }
00507   return maxSize;
00508 }
00509 
00510 
00511 void QgsMarkerSymbolV2::setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod )
00512 {
00513   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00514   {
00515     QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
00516     layer->setScaleMethod( scaleMethod );
00517   }
00518 }
00519 
00520 QgsSymbolV2::ScaleMethod QgsMarkerSymbolV2::scaleMethod()
00521 {
00522   QgsSymbolLayerV2List::const_iterator it = mLayers.begin();
00523 
00524   if ( it == mLayers.end() )
00525     return DEFAULT_SCALE_METHOD;
00526 
00527   // return scale method of the first symbol layer
00528   const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
00529   return layer->scaleMethod();
00530 }
00531 
00532 void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
00533 {
00534   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f );
00535   if ( layer != -1 )
00536   {
00537     if ( layer >= 0 && layer < mLayers.count() )
00538       (( QgsMarkerSymbolLayerV2* ) mLayers[layer] )->renderPoint( point, symbolContext );
00539     return;
00540   }
00541 
00542   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00543   {
00544     QgsMarkerSymbolLayerV2* layer = ( QgsMarkerSymbolLayerV2* ) * it;
00545     layer->renderPoint( point, symbolContext );
00546   }
00547 }
00548 
00549 QgsSymbolV2* QgsMarkerSymbolV2::clone() const
00550 {
00551   QgsSymbolV2* cloneSymbol = new QgsMarkerSymbolV2( cloneLayers() );
00552   cloneSymbol->setAlpha( mAlpha );
00553   return cloneSymbol;
00554 }
00555 
00556 
00558 // LINE
00559 
00560 QgsLineSymbolV2::QgsLineSymbolV2( QgsSymbolLayerV2List layers )
00561     : QgsSymbolV2( Line, layers )
00562 {
00563   if ( mLayers.count() == 0 )
00564     mLayers.append( new QgsSimpleLineSymbolLayerV2() );
00565 }
00566 
00567 void QgsLineSymbolV2::setWidth( double w )
00568 {
00569   double origWidth = width();
00570 
00571   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00572   {
00573     QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
00574     if ( layer->width() == origWidth )
00575     {
00576       layer->setWidth( w );
00577     }
00578     else
00579     {
00580       // proportionally scale the width
00581       if ( origWidth != 0 )
00582         layer->setWidth( layer->width() * w / origWidth );
00583     }
00584   }
00585 }
00586 
00587 double QgsLineSymbolV2::width()
00588 {
00589   double maxWidth = 0;
00590   for ( QgsSymbolLayerV2List::const_iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00591   {
00592     const QgsLineSymbolLayerV2* layer = ( const QgsLineSymbolLayerV2* ) * it;
00593     double width = layer->width();
00594     if ( width > maxWidth )
00595       maxWidth = width;
00596   }
00597   return maxWidth;
00598 }
00599 
00600 void QgsLineSymbolV2::renderPolyline( const QPolygonF& points, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
00601 {
00602   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f );
00603   if ( layer != -1 )
00604   {
00605     if ( layer >= 0 && layer < mLayers.count() )
00606       (( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolyline( points, symbolContext );
00607     return;
00608   }
00609 
00610   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00611   {
00612     QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
00613     layer->renderPolyline( points, symbolContext );
00614   }
00615 }
00616 
00617 
00618 QgsSymbolV2* QgsLineSymbolV2::clone() const
00619 {
00620   QgsSymbolV2* cloneSymbol = new QgsLineSymbolV2( cloneLayers() );
00621   cloneSymbol->setAlpha( mAlpha );
00622   return cloneSymbol;
00623 }
00624 
00626 // FILL
00627 
00628 QgsFillSymbolV2::QgsFillSymbolV2( QgsSymbolLayerV2List layers )
00629     : QgsSymbolV2( Fill, layers )
00630 {
00631   if ( mLayers.count() == 0 )
00632     mLayers.append( new QgsSimpleFillSymbolLayerV2() );
00633 }
00634 
00635 void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
00636 {
00637   QgsSymbolV2RenderContext symbolContext( context, outputUnit(), mAlpha, selected, mRenderHints, f );
00638   if ( layer != -1 )
00639   {
00640     if ( layer >= 0 && layer < mLayers.count() )
00641     {
00642       QgsSymbolV2::SymbolType layertype = mLayers.at( layer )->type();
00643       if ( layertype == QgsSymbolV2::Fill )
00644         (( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
00645       else if ( layertype == QgsSymbolV2::Line )
00646         (( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolygonOutline( points, rings, symbolContext );
00647     }
00648     return;
00649   }
00650 
00651   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00652   {
00653     QgsSymbolV2::SymbolType layertype = ( *it )->type();
00654     if ( layertype == QgsSymbolV2::Fill )
00655     {
00656       QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
00657       layer->renderPolygon( points, rings, symbolContext );
00658     }
00659     else if ( layertype == QgsSymbolV2::Line )
00660     {
00661       QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
00662       layer->renderPolygonOutline( points, rings, symbolContext );
00663     }
00664   }
00665 }
00666 
00667 
00668 QgsSymbolV2* QgsFillSymbolV2::clone() const
00669 {
00670   QgsSymbolV2* cloneSymbol = new QgsFillSymbolV2( cloneLayers() );
00671   cloneSymbol->setAlpha( mAlpha );
00672   return cloneSymbol;
00673 }
00674 
00675 void QgsFillSymbolV2::setAngle( double angle )
00676 {
00677   for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
00678   {
00679     QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
00680     layer->setAngle( angle );
00681   }
00682 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines