qwt_plot_canvas.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_canvas.h"
00011 #include "qwt_painter.h"
00012 #include "qwt_math.h"
00013 #include "qwt_plot.h"
00014 
00015 #ifndef QWT_NO_OPENGL
00016 
00017 #if QT_VERSION < 0x050000
00018 #define FBO_OPENGL 0
00019 #else
00020 #define FBO_OPENGL 1
00021 #endif
00022 
00023 #if FBO_OPENGL
00024 #include <qopenglcontext.h>
00025 #include <qopenglframebufferobject.h>
00026 #include <qopenglpaintdevice.h>
00027 
00028 #if QT_VERSION >= 0x050100
00029 #include <qoffscreensurface.h>
00030 typedef QOffscreenSurface QwtPlotCanvasSurfaceGL;
00031 
00032 #else
00033 #include <qwindow.h>
00034 class QwtPlotCanvasSurfaceGL: public QWindow
00035 {
00036 public:
00037     QwtPlotCanvasSurfaceGL() { setSurfaceType( QWindow::OpenGLSurface ); }
00038 };
00039 #endif
00040 
00041 #else
00042 #include <qglframebufferobject.h>
00043 typedef QGLWidget QwtPlotCanvasSurfaceGL;
00044 #endif
00045 
00046 #endif // !QWT_NO_OPENGL
00047 
00048 #include <qpainter.h>
00049 #include <qstyle.h>
00050 #include <qstyleoption.h>
00051 #include <qpaintengine.h>
00052 #include <qevent.h>
00053 
00054 class QwtPlotCanvas::PrivateData
00055 {
00056 public:
00057     PrivateData():
00058         paintAttributes( 0 ),
00059 #ifndef QWT_NO_OPENGL
00060         surfaceGL( NULL ),
00061 #endif
00062         backingStore( NULL )
00063     {
00064     }
00065 
00066     ~PrivateData()
00067     {
00068         delete backingStore;
00069 
00070 #ifndef QWT_NO_OPENGL
00071         delete surfaceGL;
00072 #endif
00073     }
00074 
00075     QwtPlotCanvas::PaintAttributes paintAttributes;
00076 
00077 #ifndef QWT_NO_OPENGL
00078     QwtPlotCanvasSurfaceGL *surfaceGL;
00079 #endif
00080 
00081     QPixmap *backingStore;
00082 };
00083 
00090 QwtPlotCanvas::QwtPlotCanvas( QwtPlot *plot ):
00091     QFrame( plot ),
00092     QwtPlotAbstractCanvas( this )
00093 {
00094     d_data = new PrivateData;
00095 
00096     setPaintAttribute( QwtPlotCanvas::BackingStore, true );
00097     setPaintAttribute( QwtPlotCanvas::Opaque, true );
00098     setPaintAttribute( QwtPlotCanvas::HackStyledBackground, true );
00099 }
00100 
00102 QwtPlotCanvas::~QwtPlotCanvas()
00103 {
00104     delete d_data;
00105 }
00106 
00115 void QwtPlotCanvas::setPaintAttribute( PaintAttribute attribute, bool on )
00116 {
00117     if ( bool( d_data->paintAttributes & attribute ) == on )
00118         return;
00119 
00120     if ( on )
00121         d_data->paintAttributes |= attribute;
00122     else
00123         d_data->paintAttributes &= ~attribute;
00124 
00125     switch ( attribute )
00126     {
00127         case BackingStore:
00128         {
00129             if ( on )
00130             {
00131                 if ( d_data->backingStore == NULL )
00132                     d_data->backingStore = new QPixmap();
00133 
00134                 if ( isVisible() )
00135                 {
00136 #if QT_VERSION >= 0x050000
00137                     *d_data->backingStore = grab( rect() );
00138 #else
00139                     *d_data->backingStore = 
00140                         QPixmap::grabWidget( this, rect() );
00141 #endif
00142                 }
00143             }
00144             else
00145             {
00146                 delete d_data->backingStore;
00147                 d_data->backingStore = NULL;
00148             }
00149             break;
00150         }
00151         case Opaque:
00152         {
00153             if ( on )
00154                 setAttribute( Qt::WA_OpaquePaintEvent, true );
00155 
00156             break;
00157         }
00158         default:
00159         {
00160             break;
00161         }
00162     }
00163 }
00164 
00172 bool QwtPlotCanvas::testPaintAttribute( PaintAttribute attribute ) const
00173 {
00174     return d_data->paintAttributes & attribute;
00175 }
00176 
00178 const QPixmap *QwtPlotCanvas::backingStore() const
00179 {
00180     return d_data->backingStore;
00181 }
00182 
00184 void QwtPlotCanvas::invalidateBackingStore()
00185 {
00186     if ( d_data->backingStore )
00187         *d_data->backingStore = QPixmap();
00188 }
00189 
00196 bool QwtPlotCanvas::event( QEvent *event )
00197 {
00198     if ( event->type() == QEvent::PolishRequest ) 
00199     {
00200         if ( testPaintAttribute( QwtPlotCanvas::Opaque ) )
00201         {
00202             // Setting a style sheet changes the 
00203             // Qt::WA_OpaquePaintEvent attribute, but we insist
00204             // on painting the background.
00205             
00206             setAttribute( Qt::WA_OpaquePaintEvent, true );
00207         }
00208     }
00209 
00210     if ( event->type() == QEvent::PolishRequest || 
00211         event->type() == QEvent::StyleChange )
00212     {
00213         updateStyleSheetInfo();
00214     }
00215 
00216     return QFrame::event( event );
00217 }
00218 
00223 void QwtPlotCanvas::paintEvent( QPaintEvent *event )
00224 {
00225     QPainter painter( this );
00226     painter.setClipRegion( event->region() );
00227 
00228     if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) &&
00229         d_data->backingStore != NULL )
00230     {
00231         QPixmap &bs = *d_data->backingStore;
00232         if ( bs.size() != size() )
00233         {
00234             bs = QwtPainter::backingStore( this, size() );
00235 
00236 #ifndef QWT_NO_OPENGL
00237             if ( testPaintAttribute( OpenGLBuffer ) )
00238             {
00239                 QPainter p( &bs );
00240                 p.drawImage( 0, 0, toImageFBO( size() ) );
00241                 p.end();
00242             }
00243             else
00244 #endif
00245             if ( testAttribute(Qt::WA_StyledBackground) )
00246             {
00247                 QPainter p( &bs );
00248                 drawStyled( &p, testPaintAttribute( HackStyledBackground ) );
00249             }
00250             else
00251             {
00252                 QPainter p;
00253                 if ( borderRadius() <= 0.0 )
00254                 {
00255                     QwtPainter::fillPixmap( this, bs );
00256                     p.begin( &bs );
00257                     drawCanvas( &p );
00258                 }
00259                 else
00260                 {
00261                     p.begin( &bs );
00262                     drawUnstyled( &p );
00263                 }
00264 
00265                 if ( frameWidth() > 0 )
00266                     drawBorder( &p );
00267             }
00268         }
00269 
00270         painter.drawPixmap( 0, 0, *d_data->backingStore );
00271     }
00272     else
00273     {
00274 #ifndef QWT_NO_OPENGL
00275         if ( testPaintAttribute( OpenGLBuffer ) )
00276         {
00277             painter.drawImage( 0, 0, toImageFBO( size() ) );
00278         }
00279         else
00280 #endif
00281         if ( testAttribute(Qt::WA_StyledBackground ) )
00282         {
00283             if ( testAttribute( Qt::WA_OpaquePaintEvent ) )
00284             {
00285                 drawStyled( &painter, testPaintAttribute( HackStyledBackground ) );
00286             }
00287             else
00288             {
00289                 drawCanvas( &painter );
00290             }
00291         }
00292         else
00293         {
00294             if ( testAttribute( Qt::WA_OpaquePaintEvent ) )
00295             {
00296                 if ( autoFillBackground() )
00297                 {
00298                     fillBackground( &painter );
00299                     drawBackground( &painter );
00300                 }
00301             }
00302             else
00303             {
00304                 if ( borderRadius() > 0.0 )
00305                 {
00306                     QPainterPath clipPath;
00307                     clipPath.addRect( rect() );
00308                     clipPath = clipPath.subtracted( borderPath( rect() ) );
00309 
00310                     painter.save();
00311 
00312                     painter.setClipPath( clipPath, Qt::IntersectClip );
00313                     fillBackground( &painter );
00314                     drawBackground( &painter );
00315 
00316                     painter.restore();
00317                 }
00318             }
00319 
00320             drawCanvas( &painter );
00321 
00322             if ( frameWidth() > 0 ) 
00323                 drawBorder( &painter );
00324         }
00325     }
00326 
00327     if ( hasFocus() && focusIndicator() == CanvasFocusIndicator )
00328         drawFocusIndicator( &painter );
00329 }
00330 
00337 void QwtPlotCanvas::drawBorder( QPainter *painter )
00338 {
00339 #if QT_VERSION >= 0x040500
00340     if ( borderRadius() <= 0 )
00341     {
00342         drawFrame( painter );
00343         return;
00344     }
00345 #endif
00346 
00347     QwtPlotAbstractCanvas::drawBorder( painter );
00348 }
00349 
00354 void QwtPlotCanvas::resizeEvent( QResizeEvent *event )
00355 {
00356     QFrame::resizeEvent( event );
00357     updateStyleSheetInfo();
00358 }
00359 
00364 void QwtPlotCanvas::replot()
00365 {
00366     invalidateBackingStore();
00367 
00368     if ( testPaintAttribute( QwtPlotCanvas::ImmediatePaint ) )
00369         repaint( contentsRect() );
00370     else
00371         update( contentsRect() );
00372 }
00373 
00383 QPainterPath QwtPlotCanvas::borderPath( const QRect &rect ) const
00384 {
00385     return borderPath2( rect );
00386 }
00387 
00388 #ifndef QWT_NO_OPENGL
00389 
00390 #define FIX_GL_TRANSLATION 0
00391 
00392 QImage QwtPlotCanvas::toImageFBO( const QSize &size ) 
00393 {
00394     const int numSamples = 4;
00395 
00396 #if FBO_OPENGL
00397 
00398     if ( d_data->surfaceGL == NULL )
00399     {
00400         d_data->surfaceGL = new QwtPlotCanvasSurfaceGL();
00401         d_data->surfaceGL->create();
00402     }
00403 
00404     QOpenGLContext context;
00405     context.create();
00406 
00407     context.makeCurrent( d_data->surfaceGL );
00408 
00409 
00410     QOpenGLFramebufferObjectFormat fboFormat;
00411     fboFormat.setSamples(numSamples);
00412     QOpenGLFramebufferObject fbo( size, fboFormat );
00413 
00414     QOpenGLPaintDevice pd( size );
00415 
00416 #else
00417 
00418     if ( d_data->surfaceGL == NULL )
00419     {
00420         QGLFormat format = QGLFormat::defaultFormat();
00421         format.setSampleBuffers( true );
00422         format.setSamples( numSamples );
00423 
00424         d_data->surfaceGL = new QwtPlotCanvasSurfaceGL( format );
00425     }
00426 
00427     d_data->surfaceGL->makeCurrent();
00428 
00429 #if QT_VERSION >= 0x040600
00430     QGLFramebufferObjectFormat fboFormat;
00431     fboFormat.setSamples(numSamples);
00432 
00433     QGLFramebufferObject fbo( size, fboFormat );
00434 #else
00435     QGLFramebufferObject fbo( size );
00436 #endif
00437     QGLFramebufferObject &pd = fbo;
00438 
00439 #endif
00440 
00441     QPainter painter( &pd );
00442 
00443     if ( testAttribute( Qt::WA_StyledBackground ) )
00444         drawStyled( &painter, testPaintAttribute( HackStyledBackground ) );
00445     else
00446         drawUnstyled( &painter );
00447     
00448     if ( frameWidth() > 0 )
00449         drawBorder( &painter );
00450     
00451     painter.end();
00452 
00453     QImage image = fbo.toImage();
00454 
00455 #if QT_VERSION >= 0x050000
00456     image.setDevicePixelRatio( QwtPainter::devicePixelRatio( this ) );
00457 #endif
00458     return image;
00459 }
00460 
00461 #else
00462 
00463 QImage QwtPlotCanvas::toImageFBO( const QSize &)
00464 {
00465     // will never be called
00466     return QImage();
00467 }
00468 
00469 #endif


plotjuggler
Author(s): Davide Faconti
autogenerated on Wed Jul 3 2019 19:28:05