/*! Wrapper for QPainter::drawPolyline() */ void QwtPainter::drawPolyline(QPainter *painter, const QwtPolygon &pa) { QRect clipRect; const bool deviceClipping = isClippingNeeded(painter, clipRect); QwtPolygon cpa = d_metricsMap.layoutToDevice(pa); if ( deviceClipping ) cpa = QwtClipper::clipPolygon(clipRect, cpa); #if QT_VERSION >= 0x040000 bool doSplit = false; const QPaintEngine *pe = painter->paintEngine(); if ( pe && pe->type() == QPaintEngine::Raster && painter->pen().width() >= 2 ) { /* The raster paint engine seems to use some algo with O(n*n). ( Qt 4.3 is better than Qt 4.2, but remains unacceptable) To work around this problem, we have to split the polygon into smaller pieces. */ doSplit = true; } if ( doSplit ) { const int numPoints = cpa.size(); const QPoint *points = cpa.data(); const int splitSize = 20; for ( int i = 0; i < numPoints; i += splitSize ) { const int n = qwtMin(splitSize + 1, cpa.size() - i); painter->drawPolyline(points + i, n); } } else #endif painter->drawPolyline(cpa); }
/*! \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 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, int from, int to) const { int size = to - from + 1; if ( size <= 0 ) return; QwtPolygon polyline; if ( ( d_data->attributes & Fitted ) && d_data->curveFitter ) { // Transform x and y values to window coordinates // to avoid a distinction between linear and // logarithmic scales. #if QT_VERSION < 0x040000 QwtArray<QwtDoublePoint> points(size); #else QPolygonF points(size); #endif for (int i = from; i <= to; i++) { QwtDoublePoint &p = points[i]; p.setX( xMap.xTransform(x(i)) ); p.setY( yMap.xTransform(y(i)) ); } points = d_data->curveFitter->fitCurve(points); size = points.size(); if ( size == 0 ) return; // Round QwtDoublePoints to QPoints // When Qwt support for Qt3 has been dropped (Qwt 6.x) // we will use a doubles for painting and the following // step will be obsolete. polyline.resize(size); const QwtDoublePoint *p = points.data(); QPoint *pl = polyline.data(); if ( d_data->paintAttributes & PaintFiltered ) { QPoint pp(qRound(p[0].x()), qRound(p[0].y())); pl[0] = pp; int count = 1; for (int i = 1; i < size; i++) { const QPoint pi(qRound(p[i].x()), qRound(p[i].y())); if ( pi != pp ) { pl[count++] = pi; pp = pi; } } if ( count != size ) polyline.resize(count); } else { for ( int i = 0; i < size; i++ ) { pl[i].setX( qRound(p[i].x()) ); pl[i].setY( qRound(p[i].y()) ); } } } else { polyline.resize(size); if ( d_data->paintAttributes & PaintFiltered ) { QPoint pp( xMap.transform(x(from)), yMap.transform(y(from)) ); polyline.setPoint(0, pp); int count = 1; for (int i = from + 1; i <= to; i++) { const QPoint pi(xMap.transform(x(i)), yMap.transform(y(i))); if ( pi != pp ) { polyline.setPoint(count, pi); count++; pp = pi; } } if ( count != size ) polyline.resize(count); } else { for (int i = from; i <= to; i++) { int xi = xMap.transform(x(i)); int yi = yMap.transform(y(i)); polyline.setPoint(i - from, xi, yi); } } } if ( d_data->paintAttributes & ClipPolygons ) polyline = QwtClipper::clipPolygon(painter->window(), polyline); QwtPainter::drawPolyline(painter, polyline); if ( d_data->brush.style() != Qt::NoBrush ) fillCurve(painter, xMap, yMap, polyline); }