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 
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,
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  hasClipping(false),
47  seriesItem( NULL ),
48  from( 0 ),
49  to( 0 )
50  {
51  }
52 
54 
56  QRegion clipRegion;
57 
58  QPainter painter;
59 
61  int from;
62  int to;
63 };
64 
67  QObject( parent )
68 {
69  d_data = new PrivateData;
70 }
71 
74 {
75  delete d_data;
76 }
77 
87 {
88  if ( bool( d_data->attributes & attribute ) != on )
89  {
90  if ( on )
91  d_data->attributes |= attribute;
92  else
93  d_data->attributes &= ~attribute;
94 
95  if ( ( attribute == AtomicPainter ) && on )
96  reset();
97  }
98 }
99 
106 {
107  return d_data->attributes & attribute;
108 }
109 
117 {
119 }
120 
126 {
127  return d_data->hasClipping;
128 }
129 
141 void QwtPlotDirectPainter::setClipRegion( const QRegion &region )
142 {
143  d_data->clipRegion = region;
144  d_data->hasClipping = true;
145 }
146 
152 {
153  return d_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 ( d_data->hasClipping )
188  painter.setClipRegion( d_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 ( !d_data->painter.isActive() )
213  {
214  reset();
215 
216  d_data->painter.begin( canvas );
217  canvas->installEventFilter( this );
218  }
219 
220  if ( d_data->hasClipping )
221  {
222  d_data->painter.setClipRegion(
223  QRegion( canvasRect ) & d_data->clipRegion );
224  }
225  else
226  {
227  if ( !d_data->painter.hasClipping() )
228  d_data->painter.setClipRect( canvasRect );
229  }
230 
231  qwtRenderItem( &d_data->painter, canvasRect, seriesItem, from, to );
232 
234  {
235  reset();
236  }
237  else
238  {
239  if ( d_data->hasClipping )
240  d_data->painter.setClipping( false );
241  }
242  }
243  else
244  {
245  reset();
246 
247  d_data->seriesItem = seriesItem;
248  d_data->from = from;
249  d_data->to = to;
250 
251  QRegion clipRegion = canvasRect;
252  if ( d_data->hasClipping )
253  clipRegion &= d_data->clipRegion;
254 
255  canvas->installEventFilter( this );
256  canvas->repaint(clipRegion);
257  canvas->removeEventFilter( this );
258 
259  d_data->seriesItem = NULL;
260  }
261 }
262 
265 {
266  if ( d_data->painter.isActive() )
267  {
268  QWidget *w = static_cast<QWidget *>( d_data->painter.device() );
269  if ( w )
270  w->removeEventFilter( this );
271 
272  d_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 ( d_data->seriesItem )
284  {
285  const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
286 
287  QWidget *canvas = d_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(),
313  }
314 
315  return true; // don't call QwtPlotCanvas::paintEvent()
316  }
317  }
318 
319  return false;
320 }
virtual bool eventFilter(QObject *, QEvent *) QWT_OVERRIDE
Event filter.
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:75
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 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:786
int yAxis() const
Return yAxis.
A scale map.
Definition: qwt_scale_map.h:26
QWidget * canvas()
Definition: qwt_plot.cpp:460
QFlags< Attribute > Attributes
Paint attributes.
void setClipRegion(const QRegion &)
Assign a clip region and enable clipping.
std::enable_if_t< all< Args... >::value, enable_t > enable
Definition: sol.hpp:1726
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 Sun Dec 6 2020 03:48:10