/*! \brief Return the raster to be used by the CONREC contour algorithm. A larger size will improve the precision of the CONREC algorithm, but will slow down the time that is needed to calculate the lines. The default implementation returns rect.size() / 2 bounded to the resolution depending on pixelSize(). \param area Rectangle, where to calculate the contour lines \param rect Rectangle in pixel coordinates, where to paint the contour lines \return Raster to be used by the CONREC contour algorithm. \note The size will be bounded to rect.size(). \sa drawContourLines(), QwtRasterData::contourLines() */ QSize QwtPlotSpectrogram::contourRasterSize( const QRectF &area, const QRect &rect ) const { QSize raster = rect.size() / 2; const QRectF pixelRect = pixelHint( area ); if ( !pixelRect.isEmpty() ) { const QSize res( qCeil( rect.width() / pixelRect.width() ), qCeil( rect.height() / pixelRect.height() ) ); raster = raster.boundedTo( res ); } return raster; }
/*! \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(); }