Loading...
Searching...
No Matches
qwt_plot_directpainter.cpp
/******************************************************************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_plot_directpainter.h"
#include "qwt_scale_map.h"
#include "qwt_plot.h"
#include "qwt_plot_canvas.h"
#include "qwt_plot_seriesitem.h"
#include <qpainter.h>
#include <qevent.h>
#include <qpixmap.h>
static inline void qwtRenderItem(
QPainter* painter, const QRect& canvasRect,
QwtPlotSeriesItem* seriesItem, int from, int to )
{
// A minor performance improvement is possible
// with caching the maps. TODO ...
QwtPlot* plot = seriesItem->plot();
const QwtScaleMap xMap = plot->canvasMap( seriesItem->xAxis() );
const QwtScaleMap yMap = plot->canvasMap( seriesItem->yAxis() );
painter->setRenderHint( QPainter::Antialiasing,
seriesItem->testRenderHint( QwtPlotItem::RenderAntialiased ) );
seriesItem->drawSeries( painter, xMap, yMap, canvasRect, from, to );
}
static inline bool qwtHasBackingStore( const QwtPlotCanvas* canvas )
{
return canvas->testPaintAttribute( QwtPlotCanvas::BackingStore )
&& canvas->backingStore() && !canvas->backingStore()->isNull();
}
class QwtPlotDirectPainter::PrivateData
{
public:
PrivateData()
: hasClipping( false )
, seriesItem( NULL )
, from( 0 )
, to( 0 )
{
}
QwtPlotDirectPainter::Attributes attributes;
bool hasClipping;
QRegion clipRegion;
QPainter painter;
QwtPlotSeriesItem* seriesItem;
int from;
int to;
};
QwtPlotDirectPainter::QwtPlotDirectPainter( QObject* parent )
: QObject( parent )
{
m_data = new PrivateData;
}
QwtPlotDirectPainter::~QwtPlotDirectPainter()
{
delete m_data;
}
void QwtPlotDirectPainter::setAttribute( Attribute attribute, bool on )
{
if ( bool( m_data->attributes & attribute ) != on )
{
if ( on )
m_data->attributes |= attribute;
else
m_data->attributes &= ~attribute;
if ( ( attribute == AtomicPainter ) && on )
reset();
}
}
bool QwtPlotDirectPainter::testAttribute( Attribute attribute ) const
{
return m_data->attributes & attribute;
}
void QwtPlotDirectPainter::setClipping( bool enable )
{
m_data->hasClipping = enable;
}
bool QwtPlotDirectPainter::hasClipping() const
{
return m_data->hasClipping;
}
void QwtPlotDirectPainter::setClipRegion( const QRegion& region )
{
m_data->clipRegion = region;
m_data->hasClipping = true;
}
QRegion QwtPlotDirectPainter::clipRegion() const
{
return m_data->clipRegion;
}
void QwtPlotDirectPainter::drawSeries(
QwtPlotSeriesItem* seriesItem, int from, int to )
{
if ( seriesItem == NULL || seriesItem->plot() == NULL )
return;
QWidget* canvas = seriesItem->plot()->canvas();
const QRect canvasRect = canvas->contentsRect();
QwtPlotCanvas* plotCanvas = qobject_cast< QwtPlotCanvas* >( canvas );
if ( plotCanvas && qwtHasBackingStore( plotCanvas ) )
{
QPainter painter( const_cast< QPixmap* >( plotCanvas->backingStore() ) );
if ( m_data->hasClipping )
painter.setClipRegion( m_data->clipRegion );
qwtRenderItem( &painter, canvasRect, seriesItem, from, to );
painter.end();
if ( testAttribute( QwtPlotDirectPainter::FullRepaint ) )
{
plotCanvas->repaint();
return;
}
}
bool immediatePaint = true;
if ( !canvas->testAttribute( Qt::WA_WState_InPaintEvent ) )
{
#if QT_VERSION < 0x050000
if ( !canvas->testAttribute( Qt::WA_PaintOutsidePaintEvent ) )
#endif
immediatePaint = false;
}
if ( immediatePaint )
{
if ( !m_data->painter.isActive() )
{
reset();
m_data->painter.begin( canvas );
canvas->installEventFilter( this );
}
if ( m_data->hasClipping )
{
m_data->painter.setClipRegion(
QRegion( canvasRect ) & m_data->clipRegion );
}
else
{
if ( !m_data->painter.hasClipping() )
m_data->painter.setClipRect( canvasRect );
}
qwtRenderItem( &m_data->painter, canvasRect, seriesItem, from, to );
if ( m_data->attributes & QwtPlotDirectPainter::AtomicPainter )
{
reset();
}
else
{
if ( m_data->hasClipping )
m_data->painter.setClipping( false );
}
}
else
{
reset();
m_data->seriesItem = seriesItem;
m_data->from = from;
m_data->to = to;
QRegion clipRegion = canvasRect;
if ( m_data->hasClipping )
clipRegion &= m_data->clipRegion;
canvas->installEventFilter( this );
canvas->repaint(clipRegion);
canvas->removeEventFilter( this );
m_data->seriesItem = NULL;
}
}
void QwtPlotDirectPainter::reset()
{
if ( m_data->painter.isActive() )
{
QWidget* w = static_cast< QWidget* >( m_data->painter.device() );
if ( w )
w->removeEventFilter( this );
m_data->painter.end();
}
}
bool QwtPlotDirectPainter::eventFilter( QObject*, QEvent* event )
{
if ( event->type() == QEvent::Paint )
{
reset();
if ( m_data->seriesItem )
{
const QPaintEvent* pe = static_cast< QPaintEvent* >( event );
QWidget* canvas = m_data->seriesItem->plot()->canvas();
QPainter painter( canvas );
painter.setClipRegion( pe->region() );
bool doCopyCache = testAttribute( CopyBackingStore );
if ( doCopyCache )
{
QwtPlotCanvas* plotCanvas =
qobject_cast< QwtPlotCanvas* >( canvas );
if ( plotCanvas )
{
doCopyCache = qwtHasBackingStore( plotCanvas );
if ( doCopyCache )
{
painter.drawPixmap( plotCanvas->rect().topLeft(),
*plotCanvas->backingStore() );
}
}
}
if ( !doCopyCache )
{
qwtRenderItem( &painter, canvas->contentsRect(),
m_data->seriesItem, m_data->from, m_data->to );
}
return true; // don't call QwtPlotCanvas::paintEvent()
}
}
return false;
}
QwtPlotCanvas
Canvas of a QwtPlot.
Definition qwt_plot_canvas.h:30
QwtPlotCanvas::testPaintAttribute
bool testPaintAttribute(PaintAttribute) const
Definition qwt_plot_canvas.cpp:127
QwtPlotCanvas::BackingStore
@ BackingStore
Paint double buffered reusing the content of the pixmap buffer when possible.
Definition qwt_plot_canvas.h:57
QwtPlotCanvas::backingStore
const QPixmap * backingStore() const
Definition qwt_plot_canvas.cpp:133
QwtPlotDirectPainter::setClipRegion
void setClipRegion(const QRegion &)
Assign a clip region and enable clipping.
Definition qwt_plot_directpainter.cpp:141
QwtPlotDirectPainter::hasClipping
bool hasClipping() const
Definition qwt_plot_directpainter.cpp:125
QwtPlotDirectPainter::Attribute
Attribute
Paint attributes.
Definition qwt_plot_directpainter.h:47
QwtPlotDirectPainter::FullRepaint
@ FullRepaint
Definition qwt_plot_directpainter.h:60
QwtPlotDirectPainter::CopyBackingStore
@ CopyBackingStore
Definition qwt_plot_directpainter.h:70
QwtPlotDirectPainter::AtomicPainter
@ AtomicPainter
Definition qwt_plot_directpainter.h:54
QwtPlotDirectPainter::setAttribute
void setAttribute(Attribute, bool on)
Definition qwt_plot_directpainter.cpp:86
QwtPlotDirectPainter::Attributes
QFlags< Attribute > Attributes
Definition qwt_plot_directpainter.h:73
QwtPlotDirectPainter::testAttribute
bool testAttribute(Attribute) const
Definition qwt_plot_directpainter.cpp:105
QwtPlotDirectPainter::clipRegion
QRegion clipRegion() const
Definition qwt_plot_directpainter.cpp:151
QwtPlotDirectPainter::reset
void reset()
Close the internal QPainter.
Definition qwt_plot_directpainter.cpp:264
QwtPlotDirectPainter::~QwtPlotDirectPainter
virtual ~QwtPlotDirectPainter()
Destructor.
Definition qwt_plot_directpainter.cpp:73
QwtPlotDirectPainter::drawSeries
void drawSeries(QwtPlotSeriesItem *, int from, int to)
Draw a set of points of a seriesItem.
Definition qwt_plot_directpainter.cpp:172
QwtPlotDirectPainter::setClipping
void setClipping(bool)
Definition qwt_plot_directpainter.cpp:116
QwtPlotDirectPainter::eventFilter
virtual bool eventFilter(QObject *, QEvent *) override
Event filter.
Definition qwt_plot_directpainter.cpp:277
QwtPlotDirectPainter::QwtPlotDirectPainter
QwtPlotDirectPainter(QObject *parent=NULL)
Constructor.
Definition qwt_plot_directpainter.cpp:66
QwtPlot
A 2-D plotting widget.
Definition qwt_plot.h:79
QwtPlot::canvas
QWidget * canvas()
Definition qwt_plot.cpp:463
QwtPlot::canvasMap
virtual QwtScaleMap canvasMap(QwtAxisId) const
Definition qwt_plot.cpp:800
QwtPlotItem::yAxis
QwtAxisId yAxis() const
Return yAxis.
Definition qwt_plot_item.cpp:559
QwtPlotItem::plot
QwtPlot * plot() const
Return attached plot.
Definition qwt_plot_item.cpp:142
QwtPlotItem::xAxis
QwtAxisId xAxis() const
Return xAxis.
Definition qwt_plot_item.cpp:553
QwtPlotItem::RenderAntialiased
@ RenderAntialiased
Enable antialiasing.
Definition qwt_plot_item.h:206
QwtPlotItem::testRenderHint
bool testRenderHint(RenderHint) const
Definition qwt_plot_item.cpp:332
QwtPlotSeriesItem
Base class for plot items representing a series of samples.
Definition qwt_plot_seriesitem.h:26
QwtPlotSeriesItem::drawSeries
virtual void drawSeries(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to) const =0
QwtScaleMap
A scale map.
Definition qwt_scale_map.h:27