qwt_plot_shapeitem.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot_shapeitem.h"
#include "qwt_scale_map.h"
#include "qwt_text.h"
#include "qwt_graphic.h"
#include "qwt_painter.h"
#include "qwt_weeding_curve_fitter.h"
#include "qwt_clipper.h"
#include "qwt_math.h"
#include <qpainter.h>
#include <qpainterpath.h>
static QPainterPath qwtTransformPath( const QwtScaleMap& xMap,
const QwtScaleMap& yMap, const QPainterPath& path, bool doAlign )
{
QPainterPath shape;
shape.setFillRule( path.fillRule() );
for ( int i = 0; i < path.elementCount(); i++ )
{
const QPainterPath::Element element = path.elementAt( i );
double x = xMap.transform( element.x );
double y = yMap.transform( element.y );
switch( element.type )
{
case QPainterPath::MoveToElement:
{
if ( doAlign )
{
x = qRound( x );
y = qRound( y );
}
shape.moveTo( x, y );
break;
}
case QPainterPath::LineToElement:
{
if ( doAlign )
{
x = qRound( x );
y = qRound( y );
}
shape.lineTo( x, y );
break;
}
case QPainterPath::CurveToElement:
{
const QPainterPath::Element element1 = path.elementAt( ++i );
const double x1 = xMap.transform( element1.x );
const double y1 = yMap.transform( element1.y );
const QPainterPath::Element element2 = path.elementAt( ++i );
const double x2 = xMap.transform( element2.x );
const double y2 = yMap.transform( element2.y );
shape.cubicTo( x, y, x1, y1, x2, y2 );
break;
}
case QPainterPath::CurveToDataElement:
{
break;
}
}
}
return shape;
}
class QwtPlotShapeItem::PrivateData
{
public:
PrivateData()
: legendMode( QwtPlotShapeItem::LegendColor )
, renderTolerance( 0.0 )
{
}
QwtPlotShapeItem::PaintAttributes paintAttributes;
QwtPlotShapeItem::LegendMode legendMode;
double renderTolerance;
QRectF boundingRect;
QPen pen;
QBrush brush;
QPainterPath shape;
};
QwtPlotShapeItem::QwtPlotShapeItem( const QString& title )
: QwtPlotItem( QwtText( title ) )
{
init();
}
QwtPlotShapeItem::QwtPlotShapeItem( const QwtText& title )
: QwtPlotItem( title )
{
init();
}
QwtPlotShapeItem::~QwtPlotShapeItem()
{
delete m_data;
}
void QwtPlotShapeItem::init()
{
m_data = new PrivateData();
m_data->boundingRect = QwtPlotItem::boundingRect();
setItemAttribute( QwtPlotItem::AutoScale, true );
setItemAttribute( QwtPlotItem::Legend, false );
setZ( 8.0 );
}
int QwtPlotShapeItem::rtti() const
{
return QwtPlotItem::Rtti_PlotShape;
}
void QwtPlotShapeItem::setPaintAttribute( PaintAttribute attribute, bool on )
{
if ( on )
m_data->paintAttributes |= attribute;
else
m_data->paintAttributes &= ~attribute;
}
bool QwtPlotShapeItem::testPaintAttribute( PaintAttribute attribute ) const
{
return ( m_data->paintAttributes & attribute );
}
void QwtPlotShapeItem::setLegendMode( LegendMode mode )
{
if ( mode != m_data->legendMode )
{
m_data->legendMode = mode;
legendChanged();
}
}
QwtPlotShapeItem::LegendMode QwtPlotShapeItem::legendMode() const
{
return m_data->legendMode;
}
QRectF QwtPlotShapeItem::boundingRect() const
{
return m_data->boundingRect;
}
void QwtPlotShapeItem::setRect( const QRectF& rect )
{
QPainterPath path;
path.addRect( rect );
setShape( path );
}
void QwtPlotShapeItem::setPolygon( const QPolygonF& polygon )
{
QPainterPath shape;
shape.addPolygon( polygon );
setShape( shape );
}
void QwtPlotShapeItem::setShape( const QPainterPath& shape )
{
if ( shape != m_data->shape )
{
m_data->shape = shape;
if ( shape.isEmpty() )
{
m_data->boundingRect = QwtPlotItem::boundingRect();
}
else
{
m_data->boundingRect = shape.boundingRect();
}
itemChanged();
}
}
QPainterPath QwtPlotShapeItem::shape() const
{
return m_data->shape;
}
void QwtPlotShapeItem::setPen( const QColor& color, qreal width, Qt::PenStyle style )
{
setPen( QPen( color, width, style ) );
}
void QwtPlotShapeItem::setPen( const QPen& pen )
{
if ( pen != m_data->pen )
{
m_data->pen = pen;
itemChanged();
}
}
QPen QwtPlotShapeItem::pen() const
{
return m_data->pen;
}
void QwtPlotShapeItem::setBrush( const QBrush& brush )
{
if ( brush != m_data->brush )
{
m_data->brush = brush;
itemChanged();
}
}
QBrush QwtPlotShapeItem::brush() const
{
return m_data->brush;
}
void QwtPlotShapeItem::setRenderTolerance( double tolerance )
{
tolerance = qwtMaxF( tolerance, 0.0 );
if ( tolerance != m_data->renderTolerance )
{
m_data->renderTolerance = tolerance;
itemChanged();
}
}
double QwtPlotShapeItem::renderTolerance() const
{
return m_data->renderTolerance;
}
void QwtPlotShapeItem::draw( QPainter* painter,
const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect ) const
{
if ( m_data->shape.isEmpty() )
return;
if ( m_data->pen.style() == Qt::NoPen
&& m_data->brush.style() == Qt::NoBrush )
{
return;
}
const QRectF cr = QwtScaleMap::invTransform(
xMap, yMap, canvasRect.toRect() );
const QRectF& br = m_data->boundingRect;
if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() )
|| ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) )
{
// outside the visible area
return;
}
const bool doAlign = QwtPainter::roundingAlignment( painter );
QPainterPath path = qwtTransformPath( xMap, yMap,
m_data->shape, doAlign );
if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) )
{
const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
QPainterPath clippedPath;
clippedPath.setFillRule( path.fillRule() );
QList< QPolygonF > polygons = path.toSubpathPolygons();
for ( int i = 0; i < polygons.size(); i++ )
{
QwtClipper::clipPolygonF( clipRect, polygons[i], true );
clippedPath.addPolygon( polygons[i] );
}
path = clippedPath;
}
if ( m_data->renderTolerance > 0.0 )
{
QwtWeedingCurveFitter fitter( m_data->renderTolerance );
QPainterPath fittedPath;
fittedPath.setFillRule( path.fillRule() );
const QList< QPolygonF > polygons = path.toSubpathPolygons();
for ( int i = 0; i < polygons.size(); i++ )
fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );
path = fittedPath;
}
painter->setPen( m_data->pen );
painter->setBrush( m_data->brush );
painter->drawPath( path );
}
QwtGraphic QwtPlotShapeItem::legendIcon( int index,
const QSizeF& size ) const
{
Q_UNUSED( index );
QwtGraphic icon;
icon.setDefaultSize( size );
if ( size.isEmpty() )
return icon;
if ( m_data->legendMode == QwtPlotShapeItem::LegendShape )
{
const QRectF& br = m_data->boundingRect;
QPainter painter( &icon );
painter.setRenderHint( QPainter::Antialiasing,
testRenderHint( QwtPlotItem::RenderAntialiased ) );
painter.translate( -br.topLeft() );
painter.setPen( m_data->pen );
painter.setBrush( m_data->brush );
painter.drawPath( m_data->shape );
}
else
{
QColor iconColor;
if ( m_data->brush.style() != Qt::NoBrush )
iconColor = m_data->brush.color();
else
iconColor = m_data->pen.color();
icon = defaultIcon( iconColor, size );
}
return icon;
}
QList
Definition: qwt_abstract_legend.h:17
QwtGraphic
A paint device for scalable graphics.
Definition: qwt_graphic.h:76
QwtGraphic::setDefaultSize
void setDefaultSize(const QSizeF &)
Set a default size.
Definition: qwt_graphic.cpp:553
QwtPainter::effectivePenWidth
static qreal effectivePenWidth(const QPen &)
Definition: qwt_painter.h:201
QwtPainter::roundingAlignment
static bool roundingAlignment()
Definition: qwt_painter.h:183
QwtPlotItem
Base class for items on the plot canvas.
Definition: qwt_plot_item.h:67
QwtPlotItem::legendChanged
virtual void legendChanged()
Definition: qwt_plot_item.cpp:491
QwtPlotItem::setZ
void setZ(double z)
Set the z value.
Definition: qwt_plot_item.cpp:165
QwtPlotItem::setItemAttribute
void setItemAttribute(ItemAttribute, bool on=true)
Definition: qwt_plot_item.cpp:228
QwtPlotItem::defaultIcon
QwtGraphic defaultIcon(const QBrush &, const QSizeF &) const
Return a default icon from a brush.
Definition: qwt_plot_item.cpp:422
QwtPlotItem::Rtti_PlotShape
@ Rtti_PlotShape
For QwtPlotShapeItem.
Definition: qwt_plot_item.h:120
QwtPlotItem::RenderAntialiased
@ RenderAntialiased
Enable antialiasing.
Definition: qwt_plot_item.h:206
QwtPlotItem::testRenderHint
bool testRenderHint(RenderHint) const
Definition: qwt_plot_item.cpp:332
QwtPlotItem::itemChanged
virtual void itemChanged()
Definition: qwt_plot_item.cpp:481
QwtPlotItem::Legend
@ Legend
The item is represented on the legend.
Definition: qwt_plot_item.h:150
QwtPlotItem::AutoScale
@ AutoScale
Definition: qwt_plot_item.h:157
QwtPlotItem::boundingRect
virtual QRectF boundingRect() const
Definition: qwt_plot_item.cpp:568
QwtPlotShapeItem
A plot item, which displays any graphical shape, that can be defined by a QPainterPath.
Definition: qwt_plot_shapeitem.h:39
QwtPlotShapeItem::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_shapeitem.cpp:175
QwtPlotShapeItem::boundingRect
virtual QRectF boundingRect() const override
Bounding rectangle of the shape.
Definition: qwt_plot_shapeitem.cpp:205
QwtPlotShapeItem::setRect
void setRect(const QRectF &)
Set a path built from a rectangle.
Definition: qwt_plot_shapeitem.cpp:216
QwtPlotShapeItem::setShape
void setShape(const QPainterPath &)
Set the shape to be displayed.
Definition: qwt_plot_shapeitem.cpp:244
QwtPlotShapeItem::LegendMode
LegendMode
Mode how to display the item on the legend.
Definition: qwt_plot_shapeitem.h:65
QwtPlotShapeItem::LegendColor
@ LegendColor
Display a filled rectangle.
Definition: qwt_plot_shapeitem.h:70
QwtPlotShapeItem::LegendShape
@ LegendShape
Display a scaled down version of the shape.
Definition: qwt_plot_shapeitem.h:67
QwtPlotShapeItem::setLegendMode
void setLegendMode(LegendMode)
Definition: qwt_plot_shapeitem.cpp:186
QwtPlotShapeItem::legendIcon
virtual QwtGraphic legendIcon(int index, const QSizeF &) const override
Definition: qwt_plot_shapeitem.cpp:463
QwtPlotShapeItem::draw
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override
Definition: qwt_plot_shapeitem.cpp:385
QwtPlotShapeItem::rtti
virtual int rtti() const override
Definition: qwt_plot_shapeitem.cpp:151
QwtPlotShapeItem::legendMode
LegendMode legendMode() const
Definition: qwt_plot_shapeitem.cpp:199
QwtPlotShapeItem::QwtPlotShapeItem
QwtPlotShapeItem(const QString &title=QString())
Constructor.
Definition: qwt_plot_shapeitem.cpp:112
QwtPlotShapeItem::setPen
void setPen(const QColor &, qreal width=0.0, Qt::PenStyle=Qt::SolidLine)
Definition: qwt_plot_shapeitem.cpp:284
QwtPlotShapeItem::setRenderTolerance
void setRenderTolerance(double)
Set the tolerance for the weeding optimization.
Definition: qwt_plot_shapeitem.cpp:357
QwtPlotShapeItem::setPolygon
void setPolygon(const QPolygonF &)
Set a path built from a polygon.
Definition: qwt_plot_shapeitem.cpp:230
QwtPlotShapeItem::brush
QBrush brush() const
Definition: qwt_plot_shapeitem.cpp:336
QwtPlotShapeItem::PaintAttribute
PaintAttribute
Definition: qwt_plot_shapeitem.h:48
QwtPlotShapeItem::ClipPolygons
@ ClipPolygons
Definition: qwt_plot_shapeitem.h:58
QwtPlotShapeItem::pen
QPen pen() const
Definition: qwt_plot_shapeitem.cpp:310
QwtPlotShapeItem::renderTolerance
double renderTolerance() const
Definition: qwt_plot_shapeitem.cpp:372
QwtPlotShapeItem::setBrush
void setBrush(const QBrush &)
Definition: qwt_plot_shapeitem.cpp:323
QwtPlotShapeItem::~QwtPlotShapeItem
virtual ~QwtPlotShapeItem()
Destructor.
Definition: qwt_plot_shapeitem.cpp:134
QwtPlotShapeItem::setPaintAttribute
void setPaintAttribute(PaintAttribute, bool on=true)
Definition: qwt_plot_shapeitem.cpp:163
QwtPlotShapeItem::PaintAttributes
QFlags< PaintAttribute > PaintAttributes
Definition: qwt_plot_shapeitem.h:61
QwtPlotShapeItem::shape
QPainterPath shape() const
Definition: qwt_plot_shapeitem.cpp:266
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::transform
double transform(double s) const
Definition: qwt_scale_map.h:137
QwtScaleMap::invTransform
double invTransform(double p) const
Definition: qwt_scale_map.h:154
QwtText
A class representing a text.
Definition: qwt_text.h:52
QwtWeedingCurveFitter
A curve fitter implementing Douglas and Peucker algorithm.
Definition: qwt_weeding_curve_fitter.h:39
QwtWeedingCurveFitter::fitCurve
virtual QPolygonF fitCurve(const QPolygonF &) const override
Definition: qwt_weeding_curve_fitter.cpp:124
QwtClipper::clipPolygonF
QWT_EXPORT void clipPolygonF(const QRectF &, QPolygonF &, bool closePolygon=false)
Definition: qwt_clipper.cpp:404