Skip to content
qwt_painter.cpp 34.6 KiB
Newer Older
Bryant's avatar
Bryant committed
                    gradient.setColorAt( 0.0, c1 );
                    gradient.setColorAt( 1.0, c2 );

                    arcPen.setBrush( gradient );
                    linePen.setColor( c2 );
                    break;
                }
                case 2:
                {
                    arcPen.setColor( c2 );
                    linePen.setColor( c2 );
                    break;
                }
                case 3:
                {
                    QLinearGradient gradient;

                    gradient.setStart( r.bottomRight() );
                    gradient.setFinalStop( r.topLeft() );
                    gradient.setColorAt( 0.0, c2 );
                    gradient.setColorAt( 1.0, c1 );

                    arcPen.setBrush( gradient );
                    linePen.setColor( c1 );
                    break;
                }
            }


            painter->setPen( arcPen );
            painter->drawPath( pathList[ 2 * i] );

            painter->setPen( linePen );
            painter->drawPath( pathList[ 2 * i + 1] );
        }
    }
    else
    {
        QPen pen( palette.color( QPalette::WindowText ), lineWidth );
        painter->setPen( pen );
        painter->drawPath( path );
    }

    painter->restore();
}

/*!
  Draw a color bar into a rectangle

  \param painter Painter
  \param colorMap Color map
  \param interval Value range
  \param scaleMap Scale map
  \param orientation Orientation
  \param rect Traget rectangle
*/
void QwtPainter::drawColorBar( QPainter *painter,
        const QwtColorMap &colorMap, const QwtInterval &interval,
        const QwtScaleMap &scaleMap, Qt::Orientation orientation,
        const QRectF &rect )
pixhawk's avatar
pixhawk committed
{
    QVector<QRgb> colorTable;
    if ( colorMap.format() == QwtColorMap::Indexed )
Bryant's avatar
Bryant committed
        colorTable = colorMap.colorTable( interval );
pixhawk's avatar
pixhawk committed

    QColor c;

Bryant's avatar
Bryant committed
    const QRect devRect = rect.toAlignedRect();
pixhawk's avatar
pixhawk committed

    /*
      We paint to a pixmap first to have something scalable for printing
      ( f.e. in a Pdf document )
     */
Bryant's avatar
Bryant committed
    QPixmap pixmap( devRect.size() );
    QPainter pmPainter( &pixmap );
    pmPainter.translate( -devRect.x(), -devRect.y() );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
    if ( orientation == Qt::Horizontal )
    {
pixhawk's avatar
pixhawk committed
        QwtScaleMap sMap = scaleMap;
Bryant's avatar
Bryant committed
        sMap.setPaintInterval( rect.left(), rect.right() );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        for ( int x = devRect.left(); x <= devRect.right(); x++ )
        {
            const double value = sMap.invTransform( x );
pixhawk's avatar
pixhawk committed

            if ( colorMap.format() == QwtColorMap::RGB )
Bryant's avatar
Bryant committed
                c.setRgba( colorMap.rgb( interval, value ) );
pixhawk's avatar
pixhawk committed
            else
Bryant's avatar
Bryant committed
                c = colorTable[colorMap.colorIndex( interval, value )];
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
            pmPainter.setPen( c );
            pmPainter.drawLine( x, devRect.top(), x, devRect.bottom() );
pixhawk's avatar
pixhawk committed
        }
Bryant's avatar
Bryant committed
    }
    else // Vertical
    {
pixhawk's avatar
pixhawk committed
        QwtScaleMap sMap = scaleMap;
Bryant's avatar
Bryant committed
        sMap.setPaintInterval( rect.bottom(), rect.top() );
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
        for ( int y = devRect.top(); y <= devRect.bottom(); y++ )
        {
            const double value = sMap.invTransform( y );
pixhawk's avatar
pixhawk committed

            if ( colorMap.format() == QwtColorMap::RGB )
Bryant's avatar
Bryant committed
                c.setRgb( colorMap.rgb( interval, value ) );
pixhawk's avatar
pixhawk committed
            else
Bryant's avatar
Bryant committed
                c = colorTable[colorMap.colorIndex( interval, value )];
pixhawk's avatar
pixhawk committed

Bryant's avatar
Bryant committed
            pmPainter.setPen( c );
            pmPainter.drawLine( devRect.left(), y, devRect.right(), y );
pixhawk's avatar
pixhawk committed
        }
    }
    pmPainter.end();
Bryant's avatar
Bryant committed

    drawPixmap( painter, rect, pixmap );
}

