Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_painter.cpp


Ignore:
Timestamp:
May 10, 2017, 3:20:54 PM (7 years ago)
Author:
stoecker
Message:

update qwt and qwtpolar, many QT5 fixes (unfinished)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/qwt/qwt_painter.cpp

    r4271 r8127  
    2929#include <qdesktopwidget.h>
    3030
     31#if QT_VERSION >= 0x050000
     32#include <qwindow.h>
     33#endif
     34
     35#if QT_VERSION < 0x050000
     36
     37#ifdef Q_WS_X11
     38#include <qx11info_x11.h>
     39#endif
     40
     41#endif
     42
    3143bool QwtPainter::d_polylineSplitting = true;
    3244bool QwtPainter::d_roundingAlignment = true;
    3345
    34 static inline bool isClippingNeeded( const QPainter *painter, QRectF &clipRect )
     46static inline bool qwtIsClippingNeeded(
     47    const QPainter *painter, QRectF &clipRect )
    3548{
    3649    bool doClipping = false;
     
    5063}
    5164
    52 static inline void drawPolyline( QPainter *painter,
    53     const QPointF *points, int pointCount, bool polylineSplitting )
     65template <class T>
     66static inline void qwtDrawPolyline( QPainter *painter,
     67    const T *points, int pointCount, bool polylineSplitting )
    5468{
    5569    bool doSplit = false;
     
    7185    if ( doSplit )
    7286    {
    73         const int splitSize = 20;
     87        const int splitSize = 6;
     88
    7489        for ( int i = 0; i < pointCount; i += splitSize )
    7590        {
     
    7994    }
    8095    else
     96    {
    8197        painter->drawPolyline( points, pointCount );
    82 }
    83 
    84 static inline void unscaleFont( QPainter *painter )
     98    }
     99}
     100
     101static inline QSize qwtScreenResolution()
     102{
     103    static QSize screenResolution;
     104    if ( !screenResolution.isValid() )
     105    {
     106        QDesktopWidget *desktop = QApplication::desktop();
     107        if ( desktop )
     108        {
     109            screenResolution.setWidth( desktop->logicalDpiX() );
     110            screenResolution.setHeight( desktop->logicalDpiY() );
     111        }
     112    }
     113
     114    return screenResolution;
     115}
     116
     117static inline void qwtUnscaleFont( QPainter *painter )
    85118{
    86119    if ( painter->font().pixelSize() >= 0 )
    87120        return;
    88121
    89     static QSize screenResolution;
    90     if ( !screenResolution.isValid() )
    91     {
    92         QDesktopWidget *desktop = QApplication::desktop();
    93         if ( desktop )
    94         {
    95             screenResolution.setWidth( desktop->logicalDpiX() );
    96             screenResolution.setHeight( desktop->logicalDpiY() );
    97         }
    98     }
     122    const QSize screenResolution = qwtScreenResolution();
    99123
    100124    const QPaintDevice *pd = painter->device();
     
    107131        painter->setFont( pixelFont );
    108132    }
     133}
     134
     135/*!
     136  Check is the application is running with the X11 graphics system
     137  that has some special capabilities that can be used for incremental
     138  painting to a widget.
     139
     140  \return True, when the graphics system is X11
     141*/
     142bool QwtPainter::isX11GraphicsSystem()
     143{
     144    static int onX11 = -1;
     145    if ( onX11 < 0 )
     146    {
     147        QPixmap pm( 1, 1 );
     148        QPainter painter( &pm );
     149
     150        onX11 = ( painter.paintEngine()->type() == QPaintEngine::X11 ) ? 1 : 0;
     151    }
     152
     153    return onX11 == 1;
    109154}
    110155
     
    114159  beside QPaintEngine::Pdf and QPaintEngine::SVG.
    115160
     161  If we have an integer based paint engine it is also
     162  checked if the painter has a transformation matrix,
     163  that rotates or scales.
     164
    116165  \param  painter Painter
    117   \return true, when the paint engine is aligning
     166  \return true, when the painter is aligning
    118167
    119168  \sa setRoundingAlignment()
     
    131180            default:;
    132181        }
     182
     183        const QTransform tr = painter->transform();
     184        if ( tr.isRotating() || tr.isScaling() )
     185        {
     186            // we might have to check translations too
     187            return false;
     188        }
    133189    }
    134190
     
    139195  Enable whether coordinates should be rounded, before they are painted
    140196  to a paint engine that floors to integer values. For other paint engines
    141   this ( Pdf, SVG ), this flag has no effect.
    142   QwtPainter stores this flag only, the rounding itsself is done in
     197  ( PDF, SVG ) this flag has no effect.
     198  QwtPainter stores this flag only, the rounding itself is done in
    143199  the painting code ( f.e the plot items ).
    144200
     
    155211  \brief En/Disable line splitting for the raster paint engine
    156212
    157   The raster paint engine paints polylines of many points
    158   much faster when they are splitted in smaller chunks.
     213  In some Qt versions the raster paint engine paints polylines of many points
     214  much faster when they are split in smaller chunks: f.e all supported Qt versions
     215  >= Qt 5.0 when drawing an antialiased polyline with a pen width >=2.
     216
     217  The default setting is true.
    159218
    160219  \sa polylineSplitting()
     
    183242
    184243    QRectF clipRect;
    185     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     244    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    186245
    187246    if ( deviceClipping )
     
    214273
    215274    QRectF clipRect;
    216     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     275    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    217276
    218277    /*
    219       Performance of Qt4 is horrible for non trivial brushs. Without
    220       clipping expect minutes or hours for repainting large rects
     278      Performance of Qt4 is horrible for a non trivial brush. Without
     279      clipping expect minutes or hours for repainting large rectangles
    221280      (might result from zooming)
    222281    */
     
    232291    QRectF r = rect;
    233292    if ( deviceClipping )
    234         r = r.intersect( clipRect );
     293        r = r.intersected( clipRect );
    235294
    236295    if ( r.isValid() )
     
    243302{
    244303    QRectF clipRect;
    245     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     304    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    246305    if ( deviceClipping && !clipRect.contains( rect ) )
    247306        return;
     
    254313{
    255314    QRectF clipRect;
    256     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     315    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    257316
    258317    if ( deviceClipping && !clipRect.contains( rect ) )
     
    274333{
    275334    QRectF clipRect;
    276     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     335    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    277336
    278337    if ( deviceClipping && !clipRect.contains( pos ) )
     
    281340
    282341    painter->save();
    283     unscaleFont( painter );
     342    qwtUnscaleFont( painter );
    284343    painter->drawText( pos, text );
    285344    painter->restore();
     
    299358{
    300359    painter->save();
    301     unscaleFont( painter );
     360    qwtUnscaleFont( painter );
    302361    painter->drawText( rect, flags, text );
    303362    painter->restore();
     
    321380    painter->save();
    322381
    323     painter->setFont( txt->defaultFont() );
    324     unscaleFont( painter );
     382    QRectF unscaledRect = rect;
     383
     384    if ( painter->font().pixelSize() < 0 )
     385    {
     386        const QSize res = qwtScreenResolution();
     387
     388        const QPaintDevice *pd = painter->device();
     389        if ( pd->logicalDpiX() != res.width() ||
     390            pd->logicalDpiY() != res.height() )
     391        {
     392            QTransform transform;
     393            transform.scale( res.width() / double( pd->logicalDpiX() ),
     394                res.height() / double( pd->logicalDpiY() ));
     395
     396            painter->setWorldTransform( transform, true );
     397            unscaledRect = transform.inverted().mapRect(rect);
     398        }
     399    } 
    325400
    326401    txt->setDefaultFont( painter->font() );
    327     txt->setPageSize( QSizeF( rect.width(), QWIDGETSIZE_MAX ) );
     402    txt->setPageSize( QSizeF( unscaledRect.width(), QWIDGETSIZE_MAX ) );
    328403
    329404    QAbstractTextDocumentLayout* layout = txt->documentLayout();
    330405
    331406    const double height = layout->documentSize().height();
    332     double y = rect.y();
     407    double y = unscaledRect.y();
    333408    if ( flags & Qt::AlignBottom )
    334         y += ( rect.height() - height );
     409        y += ( unscaledRect.height() - height );
    335410    else if ( flags & Qt::AlignVCenter )
    336         y += ( rect.height() - height ) / 2;
     411        y += ( unscaledRect.height() - height ) / 2;
    337412
    338413    QAbstractTextDocumentLayout::PaintContext context;
    339414    context.palette.setColor( QPalette::Text, painter->pen().color() );
    340415
    341     painter->translate( rect.x(), y );
     416    painter->translate( unscaledRect.x(), y );
    342417    layout->draw( painter, context );
    343418
     
    354429{
    355430    QRectF clipRect;
    356     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     431    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    357432
    358433    if ( deviceClipping &&
     
    373448{
    374449    QRectF clipRect;
    375     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     450    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    376451
    377452    QPolygonF cpa = polygon;
     
    386461{
    387462    QRectF clipRect;
    388     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     463    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    389464
    390465    QPolygonF cpa = polygon;
     
    392467        cpa = QwtClipper::clipPolygonF( clipRect, cpa );
    393468
    394     ::drawPolyline( painter,
     469    qwtDrawPolyline<QPointF>( painter,
    395470        cpa.constData(), cpa.size(), d_polylineSplitting );
    396471}
     
    401476{
    402477    QRectF clipRect;
    403     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     478    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    404479
    405480    if ( deviceClipping )
    406481    {
    407482        QPolygonF polygon( pointCount );
    408         qMemCopy( polygon.data(), points, pointCount * sizeof( QPointF ) );
     483        ::memcpy( polygon.data(), points, pointCount * sizeof( QPointF ) );
    409484
    410485        polygon = QwtClipper::clipPolygonF( clipRect, polygon );
    411         ::drawPolyline( painter,
     486        qwtDrawPolyline<QPointF>( painter,
    412487            polygon.constData(), polygon.size(), d_polylineSplitting );
    413488    }
    414489    else
    415         ::drawPolyline( painter, points, pointCount, d_polylineSplitting );
     490    {
     491        qwtDrawPolyline<QPointF>( painter, points, pointCount, d_polylineSplitting );
     492    }
     493}
     494
     495//! Wrapper for QPainter::drawPolygon()
     496void QwtPainter::drawPolygon( QPainter *painter, const QPolygon &polygon )
     497{
     498    QRectF clipRect;
     499    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     500
     501    QPolygon cpa = polygon;
     502    if ( deviceClipping )
     503        cpa = QwtClipper::clipPolygon( clipRect, polygon );
     504
     505    painter->drawPolygon( cpa );
     506}
     507
     508//! Wrapper for QPainter::drawPolyline()
     509void QwtPainter::drawPolyline( QPainter *painter, const QPolygon &polygon )
     510{
     511    QRectF clipRect;
     512    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     513
     514    QPolygon cpa = polygon;
     515    if ( deviceClipping )
     516        cpa = QwtClipper::clipPolygon( clipRect, cpa );
     517
     518    qwtDrawPolyline<QPoint>( painter,
     519        cpa.constData(), cpa.size(), d_polylineSplitting );
     520}
     521
     522//! Wrapper for QPainter::drawPolyline()
     523void QwtPainter::drawPolyline( QPainter *painter,
     524    const QPoint *points, int pointCount )
     525{
     526    QRectF clipRect;
     527    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     528
     529    if ( deviceClipping )
     530    {
     531        QPolygon polygon( pointCount );
     532        ::memcpy( polygon.data(), points, pointCount * sizeof( QPoint ) );
     533
     534        polygon = QwtClipper::clipPolygon( clipRect, polygon );
     535        qwtDrawPolyline<QPoint>( painter,
     536            polygon.constData(), polygon.size(), d_polylineSplitting );
     537    }
     538    else
     539        qwtDrawPolyline<QPoint>( painter, points, pointCount, d_polylineSplitting );
    416540}
    417541
     
    420544{
    421545    QRectF clipRect;
    422     const bool deviceClipping = isClippingNeeded( painter, clipRect );
     546    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
    423547
    424548    if ( deviceClipping && !clipRect.contains( pos ) )
     
    426550
    427551    painter->drawPoint( pos );
     552}
     553
     554//! Wrapper for QPainter::drawPoint()
     555void QwtPainter::drawPoint( QPainter *painter, const QPoint &pos )
     556{
     557    QRectF clipRect;
     558    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     559
     560    if ( deviceClipping )
     561    {
     562        const int minX = qCeil( clipRect.left() );
     563        const int maxX = qFloor( clipRect.right() );
     564        const int minY = qCeil( clipRect.top() );
     565        const int maxY = qFloor( clipRect.bottom() );
     566
     567        if ( pos.x() < minX || pos.x() > maxX
     568            || pos.y() < minY || pos.y() > maxY )
     569        {
     570            return;
     571        }
     572    }
     573
     574    painter->drawPoint( pos );
     575}
     576
     577//! Wrapper for QPainter::drawPoints()
     578void QwtPainter::drawPoints( QPainter *painter,
     579    const QPoint *points, int pointCount )
     580{
     581    QRectF clipRect;
     582    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     583
     584    if ( deviceClipping )
     585    {
     586        const int minX = qCeil( clipRect.left() );
     587        const int maxX = qFloor( clipRect.right() );
     588        const int minY = qCeil( clipRect.top() );
     589        const int maxY = qFloor( clipRect.bottom() );
     590
     591        const QRect r( minX, minY, maxX - minX, maxY - minY );
     592
     593        QPolygon clippedPolygon( pointCount );
     594        QPoint *clippedData = clippedPolygon.data();
     595
     596        int numClippedPoints = 0;
     597        for ( int i = 0; i < pointCount; i++ )
     598        {
     599            if ( r.contains( points[i] ) )
     600                clippedData[ numClippedPoints++ ] = points[i];
     601        }
     602        painter->drawPoints( clippedData, numClippedPoints );
     603    }
     604    else
     605    {
     606        painter->drawPoints( points, pointCount );
     607    }
     608}
     609
     610//! Wrapper for QPainter::drawPoints()
     611void QwtPainter::drawPoints( QPainter *painter,
     612    const QPointF *points, int pointCount )
     613{
     614    QRectF clipRect;
     615    const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect );
     616
     617    if ( deviceClipping )
     618    {
     619        QPolygonF clippedPolygon( pointCount );
     620        QPointF *clippedData = clippedPolygon.data();
     621
     622        int numClippedPoints = 0;
     623        for ( int i = 0; i < pointCount; i++ )
     624        {
     625            if ( clipRect.contains( points[i] ) )
     626                clippedData[ numClippedPoints++ ] = points[i];
     627        }
     628        painter->drawPoints( clippedData, numClippedPoints );
     629    }
     630    else
     631    {
     632        painter->drawPoints( points, pointCount );
     633    }
    428634}
    429635
     
    471677
    472678//! Draw a focus rectangle on a widget using its style.
    473 void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget )
     679void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget )
    474680{
    475681    drawFocusRect( painter, widget, widget->rect() );
     
    477683
    478684//! Draw a focus rectangle on a widget using its style.
    479 void QwtPainter::drawFocusRect( QPainter *painter, QWidget *widget,
     685void QwtPainter::drawFocusRect( QPainter *painter, const QWidget *widget,
    480686    const QRect &rect )
    481687{
     
    484690    opt.rect = rect;
    485691    opt.state |= QStyle::State_HasFocus;
    486 
    487     widget->style()->drawPrimitive( QStyle::PE_FrameFocusRect,
    488         &opt, painter, widget );
     692    opt.backgroundColor = widget->palette().color( widget->backgroundRole() );
     693
     694    widget->style()->drawPrimitive(
     695        QStyle::PE_FrameFocusRect, &opt, painter, widget );
    489696}
    490697
    491698/*!
    492   Draw a frame with rounded borders
     699  Draw a round frame
     700
     701  \param painter Painter
     702  \param rect Frame rectangle
     703  \param palette QPalette::WindowText is used for plain borders
     704                 QPalette::Dark and QPalette::Light for raised
     705                 or sunken borders
     706  \param lineWidth Line width
     707  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
     708*/
     709void QwtPainter::drawRoundFrame( QPainter *painter,
     710    const QRectF &rect, const QPalette &palette,
     711    int lineWidth, int frameStyle )
     712{
     713    enum Style
     714    {
     715        Plain,
     716        Sunken,
     717        Raised
     718    };
     719
     720    Style style = Plain;
     721    if ( (frameStyle & QFrame::Sunken) == QFrame::Sunken )
     722        style = Sunken;
     723    else if ( (frameStyle & QFrame::Raised) == QFrame::Raised )
     724        style = Raised;
     725
     726    const double lw2 = 0.5 * lineWidth;
     727    QRectF r = rect.adjusted( lw2, lw2, -lw2, -lw2 );
     728
     729    QBrush brush;
     730
     731    if ( style != Plain )
     732    {
     733        QColor c1 = palette.color( QPalette::Light );
     734        QColor c2 = palette.color( QPalette::Dark );
     735
     736        if ( style == Sunken )
     737            qSwap( c1, c2 );
     738
     739        QLinearGradient gradient( r.topLeft(), r.bottomRight() );
     740        gradient.setColorAt( 0.0, c1 );
     741#if 0
     742        gradient.setColorAt( 0.3, c1 );
     743        gradient.setColorAt( 0.7, c2 );
     744#endif
     745        gradient.setColorAt( 1.0, c2 );
     746
     747        brush = QBrush( gradient );
     748    }
     749    else // Plain
     750    {
     751        brush = palette.brush( QPalette::WindowText );
     752    }
     753
     754    painter->save();
     755
     756    painter->setPen( QPen( brush, lineWidth ) );
     757    painter->setBrush( Qt::NoBrush );
     758
     759    painter->drawEllipse( r );
     760
     761    painter->restore();
     762}
     763
     764/*!
     765  Draw a rectangular frame
     766
     767  \param painter Painter
     768  \param rect Frame rectangle
     769  \param palette Palette
     770  \param foregroundRole Foreground role used for QFrame::Plain
     771  \param frameWidth Frame width
     772  \param midLineWidth Used for QFrame::Box
     773  \param frameStyle bitwise OR´ed value of QFrame::Shape and QFrame::Shadow
     774*/
     775void QwtPainter::drawFrame( QPainter *painter, const QRectF &rect,
     776    const QPalette &palette, QPalette::ColorRole foregroundRole,
     777    int frameWidth, int midLineWidth, int frameStyle )
     778{
     779    if ( frameWidth <= 0 || rect.isEmpty() )
     780        return;
     781
     782    const int shadow = frameStyle & QFrame::Shadow_Mask;
     783
     784    painter->save();
     785
     786    if ( shadow == QFrame::Plain )
     787    {
     788        const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     789        const QRectF innerRect = outerRect.adjusted(
     790            frameWidth, frameWidth, -frameWidth, -frameWidth );
     791
     792        QPainterPath path;
     793        path.addRect( outerRect );
     794        path.addRect( innerRect );
     795
     796        painter->setPen( Qt::NoPen );
     797        painter->setBrush( palette.color( foregroundRole ) );
     798
     799        painter->drawPath( path );
     800    }
     801    else
     802    {
     803        const int shape = frameStyle & QFrame::Shape_Mask;
     804
     805        if ( shape == QFrame::Box )
     806        {
     807            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     808            const QRectF midRect1 = outerRect.adjusted(
     809                frameWidth, frameWidth, -frameWidth, -frameWidth );
     810            const QRectF midRect2 = midRect1.adjusted(
     811                midLineWidth, midLineWidth, -midLineWidth, -midLineWidth );
     812
     813            const QRectF innerRect = midRect2.adjusted(
     814                frameWidth, frameWidth, -frameWidth, -frameWidth );
     815
     816            QPainterPath path1;
     817            path1.moveTo( outerRect.bottomLeft() );
     818            path1.lineTo( outerRect.topLeft() );
     819            path1.lineTo( outerRect.topRight() );
     820            path1.lineTo( midRect1.topRight() );
     821            path1.lineTo( midRect1.topLeft() );
     822            path1.lineTo( midRect1.bottomLeft() );
     823
     824            QPainterPath path2;
     825            path2.moveTo( outerRect.bottomLeft() );
     826            path2.lineTo( outerRect.bottomRight() );
     827            path2.lineTo( outerRect.topRight() );
     828            path2.lineTo( midRect1.topRight() );
     829            path2.lineTo( midRect1.bottomRight() );
     830            path2.lineTo( midRect1.bottomLeft() );
     831
     832            QPainterPath path3;
     833            path3.moveTo( midRect2.bottomLeft() );
     834            path3.lineTo( midRect2.topLeft() );
     835            path3.lineTo( midRect2.topRight() );
     836            path3.lineTo( innerRect.topRight() );
     837            path3.lineTo( innerRect.topLeft() );
     838            path3.lineTo( innerRect.bottomLeft() );
     839
     840            QPainterPath path4;
     841            path4.moveTo( midRect2.bottomLeft() );
     842            path4.lineTo( midRect2.bottomRight() );
     843            path4.lineTo( midRect2.topRight() );
     844            path4.lineTo( innerRect.topRight() );
     845            path4.lineTo( innerRect.bottomRight() );
     846            path4.lineTo( innerRect.bottomLeft() );
     847
     848            QPainterPath path5;
     849            path5.addRect( midRect1 );
     850            path5.addRect( midRect2 );
     851
     852            painter->setPen( Qt::NoPen );
     853
     854            QBrush brush1 = palette.dark().color();
     855            QBrush brush2 = palette.light().color();
     856
     857            if ( shadow == QFrame::Raised )
     858                qSwap( brush1, brush2 );
     859
     860            painter->setBrush( brush1 );
     861            painter->drawPath( path1 );
     862            painter->drawPath( path4 );
     863
     864            painter->setBrush( brush2 );
     865            painter->drawPath( path2 );
     866            painter->drawPath( path3 );
     867
     868            painter->setBrush( palette.mid() );
     869            painter->drawPath( path5 );
     870        }
     871#if 0
     872        // qDrawWinPanel doesn't result in something nice
     873        // on a scalable document like PDF. Better draw a
     874        // Panel.
     875
     876        else if ( shape == QFrame::WinPanel )
     877        {
     878            painter->setRenderHint( QPainter::NonCosmeticDefaultPen, true );
     879            qDrawWinPanel ( painter, rect.toRect(), palette,
     880                frameStyle & QFrame::Sunken );
     881        }
     882        else if ( shape == QFrame::StyledPanel )
     883        {
     884        }
     885#endif
     886        else
     887        {
     888            const QRectF outerRect = rect.adjusted( 0.0, 0.0, -1.0, -1.0 );
     889            const QRectF innerRect = outerRect.adjusted(
     890                frameWidth - 1.0, frameWidth - 1.0,
     891                -( frameWidth - 1.0 ), -( frameWidth - 1.0 ) );
     892
     893            QPainterPath path1;
     894            path1.moveTo( outerRect.bottomLeft() );
     895            path1.lineTo( outerRect.topLeft() );
     896            path1.lineTo( outerRect.topRight() );
     897            path1.lineTo( innerRect.topRight() );
     898            path1.lineTo( innerRect.topLeft() );
     899            path1.lineTo( innerRect.bottomLeft() );
     900
     901
     902            QPainterPath path2;
     903            path2.moveTo( outerRect.bottomLeft() );
     904            path2.lineTo( outerRect.bottomRight() );
     905            path2.lineTo( outerRect.topRight() );
     906            path2.lineTo( innerRect.topRight() );
     907            path2.lineTo( innerRect.bottomRight() );
     908            path2.lineTo( innerRect.bottomLeft() );
     909
     910            painter->setPen( Qt::NoPen );
     911
     912            QBrush brush1 = palette.dark().color();
     913            QBrush brush2 = palette.light().color();
     914
     915            if ( shadow == QFrame::Raised )
     916                qSwap( brush1, brush2 );
     917
     918            painter->setBrush( brush1 );
     919            painter->drawPath( path1 );
     920
     921            painter->setBrush( brush2 );
     922            painter->drawPath( path2 );
     923        }
     924
     925    }
     926
     927    painter->restore();
     928}
     929
     930/*!
     931  Draw a rectangular frame with rounded borders
    493932
    494933  \param painter Painter
     
    5671006
    5681007            QPen arcPen;
     1008            arcPen.setCapStyle( Qt::FlatCap );
    5691009            arcPen.setWidth( lineWidth );
    5701010
    5711011            QPen linePen;
     1012            linePen.setCapStyle( Qt::FlatCap );
    5721013            linePen.setWidth( lineWidth );
    5731014
     
    6601101
    6611102    QPixmap pixmap( devRect.size() );
     1103    pixmap.fill( Qt::transparent );
     1104
    6621105    QPainter pmPainter( &pixmap );
    6631106    pmPainter.translate( -devRect.x(), -devRect.y() );
     
    6731116
    6741117            if ( colorMap.format() == QwtColorMap::RGB )
    675                 c.setRgb( colorMap.rgb( interval, value ) );
     1118                c.setRgba( colorMap.rgb( interval, value ) );
    6761119            else
    6771120                c = colorTable[colorMap.colorIndex( interval, value )];
     
    6911134
    6921135            if ( colorMap.format() == QwtColorMap::RGB )
    693                 c.setRgb( colorMap.rgb( interval, value ) );
     1136                c.setRgba( colorMap.rgb( interval, value ) );
    6941137            else
    6951138                c = colorTable[colorMap.colorIndex( interval, value )];
     
    7031146    drawPixmap( painter, rect, pixmap );
    7041147}
     1148
     1149static inline void qwtFillRect( const QWidget *widget, QPainter *painter,
     1150    const QRect &rect, const QBrush &brush)
     1151{
     1152    if ( brush.style() == Qt::TexturePattern )
     1153    {
     1154        painter->save();
     1155
     1156        painter->setClipRect( rect );
     1157        painter->drawTiledPixmap(rect, brush.texture(), rect.topLeft());
     1158
     1159        painter->restore();
     1160    }
     1161    else if ( brush.gradient() )
     1162    {
     1163        painter->save();
     1164
     1165        painter->setClipRect( rect );
     1166        painter->fillRect(0, 0, widget->width(),
     1167            widget->height(), brush);
     1168
     1169        painter->restore();
     1170    }
     1171    else
     1172    {
     1173        painter->fillRect(rect, brush);
     1174    }
     1175}
     1176
     1177/*!
     1178  Fill a pixmap with the content of a widget
     1179
     1180  In Qt >= 5.0 QPixmap::fill() is a nop, in Qt 4.x it is buggy
     1181  for backgrounds with gradients. Thus fillPixmap() offers
     1182  an alternative implementation.
     1183
     1184  \param widget Widget
     1185  \param pixmap Pixmap to be filled
     1186  \param offset Offset
     1187
     1188  \sa QPixmap::fill()
     1189 */
     1190void QwtPainter::fillPixmap( const QWidget *widget,
     1191    QPixmap &pixmap, const QPoint &offset )
     1192{
     1193    const QRect rect( offset, pixmap.size() );
     1194
     1195    QPainter painter( &pixmap );
     1196    painter.translate( -offset );
     1197
     1198    const QBrush autoFillBrush =
     1199        widget->palette().brush( widget->backgroundRole() );
     1200
     1201    if ( !( widget->autoFillBackground() && autoFillBrush.isOpaque() ) )
     1202    {
     1203        const QBrush bg = widget->palette().brush( QPalette::Window );
     1204        qwtFillRect( widget, &painter, rect, bg);
     1205    }
     1206
     1207    if ( widget->autoFillBackground() )
     1208        qwtFillRect( widget, &painter, rect, autoFillBrush);
     1209
     1210    if ( widget->testAttribute(Qt::WA_StyledBackground) )
     1211    {
     1212        painter.setClipRegion( rect );
     1213
     1214        QStyleOption opt;
     1215        opt.initFrom( widget );
     1216        widget->style()->drawPrimitive( QStyle::PE_Widget,
     1217            &opt, &painter, widget );
     1218    }
     1219}
     1220
     1221/*!
     1222  Fill rect with the background of a widget
     1223
     1224  \param painter Painter
     1225  \param rect Rectangle to be filled
     1226  \param widget Widget
     1227
     1228  \sa QStyle::PE_Widget, QWidget::backgroundRole()
     1229 */
     1230void QwtPainter::drawBackgound( QPainter *painter,
     1231    const QRectF &rect, const QWidget *widget )
     1232{
     1233    if ( widget->testAttribute( Qt::WA_StyledBackground ) )
     1234    {
     1235        QStyleOption opt;
     1236        opt.initFrom( widget );
     1237        opt.rect = rect.toAlignedRect();
     1238
     1239        widget->style()->drawPrimitive(
     1240            QStyle::PE_Widget, &opt, painter, widget);
     1241    }
     1242    else
     1243    {
     1244        const QBrush brush =
     1245            widget->palette().brush( widget->backgroundRole() );
     1246
     1247        painter->fillRect( rect, brush );
     1248    }
     1249}
     1250
     1251/*!
     1252  \return A pixmap that can be used as backing store
     1253
     1254  \param widget Widget, for which the backingstore is intended
     1255  \param size Size of the pixmap
     1256 */
     1257QPixmap QwtPainter::backingStore( QWidget *widget, const QSize &size )
     1258{
     1259    QPixmap pm;
     1260
     1261#define QWT_HIGH_DPI 1
     1262
     1263#if QT_VERSION >= 0x050000 && QWT_HIGH_DPI
     1264    qreal pixelRatio = 1.0;
     1265
     1266    if ( widget && widget->windowHandle() )
     1267    {
     1268#if QT_VERSION < 0x050100
     1269        pixelRatio = widget->windowHandle()->devicePixelRatio();
     1270#else
     1271        pixelRatio = widget->devicePixelRatio();
     1272#endif
     1273    }
     1274    else
     1275    {
     1276        if ( qApp )
     1277            pixelRatio = qApp->devicePixelRatio();
     1278    }
     1279
     1280    pm = QPixmap( size * pixelRatio );
     1281    pm.setDevicePixelRatio( pixelRatio );
     1282#else
     1283    Q_UNUSED( widget )
     1284    pm = QPixmap( size );
     1285#endif
     1286
     1287#if QT_VERSION < 0x050000
     1288#ifdef Q_WS_X11
     1289    if ( widget && isX11GraphicsSystem() )
     1290    {
     1291        if ( pm.x11Info().screen() != widget->x11Info().screen() )
     1292            pm.x11SetScreen( widget->x11Info().screen() );
     1293    }
     1294#endif
     1295#endif
     1296
     1297    return pm;
     1298}
     1299
Note: See TracChangeset for help on using the changeset viewer.