qwt_plot_directpainter.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 #include <qpainter.h>
16 #include <qevent.h>
17 #include <qapplication.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,
33  seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
34 }
35 
36 static inline bool qwtHasBackingStore( const QwtPlotCanvas *canvas )
37 {
39  && canvas->backingStore() && !canvas->backingStore()->isNull();
40 }
41 
43 {
44 public:
46  attributes( 0 ),
47  hasClipping(false),
48  seriesItem( NULL ),
49  from( 0 ),
50  to( 0 )
51  {
52  }
53 
55 
57  QRegion clipRegion;
58 
59  QPainter painter;
60 
62  int from;
63  int to;
64 };
65 
68  QObject( parent )
69 {
70  d_data = new PrivateData;
71 }
72 
75 {
76  delete d_data;
77 }
78 
88 {
89  if ( bool( d_data->attributes & attribute ) != on )
90  {
91  if ( on )
92  d_data->attributes |= attribute;
93  else
94  d_data->attributes &= ~attribute;
95 
96  if ( ( attribute == AtomicPainter ) && on )
97  reset();
98  }
99 }
100 
107 {
108  return d_data->attributes & attribute;
109 }
110 
118 {
119  d_data->hasClipping = enable;
120 }
121 
127 {
128  return d_data->hasClipping;
129 }
130 
142 void QwtPlotDirectPainter::setClipRegion( const QRegion &region )
143 {
144  d_data->clipRegion = region;
145  d_data->hasClipping = true;
146 }
147 
153 {
154  return d_data->clipRegion;
155 }
156 
174  QwtPlotSeriesItem *seriesItem, int from, int to )
175 {
176  if ( seriesItem == NULL || seriesItem->plot() == NULL )
177  return;
178 
179  QWidget *canvas = seriesItem->plot()->canvas();
180  const QRect canvasRect = canvas->contentsRect();
181 
182  QwtPlotCanvas *plotCanvas = qobject_cast<QwtPlotCanvas *>( canvas );
183 
184  if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
185  {
186  QPainter painter( const_cast<QPixmap *>( plotCanvas->backingStore() ) );
187 
188  if ( d_data->hasClipping )
189  painter.setClipRegion( d_data->clipRegion );
190 
191  qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
192 
193  painter.end();
194 
196  {
197  plotCanvas->repaint();
198  return;
199  }
200  }
201 
202  bool immediatePaint = true;
203  if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) )
204  {
205 #if QT_VERSION < 0x050000
206  if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
207 #endif
208  immediatePaint = false;
209  }
210 
211  if ( immediatePaint )
212  {
213  if ( !d_data->painter.isActive() )
214  {
215  reset();
216 
217  d_data->painter.begin( canvas );
218  canvas->installEventFilter( this );
219  }
220 
221  if ( d_data->hasClipping )
222  {
223  d_data->painter.setClipRegion(
224  QRegion( canvasRect ) & d_data->clipRegion );
225  }
226  else
227  {
228  if ( !d_data->painter.hasClipping() )
229  d_data->painter.setClipRect( canvasRect );
230  }
231 
232  qwtRenderItem( &d_data->painter, canvasRect, seriesItem, from, to );
233 
235  {
236  reset();
237  }
238  else
239  {
240  if ( d_data->hasClipping )
241  d_data->painter.setClipping( false );
242  }
243  }
244  else
245  {
246  reset();
247 
248  d_data->seriesItem = seriesItem;
249  d_data->from = from;
250  d_data->to = to;
251 
252  QRegion clipRegion = canvasRect;
253  if ( d_data->hasClipping )
254  clipRegion &= d_data->clipRegion;
255 
256  canvas->installEventFilter( this );
257  canvas->repaint(clipRegion);
258  canvas->removeEventFilter( this );
259 
260  d_data->seriesItem = NULL;
261  }
262 }
263 
266 {
267  if ( d_data->painter.isActive() )
268  {
269  QWidget *w = static_cast<QWidget *>( d_data->painter.device() );
270  if ( w )
271  w->removeEventFilter( this );
272 
273  d_data->painter.end();
274  }
275 }
276 
278 bool QwtPlotDirectPainter::eventFilter( QObject *, QEvent *event )
279 {
280  if ( event->type() == QEvent::Paint )
281  {
282  reset();
283 
284  if ( d_data->seriesItem )
285  {
286  const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
287 
288  QWidget *canvas = d_data->seriesItem->plot()->canvas();
289 
290  QPainter painter( canvas );
291  painter.setClipRegion( pe->region() );
292 
293  bool doCopyCache = testAttribute( CopyBackingStore );
294 
295  if ( doCopyCache )
296  {
297  QwtPlotCanvas *plotCanvas =
298  qobject_cast<QwtPlotCanvas *>( canvas );
299  if ( plotCanvas )
300  {
301  doCopyCache = qwtHasBackingStore( plotCanvas );
302  if ( doCopyCache )
303  {
304  painter.drawPixmap( plotCanvas->rect().topLeft(),
305  *plotCanvas->backingStore() );
306  }
307  }
308  }
309 
310  if ( !doCopyCache )
311  {
312  qwtRenderItem( &painter, canvas->contentsRect(),
314  }
315 
316  return true; // don't call QwtPlotCanvas::paintEvent()
317  }
318  }
319 
320  return false;
321 }
Enable antialiasing.
static void qwtRenderItem(QPainter *painter, const QRect &canvasRect, QwtPlotSeriesItem *seriesItem, int from, int to)
Attribute
Paint attributes.
int xAxis() const
Return xAxis.
void drawSeries(QwtPlotSeriesItem *, int from, int to)
Draw a set of points of a seriesItem.
bool testAttribute(Attribute) const
Canvas of a QwtPlot.
A 2-D plotting widget.
Definition: qwt_plot.h:74
QwtPlot * plot() const
Return attached plot.
QwtPlotDirectPainter::Attributes attributes
bool testPaintAttribute(PaintAttribute) const
virtual ~QwtPlotDirectPainter()
Destructor.
void setAttribute(Attribute, bool on)
const QPixmap * backingStore() const
void reset()
Close the internal QPainter.
bool testRenderHint(RenderHint) const
virtual bool eventFilter(QObject *, QEvent *)
Event filter.
virtual void drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
virtual QwtScaleMap canvasMap(int axisId) const
Definition: qwt_plot.cpp:790
int yAxis() const
Return yAxis.
A scale map.
Definition: qwt_scale_map.h:30
TFSIMD_FORCE_INLINE const tfScalar & w() const
QWidget * canvas()
Definition: qwt_plot.cpp:467
QFlags< Attribute > Attributes
Paint attributes.
void setClipRegion(const QRegion &)
Assign a clip region and enable clipping.
QwtPlotDirectPainter(QObject *parent=NULL)
Constructor.
static bool qwtHasBackingStore(const QwtPlotCanvas *canvas)
Base class for plot items representing a series of samples.
Paint double buffered reusing the content of the pixmap buffer when possible.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17