static inline void qwtFillRect( const QWidget *widget, QPainter *painter, 
    const QRect &rect, const QBrush &brush)
{
    if ( brush.style() == Qt::TexturePattern ) 
    {
        painter->save();

        painter->setClipRect( rect );
        painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());

        painter->restore();
    } 
    else if ( brush.gradient() )
    {
        painter->save();

        painter->setClipRect( rect );
        painter->fillRect(0, 0, widget->width(), 
            widget->height(), brush);

        painter->restore();
    } 
    else 
    {
        painter->fillRect(rect, brush);
    }
pixhawk's avatar
pixhawk committed
}
Bryant's avatar
Bryant committed

/*!
  Fill a pixmap with the content of a widget

  In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy
  for backgrounds with gradients. Thus fillPixmap() offers 
  an alternative implementation.

  \param widget Widget
  \param pixmap Pixmap to be filled
  \param offset Offset 

  \sa QPixmap::fill()
 */
void QwtPainter::fillPixmap( const QWidget *widget, 
    QPixmap &pixmap, const QPoint &offset )
{
    const QRect rect( offset, pixmap.size() );

    QPainter painter( &pixmap );
    painter.translate( -offset );

    const QBrush autoFillBrush = 
        widget->palette().brush( widget->backgroundRole() );

    if ( !( widget->autoFillBackground() && autoFillBrush.isOpaque() ) ) 
    {
        const QBrush bg = widget->palette().brush( QPalette::Window );
        qwtFillRect( widget, &painter, rect, bg);
    }

    if ( widget->autoFillBackground() )
        qwtFillRect( widget, &painter, rect, autoFillBrush);

    if ( widget->testAttribute(Qt::WA_StyledBackground) ) 
    {
        painter.setClipRegion( rect );

        QStyleOption opt;
        opt.initFrom( widget );
        widget->style()->drawPrimitive( QStyle::PE_Widget, 
            &opt, &painter, widget );
    }
}

/*!
  Fill rect with the background of a widget

  \param painter Painter
  \param rect Rectangle to be filled
  \param widget Widget

  \sa QStyle::PE_Widget, QWidget::backgroundRole()
 */
void QwtPainter::drawBackgound( QPainter *painter,
    const QRectF &rect, const QWidget *widget )
{
    if ( widget->testAttribute( Qt::WA_StyledBackground ) )
    {
        QStyleOption opt;
        opt.initFrom( widget );
        opt.rect = rect.toAlignedRect();

        widget->style()->drawPrimitive(
            QStyle::PE_Widget, &opt, painter, widget);
    }
    else
    {
        const QBrush brush =
            widget->palette().brush( widget->backgroundRole() );

        painter->fillRect( rect, brush );
    }
}

/*!
  \return A pixmap that can be used as backing store

  \param widget Widget, for which the backinstore is intended
  \param size Size of the pixmap
 */
QPixmap QwtPainter::backingStore( QWidget *widget, const QSize &size )
{
    QPixmap pm;

#define QWT_HIGH_DPI 1

#if QT_VERSION >= 0x050000 && QWT_HIGH_DPI
    qreal pixelRatio = 1.0;

    if ( widget && widget->windowHandle() )
    {
        pixelRatio = widget->windowHandle()->devicePixelRatio();
    }
    else
    {
        if ( qApp )
            pixelRatio = qApp->devicePixelRatio();
    }

    pm = QPixmap( size * pixelRatio );
    pm.setDevicePixelRatio( pixelRatio );
#else
    Q_UNUSED( widget )
    pm = QPixmap( size );
#endif

#if QT_VERSION < 0x050000 
#ifdef Q_WS_X11
    if ( widget && isX11GraphicsSystem() )
    {
        if ( pm.x11Info().screen() != widget->x11Info().screen() )
            pm.x11SetScreen( widget->x11Info().screen() );
    }
#endif
#endif

    return pm;
}