Qwt User's Guide: qwt_plot_shapeitem.cpp Source File

Qwt User's Guide 6.3.0

Loading...
Searching...
No Matches
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
22static 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
83class 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
112QwtPlotShapeItem::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
134QwtPlotShapeItem::~QwtPlotShapeItem()
135{
136 delete m_data;
137}
138
139void 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
205QRectF 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
266QPainterPath 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
310QPen 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
336QBrush 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