Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
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
20static 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,
33 seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
34}
35
36static inline bool qwtHasBackingStore( const QwtPlotCanvas* canvas )
37{
39 && canvas->backingStore() && !canvas->backingStore()->isNull();
40}
41
42class QwtPlotDirectPainter::PrivateData
43{
44 public:
45 PrivateData()
46 : hasClipping( false )
47 , seriesItem( NULL )
48 , from( 0 )
49 , to( 0 )
50 {
51 }
52
54
55 bool hasClipping;
56 QRegion clipRegion;
57
58 QPainter painter;
59
60 QwtPlotSeriesItem* seriesItem;
61 int from;
62 int to;
63};
64
67 : QObject( parent )
68{
69 m_data = new PrivateData;
70}
71
77
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
106{
107 return m_data->attributes & attribute;
108}
109
117{
118 m_data->hasClipping = enable;
119}
120
126{
127 return m_data->hasClipping;
128}
129
141void QwtPlotDirectPainter::setClipRegion( const QRegion& region )
142{
143 m_data->clipRegion = region;
144 m_data->hasClipping = true;
145}
146
152{
153 return m_data->clipRegion;
154}
155
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
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
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
277bool 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}
Canvas of a QwtPlot.
bool testPaintAttribute(PaintAttribute) const
@ BackingStore
Paint double buffered reusing the content of the pixmap buffer when possible.
const QPixmap * backingStore() const
void setClipRegion(const QRegion &)
Assign a clip region and enable clipping.
void setAttribute(Attribute, bool on)
QFlags< Attribute > Attributes
bool testAttribute(Attribute) const
void reset()
Close the internal QPainter.
virtual ~QwtPlotDirectPainter()
Destructor.
void drawSeries(QwtPlotSeriesItem *, int from, int to)
Draw a set of points of a seriesItem.
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
QwtPlotDirectPainter(QObject *parent=NULL)
Constructor.
A 2-D plotting widget.
Definition qwt_plot.h:79
QWidget * canvas()
Definition qwt_plot.cpp:463
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition qwt_plot.cpp:800
QwtAxisId yAxis() const
Return yAxis.
QwtPlot * plot() const
Return attached plot.
QwtAxisId xAxis() const
Return xAxis.
@ RenderAntialiased
Enable antialiasing.
bool testRenderHint(RenderHint) const
Base class for plot items representing a series of samples.
virtual void drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
A scale map.