void QgsUniqueValueRenderer::renderFeature( QgsRenderContext &renderContext, QgsFeature& f, QImage* img, bool selected, double opacity )
{
  QPainter *p = renderContext.painter();
  QgsSymbol* symbol = symbolForFeature( &f );
  if ( !symbol ) //no matching symbol
  {
    if ( img && mGeometryType == QGis::Point )
    {
      img->fill( 0 );
    }
    else if ( mGeometryType != QGis::Point )
    {
      p->setPen( Qt::NoPen );
      p->setBrush( Qt::NoBrush );
    }
    return;
  }

  // Point
  if ( img && mGeometryType == QGis::Point )
  {
    double fieldScale = 1.0;
    double rotation = 0.0;

    if ( symbol->scaleClassificationField() >= 0 )
    {
      //first find out the value for the scale classification attribute
      fieldScale = sqrt( qAbs( f.attribute( symbol->scaleClassificationField() ).toDouble() ) );
    }
    if ( symbol->rotationClassificationField() >= 0 )
    {
      rotation = f.attribute( symbol->rotationClassificationField() ).toDouble();
    }

    QString oldName;

    if ( symbol->symbolField() >= 0 )
    {
      QString name = f.attribute( symbol->symbolField() ).toString();
      oldName = symbol->pointSymbolName();
      symbol->setNamedPointSymbol( name );
    }

    double scale = renderContext.scaleFactor();

    if ( symbol->pointSizeUnits() )
    {
      scale = 1.0 / renderContext.mapToPixel().mapUnitsPerPixel();
    }

    *img = symbol->getPointSymbolAsImage( scale, selected, mSelectionColor,
                                          fieldScale, rotation, renderContext.rasterScaleFactor(),
                                          opacity );
    if ( !oldName.isNull() )
    {
      symbol->setNamedPointSymbol( oldName );
    }
  }
  // Line, polygon
  else if ( mGeometryType != QGis::Point )
  {
    if ( !selected )
    {
      QPen pen = symbol->pen();
      pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
      p->setPen( pen );
      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = symbol->brush();
        scaleBrush( brush, renderContext.rasterScaleFactor() ); //scale brush content for printout
        p->setBrush( brush );
      }
    }
    else
    {
      QPen pen = symbol->pen();
      pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = symbol->brush();
        scaleBrush( brush, renderContext.rasterScaleFactor() ); //scale brush content for printout
        brush.setColor( mSelectionColor );
        p->setBrush( brush );
      }
      else //don't draw outlines of polygons in selection color otherwise they appear merged
      {
        pen.setColor( mSelectionColor );
      }
      p->setPen( pen );
    }
  }
}
void QgsSingleSymbolRenderer::renderFeature( QPainter * p, QgsFeature & f, QImage* img, bool selected, double widthScale, double rasterScaleFactor )
{
  // Point
  if ( img && mGeometryType == QGis::Point )
  {

    // If scale field is non-negative, use it to scale.
    double fieldScale = 1.0;
    double rotation = 0.0;

    if ( mSymbol->scaleClassificationField() >= 0 )
    {
      //first find out the value for the scale classification attribute
      const QgsAttributeMap& attrs = f.attributeMap();
      fieldScale = sqrt( fabs( attrs[mSymbol->scaleClassificationField()].toDouble() ) );
      QgsDebugMsgLevel( QString( "Feature has field scale factor %1" ).arg( fieldScale ), 3 );
    }
    if ( mSymbol->rotationClassificationField() >= 0 )
    {
      const QgsAttributeMap& attrs = f.attributeMap();
      rotation = attrs[mSymbol->rotationClassificationField()].toDouble();
      QgsDebugMsgLevel( QString( "Feature has rotation factor %1" ).arg( rotation ), 3 );
    }

    *img = mSymbol->getPointSymbolAsImage( widthScale, selected, mSelectionColor, fieldScale, rotation, rasterScaleFactor );
  }


  // Line, polygon
  if ( mGeometryType != QGis::Point )
  {
    if ( !selected )
    {
      QPen pen = mSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );
      p->setPen( pen );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = mSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        p->setBrush( brush );
      }
    }
    else
    {
      QPen pen = mSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );
      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = mSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        brush.setColor( mSelectionColor );
        p->setBrush( brush );
      }
      else //for lines we draw in selection color
      {
        // We set pen color in case it is an area with no brush (transparent).
        // Previously, this was only done for lines. Why?
        pen.setColor( mSelectionColor );
        p->setPen( pen );
      }
    }
  }
}
void QgsGraduatedSymbolRenderer::renderFeature( QPainter * p, QgsFeature & f, QImage* img, bool selected, double widthScale, double rasterScaleFactor )
{
  QgsSymbol* theSymbol = symbolForFeature( &f );
  if ( !theSymbol )
  {
    if ( img && mGeometryType == QGis::Point )
    {
      img->fill( 0 );
    }
    else if ( mGeometryType != QGis::Point )
    {
      p->setPen( Qt::NoPen );
      p->setBrush( Qt::NoBrush );
    }
    return;
  }

  //set the qpen and qpainter to the right values
  // Point
  if ( img && mGeometryType == QGis::Point )
  {
    double fieldScale = 1.0;
    double rotation = 0.0;

    if ( theSymbol->scaleClassificationField() >= 0 )
    {
      //first find out the value for the scale classification attribute
      const QgsAttributeMap& attrs = f.attributeMap();
      fieldScale = sqrt( fabs( attrs[theSymbol->scaleClassificationField()].toDouble() ) );
      QgsDebugMsg( QString( "Feature has field scale factor %1" ).arg( fieldScale ) );
    }
    if ( theSymbol->rotationClassificationField() >= 0 )
    {
      const QgsAttributeMap& attrs = f.attributeMap();
      rotation = attrs[theSymbol->rotationClassificationField()].toDouble();
      QgsDebugMsg( QString( "Feature has rotation factor %1" ).arg( rotation ) );
    }
    *img = theSymbol->getPointSymbolAsImage( widthScale, selected, mSelectionColor, fieldScale, rotation, rasterScaleFactor );
  }

  // Line, polygon
  if ( mGeometryType != QGis::Point )
  {
    if ( !selected )
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );
      p->setPen( pen );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        p->setBrush( brush );
      }
    }
    else
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( widthScale * pen.widthF() );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, rasterScaleFactor ); //scale brush content for printout
        brush.setColor( mSelectionColor );
        p->setBrush( brush );
      }
      else //dont draw outlines in selection colour for polys otherwise they appear merged
      {
        pen.setColor( mSelectionColor );
      }
      p->setPen( pen );
    }
  }
}
void QgsGraduatedSymbolRenderer::renderFeature( QgsRenderContext &renderContext, QgsFeature & f, QImage* img, bool selected, double opacity )
{
  QPainter *p = renderContext.painter();
  QgsSymbol* theSymbol = symbolForFeature( &f );
  if ( !theSymbol )
  {
    if ( img && mGeometryType == QGis::Point )
    {
      img->fill( 0 );
    }
    else if ( mGeometryType != QGis::Point )
    {
      p->setPen( Qt::NoPen );
      p->setBrush( Qt::NoBrush );
    }
    return;
  }

  //set the qpen and qpainter to the right values
  // Point
  if ( img && mGeometryType == QGis::Point )
  {
    double fieldScale = 1.0;
    double rotation = 0.0;

    if ( theSymbol->scaleClassificationField() >= 0 )
    {
      //first find out the value for the scale classification attribute
      const QgsAttributeMap& attrs = f.attributeMap();
      fieldScale = sqrt( qAbs( attrs[theSymbol->scaleClassificationField()].toDouble() ) );
      QgsDebugMsgLevel( QString( "Feature has field scale factor %1" ).arg( fieldScale ), 3 );
    }
    if ( theSymbol->rotationClassificationField() >= 0 )
    {
      const QgsAttributeMap& attrs = f.attributeMap();
      rotation = attrs[theSymbol->rotationClassificationField()].toDouble();
      QgsDebugMsgLevel( QString( "Feature has rotation factor %1" ).arg( rotation ), 3 );
    }

    QString oldName;

    if ( theSymbol->symbolField() >= 0 )
    {
      const QgsAttributeMap& attrs = f.attributeMap();
      QString name = attrs[theSymbol->symbolField()].toString();
      QgsDebugMsgLevel( QString( "Feature has name %1" ).arg( name ), 3 );
      oldName = theSymbol->pointSymbolName();
      theSymbol->setNamedPointSymbol( name );
    }

    double scale = renderContext.scaleFactor();

    if ( theSymbol->pointSizeUnits() )
    {
      scale = 1.0 / renderContext.mapToPixel().mapUnitsPerPixel();
    }

    *img = theSymbol->getPointSymbolAsImage( scale, selected, mSelectionColor, fieldScale,
           rotation, renderContext.rasterScaleFactor(), opacity );

    if ( !oldName.isNull() )
    {
      theSymbol->setNamedPointSymbol( oldName );
    }
  }

  // Line, polygon
  if ( mGeometryType != QGis::Point )
  {
    if ( !selected )
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );
      p->setPen( pen );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, renderContext.rasterScaleFactor() ); //scale brush content for printout
        p->setBrush( brush );
      }
    }
    else
    {
      QPen pen = theSymbol->pen();
      pen.setWidthF( renderContext.scaleFactor() * pen.widthF() );

      if ( mGeometryType == QGis::Polygon )
      {
        QBrush brush = theSymbol->brush();
        scaleBrush( brush, renderContext.rasterScaleFactor() ); //scale brush content for printout
        brush.setColor( mSelectionColor );
        p->setBrush( brush );
      }
      else //don't draw outlines in selection color for polys otherwise they appear merged
      {
        pen.setColor( mSelectionColor );
      }
      p->setPen( pen );
    }
  }
}