Qwt User's Guide: qwt_plot_directpainter.cpp Source File

Qwt User's Guide 6.2.0

qwt_plot_directpainter.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_directpainter.h"
11 #include "qwt_scale_map.h"
12 #include "qwt_plot.h"
13 #include "qwt_plot_canvas.h"
14 #include "qwt_plot_seriesitem.h"
15
16 #include <qpainter.h>
17 #include <qevent.h>
18 #include <qpixmap.h>
19
20 static inline void qwtRenderItem(
21 QPainter* painter, const QRect& canvasRect,
22 QwtPlotSeriesItem* seriesItem, int from, int to )
23 {
24 // A minor performance improvement is possible
25 // with caching the maps. TODO ...
26
27 QwtPlot* plot = seriesItem->plot();
28 const QwtScaleMap xMap = plot->canvasMap( seriesItem->xAxis() );
29 const QwtScaleMap yMap = plot->canvasMap( seriesItem->yAxis() );
30
31 painter->setRenderHint( QPainter::Antialiasing,
32 seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
33 seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
34 }
35
36 static inline bool qwtHasBackingStore( const QwtPlotCanvas* canvas )
37 {
38 return canvas->testPaintAttribute( QwtPlotCanvas::BackingStore )
39 && canvas->backingStore() && !canvas->backingStore()->isNull();
40 }
41
42 class QwtPlotDirectPainter::PrivateData
43 {
44 public:
45 PrivateData()
46 : hasClipping( false )
47 , seriesItem( NULL )
48 , from( 0 )
49 , to( 0 )
50 {
51 }
52
53 QwtPlotDirectPainter::Attributes attributes;
54
55 bool hasClipping;
56 QRegion clipRegion;
57
58 QPainter painter;
59
60 QwtPlotSeriesItem* seriesItem;
61 int from;
62 int to;
63 };
64
66 QwtPlotDirectPainter::QwtPlotDirectPainter( QObject* parent )
67 : QObject( parent )
68 {
69 m_data = new PrivateData;
70 }
71
73 QwtPlotDirectPainter::~QwtPlotDirectPainter()
74 {
75 delete m_data;
76 }
77
86 void QwtPlotDirectPainter::setAttribute( Attribute attribute, bool on )
87 {
88 if ( bool( m_data->attributes & attribute ) != on )
89 {
90 if ( on )
91 m_data->attributes |= attribute;
92 else
93 m_data->attributes &= ~attribute;
94
95 if ( ( attribute == AtomicPainter ) && on )
96 reset();
97 }
98 }
99
105 bool QwtPlotDirectPainter::testAttribute( Attribute attribute ) const
106 {
107 return m_data->attributes & attribute;
108 }
109
116 void QwtPlotDirectPainter::setClipping( bool enable )
117 {
118 m_data->hasClipping = enable;
119 }
120
125 bool QwtPlotDirectPainter::hasClipping() const
126 {
127 return m_data->hasClipping;
128 }
129
141 void QwtPlotDirectPainter::setClipRegion( const QRegion& region )
142 {
143 m_data->clipRegion = region;
144 m_data->hasClipping = true;
145 }
146
151 QRegion QwtPlotDirectPainter::clipRegion() const
152 {
153 return m_data->clipRegion;
154 }
155
172 void QwtPlotDirectPainter::drawSeries(
173 QwtPlotSeriesItem* seriesItem, int from, int to )
174 {
175 if ( seriesItem == NULL || seriesItem->plot() == NULL )
176 return;
177
178 QWidget* canvas = seriesItem->plot()->canvas();
179 const QRect canvasRect = canvas->contentsRect();
180
181 QwtPlotCanvas* plotCanvas = qobject_cast< QwtPlotCanvas* >( canvas );
182
183 if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
184 {
185 QPainter painter( const_cast< QPixmap* >( plotCanvas->backingStore() ) );
186
187 if ( m_data->hasClipping )
188 painter.setClipRegion( m_data->clipRegion );
189
190 qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
191
192 painter.end();
193
194 if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
195 {
196 plotCanvas->repaint();
197 return;
198 }
199 }
200
201 bool immediatePaint = true;
202 if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) )
203 {
204 #if QT_VERSION < 0x050000
205 if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
206 #endif
207 immediatePaint = false;
208 }
209
210 if ( immediatePaint )
211 {
212 if ( !m_data->painter.isActive() )
213 {
214 reset();
215
216 m_data->painter.begin( canvas );
217 canvas->installEventFilter( this );
218 }
219
220 if ( m_data->hasClipping )
221 {
222 m_data->painter.setClipRegion(
223 QRegion( canvasRect ) & m_data->clipRegion );
224 }
225 else
226 {
227 if ( !m_data->painter.hasClipping() )
228 m_data->painter.setClipRect( canvasRect );
229 }
230
231 qwtRenderItem( &m_data->painter, canvasRect, seriesItem, from, to );
232
233 if ( m_data->attributes & QwtPlotDirectPainter::AtomicPainter )
234 {
235 reset();
236 }
237 else
238 {
239 if ( m_data->hasClipping )
240 m_data->painter.setClipping( false );
241 }
242 }
243 else
244 {
245 reset();
246
247 m_data->seriesItem = seriesItem;
248 m_data->from = from;
249 m_data->to = to;
250
251 QRegion clipRegion = canvasRect;
252 if ( m_data->hasClipping )
253 clipRegion &= m_data->clipRegion;
254
255 canvas->installEventFilter( this );
256 canvas->repaint(clipRegion);
257 canvas->removeEventFilter( this );
258
259 m_data->seriesItem = NULL;
260 }
261 }
262
264 void QwtPlotDirectPainter::reset()
265 {
266 if ( m_data->painter.isActive() )
267 {
268 QWidget* w = static_cast< QWidget* >( m_data->painter.device() );
269 if ( w )
270 w->removeEventFilter( this );
271
272 m_data->painter.end();
273 }
274 }
275
277 bool QwtPlotDirectPainter::eventFilter( QObject*, QEvent* event )
278 {
279 if ( event->type() == QEvent::Paint )
280 {
281 reset();
282
283 if ( m_data->seriesItem )
284 {
285 const QPaintEvent* pe = static_cast< QPaintEvent* >( event );
286
287 QWidget* canvas = m_data->seriesItem->plot()->canvas();
288
289 QPainter painter( canvas );
290 painter.setClipRegion( pe->region() );
291
292 bool doCopyCache = testAttribute( CopyBackingStore );
293
294 if ( doCopyCache )
295 {
296 QwtPlotCanvas* plotCanvas =
297 qobject_cast< QwtPlotCanvas* >( canvas );
298 if ( plotCanvas )
299 {
300 doCopyCache = qwtHasBackingStore( plotCanvas );
301 if ( doCopyCache )
302 {
303 painter.drawPixmap( plotCanvas->rect().topLeft(),
304 *plotCanvas->backingStore() );
305 }
306 }
307 }
308
309 if ( !doCopyCache )
310 {
311 qwtRenderItem( &painter, canvas->contentsRect(),
312 m_data->seriesItem, m_data->from, m_data->to );
313 }
314
315 return true; // don't call QwtPlotCanvas::paintEvent()
316 }
317 }
318
319 return false;
320 }
QwtPlotCanvas
Canvas of a QwtPlot.
Definition: qwt_plot_canvas.h:30
QwtPlotCanvas::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition: qwt_plot_canvas.cpp:127
QwtPlotCanvas::BackingStore
@ BackingStore
Paint double buffered reusing the content of the pixmap buffer when possible.
Definition: qwt_plot_canvas.h:57
QwtPlotCanvas::backingStore
const QPixmap * backingStore() const
Definition: qwt_plot_canvas.cpp:133
QwtPlotDirectPainter::setClipRegion
void setClipRegion(const QRegion &)
Assign a clip region and enable clipping.
Definition: qwt_plot_directpainter.cpp:141
QwtPlotDirectPainter::hasClipping
bool hasClipping() const
Definition: qwt_plot_directpainter.cpp:125
QwtPlotDirectPainter::Attribute
Attribute
Paint attributes.
Definition: qwt_plot_directpainter.h:47
QwtPlotDirectPainter::FullRepaint
@ FullRepaint
Definition: qwt_plot_directpainter.h:60
QwtPlotDirectPainter::CopyBackingStore
@ CopyBackingStore
Definition: qwt_plot_directpainter.h:70
QwtPlotDirectPainter::AtomicPainter
@ AtomicPainter
Definition: qwt_plot_directpainter.h:54
QwtPlotDirectPainter::setAttribute
void setAttribute(Attribute, bool on)
Definition: qwt_plot_directpainter.cpp:86
QwtPlotDirectPainter::Attributes
QFlags< Attribute > Attributes
Definition: qwt_plot_directpainter.h:73
QwtPlotDirectPainter::testAttribute
bool testAttribute(Attribute) const
Definition: qwt_plot_directpainter.cpp:105
QwtPlotDirectPainter::clipRegion
QRegion clipRegion() const
Definition: qwt_plot_directpainter.cpp:151
QwtPlotDirectPainter::reset
void reset()
Close the internal QPainter.
Definition: qwt_plot_directpainter.cpp:264
QwtPlotDirectPainter::~QwtPlotDirectPainter
virtual ~QwtPlotDirectPainter()
Destructor.
Definition: qwt_plot_directpainter.cpp:73
QwtPlotDirectPainter::drawSeries
void drawSeries(QwtPlotSeriesItem *, int from, int to)
Draw a set of points of a seriesItem.
Definition: qwt_plot_directpainter.cpp:172
QwtPlotDirectPainter::setClipping
void setClipping(bool)
Definition: qwt_plot_directpainter.cpp:116
QwtPlotDirectPainter::eventFilter
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
Definition: qwt_plot_directpainter.cpp:277
QwtPlotDirectPainter::QwtPlotDirectPainter
QwtPlotDirectPainter(QObject *parent=NULL)
Constructor.
Definition: qwt_plot_directpainter.cpp:66
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlot::canvas
QWidget * canvas()
Definition: qwt_plot.cpp:463
QwtPlot::canvasMap
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition: qwt_plot.cpp:800
QwtPlotItem::yAxis
QwtAxisId yAxis() const
Return yAxis.
Definition: qwt_plot_item.cpp:559
QwtPlotItem::plot
QwtPlot * plot() const
Return attached plot.
Definition: qwt_plot_item.cpp:142
QwtPlotItem::xAxis
QwtAxisId xAxis() const
Return xAxis.
Definition: qwt_plot_item.cpp:553
QwtPlotItem::RenderAntialiased
@ RenderAntialiased
Enable antialiasing.
Definition: qwt_plot_item.h:206
QwtPlotItem::testRenderHint
bool testRenderHint(RenderHint) const
Definition: qwt_plot_item.cpp:332
QwtPlotSeriesItem
Base class for plot items representing a series of samples.
Definition: qwt_plot_seriesitem.h:26
QwtPlotSeriesItem::drawSeries
virtual void drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27