Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_plot_curve.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_plot_curve.cpp

    r4271 r8127  
    99
    1010#include "qwt_plot_curve.h"
     11#include "qwt_point_data.h"
    1112#include "qwt_math.h"
    1213#include "qwt_clipper.h"
    1314#include "qwt_painter.h"
    14 #include "qwt_legend.h"
    15 #include "qwt_legend_item.h"
    1615#include "qwt_scale_map.h"
    1716#include "qwt_plot.h"
    18 #include "qwt_plot_canvas.h"
    1917#include "qwt_curve_fitter.h"
    2018#include "qwt_symbol.h"
     19#include "qwt_point_mapper.h"
    2120#include <qpainter.h>
    2221#include <qpixmap.h>
     
    2423#include <qmath.h>
    2524
    26 static int verifyRange( int size, int &i1, int &i2 )
     25static void qwtUpdateLegendIconSize( QwtPlotCurve *curve )
     26{
     27    if ( curve->symbol() &&
     28        curve->testLegendAttribute( QwtPlotCurve::LegendShowSymbol ) )
     29    {
     30        QSize sz = curve->symbol()->boundingRect().size();
     31        sz += QSize( 2, 2 ); // margin
     32
     33        if ( curve->testLegendAttribute( QwtPlotCurve::LegendShowLine ) )
     34        {
     35            // Avoid, that the line is completely covered by the symbol
     36
     37            int w = qCeil( 1.5 * sz.width() );
     38            if ( w % 2 )
     39                w++;
     40
     41            sz.setWidth( qMax( 8, w ) );
     42        }
     43
     44        curve->setLegendIconSize( sz );
     45    }
     46}
     47
     48static int qwtVerifyRange( int size, int &i1, int &i2 )
    2749{
    2850    if ( size < 1 )
     
    4668        symbol( NULL ),
    4769        attributes( 0 ),
    48         paintAttributes( QwtPlotCurve::ClipPolygons ),
     70        paintAttributes(
     71            QwtPlotCurve::ClipPolygons | QwtPlotCurve::FilterPoints ),
    4972        legendAttributes( 0 )
    5073    {
     
    79102*/
    80103QwtPlotCurve::QwtPlotCurve( const QwtText &title ):
    81     QwtPlotSeriesItem<QPointF>( title )
     104    QwtPlotSeriesItem( title )
    82105{
    83106    init();
     
    89112*/
    90113QwtPlotCurve::QwtPlotCurve( const QString &title ):
    91     QwtPlotSeriesItem<QPointF>( QwtText( title ) )
     114    QwtPlotSeriesItem( QwtText( title ) )
    92115{
    93116    init();
     
    107130
    108131    d_data = new PrivateData;
    109     d_series = new QwtPointSeriesData();
     132    setData( new QwtPointSeriesData() );
    110133
    111134    setZ( 20.0 );
     
    134157
    135158/*!
    136     \brief Return the current paint attributes
     159    \return True, when attribute is enabled
    137160    \sa setPaintAttribute()
    138161*/
     
    143166
    144167/*!
    145   Specify an attribute how to draw the legend identifier
     168  Specify an attribute how to draw the legend icon
    146169
    147170  \param attribute Attribute
    148171  \param on On/Off
    149   /sa testLegendAttribute()
     172  /sa testLegendAttribute(). legendIcon()
    150173*/
    151174void QwtPlotCurve::setLegendAttribute( LegendAttribute attribute, bool on )
    152175{
    153     if ( on )
    154         d_data->legendAttributes |= attribute;
    155     else
    156         d_data->legendAttributes &= ~attribute;
    157 }
    158 
    159 /*!
    160     \brief Return the current paint attributes
    161     \sa setLegendAttribute()
     176    if ( on != testLegendAttribute( attribute ) )
     177    {
     178        if ( on )
     179            d_data->legendAttributes |= attribute;
     180        else
     181            d_data->legendAttributes &= ~attribute;
     182
     183        qwtUpdateLegendIconSize( this );
     184        legendChanged();
     185    }
     186}
     187
     188/*!
     189  \return True, when attribute is enabled
     190  \sa setLegendAttribute()
    162191*/
    163192bool QwtPlotCurve::testLegendAttribute( LegendAttribute attribute ) const
     
    177206    {
    178207        d_data->style = style;
     208
     209        legendChanged();
    179210        itemChanged();
    180211    }
     
    182213
    183214/*!
    184     Return the current style
    185     \sa setStyle()
     215  \return Style of the curve
     216  \sa setStyle()
    186217*/
    187218QwtPlotCurve::CurveStyle QwtPlotCurve::style() const
     
    191222
    192223/*!
    193   Assign a symbol
     224  \brief Assign a symbol
     225
     226  The curve will take the ownership of the symbol, hence the previously
     227  set symbol will be delete by setting a new one. If \p symbol is
     228  \c NULL no symbol will be drawn.
    194229
    195230  \param symbol Symbol
    196231  \sa symbol()
    197232*/
    198 void QwtPlotCurve::setSymbol( const QwtSymbol *symbol )
     233void QwtPlotCurve::setSymbol( QwtSymbol *symbol )
    199234{
    200235    if ( symbol != d_data->symbol )
     
    202237        delete d_data->symbol;
    203238        d_data->symbol = symbol;
     239
     240        qwtUpdateLegendIconSize( this );
     241
     242        legendChanged();
    204243        itemChanged();
    205244    }
     
    216255
    217256/*!
     257  Build and assign a pen
     258
     259  In Qt5 the default pen width is 1.0 ( 0.0 in Qt4 ) what makes it
     260  non cosmetic ( see QPen::isCosmetic() ). This method has been introduced
     261  to hide this incompatibility.
     262
     263  \param color Pen color
     264  \param width Pen width
     265  \param style Pen style
     266
     267  \sa pen(), brush()
     268 */
     269void QwtPlotCurve::setPen( const QColor &color, qreal width, Qt::PenStyle style )
     270{
     271    setPen( QPen( color, width, style ) );
     272}
     273
     274/*!
    218275  Assign a pen
    219276
     
    226283    {
    227284        d_data->pen = pen;
     285
     286        legendChanged();
    228287        itemChanged();
    229288    }
     
    259318    {
    260319        d_data->brush = brush;
     320
     321        legendChanged();
    261322        itemChanged();
    262323    }
     
    278339  \param xMap Maps x-values into pixel coordinates.
    279340  \param yMap Maps y-values into pixel coordinates.
    280   \param canvasRect Contents rect of the canvas
     341  \param canvasRect Contents rectangle of the canvas
    281342  \param from Index of the first point to be painted
    282343  \param to Index of the last point to be painted. If to < 0 the
     
    289350    const QRectF &canvasRect, int from, int to ) const
    290351{
    291     if ( !painter || dataSize() <= 0 )
     352    const size_t numSamples = dataSize();
     353
     354    if ( !painter || numSamples <= 0 )
    292355        return;
    293356
    294357    if ( to < 0 )
    295         to = dataSize() - 1;
    296 
    297     if ( verifyRange( dataSize(), from, to ) > 0 )
     358        to = numSamples - 1;
     359
     360    if ( qwtVerifyRange( numSamples, from, to ) > 0 )
    298361    {
    299362        painter->save();
     
    326389  \param xMap x map
    327390  \param yMap y map
    328   \param canvasRect Contents rect of the canvas
     391  \param canvasRect Contents rectangle of the canvas
    329392  \param from index of the first point to be painted
    330393  \param to index of the last point to be painted
     
    371434  \param xMap x map
    372435  \param yMap y map
    373   \param canvasRect Contents rect of the canvas
     436  \param canvasRect Contents rectangle of the canvas
    374437  \param from index of the first point to be painted
    375438  \param to index of the last point to be painted
     
    382445    const QRectF &canvasRect, int from, int to ) const
    383446{
    384     int size = to - from + 1;
    385     if ( size <= 0 )
     447    if ( from > to )
    386448        return;
    387449
    388450    const bool doAlign = QwtPainter::roundingAlignment( painter );
    389 
    390     QPolygonF polyline( size );
    391 
    392     QPointF *points = polyline.data();
    393     for ( int i = from; i <= to; i++ )
    394     {
    395         const QPointF sample = d_series->sample( i );
    396 
    397         double x = xMap.transform( sample.x() );
    398         double y = yMap.transform( sample.y() );
    399         if ( doAlign )
    400         {
    401             x = qRound( x );
    402             y = qRound( y );
    403         }
    404 
    405         points[i - from].rx() = x;
    406         points[i - from].ry() = y;
    407     }
    408 
    409     if ( ( d_data->attributes & Fitted ) && d_data->curveFitter )
    410         polyline = d_data->curveFitter->fitCurve( polyline );
    411 
     451    const bool doFit = ( d_data->attributes & Fitted ) && d_data->curveFitter;
     452    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
     453            && ( d_data->brush.color().alpha() > 0 );
     454
     455    QRectF clipRect;
    412456    if ( d_data->paintAttributes & ClipPolygons )
    413457    {
    414458        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
    415         const QPolygonF clipped = QwtClipper::clipPolygonF(
    416             canvasRect.adjusted(-pw, -pw, pw, pw), polyline, false );
    417 
    418         QwtPainter::drawPolyline( painter, clipped );
     459        clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
     460    }
     461
     462    bool doIntegers = false;
     463
     464#if QT_VERSION < 0x040800
     465
     466    // For Qt <= 4.7 the raster paint engine is significantly faster
     467    // for rendering QPolygon than for QPolygonF. So let's
     468    // see if we can use it.
     469
     470    if ( painter->paintEngine()->type() == QPaintEngine::Raster )
     471    {
     472        // In case of filling or fitting performance doesn't count
     473        // because both operations are much more expensive
     474        // then drawing the polyline itself
     475
     476        if ( !doFit && !doFill )
     477            doIntegers = true;
     478    }
     479#endif
     480
     481    const bool noDuplicates = d_data->paintAttributes & FilterPoints;
     482
     483    QwtPointMapper mapper;
     484    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
     485    mapper.setFlag( QwtPointMapper::WeedOutPoints, noDuplicates );
     486    mapper.setBoundingRect( canvasRect );
     487
     488    if ( doIntegers )
     489    {
     490        QPolygon polyline = mapper.toPolygon(
     491            xMap, yMap, data(), from, to );
     492
     493        if ( d_data->paintAttributes & ClipPolygons )
     494        {
     495            polyline = QwtClipper::clipPolygon(
     496                clipRect.toAlignedRect(), polyline, false );
     497        }
     498
     499        QwtPainter::drawPolyline( painter, polyline );
    419500    }
    420501    else
    421502    {
    422         QwtPainter::drawPolyline( painter, polyline );
    423     }
    424 
    425     if ( d_data->brush.style() != Qt::NoBrush )
    426         fillCurve( painter, xMap, yMap, canvasRect, polyline );
     503        QPolygonF polyline = mapper.toPolygonF( xMap, yMap, data(), from, to );
     504
     505        if ( doFit )
     506            polyline = d_data->curveFitter->fitCurve( polyline );
     507
     508        if ( doFill )
     509        {
     510            if ( painter->pen().style() != Qt::NoPen )
     511            {
     512                // here we are wasting memory for the filled copy,
     513                // do polygon clipping twice etc .. TODO
     514
     515                QPolygonF filled = polyline;
     516                fillCurve( painter, xMap, yMap, canvasRect, filled );
     517                filled.clear();
     518
     519                if ( d_data->paintAttributes & ClipPolygons )
     520                {
     521                    polyline = QwtClipper::clipPolygonF(
     522                        clipRect, polyline, false );
     523                }
     524
     525                QwtPainter::drawPolyline( painter, polyline );
     526            }
     527            else
     528            {
     529                fillCurve( painter, xMap, yMap, canvasRect, polyline );
     530            }
     531        }
     532        else
     533        {
     534            if ( d_data->paintAttributes & ClipPolygons )
     535            {
     536                polyline = QwtClipper::clipPolygonF(
     537                    clipRect, polyline, false );
     538            }
     539
     540            QwtPainter::drawPolyline( painter, polyline );
     541        }
     542    }
    427543}
    428544
     
    433549  \param xMap x map
    434550  \param yMap y map
    435   \param canvasRect Contents rect of the canvas
     551  \param canvasRect Contents rectangle of the canvas
    436552  \param from index of the first point to be painted
    437553  \param to index of the last point to be painted
     
    458574    const Qt::Orientation o = orientation();
    459575
     576    const QwtSeriesData<QPointF> *series = data();
     577
    460578    for ( int i = from; i <= to; i++ )
    461579    {
    462         const QPointF sample = d_series->sample( i );
     580        const QPointF sample = series->sample( i );
    463581        double xi = xMap.transform( sample.x() );
    464582        double yi = yMap.transform( sample.y() );
     
    484602  \param xMap x map
    485603  \param yMap y map
    486   \param canvasRect Contents rect of the canvas
     604  \param canvasRect Contents rectangle of the canvas
    487605  \param from index of the first point to be painted
    488606  \param to index of the last point to be painted
     
    494612    const QRectF &canvasRect, int from, int to ) const
    495613{
    496     const bool doFill = d_data->brush.style() != Qt::NoBrush;
     614    const QColor color = painter->pen().color();
     615
     616    if ( painter->pen().style() == Qt::NoPen || color.alpha() == 0 )
     617    {
     618        return;
     619    }
     620
     621    const bool doFill = ( d_data->brush.style() != Qt::NoBrush )
     622            && ( d_data->brush.color().alpha() > 0 );
    497623    const bool doAlign = QwtPainter::roundingAlignment( painter );
    498624
    499     QPolygonF polyline;
     625    QwtPointMapper mapper;
     626    mapper.setBoundingRect( canvasRect );
     627    mapper.setFlag( QwtPointMapper::RoundPoints, doAlign );
     628
     629    if ( d_data->paintAttributes & FilterPoints )
     630    {
     631        if ( ( color.alpha() == 255 )
     632            && !( painter->renderHints() & QPainter::Antialiasing ) )
     633        {
     634            mapper.setFlag( QwtPointMapper::WeedOutPoints, true );
     635        }
     636    }
     637
    500638    if ( doFill )
    501         polyline.resize( to - from + 1 );
    502 
    503     QPointF *points = polyline.data();
    504 
    505     for ( int i = from; i <= to; i++ )
    506     {
    507         const QPointF sample = d_series->sample( i );
    508         double xi = xMap.transform( sample.x() );
    509         double yi = yMap.transform( sample.y() );
     639    {
     640        mapper.setFlag( QwtPointMapper::WeedOutPoints, false );
     641
     642        QPolygonF points = mapper.toPointsF(
     643            xMap, yMap, data(), from, to );
     644
     645        QwtPainter::drawPoints( painter, points );
     646        fillCurve( painter, xMap, yMap, canvasRect, points );
     647    }
     648    else if ( d_data->paintAttributes & ImageBuffer )
     649    {
     650        const QImage image = mapper.toImage( xMap, yMap,
     651            data(), from, to, d_data->pen,
     652            painter->testRenderHint( QPainter::Antialiasing ),
     653            renderThreadCount() );
     654
     655        painter->drawImage( canvasRect.toAlignedRect(), image );
     656    }
     657    else if ( d_data->paintAttributes & MinimizeMemory )
     658    {
     659        const QwtSeriesData<QPointF> *series = data();
     660
     661        for ( int i = from; i <= to; i++ )
     662        {
     663            const QPointF sample = series->sample( i );
     664
     665            double xi = xMap.transform( sample.x() );
     666            double yi = yMap.transform( sample.y() );
     667
     668            if ( doAlign )
     669            {
     670                xi = qRound( xi );
     671                yi = qRound( yi );
     672            }
     673
     674            QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
     675        }
     676    }
     677    else
     678    {
    510679        if ( doAlign )
    511680        {
    512             xi = qRound( xi );
    513             yi = qRound( yi );
    514         }
    515 
    516         QwtPainter::drawPoint( painter, QPointF( xi, yi ) );
    517 
    518         if ( doFill )
    519         {
    520             points[i - from].rx() = xi;
    521             points[i - from].ry() = yi;
    522         }
    523     }
    524 
    525     if ( doFill )
    526         fillCurve( painter, xMap, yMap, canvasRect, polyline );
     681            const QPolygon points = mapper.toPoints(
     682                xMap, yMap, data(), from, to );
     683
     684            QwtPainter::drawPoints( painter, points );
     685        }
     686        else
     687        {
     688            const QPolygonF points = mapper.toPointsF(
     689                xMap, yMap, data(), from, to );
     690
     691            QwtPainter::drawPoints( painter, points );
     692        }
     693    }
    527694}
    528695
     
    535702  \param xMap x map
    536703  \param yMap y map
    537   \param canvasRect Contents rect of the canvas
     704  \param canvasRect Contents rectangle of the canvas
    538705  \param from index of the first point to be painted
    539706  \param to index of the last point to be painted
     
    555722        inverted = !inverted;
    556723
     724    const QwtSeriesData<QPointF> *series = data();
     725
    557726    int i, ip;
    558727    for ( i = from, ip = 0; i <= to; i++, ip += 2 )
    559728    {
    560         const QPointF sample = d_series->sample( i );
     729        const QPointF sample = series->sample( i );
    561730        double xi = xMap.transform( sample.x() );
    562731        double yi = yMap.transform( sample.y() );
     
    590759    if ( d_data->paintAttributes & ClipPolygons )
    591760    {
     761        qreal pw = qMax( qreal( 1.0 ), painter->pen().widthF());
     762        const QRectF clipRect = canvasRect.adjusted(-pw, -pw, pw, pw);
     763       
    592764        const QPolygonF clipped = QwtClipper::clipPolygonF(
    593             canvasRect, polygon, false );
     765            clipRect, polygon, false );
    594766
    595767        QwtPainter::drawPolyline( painter, clipped );
     
    678850  \param xMap x map
    679851  \param yMap y map
    680   \param canvasRect Contents rect of the canvas
     852  \param canvasRect Contents rectangle of the canvas
    681853  \param polygon Polygon - will be modified !
    682854
     
    733905    if ( orientation() == Qt::Vertical )
    734906    {
    735         if ( yMap.transformation()->type() == QwtScaleTransformation::Log10 )
    736         {
    737             if ( baseline < QwtScaleMap::LogMin )
    738                 baseline = QwtScaleMap::LogMin;
    739         }
     907        if ( yMap.transformation() )
     908            baseline = yMap.transformation()->bounded( baseline );
    740909
    741910        double refY = yMap.transform( baseline );
     
    748917    else
    749918    {
    750         if ( xMap.transformation()->type() == QwtScaleTransformation::Log10 )
    751         {
    752             if ( baseline < QwtScaleMap::LogMin )
    753                 baseline = QwtScaleMap::LogMin;
    754         }
     919        if ( xMap.transformation() )
     920            baseline = xMap.transformation()->bounded( baseline );
    755921
    756922        double refX = xMap.transform( baseline );
     
    770936  \param xMap x map
    771937  \param yMap y map
    772   \param canvasRect Contents rect of the canvas
     938  \param canvasRect Contents rectangle of the canvas
    773939  \param from Index of the first point to be painted
    774940  \param to Index of the last point to be painted
     
    780946    const QRectF &canvasRect, int from, int to ) const
    781947{
    782     const bool doAlign = QwtPainter::roundingAlignment( painter );
    783 
    784     bool usePixmap = testPaintAttribute( CacheSymbols );
    785     if ( usePixmap && !doAlign )
    786     {
    787         // Don't use the pixmap, when the paint device
    788         // could generate scalable vectors
    789 
    790         usePixmap = false;
    791     }
    792 
    793     if ( usePixmap )
    794     {
    795         QPixmap pm( symbol.boundingSize() );
    796         pm.fill( Qt::transparent );
    797 
    798         const double pw2 = 0.5 * pm.width();
    799         const double ph2 = 0.5 * pm.height();
    800 
    801         QPainter p( &pm );
    802         p.setRenderHints( painter->renderHints() );
    803         symbol.drawSymbol( &p, QPointF( pw2, ph2 ) );
    804         p.end();
    805 
    806         for ( int i = from; i <= to; i++ )
    807         {
    808             const QPointF sample = d_series->sample( i );
    809 
    810             double xi = xMap.transform( sample.x() );
    811             double yi = yMap.transform( sample.y() );
    812             if ( doAlign )
    813             {
    814                 xi = qRound( xi );
    815                 yi = qRound( yi );
    816             }
    817 
    818             if ( canvasRect.contains( xi, yi ) )
    819             {
    820                 const int left = qCeil( xi ) - pw2;
    821                 const int top = qCeil( yi ) - ph2;
    822 
    823                 painter->drawPixmap( left, top, pm );
    824             }
    825         }
    826     }
    827     else
    828     {
    829         const int chunkSize = 500;
    830 
    831         for ( int i = from; i <= to; i += chunkSize )
    832         {
    833             const int n = qMin( chunkSize, to - i + 1 );
    834 
    835             QPolygonF points;
    836             for ( int j = 0; j < n; j++ )
    837             {
    838                 const QPointF sample = d_series->sample( i + j );
    839 
    840                 const double xi = xMap.transform( sample.x() );
    841                 const double yi = yMap.transform( sample.y() );
    842 
    843                 if ( canvasRect.contains( xi, yi ) )
    844                     points += QPointF( xi, yi );
    845             }
    846 
    847             if ( points.size() > 0 )
    848                 symbol.drawSymbols( painter, points );
    849         }
     948    QwtPointMapper mapper;
     949    mapper.setFlag( QwtPointMapper::RoundPoints,
     950        QwtPainter::roundingAlignment( painter ) );
     951    mapper.setFlag( QwtPointMapper::WeedOutPoints,
     952        testPaintAttribute( QwtPlotCurve::FilterPoints ) );
     953    mapper.setBoundingRect( canvasRect );
     954
     955    const int chunkSize = 500;
     956
     957    for ( int i = from; i <= to; i += chunkSize )
     958    {
     959        const int n = qMin( chunkSize, to - i + 1 );
     960
     961        const QPolygonF points = mapper.toPointsF( xMap, yMap,
     962            data(), i, i + n - 1 );
     963
     964        if ( points.size() > 0 )
     965            symbol.drawSymbols( painter, points );
    850966    }
    851967}
     
    856972  The baseline is needed for filling the curve with a brush or
    857973  the Sticks drawing style.
    858   The interpretation of the baseline depends on the CurveType.
    859   With QwtPlotCurve::Yfx, the baseline is interpreted as a horizontal line
    860   at y = baseline(), with QwtPlotCurve::Yfy, it is interpreted as a vertical
     974
     975  The interpretation of the baseline depends on the orientation().
     976  With Qt::Horizontal, the baseline is interpreted as a horizontal line
     977  at y = baseline(), with Qt::Vertical, it is interpreted as a vertical
    861978  line at x = baseline().
    862979
     
    864981
    865982  \param value Value of the baseline
    866   \sa baseline(), setBrush(), setStyle(), setStyle()
     983  \sa baseline(), setBrush(), setStyle(), QwtPlotAbstractSeriesItem::orientation()
    867984*/
    868985void QwtPlotCurve::setBaseline( double value )
     
    8891006  \param pos Position, where to look for the closest curve point
    8901007  \param dist If dist != NULL, closestPoint() returns the distance between
    891               the position and the clostest curve point
     1008              the position and the closest curve point
    8921009  \return Index of the closest curve point, or -1 if none can be found
    8931010          ( f.e when the curve has no points )
     
    8971014int QwtPlotCurve::closestPoint( const QPoint &pos, double *dist ) const
    8981015{
    899     if ( plot() == NULL || dataSize() <= 0 )
     1016    const size_t numSamples = dataSize();
     1017
     1018    if ( plot() == NULL || numSamples <= 0 )
    9001019        return -1;
     1020
     1021    const QwtSeriesData<QPointF> *series = data();
    9011022
    9021023    const QwtScaleMap xMap = plot()->canvasMap( xAxis() );
     
    9061027    double dmin = 1.0e10;
    9071028
    908     for ( uint i = 0; i < dataSize(); i++ )
    909     {
    910         const QPointF sample = d_series->sample( i );
     1029    for ( uint i = 0; i < numSamples; i++ )
     1030    {
     1031        const QPointF sample = series->sample( i );
    9111032
    9121033        const double cx = xMap.transform( sample.x() ) - pos.x();
     
    9271048
    9281049/*!
    929    \brief Update the widget that represents the item on the legend
    930 
    931    \param legend Legend
    932    \sa drawLegendIdentifier(), legendItem(), QwtPlotItem::Legend
    933 */
    934 void QwtPlotCurve::updateLegend( QwtLegend *legend ) const
    935 {
    936     if ( legend && testItemAttribute( QwtPlotItem::Legend )
    937         && ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
    938         && d_data->symbol
    939         && d_data->symbol->style() != QwtSymbol::NoSymbol )
    940     {
    941         QWidget *lgdItem = legend->find( this );
    942         if ( lgdItem == NULL )
    943         {
    944             lgdItem = legendItem();
    945             if ( lgdItem )
    946                 legend->insert( this, lgdItem );
    947         }
    948 
    949         QwtLegendItem *l = qobject_cast<QwtLegendItem *>( lgdItem );
    950         if ( l )
    951         {
    952             QSize sz = d_data->symbol->boundingSize();
    953             sz += QSize( 2, 2 ); // margin
    954 
    955             if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
     1050   \return Icon representing the curve on the legend
     1051
     1052   \param index Index of the legend entry
     1053                ( ignored as there is only one )
     1054   \param size Icon size
     1055
     1056   \sa QwtPlotItem::setLegendIconSize(), QwtPlotItem::legendData()
     1057 */
     1058QwtGraphic QwtPlotCurve::legendIcon( int index,
     1059    const QSizeF &size ) const
     1060{
     1061    Q_UNUSED( index );
     1062
     1063    if ( size.isEmpty() )
     1064        return QwtGraphic();
     1065
     1066    QwtGraphic graphic;
     1067    graphic.setDefaultSize( size );
     1068    graphic.setRenderHint( QwtGraphic::RenderPensUnscaled, true );
     1069
     1070    QPainter painter( &graphic );
     1071    painter.setRenderHint( QPainter::Antialiasing,
     1072        testRenderHint( QwtPlotItem::RenderAntialiased ) );
     1073
     1074    if ( d_data->legendAttributes == 0 ||
     1075        d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
     1076    {
     1077        QBrush brush = d_data->brush;
     1078
     1079        if ( brush.style() == Qt::NoBrush &&
     1080            d_data->legendAttributes == 0 )
     1081        {
     1082            if ( style() != QwtPlotCurve::NoCurve )
    9561083            {
    957                 // Avoid, that the line is completely covered by the symbol
    958 
    959                 int w = qCeil( 1.5 * sz.width() );
    960                 if ( w % 2 )
    961                     w++;
    962 
    963                 sz.setWidth( qMax( 8, w ) );
     1084                brush = QBrush( pen().color() );
    9641085            }
    965 
    966             l->setIdentifierSize( sz );
    967         }
    968     }
    969 
    970     QwtPlotItem::updateLegend( legend );
    971 }
    972 
    973 /*!
    974   \brief Draw the identifier representing the curve on the legend
    975 
    976   \param painter Painter
    977   \param rect Bounding rectangle for the identifier
    978 
    979   \sa setLegendAttribute(), QwtPlotItem::Legend
    980 */
    981 void QwtPlotCurve::drawLegendIdentifier(
    982     QPainter *painter, const QRectF &rect ) const
    983 {
    984     if ( rect.isEmpty() )
    985         return;
    986 
    987     const int dim = qMin( rect.width(), rect.height() );
    988 
    989     QSize size( dim, dim );
    990 
    991     QRectF r( 0, 0, size.width(), size.height() );
    992     r.moveCenter( rect.center() );
    993 
    994     if ( d_data->legendAttributes == 0 )
    995     {
    996         QBrush brush = d_data->brush;
    997         if ( brush.style() == Qt::NoBrush )
    998         {
    999             if ( style() != QwtPlotCurve::NoCurve )
    1000                 brush = QBrush( pen().color() );
    10011086            else if ( d_data->symbol &&
    10021087                ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
     
    10051090            }
    10061091        }
     1092
    10071093        if ( brush.style() != Qt::NoBrush )
    1008             painter->fillRect( r, brush );
    1009     }
    1010     if ( d_data->legendAttributes & QwtPlotCurve::LegendShowBrush )
    1011     {
    1012         if ( d_data->brush.style() != Qt::NoBrush )
    1013             painter->fillRect( r, d_data->brush );
    1014     }
     1094        {
     1095            QRectF r( 0, 0, size.width(), size.height() );
     1096            painter.fillRect( r, brush );
     1097        }
     1098    }
     1099
    10151100    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowLine )
    10161101    {
    10171102        if ( pen() != Qt::NoPen )
    10181103        {
    1019             painter->setPen( pen() );
    1020             QwtPainter::drawLine( painter, rect.left(), rect.center().y(),
    1021                                   rect.right() - 1.0, rect.center().y() );
    1022         }
    1023     }
     1104            QPen pn = pen();
     1105            pn.setCapStyle( Qt::FlatCap );
     1106
     1107            painter.setPen( pn );
     1108
     1109            const double y = 0.5 * size.height();
     1110            QwtPainter::drawLine( &painter, 0.0, y, size.width(), y );
     1111        }
     1112    }
     1113
    10241114    if ( d_data->legendAttributes & QwtPlotCurve::LegendShowSymbol )
    10251115    {
    1026         if ( d_data->symbol &&
    1027             ( d_data->symbol->style() != QwtSymbol::NoSymbol ) )
    1028         {
    1029             QSize symbolSize = d_data->symbol->boundingSize();
    1030             symbolSize -= QSize( 2, 2 );
    1031 
    1032             // scale the symbol size down if it doesn't fit into rect.
    1033 
    1034             double xRatio = 1.0;
    1035             if ( rect.width() < symbolSize.width() )
    1036                 xRatio = rect.width() / symbolSize.width();
    1037             double yRatio = 1.0;
    1038             if ( rect.height() < symbolSize.height() )
    1039                 yRatio = rect.height() / symbolSize.height();
    1040 
    1041             const double ratio = qMin( xRatio, yRatio );
    1042 
    1043             painter->save();
    1044             painter->scale( ratio, ratio );
    1045 
    1046             d_data->symbol->drawSymbol( painter, rect.center() / ratio );
    1047 
    1048             painter->restore();
    1049         }
    1050     }
    1051 }
    1052 
    1053 /*!
    1054   Initialize data with an array of points (explicitly shared).
     1116        if ( d_data->symbol )
     1117        {
     1118            QRectF r( 0, 0, size.width(), size.height() );
     1119            d_data->symbol->drawSymbol( &painter, r );
     1120        }
     1121    }
     1122
     1123    return graphic;
     1124}
     1125
     1126/*!
     1127  Initialize data with an array of points.
    10551128
    10561129  \param samples Vector of points
     1130  \note QVector is implicitly shared
     1131  \note QPolygonF is derived from QVector<QPointF>
    10571132*/
    10581133void QwtPlotCurve::setSamples( const QVector<QPointF> &samples )
    10591134{
    1060     delete d_series;
    1061     d_series = new QwtPointSeriesData( samples );
    1062     itemChanged();
     1135    setData( new QwtPointSeriesData( samples ) );
     1136}
     1137
     1138/*!
     1139  Assign a series of points
     1140
     1141  setSamples() is just a wrapper for setData() without any additional
     1142  value - beside that it is easier to find for the developer.
     1143
     1144  \param data Data
     1145  \warning The item takes ownership of the data object, deleting
     1146           it when its not used anymore.
     1147*/
     1148void QwtPlotCurve::setSamples( QwtSeriesData<QPointF> *data )
     1149{
     1150    setData( data );
    10631151}
    10641152
     
    10821170    const double *xData, const double *yData, int size )
    10831171{
    1084     delete d_series;
    1085     d_series = new QwtCPointerData( xData, yData, size );
    1086     itemChanged();
     1172    setData( new QwtCPointerData( xData, yData, size ) );
    10871173}
    10881174
     
    11011187    const double *xData, const double *yData, int size )
    11021188{
    1103     delete d_series;
    1104     d_series = new QwtPointArrayData( xData, yData, size );
    1105     itemChanged();
     1189    setData( new QwtPointArrayData( xData, yData, size ) );
    11061190}
    11071191
     
    11171201    const QVector<double> &yData )
    11181202{
    1119     delete d_series;
    1120     d_series = new QwtPointArrayData( xData, yData );
    1121     itemChanged();
    1122 }
     1203    setData( new QwtPointArrayData( xData, yData ) );
     1204}
     1205
    11231206#endif // !QWT_NO_COMPAT
    11241207
Note: See TracChangeset for help on using the changeset viewer.