/*! Invalidate the paint cache and repaint the canvas \sa invalidatePaintCache() */ void QwtPlotCanvas::replot() { invalidatePaintCache(); /* In case of cached or packed painting the canvas is repainted completely and doesn't need to be erased. */ const bool erase = !testPaintAttribute(QwtPlotCanvas::PaintPacked) && !testPaintAttribute(QwtPlotCanvas::PaintCached); #if QT_VERSION >= 0x040000 const bool noBackgroundMode = testAttribute(Qt::WA_NoBackground); if ( !erase && !noBackgroundMode ) setAttribute(Qt::WA_NoBackground, true); repaint(contentsRect()); if ( !erase && !noBackgroundMode ) setAttribute(Qt::WA_NoBackground, false); #else repaint(contentsRect(), erase); #endif }
/*! Draw symbols \param painter Painter \param symbol Curve symbol \param xMap x map \param yMap y map \param canvasRect Contents rectangle of the canvas \param from Index of the first point to be painted \param to Index of the last point to be painted \sa setSymbol(), drawSeries(), drawCurve() */ void QwtPlotCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to ) const { QwtPointMapper mapper; mapper.setFlag( QwtPointMapper::RoundPoints, QwtPainter::roundingAlignment( painter ) ); mapper.setFlag( QwtPointMapper::WeedOutPoints, testPaintAttribute( QwtPlotCurve::FilterPoints ) ); const QRectF clipRect = qwtIntersectedClipRect( canvasRect, painter ); mapper.setBoundingRect( clipRect ); const int chunkSize = 500; for ( int i = from; i <= to; i += chunkSize ) { const int n = qMin( chunkSize, to - i + 1 ); const QPolygonF points = mapper.toPointsF( xMap, yMap, data(), i, i + n - 1 ); if ( points.size() > 0 ) symbol.drawSymbols( painter, points ); } }
/*! Draw the canvas Paints all plot items to the canvasRect, using QwtPolarPlot::drawCanvas and updates the paint cache. \sa QwtPolarPlot::drawCanvas, setPaintAttributes(), testPaintAttributes() */ void QwtPolarCanvas::drawCanvas( QPainter *painter, const QwtDoubleRect& canvasRect ) { if ( !canvasRect.isValid() ) return; if ( testPaintAttribute( PaintCached ) && d_data->cache ) { *d_data->cache = QPixmap( contentsRect().size() ); #ifdef Q_WS_X11 #if QT_VERSION >= 0x040000 if ( d_data->cache->x11Info().screen() != x11Info().screen() ) d_data->cache->x11SetScreen( x11Info().screen() ); #else if ( d_data->cache->x11Screen() != x11Screen() ) d_data->cache->x11SetScreen( x11Screen() ); #endif #endif d_data->cache->fill( this, d_data->cache->rect().topLeft() ); QPainter cachePainter( d_data->cache ); cachePainter.translate( -contentsRect().x(), -contentsRect().y() ); plot()->drawCanvas( &cachePainter, canvasRect ); cachePainter.end(); painter->drawPixmap( canvasRect.topLeft().toPoint(), *d_data->cache ); } else plot()->drawCanvas( painter, canvasRect ); }
/*! Invalidate the paint cache and repaint the canvas \sa invalidatePaintCache() */ void QwtPlotCanvas::replot() { invalidateBackingStore(); if ( testPaintAttribute( QwtPlotCanvas::ImmediatePaint ) ) repaint( contentsRect() ); else update( contentsRect() ); }
/*! Invalidate the paint cache and repaint the canvas \sa invalidatePaintCache() */ void QwtPlotAbstractGLCanvas::replot() { invalidateBackingStore(); QWidget *w = canvasWidget(); if ( testPaintAttribute( QwtPlotAbstractGLCanvas::ImmediatePaint ) ) w->repaint( w->contentsRect() ); else w->update( w->contentsRect() ); }
/*! Qt event handler for QEvent::PolishRequest and QEvent::StyleChange \param event Qt Event */ bool QwtPlotCanvas::event( QEvent *event ) { if ( event->type() == QEvent::PolishRequest ) { if ( testPaintAttribute( QwtPlotCanvas::Opaque ) ) { // Setting a style sheet changes the // Qt::WA_OpaquePaintEvent attribute, but we insist // on painting the background. setAttribute( Qt::WA_OpaquePaintEvent, true ); } } if ( event->type() == QEvent::PolishRequest || event->type() == QEvent::StyleChange ) { updateStyleSheetInfo(); } return QFrame::event( event ); }
Canvas( QwtPlot *plot = NULL ): QwtPlotCanvas( plot ) { // The backing store is important, when working with widget // overlays ( f.e rubberbands for zooming ). // Here we don't have them and the internal // backing store of QWidget is good enough. setPaintAttribute( QwtPlotCanvas::BackingStore, false ); setBorderRadius( 10 ); if ( QwtPainter::isX11GraphicsSystem() ) { #if QT_VERSION < 0x050000 // Even if not liked by the Qt development, Qt::WA_PaintOutsidePaintEvent // works on X11. This has a nice effect on the performance. setAttribute( Qt::WA_PaintOutsidePaintEvent, true ); #endif // Disabling the backing store of Qt improves the performance // for the direct painter even more, but the canvas becomes // a native window of the window system, receiving paint events // for resize and expose operations. Those might be expensive // when there are many points and the backing store of // the canvas is disabled. So in this application // we better don't disable both backing stores. if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) ) { setAttribute( Qt::WA_PaintOnScreen, true ); setAttribute( Qt::WA_NoSystemBackground, true ); } } setupPalette(); }
void QwtPlotCanvas::drawCanvas( QPainter *painter, bool withBackground ) { bool hackStyledBackground = false; if ( withBackground && testAttribute( Qt::WA_StyledBackground ) && testPaintAttribute( HackStyledBackground ) ) { // Antialiasing rounded borders is done by // inserting pixels with colors between the // border color and the color on the canvas, // When the border is painted before the plot items // these colors are interpolated for the canvas // and the plot items need to be clipped excluding // the anialiased pixels. In situations, where // the plot items fill the area at the rounded // borders this is noticeable. // The only way to avoid these annoying "artefacts" // is to paint the border on top of the plot items. if ( d_data->styleSheet.hasBorder && !d_data->styleSheet.borderPath.isEmpty() ) { // We have a border with at least one rounded corner hackStyledBackground = true; } } if ( withBackground ) { painter->save(); if ( testAttribute( Qt::WA_StyledBackground ) ) { if ( hackStyledBackground ) { // paint background without border painter->setPen( Qt::NoPen ); painter->setBrush( d_data->styleSheet.background.brush ); painter->setBrushOrigin( d_data->styleSheet.background.origin ); painter->setClipPath( d_data->styleSheet.borderPath ); painter->drawRect( contentsRect() ); } else { qwtDrawStyledBackground( this, painter ); } } else if ( autoFillBackground() ) { painter->setPen( Qt::NoPen ); painter->setBrush( palette().brush( backgroundRole() ) ); if ( d_data->borderRadius > 0.0 && ( rect() == frameRect() ) ) { if ( frameWidth() > 0 ) { painter->setClipPath( borderPath( rect() ) ); painter->drawRect( rect() ); } else { painter->setRenderHint( QPainter::Antialiasing, true ); painter->drawPath( borderPath( rect() ) ); } } else { painter->drawRect( rect() ); } } painter->restore(); } painter->save(); if ( !d_data->styleSheet.borderPath.isEmpty() ) { painter->setClipPath( d_data->styleSheet.borderPath, Qt::IntersectClip ); } else { if ( d_data->borderRadius > 0.0 ) painter->setClipPath( borderPath( frameRect() ), Qt::IntersectClip ); else painter->setClipRect( contentsRect(), Qt::IntersectClip ); } plot()->drawCanvas( painter ); painter->restore(); if ( withBackground && hackStyledBackground ) { // Now paint the border on top QStyleOptionFrame opt; opt.initFrom(this); style()->drawPrimitive( QStyle::PE_Frame, &opt, painter, this); } }
/*! Paint event \param event Paint event */ void QwtPlotCanvas::paintEvent( QPaintEvent *event ) { QPainter painter( this ); painter.setClipRegion( event->region() ); if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) && d_data->backingStore != NULL ) { QPixmap &bs = *d_data->backingStore; if ( bs.size() != size() ) { bs = QPixmap( size() ); #ifdef Q_WS_X11 if ( bs.x11Info().screen() != x11Info().screen() ) bs.x11SetScreen( x11Info().screen() ); #endif if ( testAttribute(Qt::WA_StyledBackground) ) { QPainter p( &bs ); qwtFillBackground( &p, this ); drawCanvas( &p, true ); } else { QPainter p; if ( d_data->borderRadius <= 0.0 ) { qwtFillPixmap( this, bs ); p.begin( &bs ); drawCanvas( &p, false ); } else { p.begin( &bs ); qwtFillBackground( &p, this ); drawCanvas( &p, true ); } if ( frameWidth() > 0 ) drawBorder( &p ); } } painter.drawPixmap( 0, 0, *d_data->backingStore ); } else { if ( testAttribute(Qt::WA_StyledBackground ) ) { if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) { qwtFillBackground( &painter, this ); drawCanvas( &painter, true ); } else { drawCanvas( &painter, false ); } } else { if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) { if ( autoFillBackground() ) { qwtFillBackground( &painter, this ); qwtDrawBackground( &painter, this ); } } else { if ( borderRadius() > 0.0 ) { QPainterPath clipPath; clipPath.addRect( rect() ); clipPath = clipPath.subtracted( borderPath( rect() ) ); painter.save(); painter.setClipPath( clipPath, Qt::IntersectClip ); qwtFillBackground( &painter, this ); qwtDrawBackground( &painter, this ); painter.restore(); } } drawCanvas( &painter, false ); if ( frameWidth() > 0 ) drawBorder( &painter ); } } if ( hasFocus() && focusIndicator() == CanvasFocusIndicator ) drawFocusIndicator( &painter ); }
/*! \brief Draw the raster data \param painter Painter \param xMap X-Scale Map \param yMap Y-Scale Map \param canvasRect Contents rectangle of the plot canvas */ void QwtPlotRasterItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { if ( canvasRect.isEmpty() || d_data->alpha == 0 ) return; const bool doCache = qwtUseCache( d_data->cache.policy, painter ); const QwtInterval xInterval = interval( Qt::XAxis ); const QwtInterval yInterval = interval( Qt::YAxis ); /* Scaling an image always results in a loss of precision/quality. So we always render the image in paint device resolution. */ QwtScaleMap xxMap, yyMap; qwtTransformMaps( painter->transform(), xMap, yMap, xxMap, yyMap ); QRectF paintRect = painter->transform().mapRect( canvasRect ); QRectF area = QwtScaleMap::invTransform( xxMap, yyMap, paintRect ); const QRectF br = boundingRect(); if ( br.isValid() && !br.contains( area ) ) { area &= br; if ( !area.isValid() ) return; paintRect = QwtScaleMap::transform( xxMap, yyMap, area ); } QRectF imageRect; QImage image; QRectF pixelRect = pixelHint(area); if ( !pixelRect.isEmpty() ) { // pixel in target device resolution const double dx = qAbs( xxMap.invTransform( 1 ) - xxMap.invTransform( 0 ) ); const double dy = qAbs( yyMap.invTransform( 1 ) - yyMap.invTransform( 0 ) ); if ( dx > pixelRect.width() && dy > pixelRect.height() ) { /* When the resolution of the data pixels is higher than the resolution of the target device we render in target device resolution. */ pixelRect = QRectF(); } } if ( pixelRect.isEmpty() ) { if ( QwtPainter::roundingAlignment( painter ) ) { // we want to have maps, where the boundaries of // the aligned paint rectangle exactly match the area paintRect = qwtAlignRect(paintRect); qwtAdjustMaps(xxMap, yyMap, area, paintRect); } // When we have no information about position and size of // data pixels we render in resolution of the paint device. image = compose(xxMap, yyMap, area, paintRect, paintRect.size().toSize(), doCache); if ( image.isNull() ) return; // Remove pixels at the boundaries, when explicitly // excluded in the intervals imageRect = qwtStripRect(paintRect, area, xxMap, yyMap, xInterval, yInterval); if ( imageRect != paintRect ) { const QRect r( qRound( imageRect.x() - paintRect.x()), qRound( imageRect.y() - paintRect.y() ), qRound( imageRect.width() ), qRound( imageRect.height() ) ); image = image.copy(r); } } else { if ( QwtPainter::roundingAlignment( painter ) ) paintRect = qwtAlignRect(paintRect); // align the area to the data pixels QRectF imageArea = qwtExpandToPixels(area, pixelRect); if ( imageArea.right() == xInterval.maxValue() && !( xInterval.borderFlags() & QwtInterval::ExcludeMaximum ) ) { imageArea.adjust(0, 0, pixelRect.width(), 0); } if ( imageArea.bottom() == yInterval.maxValue() && !( yInterval.borderFlags() & QwtInterval::ExcludeMaximum ) ) { imageArea.adjust(0, 0, 0, pixelRect.height() ); } QSize imageSize; imageSize.setWidth( qRound( imageArea.width() / pixelRect.width() ) ); imageSize.setHeight( qRound( imageArea.height() / pixelRect.height() ) ); image = compose(xxMap, yyMap, imageArea, paintRect, imageSize, doCache ); if ( image.isNull() ) return; imageRect = qwtStripRect(paintRect, area, xxMap, yyMap, xInterval, yInterval); if ( ( image.width() > 1 || image.height() > 1 ) && testPaintAttribute( PaintInDeviceResolution ) ) { // Because of rounding errors the pixels // need to be expanded manually to rectangles of // different sizes image = qwtExpandImage(image, xxMap, yyMap, imageArea, area, paintRect, xInterval, yInterval ); } } painter->save(); painter->setWorldTransform( QTransform() ); QwtPainter::drawImage( painter, imageRect, image ); painter->restore(); }
/*! Draw the shape item \param painter Painter \param xMap X-Scale Map \param yMap Y-Scale Map \param canvasRect Contents rect of the plot canvas */ void QwtPlotShapeItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { if ( d_data->shape.isEmpty() ) return; if ( d_data->pen.style() == Qt::NoPen && d_data->brush.style() == Qt::NoBrush ) { return; } const QRectF cRect = QwtScaleMap::invTransform( xMap, yMap, canvasRect.toRect() ); if ( d_data->boundingRect.intersects( cRect ) ) { const bool doAlign = QwtPainter::roundingAlignment( painter ); QPainterPath path = qwtTransformPath( xMap, yMap, d_data->shape, doAlign ); if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) ) { qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF()); QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw ); QPainterPath clippedPath; clippedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) { const QPolygonF p = QwtClipper::clipPolygonF( clipRect, polygons[i], true ); clippedPath.addPolygon( p ); } path = clippedPath; } if ( d_data->renderTolerance > 0.0 ) { QwtWeedingCurveFitter fitter( d_data->renderTolerance ); QPainterPath fittedPath; fittedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) ); path = fittedPath; } painter->setPen( d_data->pen ); painter->setBrush( d_data->brush ); painter->drawPath( path ); } }
/*! \brief Render a sub-rectangle of an image renderTile() is called by renderImage() to render different parts of the image by concurrent threads. \param azimuthMap Maps azimuth values to values related to 0.0, M_2PI \param radialMap Maps radius values into painter coordinates. \param pole Position of the pole in painter coordinates \param imagePos Top/left position of the image in painter coordinates \param tile Sub-rectangle of the tile in painter coordinates \param image Image to be rendered \sa setRenderThreadCount() \note renderTile needs to be reentrant */ void QwtPolarSpectrogram::renderTile( const QwtScaleMap &azimuthMap, const QwtScaleMap &radialMap, const QPointF &pole, const QPoint &imagePos, const QRect &tile, QImage *image ) const { const QwtInterval intensityRange = d_data->data->interval( Qt::ZAxis ); if ( !intensityRange.isValid() ) return; const bool doFastAtan = testPaintAttribute( ApproximatedAtan ); const int y0 = imagePos.y(); const int y1 = tile.top(); const int y2 = tile.bottom(); const int x0 = imagePos.x(); const int x1 = tile.left(); const int x2 = tile.right(); if ( d_data->colorMap->format() == QwtColorMap::RGB ) { for ( int y = y1; y <= y2; y++ ) { const double dy = pole.y() - y; const double dy2 = qwtSqr( dy ); QRgb *line = reinterpret_cast<QRgb *>( image->scanLine( y - y0 ) ); line += x1 - x0; for ( int x = x1; x <= x2; x++ ) { const double dx = x - pole.x(); double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx ); if ( a < 0.0 ) a += 2 * M_PI; if ( a < azimuthMap.p1() ) a += 2 * M_PI; const double r = qSqrt( qwtSqr( dx ) + dy2 ); const double azimuth = azimuthMap.invTransform( a ); const double radius = radialMap.invTransform( r ); const double value = d_data->data->value( azimuth, radius ); *line++ = d_data->colorMap->rgb( intensityRange, value ); } } } else if ( d_data->colorMap->format() == QwtColorMap::Indexed ) { for ( int y = y1; y <= y2; y++ ) { const double dy = pole.y() - y; const double dy2 = qwtSqr( dy ); unsigned char *line = image->scanLine( y - y0 ); line += x1 - x0; for ( int x = x1; x <= x2; x++ ) { const double dx = x - pole.x(); double a = doFastAtan ? qwtFastAtan2( dy, dx ) : qAtan2( dy, dx ); if ( a < 0.0 ) a += 2 * M_PI; if ( a < azimuthMap.p1() ) a += 2 * M_PI; const double r = qSqrt( qwtSqr( dx ) + dy2 ); const double azimuth = azimuthMap.invTransform( a ); const double radius = radialMap.invTransform( r ); const double value = d_data->data->value( azimuth, radius ); *line++ = d_data->colorMap->colorIndex( intensityRange, value ); } } } }
/*! \brief Draw lines If the CurveAttribute Fitted is enabled a QwtCurveFitter tries to interpolate/smooth the curve, before it is painted. \param painter Painter \param xMap x map \param yMap y map \param canvasRect Contents rectangle of the canvas \param from index of the first point to be painted \param to index of the last point to be painted \sa setCurveAttribute(), setCurveFitter(), draw(), drawLines(), drawDots(), drawSteps(), drawSticks() */ void QwtPlotCurve::drawLines( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to ) const { if ( from > to ) return; const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter; const bool doAlign = !doFit && QwtPainter::roundingAlignment( painter ); const bool doFill = ( d_data->brush.style() != Qt::NoBrush ) && ( d_data->brush.color().alpha() > 0 ); QRectF clipRect; if ( d_data->paintAttributes & ClipPolygons ) { clipRect = qwtIntersectedClipRect( canvasRect, painter ); const qreal pw = QwtPainter::effectivePenWidth( painter->pen() ); clipRect = clipRect.adjusted(-pw, -pw, pw, pw); } bool doIntegers = false; #if QT_VERSION < 0x040800 if ( painter->paintEngine()->type() == QPaintEngine::Raster ) { // For Qt <= 4.7 the raster paint engine is significantly faster // for rendering QPolygon than for QPolygonF. So let's // see if we can use it. // In case of filling or fitting performance doesn't count // because both operations are much more expensive // then drawing the polyline itself if ( !doFit && !doFill ) doIntegers = true; } #endif QwtPointMapper mapper; if ( doAlign ) { mapper.setFlag( QwtPointMapper::RoundPoints, true ); mapper.setFlag( QwtPointMapper::WeedOutIntermediatePoints, testPaintAttribute( FilterPointsAggressive ) ); } mapper.setFlag( QwtPointMapper::WeedOutPoints, testPaintAttribute( FilterPoints ) || testPaintAttribute( FilterPointsAggressive ) ); mapper.setBoundingRect( canvasRect ); if ( doIntegers ) { QPolygon polyline = mapper.toPolygon( xMap, yMap, data(), from, to ); if ( testPaintAttribute( ClipPolygons ) ) { QwtClipper::clipPolygon( clipRect, polyline, false ); } QwtPainter::drawPolyline( painter, polyline ); } else { QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to ); if ( doFill ) { if ( doFit ) { // it might be better to extend and draw the curvePath, but for // the moment we keep an implementation, where we translate the // path back to a polyline. polyline = d_data->curveFitter->fitCurve( polyline ); } if ( painter->pen().style() != Qt::NoPen ) { // here we are wasting memory for the filled copy, // do polygon clipping twice etc .. TODO QPolygonF filled = polyline; fillCurve( painter, xMap, yMap, canvasRect, filled ); filled.clear(); if ( d_data->paintAttributes & ClipPolygons ) QwtClipper::clipPolygonF( clipRect, polyline, false ); QwtPainter::drawPolyline( painter, polyline ); } else { fillCurve( painter, xMap, yMap, canvasRect, polyline ); } } else { if ( testPaintAttribute( ClipPolygons ) ) { QwtClipper::clipPolygonF( clipRect, polyline, false ); } if ( doFit ) { if ( d_data->curveFitter->mode() == QwtCurveFitter::Path ) { const QPainterPath curvePath = d_data->curveFitter->fitCurvePath( polyline ); painter->drawPath( curvePath ); } else { polyline = d_data->curveFitter->fitCurve( polyline ); QwtPainter::drawPolyline( painter, polyline ); } } else { QwtPainter::drawPolyline( painter, polyline ); } } } }
/*! Draw the shape item \param painter Painter \param xMap X-Scale Map \param yMap Y-Scale Map \param canvasRect Contents rect of the plot canvas */ void QwtPlotShapeItem::draw( QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect ) const { if ( d_data->shape.isEmpty() ) return; if ( d_data->pen.style() == Qt::NoPen && d_data->brush.style() == Qt::NoBrush ) { return; } const QRectF cr = QwtScaleMap::invTransform( xMap, yMap, canvasRect.toRect() ); const QRectF &br = d_data->boundingRect; if ( ( br.left() > cr.right() ) || ( br.right() < cr.left() ) || ( br.top() > cr.bottom() ) || ( br.bottom() < cr.top() ) ) { // outside the visisble area return; } const bool doAlign = QwtPainter::roundingAlignment( painter ); QPainterPath path = qwtTransformPath( xMap, yMap, d_data->shape, doAlign ); if ( testPaintAttribute( QwtPlotShapeItem::ClipPolygons ) ) { const qreal pw = QwtPainter::effectivePenWidth( painter->pen() ); const QRectF clipRect = canvasRect.adjusted( -pw, -pw, pw, pw ); QPainterPath clippedPath; clippedPath.setFillRule( path.fillRule() ); QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) { QwtClipper::clipPolygonF( clipRect, polygons[i], true ); clippedPath.addPolygon( polygons[i] ); } path = clippedPath; } if ( d_data->renderTolerance > 0.0 ) { QwtWeedingCurveFitter fitter( d_data->renderTolerance ); QPainterPath fittedPath; fittedPath.setFillRule( path.fillRule() ); const QList<QPolygonF> polygons = path.toSubpathPolygons(); for ( int i = 0; i < polygons.size(); i++ ) fittedPath.addPolygon( fitter.fitCurve( polygons[ i ] ) ); path = fittedPath; } painter->setPen( d_data->pen ); painter->setBrush( d_data->brush ); painter->drawPath( path ); }
/*! Paint event \param event Paint event */ void QwtPlotCanvas::paintEvent( QPaintEvent *event ) { QPainter painter( this ); painter.setClipRegion( event->region() ); if ( testPaintAttribute( QwtPlotCanvas::BackingStore ) && d_data->backingStore != NULL ) { QPixmap &bs = *d_data->backingStore; if ( bs.size() != size() ) { bs = QPixmap( size() ); #ifdef Q_WS_X11 if ( bs.x11Info().screen() != x11Info().screen() ) bs.x11SetScreen( x11Info().screen() ); #endif if ( testAttribute(Qt::WA_StyledBackground) ) { QPainter p( &bs ); qwtFillBackground( &p, this ); drawCanvas( &p, true ); } else { QPainter p; if ( d_data->borderRadius <= 0.0 ) { #if QT_VERSION >= 0x050000 QwtPainter::fillPixmap( this, bs ); #else bs.fill( this, 0, 0 ); #endif p.begin( &bs ); drawCanvas( &p, false ); } else { p.begin( &bs ); qwtFillBackground( &p, this ); drawCanvas( &p, true ); } if ( frameWidth() > 0 ) drawBorder( &p ); } } painter.drawPixmap( 0, 0, *d_data->backingStore ); } else { if ( testAttribute(Qt::WA_StyledBackground ) ) { if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) { qwtFillBackground( &painter, this ); drawCanvas( &painter, true ); } else { drawCanvas( &painter, false ); } } else { if ( testAttribute( Qt::WA_OpaquePaintEvent ) ) { if ( autoFillBackground() ) qwtDrawBackground( &painter, this ); } drawCanvas( &painter, false ); if ( frameWidth() > 0 ) drawBorder( &painter ); } } if ( hasFocus() && focusIndicator() == CanvasFocusIndicator ) drawFocusIndicator( &painter ); }
/*! Draw symbols \param painter Painter \param symbol Curve symbol \param xMap x map \param yMap y map \param canvasRect Contents rect of the canvas \param from Index of the first point to be painted \param to Index of the last point to be painted \sa setSymbol(), drawSeries(), drawCurve() */ void QwtPlotCurve::drawSymbols( QPainter *painter, const QwtSymbol &symbol, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect, int from, int to ) const { const bool doAlign = QwtPainter::roundingAlignment( painter ); bool usePixmap = testPaintAttribute( CacheSymbols ); if ( usePixmap && !doAlign ) { // Don't use the pixmap, when the paint device // could generate scalable vectors usePixmap = false; } if ( usePixmap ) { QPixmap pm( symbol.boundingSize() ); pm.fill( Qt::transparent ); const double pw2 = 0.5 * pm.width(); const double ph2 = 0.5 * pm.height(); QPainter p( &pm ); p.setRenderHints( painter->renderHints() ); symbol.drawSymbol( &p, QPointF( pw2, ph2 ) ); p.end(); for ( int i = from; i <= to; i++ ) { const QPointF sample = d_series->sample( i ); double xi = xMap.transform( sample.x() ); double yi = yMap.transform( sample.y() ); if ( doAlign ) { xi = qRound( xi ); yi = qRound( yi ); } if ( canvasRect.contains( xi, yi ) ) { const int left = qCeil( xi - pw2 ); const int top = qCeil( yi - ph2 ); painter->drawPixmap( left, top, pm ); } } } else { const int chunkSize = 500; for ( int i = from; i <= to; i += chunkSize ) { const int n = qMin( chunkSize, to - i + 1 ); QPolygonF points; for ( int j = 0; j < n; j++ ) { const QPointF sample = d_series->sample( i + j ); const double xi = xMap.transform( sample.x() ); const double yi = yMap.transform( sample.y() ); if ( canvasRect.contains( xi, yi ) ) points += QPointF( xi, yi ); } if ( points.size() > 0 ) symbol.drawSymbols( painter, points ); } } }
void QwtPlotGLCanvas::paintGL() { const bool hasFocusIndicator = hasFocus() && focusIndicator() == CanvasFocusIndicator; QPainter painter; #if QT_VERSION < 0x040600 painter.begin( this ); draw( &painter ); #else if ( testPaintAttribute( QwtPlotGLCanvas::BackingStore ) ) { if ( d_data->fbo == NULL || d_data->fbo->size() != size() ) { invalidateBackingStore(); const int numSamples = 16; QGLFramebufferObjectFormat format; format.setSamples( numSamples ); format.setAttachment(QGLFramebufferObject::CombinedDepthStencil); QGLFramebufferObject fbo( size(), format ); QPainter fboPainter( &fbo ); draw( &fboPainter); fboPainter.end(); d_data->fbo = new QGLFramebufferObject( size() ); QRect rect(0, 0, width(), height()); QGLFramebufferObject::blitFramebuffer(d_data->fbo, rect, &fbo, rect); } // drawTexture( QRectF( -1.0, 1.0, 2.0, -2.0 ), d_data->fbo->texture() ); if ( hasFocusIndicator ) painter.begin( this ); glBindTexture(GL_TEXTURE_2D, d_data->fbo->texture()); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); glTexCoord2f(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); glTexCoord2f(1.0f, 1.0f); glVertex2f( 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex2f(-1.0f, 1.0f); glEnd(); } else { painter.begin( this ); draw( &painter ); } #endif if ( hasFocus() && focusIndicator() == CanvasFocusIndicator ) drawFocusIndicator( &painter ); }