Qwt User's Guide 6.2.0

qwt_plot_shapeitem.cpp
1 /******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10 #include "qwt_plot_shapeitem.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_text.h"
13 #include "qwt_graphic.h"
14 #include "qwt_painter.h"
15 #include "qwt_weeding_curve_fitter.h"
16 #include "qwt_clipper.h"
17 #include "qwt_math.h"
18
19 #include <qpainter.h>
20 #include <qpainterpath.h>
21
22 static QPainterPath qwtTransformPath( const QwtScaleMap& xMap,
23 const QwtScaleMap& yMap, const QPainterPath& path, bool doAlign )
24 {
25 QPainterPath shape;
26 shape.setFillRule( path.fillRule() );
27
28 for ( int i = 0; i < path.elementCount(); i++ )
29 {
30 const QPainterPath::Element element = path.elementAt( i );
31
32 double x = xMap.transform( element.x );
33 double y = yMap.transform( element.y );
34
35 switch( element.type )
36 {
37 case QPainterPath::MoveToElement:
38 {
39 if ( doAlign )
40 {
41 x = qRound( x );
42 y = qRound( y );
43 }
44
45 shape.moveTo( x, y );
46 break;
47 }
48 case QPainterPath::LineToElement:
49 {
50 if ( doAlign )
51 {
52 x = qRound( x );
53 y = qRound( y );
54 }
55
56 shape.lineTo( x, y );
57 break;
58 }
59 case QPainterPath::CurveToElement:
60 {
61 const QPainterPath::Element element1 = path.elementAt( ++i );
62 const double x1 = xMap.transform( element1.x );
63 const double y1 = yMap.transform( element1.y );
64
65 const QPainterPath::Element element2 = path.elementAt( ++i );
66 const double x2 = xMap.transform( element2.x );
67 const double y2 = yMap.transform( element2.y );
68
69 shape.cubicTo( x, y, x1, y1, x2, y2 );
70 break;
71 }
72 case QPainterPath::CurveToDataElement:
73 {
74 break;
75 }
76 }
77 }
78
79 return shape;
80 }
81
82
83 class QwtPlotShapeItem::PrivateData
84 {
85 public:
86 PrivateData()
87 : legendMode( QwtPlotShapeItem::LegendColor )
88 , renderTolerance( 0.0 )
89 {
90 }
91
92 QwtPlotShapeItem::PaintAttributes paintAttributes;
93 QwtPlotShapeItem::LegendMode legendMode;
94
95 double renderTolerance;
96 QRectF boundingRect;
97
98 QPen pen;
99 QBrush brush;
100 QPainterPath shape;
101 };
102
112 QwtPlotShapeItem::QwtPlotShapeItem( const QString& title )
113 : QwtPlotItem( QwtText( title ) )
114 {
115 init();
116 }
117
127 QwtPlotShapeItem::QwtPlotShapeItem( const QwtText& title )
128 : QwtPlotItem( title )
129 {
130 init();
131 }
132
134 QwtPlotShapeItem::~QwtPlotShapeItem()
135 {
136 delete m_data;
137 }
138
139 void QwtPlotShapeItem::init()
140 {
141 m_data = new PrivateData();
142 m_data->boundingRect = QwtPlotItem::boundingRect();
143
144 setItemAttribute( QwtPlotItem::AutoScale, true );
145 setItemAttribute( QwtPlotItem::Legend, false );
146
147 setZ( 8.0 );
148 }
149
151 int QwtPlotShapeItem::rtti() const
152 {
153 return QwtPlotItem::Rtti_PlotShape;
154 }
155
163 void QwtPlotShapeItem::setPaintAttribute( PaintAttribute attribute, bool on )
164 {
165 if ( on )
166 m_data->paintAttributes |= attribute;
167 else
168 m_data->paintAttributes &= ~attribute;
169 }
170
175 bool QwtPlotShapeItem::testPaintAttribute( PaintAttribute attribute ) const
176 {
177 return ( m_data->paintAttributes & attribute );
178 }
179
186 void QwtPlotShapeItem::setLegendMode( LegendMode mode )
187 {
188 if ( mode != m_data->legendMode )
189 {
190 m_data->legendMode = mode;
191 legendChanged();
192 }
193 }
194
199 QwtPlotShapeItem::LegendMode QwtPlotShapeItem::legendMode() const
200 {
201 return m_data->legendMode;
202 }
203
205 QRectF QwtPlotShapeItem::boundingRect() const
206 {
207 return m_data->boundingRect;
208 }
209
216 void QwtPlotShapeItem::setRect( const QRectF& rect )
217 {
218 QPainterPath path;
219 path.addRect( rect );
220
221 setShape( path );
222 }
223
230 void QwtPlotShapeItem::setPolygon( const QPolygonF& polygon )
231 {
232 QPainterPath shape;
233 shape.addPolygon( polygon );
234
235 setShape( shape );
236 }
237
244 void QwtPlotShapeItem::setShape( const QPainterPath& shape )
245 {
246 if ( shape != m_data->shape )
247 {
248 m_data->shape = shape;
249 if ( shape.isEmpty() )
250 {
251 m_data->boundingRect = QwtPlotItem::boundingRect();
252 }
253 else
254 {
255 m_data->boundingRect = shape.boundingRect();
256 }
257
258 itemChanged();
259 }
260 }
261
266 QPainterPath QwtPlotShapeItem::shape() const
267 {
268 return m_data->shape;
269 }
270
284 void QwtPlotShapeItem::setPen( const QColor& color, qreal width, Qt::PenStyle style )
285 {
286 setPen( QPen( color, width, style ) );
287 }
288
297 void QwtPlotShapeItem::setPen( const QPen& pen )
298 {
299 if ( pen != m_data->pen )
300 {
301 m_data->pen = pen;
302 itemChanged();
303 }
304 }
305
310 QPen QwtPlotShapeItem::pen() const
311 {
312 return m_data->pen;
313 }
314
323 void QwtPlotShapeItem::setBrush( const QBrush& brush )
324 {
325 if ( brush != m_data->brush )
326 {
327 m_data->brush = brush;
328 itemChanged();
329 }
330 }
331
336 QBrush QwtPlotShapeItem::brush() const
337 {
338 return m_data->brush;
339 }
340
357 void QwtPlotShapeItem::setRenderTolerance( double tolerance )
358 {
359 tolerance = qwtMaxF( tolerance, 0.0 );
360
361 if ( tolerance != m_data->renderTolerance )
362 {
363 m_data->renderTolerance = tolerance;
364 itemChanged();
365 }
366 }
367
372 double QwtPlotShapeItem::renderTolerance() const
373 {
374 return m_data->renderTolerance;
375 }
376
385 void QwtPlotShapeItem::draw( QPainter* painter,
386 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
387 const QRectF& canvasRect ) const
388 {
389 if ( m_data->shape.isEmpty() )
390 return;
391
392 if ( m_data->pen.style() == Qt::NoPen
393 && m_data->brush.style() == Qt::NoBrush )
394 {
395 return;
396 }
397
398 const QRectF cr = QwtScaleMap::invTransform(
399 xMap, yMap, canvasRect.toRect() );
400
401 const QRectF& br = m_data->boundingRect;
402
403 if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() )
404 || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) )
405 {
406 // outside the visible area
407 return;
408 }
409
410 const bool doAlign = QwtPainter::roundingAlignment( painter );
411
412 QPainterPath path = qwtTransformPath( xMap, yMap,
413 m_data->shape, doAlign );
414
415 if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) )
416 {
417 const qreal pw = QwtPainter::effectivePenWidth( painter->pen() );
418 const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw );
419
420 QPainterPath clippedPath;
421 clippedPath.setFillRule( path.fillRule() );
422
423 QList< QPolygonF > polygons = path.toSubpathPolygons();
424 for ( int i = 0; i < polygons.size(); i++ )
425 {
426 QwtClipper::clipPolygonF( clipRect, polygons[i], true );
427 clippedPath.addPolygon( polygons[i] );
428
429 }
430
431 path = clippedPath;
432 }
433
434 if ( m_data->renderTolerance > 0.0 )
435 {
436 QwtWeedingCurveFitter fitter( m_data->renderTolerance );
437
438 QPainterPath fittedPath;
439 fittedPath.setFillRule( path.fillRule() );
440
441 const QList< QPolygonF > polygons = path.toSubpathPolygons();
442 for ( int i = 0; i < polygons.size(); i++ )
443 fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) );
444
445 path = fittedPath;
446 }
447
448 painter->setPen( m_data->pen );
449 painter->setBrush( m_data->brush );
450
451 painter->drawPath( path );
452 }
453
463 QwtGraphic QwtPlotShapeItem::legendIcon( int index,
464 const QSizeF& size ) const
465 {
466 Q_UNUSED( index );
467
468 QwtGraphic icon;
469 icon.setDefaultSize( size );
470
471 if ( size.isEmpty() )
472 return icon;
473
474 if ( m_data->legendMode == QwtPlotShapeItem::LegendShape )
475 {
476 const QRectF& br = m_data->boundingRect;
477
478 QPainter painter( &icon );
479 painter.setRenderHint( QPainter::Antialiasing,
480 testRenderHint( QwtPlotItem::RenderAntialiased ) );
481
482 painter.translate( -br.topLeft() );
483
484 painter.setPen( m_data->pen );
485 painter.setBrush( m_data->brush );
486 painter.drawPath( m_data->shape );
487 }
488 else
489 {
490 QColor iconColor;
491 if ( m_data->brush.style() != Qt::NoBrush )
492 iconColor = m_data->brush.color();
493 else
494 iconColor = m_data->pen.color();
495
496 icon = defaultIcon( iconColor, size );
497 }
498
499 return icon;
500 }
501
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