qwt_plot_directpainter.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_plot_directpainter.h"
00011 #include "qwt_scale_map.h"
00012 #include "qwt_plot.h"
00013 #include "qwt_plot_canvas.h"
00014 #include "qwt_plot_seriesitem.h"
00015 #include <qpainter.h>
00016 #include <qevent.h>
00017 #include <qapplication.h>
00018 #include <qpixmap.h>
00019 
00020 static inline void qwtRenderItem( 
00021     QPainter *painter, const QRect &canvasRect,
00022     QwtPlotSeriesItem *seriesItem, int from, int to )
00023 {
00024     // A minor performance improvement is possible
00025     // with caching the maps. TODO ...
00026 
00027     QwtPlot *plot = seriesItem->plot();
00028     const QwtScaleMap xMap = plot->canvasMap( seriesItem->xAxis() );
00029     const QwtScaleMap yMap = plot->canvasMap( seriesItem->yAxis() );
00030 
00031     painter->setRenderHint( QPainter::Antialiasing,
00032         seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
00033     seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
00034 }
00035 
00036 static inline bool qwtHasBackingStore( const QwtPlotCanvas *canvas )
00037 {
00038     return canvas->testPaintAttribute( QwtPlotCanvas::BackingStore )
00039         && canvas->backingStore() && !canvas->backingStore()->isNull();
00040 }
00041 
00042 class QwtPlotDirectPainter::PrivateData
00043 {
00044 public:
00045     PrivateData():
00046         attributes( 0 ),
00047         hasClipping(false),
00048         seriesItem( NULL ),
00049         from( 0 ),
00050         to( 0 )
00051     {
00052     }
00053 
00054     QwtPlotDirectPainter::Attributes attributes;
00055 
00056     bool hasClipping;
00057     QRegion clipRegion;
00058 
00059     QPainter painter;
00060 
00061     QwtPlotSeriesItem *seriesItem;
00062     int from;
00063     int to;
00064 };
00065 
00067 QwtPlotDirectPainter::QwtPlotDirectPainter( QObject *parent ):
00068     QObject( parent )
00069 {
00070     d_data = new PrivateData;
00071 }
00072 
00074 QwtPlotDirectPainter::~QwtPlotDirectPainter()
00075 {
00076     delete d_data;
00077 }
00078 
00087 void QwtPlotDirectPainter::setAttribute( Attribute attribute, bool on )
00088 {
00089     if ( bool( d_data->attributes & attribute ) != on )
00090     {
00091         if ( on )
00092             d_data->attributes |= attribute;
00093         else
00094             d_data->attributes &= ~attribute;
00095 
00096         if ( ( attribute == AtomicPainter ) && on )
00097             reset();
00098     }
00099 }
00100 
00106 bool QwtPlotDirectPainter::testAttribute( Attribute attribute ) const
00107 {
00108     return d_data->attributes & attribute;
00109 }
00110 
00117 void QwtPlotDirectPainter::setClipping( bool enable )
00118 {
00119     d_data->hasClipping = enable;
00120 }
00121 
00126 bool QwtPlotDirectPainter::hasClipping() const
00127 {
00128     return d_data->hasClipping;
00129 }
00130 
00142 void QwtPlotDirectPainter::setClipRegion( const QRegion &region )
00143 {
00144     d_data->clipRegion = region;
00145     d_data->hasClipping = true;
00146 }
00147 
00152 QRegion QwtPlotDirectPainter::clipRegion() const
00153 {
00154     return d_data->clipRegion;
00155 }
00156 
00173 void QwtPlotDirectPainter::drawSeries(
00174     QwtPlotSeriesItem *seriesItem, int from, int to )
00175 {
00176     if ( seriesItem == NULL || seriesItem->plot() == NULL )
00177         return;
00178 
00179     QWidget *canvas = seriesItem->plot()->canvas();
00180     const QRect canvasRect = canvas->contentsRect();
00181 
00182     QwtPlotCanvas *plotCanvas = qobject_cast<QwtPlotCanvas *>( canvas );
00183 
00184     if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
00185     {
00186         QPainter painter( const_cast<QPixmap *>( plotCanvas->backingStore() ) );
00187 
00188         if ( d_data->hasClipping )
00189             painter.setClipRegion( d_data->clipRegion );
00190 
00191         qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
00192 
00193         painter.end();
00194 
00195         if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
00196         {
00197             plotCanvas->repaint();
00198             return;
00199         }
00200     }
00201 
00202     bool immediatePaint = true;
00203     if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) ) 
00204     {
00205 #if QT_VERSION < 0x050000
00206         if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
00207 #endif
00208             immediatePaint = false;
00209     }
00210 
00211     if ( immediatePaint )
00212     {
00213         if ( !d_data->painter.isActive() )
00214         {
00215             reset();
00216 
00217             d_data->painter.begin( canvas );
00218             canvas->installEventFilter( this );
00219         }
00220 
00221         if ( d_data->hasClipping )
00222         {
00223             d_data->painter.setClipRegion( 
00224                 QRegion( canvasRect ) & d_data->clipRegion );
00225         }
00226         else
00227         {
00228             if ( !d_data->painter.hasClipping() )
00229                 d_data->painter.setClipRect( canvasRect );
00230         }
00231 
00232         qwtRenderItem( &d_data->painter, canvasRect, seriesItem, from, to );
00233 
00234         if ( d_data->attributes & QwtPlotDirectPainter::AtomicPainter )
00235         {
00236             reset();
00237         }
00238         else
00239         {
00240             if ( d_data->hasClipping )
00241                 d_data->painter.setClipping( false );
00242         }
00243     }
00244     else
00245     {
00246         reset();
00247 
00248         d_data->seriesItem = seriesItem;
00249         d_data->from = from;
00250         d_data->to = to;
00251 
00252         QRegion clipRegion = canvasRect;
00253         if ( d_data->hasClipping )
00254             clipRegion &= d_data->clipRegion;
00255 
00256         canvas->installEventFilter( this );
00257         canvas->repaint(clipRegion);
00258         canvas->removeEventFilter( this );
00259 
00260         d_data->seriesItem = NULL;
00261     }
00262 }
00263 
00265 void QwtPlotDirectPainter::reset()
00266 {
00267     if ( d_data->painter.isActive() )
00268     {
00269         QWidget *w = static_cast<QWidget *>( d_data->painter.device() );
00270         if ( w )
00271             w->removeEventFilter( this );
00272 
00273         d_data->painter.end();
00274     }
00275 }
00276 
00278 bool QwtPlotDirectPainter::eventFilter( QObject *, QEvent *event )
00279 {
00280     if ( event->type() == QEvent::Paint )
00281     {
00282         reset();
00283 
00284         if ( d_data->seriesItem )
00285         {
00286             const QPaintEvent *pe = static_cast< QPaintEvent *>( event );
00287 
00288             QWidget *canvas = d_data->seriesItem->plot()->canvas();
00289 
00290             QPainter painter( canvas );
00291             painter.setClipRegion( pe->region() );
00292 
00293             bool doCopyCache = testAttribute( CopyBackingStore );
00294 
00295             if ( doCopyCache )
00296             {
00297                 QwtPlotCanvas *plotCanvas = 
00298                     qobject_cast<QwtPlotCanvas *>( canvas );
00299                 if ( plotCanvas )
00300                 {
00301                     doCopyCache = qwtHasBackingStore( plotCanvas );
00302                     if ( doCopyCache )
00303                     {
00304                         painter.drawPixmap( plotCanvas->rect().topLeft(), 
00305                             *plotCanvas->backingStore() );
00306                     }
00307                 }
00308             }
00309 
00310             if ( !doCopyCache )
00311             {
00312                 qwtRenderItem( &painter, canvas->contentsRect(),
00313                     d_data->seriesItem, d_data->from, d_data->to );
00314             }
00315 
00316             return true; // don't call QwtPlotCanvas::paintEvent()
00317         }
00318     }
00319 
00320     return false;
00321 }


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56