qwt_plot_shapeitem.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_plot_shapeitem.h"
00011 #include "qwt_scale_map.h"
00012 #include "qwt_painter.h"
00013 #include "qwt_weeding_curve_fitter.h"
00014 #include "qwt_clipper.h"
00015 
00016 static QPainterPath qwtTransformPath( const QwtScaleMap &xMap,
00017         const QwtScaleMap &yMap, const QPainterPath &path, bool doAlign )
00018 {
00019     QPainterPath shape;
00020     shape.setFillRule( path.fillRule() );
00021 
00022     for ( int i = 0; i < path.elementCount(); i++ )
00023     {
00024         const QPainterPath::Element &element = path.elementAt( i );
00025 
00026         double x = xMap.transform( element.x );
00027         double y = yMap.transform( element.y );
00028 
00029         switch( element.type )
00030         {
00031             case QPainterPath::MoveToElement:
00032             {
00033                 if ( doAlign )
00034                 {
00035                     x = qRound( x );
00036                     y = qRound( y );
00037                 }
00038 
00039                 shape.moveTo( x, y );
00040                 break;
00041             }
00042             case QPainterPath::LineToElement:
00043             {
00044                 if ( doAlign )
00045                 {
00046                     x = qRound( x );
00047                     y = qRound( y );
00048                 }
00049 
00050                 shape.lineTo( x, y );
00051                 break;
00052             }
00053             case QPainterPath::CurveToElement:
00054             {
00055                 const QPainterPath::Element& element1 = path.elementAt( ++i );
00056                 const double x1 = xMap.transform( element1.x );
00057                 const double y1 = yMap.transform( element1.y );
00058 
00059                 const QPainterPath::Element& element2 = path.elementAt( ++i );
00060                 const double x2 = xMap.transform( element2.x );
00061                 const double y2 = yMap.transform( element2.y );
00062 
00063                 shape.cubicTo( x, y, x1, y1, x2, y2 );
00064                 break;
00065             }
00066             case QPainterPath::CurveToDataElement:
00067             {
00068                 break;
00069             }
00070         }
00071     }
00072 
00073     return shape;
00074 }
00075 
00076 
00077 class QwtPlotShapeItem::PrivateData
00078 {
00079 public:
00080     PrivateData():
00081         legendMode( QwtPlotShapeItem::LegendColor ),
00082         renderTolerance( 0.0 )
00083     {
00084     }
00085 
00086     QwtPlotShapeItem::PaintAttributes paintAttributes;
00087     QwtPlotShapeItem::LegendMode legendMode;
00088 
00089     double renderTolerance;
00090     QRectF boundingRect;
00091 
00092     QPen pen;
00093     QBrush brush;
00094     QPainterPath shape;
00095 };
00096 
00106 QwtPlotShapeItem::QwtPlotShapeItem( const QString& title ):
00107     QwtPlotItem( QwtText( title ) )
00108 {
00109     init();
00110 }
00111 
00121 QwtPlotShapeItem::QwtPlotShapeItem( const QwtText& title ):
00122     QwtPlotItem( title )
00123 {
00124     init();
00125 }
00126 
00128 QwtPlotShapeItem::~QwtPlotShapeItem()
00129 {
00130     delete d_data;
00131 }
00132 
00133 void QwtPlotShapeItem::init()
00134 {
00135     d_data = new PrivateData();
00136     d_data->boundingRect = QwtPlotItem::boundingRect();
00137 
00138     setItemAttribute( QwtPlotItem::AutoScale, true );
00139     setItemAttribute( QwtPlotItem::Legend, false );
00140 
00141     setZ( 8.0 );
00142 }
00143 
00145 int QwtPlotShapeItem::rtti() const
00146 {
00147     return QwtPlotItem::Rtti_PlotShape;
00148 }
00149 
00157 void QwtPlotShapeItem::setPaintAttribute( PaintAttribute attribute, bool on )
00158 {
00159     if ( on )
00160         d_data->paintAttributes |= attribute;
00161     else
00162         d_data->paintAttributes &= ~attribute;
00163 }
00164 
00169 bool QwtPlotShapeItem::testPaintAttribute( PaintAttribute attribute ) const
00170 {
00171     return ( d_data->paintAttributes & attribute );
00172 }
00173 
00180 void QwtPlotShapeItem::setLegendMode( LegendMode mode )
00181 {
00182     if ( mode != d_data->legendMode )
00183     {
00184         d_data->legendMode = mode;
00185         legendChanged();
00186     }
00187 }
00188 
00193 QwtPlotShapeItem::LegendMode QwtPlotShapeItem::legendMode() const
00194 {
00195     return d_data->legendMode;
00196 }
00197 
00199 QRectF QwtPlotShapeItem::boundingRect() const
00200 {
00201     return d_data->boundingRect;
00202 }
00203 
00210 void QwtPlotShapeItem::setRect( const QRectF &rect ) 
00211 {
00212     QPainterPath path;
00213     path.addRect( rect );
00214 
00215     setShape( path );
00216 }
00217 
00224 void QwtPlotShapeItem::setPolygon( const QPolygonF &polygon )
00225 {
00226     QPainterPath shape;
00227     shape.addPolygon( polygon );
00228 
00229     setShape( shape );
00230 }
00231 
00238 void QwtPlotShapeItem::setShape( const QPainterPath &shape )
00239 {
00240     if ( shape != d_data->shape )
00241     {
00242         d_data->shape = shape;
00243         if ( shape.isEmpty() )
00244         {
00245             d_data->boundingRect = QwtPlotItem::boundingRect();
00246         }
00247         else
00248         {
00249             d_data->boundingRect = shape.boundingRect();
00250         }
00251 
00252         itemChanged();
00253     }
00254 }
00255 
00260 QPainterPath QwtPlotShapeItem::shape() const
00261 {
00262     return d_data->shape;
00263 }
00264 
00278 void QwtPlotShapeItem::setPen( const QColor &color, qreal width, Qt::PenStyle style )
00279 {   
00280     setPen( QPen( color, width, style ) );
00281 }
00282 
00291 void QwtPlotShapeItem::setPen( const QPen &pen )
00292 {
00293     if ( pen != d_data->pen )
00294     {
00295         d_data->pen = pen;
00296         itemChanged();
00297     }
00298 }
00299 
00304 QPen QwtPlotShapeItem::pen() const
00305 {
00306     return d_data->pen;
00307 }
00308 
00317 void QwtPlotShapeItem::setBrush( const QBrush &brush )
00318 {
00319     if ( brush != d_data->brush )
00320     {
00321         d_data->brush = brush;
00322         itemChanged();
00323     }
00324 }
00325 
00330 QBrush QwtPlotShapeItem::brush() const
00331 {
00332     return d_data->brush;
00333 }
00334 
00351 void QwtPlotShapeItem::setRenderTolerance( double tolerance )
00352 {
00353     tolerance = qMax( tolerance, 0.0 );
00354 
00355     if ( tolerance != d_data->renderTolerance )
00356     {
00357         d_data->renderTolerance = tolerance;
00358         itemChanged();
00359     }
00360 }
00361 
00366 double QwtPlotShapeItem::renderTolerance() const
00367 {
00368     return d_data->renderTolerance;
00369 }
00370 
00379 void QwtPlotShapeItem::draw( QPainter *painter,
00380     const QwtScaleMap &xMap, const QwtScaleMap &yMap,
00381     const QRectF &canvasRect ) const
00382 {
00383     if ( d_data->shape.isEmpty() )
00384         return;
00385 
00386     if ( d_data->pen.style() == Qt::NoPen 
00387         && d_data->brush.style() == Qt::NoBrush )
00388     {
00389         return;
00390     }
00391 
00392     const QRectF cr = QwtScaleMap::invTransform(
00393         xMap, yMap, canvasRect.toRect() );
00394 
00395     const QRectF &br = d_data->boundingRect;
00396 
00397     if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() )
00398         || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) )
00399     {
00400         // outside the visisble area
00401         return;
00402     }
00403 
00404     const bool doAlign = QwtPainter::roundingAlignment( painter );
00405 
00406     QPainterPath path = qwtTransformPath( xMap, yMap, 
00407         d_data->shape, doAlign );
00408 
00409     if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) )
00410     {
00411         qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
00412         QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
00413 
00414         QPainterPath clippedPath;
00415         clippedPath.setFillRule( path.fillRule() );
00416 
00417         const QList<QPolygonF> polygons = path.toSubpathPolygons();
00418         for ( int i = 0; i < polygons.size(); i++ )
00419         {
00420             const QPolygonF p = QwtClipper::clipPolygonF(
00421                 clipRect, polygons[i], true );
00422 
00423             clippedPath.addPolygon( p );
00424 
00425         }
00426 
00427         path = clippedPath;
00428     }
00429 
00430     if ( d_data->renderTolerance > 0.0 )
00431     {
00432         QwtWeedingCurveFitter fitter( d_data->renderTolerance );
00433 
00434         QPainterPath fittedPath;
00435         fittedPath.setFillRule( path.fillRule() );
00436 
00437         const QList<QPolygonF> polygons = path.toSubpathPolygons();
00438         for ( int i = 0; i < polygons.size(); i++ )
00439             fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );
00440 
00441         path = fittedPath;
00442     }
00443 
00444     painter->setPen( d_data->pen );
00445     painter->setBrush( d_data->brush );
00446 
00447     painter->drawPath( path );
00448 }
00449 
00459 QwtGraphic QwtPlotShapeItem::legendIcon( int index,
00460     const QSizeF &size ) const
00461 {
00462     Q_UNUSED( index );
00463 
00464     QwtGraphic icon;
00465     icon.setDefaultSize( size );
00466 
00467     if ( size.isEmpty() )
00468         return icon;
00469 
00470     if ( d_data->legendMode == QwtPlotShapeItem::LegendShape )
00471     {
00472         const QRectF &br = d_data->boundingRect;
00473 
00474         QPainter painter( &icon );
00475         painter.setRenderHint( QPainter::Antialiasing,
00476             testRenderHint( QwtPlotItem::RenderAntialiased ) );
00477 
00478         painter.translate( -br.topLeft() );
00479 
00480         painter.setPen( d_data->pen );
00481         painter.setBrush( d_data->brush );
00482         painter.drawPath( d_data->shape );
00483     }
00484     else
00485     {
00486         QColor iconColor;
00487         if ( d_data->brush.style() != Qt::NoBrush )
00488             iconColor = d_data->brush.color();
00489         else
00490             iconColor = d_data->pen.color();
00491 
00492         icon = defaultIcon( iconColor, size );
00493     }
00494 
00495     return icon;
00496 }
00497 


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56