Esempio n. 1
0
/*!
   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
}
Esempio n. 2
0
/*!
  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 );
    }
}
Esempio n. 3
0
/*!
  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() );
}
Esempio n. 5
0
/*!
   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 );
}
Esempio n. 10
0
/*!
  \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();
}
Esempio n. 11
0
/*!
  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 );
    }
}
Esempio n. 12
0
/*!
  \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 );
            }
        }
    }
}
Esempio n. 13
0
/*!
  \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 );
            }
        }
    }
}
Esempio n. 14
0
/*!
  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 );
}
Esempio n. 15
0
/*!
  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 );
}
Esempio n. 16
0
/*!
  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 );
        }
    }
}
Esempio n. 17
0
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 );
}