10#include "qwt_widget_overlay.h"
11#include "qwt_painter.h"
14#include <qpaintengine.h>
15#include <qpainterpath.h>
21static QImage::Format qwtMaskImageFormat()
24 return QImage::Format_ARGB32;
26 return QImage::Format_ARGB32_Premultiplied;
29static QRegion qwtAlphaMask(
const QImage& image,
const QRegion& region )
31 const int w = image.width();
32 const int h = image.height();
37#if QT_VERSION >= 0x050800
38 for ( QRegion::const_iterator it = region.cbegin();
39 it != region.cend(); ++it )
44 for (
int i = 0; i < rects.size(); i++ )
46 const QRect& r = rects[i];
49 r.getCoords( &x1, &y1, &x2, &y2 );
52 x2 = qMin( x2, w - 1 );
54 y2 = qMin( y2, h - 1 );
56 for (
int y = y1; y <= y2; ++y )
62 reinterpret_cast< const uint*
> ( image.scanLine( y ) ) + x1;
63 for (
int x = x1; x <= x2; x++ )
65 const bool on = ( ( *line++ >> 24 ) != 0 );
70 rect.setCoords( rx0, y, x - 1, y );
84 rect.setCoords( rx0, y, x2, y );
85 mask = mask.united( rect );
93class QwtWidgetOverlay::PrivateData
108 void resetRgbaBuffer()
112 std::free( rgbaBuffer );
129 m_data =
new PrivateData;
131 setAttribute( Qt::WA_TransparentForMouseEvents );
132 setAttribute( Qt::WA_NoSystemBackground );
133 setFocusPolicy( Qt::NoFocus );
137 resize( widget->size() );
138 widget->installEventFilter(
this );
156 if ( mode != m_data->maskMode )
158 m_data->maskMode = mode;
159 m_data->resetRgbaBuffer();
169 return m_data->maskMode;
180 m_data->renderMode = mode;
189 return m_data->renderMode;
201void QwtWidgetOverlay::updateMask()
203 m_data->resetRgbaBuffer();
217 if ( hint.isEmpty() )
218 hint += QRect( 0, 0, width(), height() );
224 m_data->rgbaBuffer = ( uchar* )::calloc( width() * height(), 4 );
226 QImage image( m_data->rgbaBuffer,
227 width(), height(), qwtMaskImageFormat() );
229 QPainter painter( &image );
233 mask = qwtAlphaMask( image, hint );
238 m_data->resetRgbaBuffer();
247 if ( mask.isEmpty() )
263 const QRegion& clipRegion =
event->region();
265 QPainter painter(
this );
267 bool useRgbaBuffer =
false;
270 useRgbaBuffer =
true;
274 if ( painter.paintEngine()->type() == QPaintEngine::Raster )
275 useRgbaBuffer =
true;
278 if ( m_data->rgbaBuffer && useRgbaBuffer )
280 const QImage image( m_data->rgbaBuffer,
281 width(), height(), qwtMaskImageFormat() );
283 const int rectCount = clipRegion.rectCount();
285 if ( rectCount > 2000 )
288 painter.setClipRegion( clipRegion );
290 const QRect r = clipRegion.boundingRect();
291 painter.drawImage( r.topLeft(), image, r );
295#if QT_VERSION >= 0x050800
296 for ( QRegion::const_iterator it = clipRegion.cbegin();
297 it != clipRegion.cend(); ++it )
299 const QRect& r = *it;
300 painter.drawImage( r.topLeft(), image, r );
304 for (
int i = 0; i < rects.size(); i++ )
306 const QRect& r = rects[i];
307 painter.drawImage( r.topLeft(), image, r );
314 painter.setClipRegion( clipRegion );
327 m_data->resetRgbaBuffer();
330void QwtWidgetOverlay::draw( QPainter* painter )
const
332 if ( QWidget* widget = parentWidget() )
334 painter->setClipRect( widget->contentsRect() );
338 const int idx = widget->metaObject()->indexOfMethod(
"borderPath(QRect)" );
341 QPainterPath clipPath;
343 ( void )QMetaObject::invokeMethod(
344 widget,
"borderPath", Qt::DirectConnection,
345 Q_RETURN_ARG( QPainterPath, clipPath ), Q_ARG( QRect, rect() ) );
347 if (!clipPath.isEmpty() )
348 painter->setClipPath( clipPath, Qt::IntersectClip );
391 if (
object == parent() && event->type() == QEvent::Resize )
393 QResizeEvent*
resizeEvent =
static_cast< QResizeEvent*
>( event );
397 return QObject::eventFilter(
object, event );
400#include "moc_qwt_widget_overlay.cpp"
static bool isX11GraphicsSystem()