static QRectF qwtStripRect(const QRectF &rect, const QRectF &area, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QwtInterval &xInterval, const QwtInterval &yInterval) { QRectF r = rect; if ( xInterval.borderFlags() & QwtInterval::ExcludeMinimum ) { if ( area.left() <= xInterval.minValue() ) { if ( xMap.isInverting() ) r.adjust(0, 0, -1, 0); else r.adjust(1, 0, 0, 0); } } if ( xInterval.borderFlags() & QwtInterval::ExcludeMaximum ) { if ( area.right() >= xInterval.maxValue() ) { if ( xMap.isInverting() ) r.adjust(1, 0, 0, 0); else r.adjust(0, 0, -1, 0); } } if ( yInterval.borderFlags() & QwtInterval::ExcludeMinimum ) { if ( area.top() <= yInterval.minValue() ) { if ( yMap.isInverting() ) r.adjust(0, 0, 0, -1); else r.adjust(0, 1, 0, 0); } } if ( yInterval.borderFlags() & QwtInterval::ExcludeMaximum ) { if ( area.bottom() >= yInterval.maxValue() ) { if ( yMap.isInverting() ) r.adjust(0, 1, 0, 0); else r.adjust(0, 0, 0, -1); } } return r; }
inline static bool qwtIsIncreasing( const QwtScaleMap &map, const QVector<double> &values ) { bool isInverting = map.isInverting(); for ( int i = 0; i < values.size(); i++ ) { const double y = values[ i ]; if ( y != 0.0 ) return ( map.isInverting() != ( y > 0.0 ) ); } return !isInverting; }
/*! \brief Calculate a scale map for painting to an image \param orientation Orientation, Qt::Horizontal means a X axis \param map Scale map for rendering the plot item \param area Area to be painted on the image \param imageSize Image size \param pixelSize Width/Height of a data pixel \return Calculated scale map */ QwtScaleMap QwtPlotRasterItem::imageMap( Qt::Orientation orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const { double p1, p2, s1, s2; if ( orientation == Qt::Horizontal ) { p1 = 0.0; p2 = imageSize.width(); s1 = area.left(); s2 = area.right(); } else { p1 = 0.0; p2 = imageSize.height(); s1 = area.top(); s2 = area.bottom(); } if ( pixelSize > 0.0 ) { double off = 0.5 * pixelSize; if ( map.isInverting() ) off = -off; s1 += off; s2 += off; } else { p2--; } if ( map.isInverting() && ( s1 < s2 ) ) qSwap( s1, s2 ); QwtScaleMap newMap = map; newMap.setPaintInterval( p1, p2 ); newMap.setScaleInterval( s1, s2 ); return newMap; }
static void qwtAdjustMaps( QwtScaleMap &xMap, QwtScaleMap &yMap, const QRectF &area, const QRectF &paintRect) { double sx1 = area.left(); double sx2 = area.right(); if ( xMap.isInverting() ) qSwap(sx1, sx2); double sy1 = area.top(); double sy2 = area.bottom(); if ( yMap.isInverting() ) qSwap(sy1, sy2); xMap.setPaintInterval(paintRect.left(), paintRect.right()); xMap.setScaleInterval(sx1, sx2); yMap.setPaintInterval(paintRect.top(), paintRect.bottom()); yMap.setScaleInterval(sy1, sy2); }
static inline bool qwtInsidePole( const QwtScaleMap &map, double radius ) { return map.isInverting() ? ( radius > map.s1() ) : ( radius < map.s1() ); }
static QImage qwtExpandImage(const QImage &image, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QRectF &area2, const QRectF &paintRect, const QwtInterval &xInterval, const QwtInterval &yInterval ) { const QRectF strippedRect = qwtStripRect(paintRect, area2, xMap, yMap, xInterval, yInterval); const QSize sz = strippedRect.toRect().size(); const int w = image.width(); const int h = image.height(); const QRectF r = QwtScaleMap::transform(xMap, yMap, area).normalized(); const double pw = ( r.width() - 1) / w; const double ph = ( r.height() - 1) / h; double px0, py0; if ( !xMap.isInverting() ) { px0 = xMap.transform( area2.left() ); px0 = qRound( px0 ); px0 = px0 - xMap.transform( area.left() ); } else { px0 = xMap.transform( area2.right() ); px0 = qRound( px0 ); px0 -= xMap.transform( area.right() ); px0 -= 1.0; } px0 += strippedRect.left() - paintRect.left(); if ( !yMap.isInverting() ) { py0 = yMap.transform( area2.top() ); py0 = qRound( py0 ); py0 -= yMap.transform( area.top() ); } else { py0 = yMap.transform( area2.bottom() ); py0 = qRound( py0 ); py0 -= yMap.transform( area.bottom() ); py0 -= 1.0; } py0 += strippedRect.top() - paintRect.top(); QImage expanded(sz, image.format()); switch( image.depth() ) { case 32: { for ( int y1 = 0; y1 < h; y1++ ) { int yy1; if ( y1 == 0 ) { yy1 = 0; } else { yy1 = qRound( y1 * ph - py0 ); if ( yy1 < 0 ) yy1 = 0; } int yy2; if ( y1 == h - 1 ) { yy2 = sz.height(); } else { yy2 = qRound( ( y1 + 1 ) * ph - py0 ); if ( yy2 > sz.height() ) yy2 = sz.height(); } const quint32 *line1 = reinterpret_cast<const quint32 *>( image.scanLine( y1 ) ); for ( int x1 = 0; x1 < w; x1++ ) { int xx1; if ( x1 == 0 ) { xx1 = 0; } else { xx1 = qRound( x1 * pw - px0 ); if ( xx1 < 0 ) xx1 = 0; } int xx2; if ( x1 == w - 1 ) { xx2 = sz.width(); } else { xx2 = qRound( ( x1 + 1 ) * pw - px0 ); if ( xx2 > sz.width() ) xx2 = sz.width(); } const quint32 rgb( line1[x1] ); for ( int y2 = yy1; y2 < yy2; y2++ ) { quint32 *line2 = reinterpret_cast<quint32 *>( expanded.scanLine( y2 ) ); for ( int x2 = xx1; x2 < xx2; x2++ ) line2[x2] = rgb; } } } break; } case 8: { for ( int y1 = 0; y1 < h; y1++ ) { int yy1; if ( y1 == 0 ) { yy1 = 0; } else { yy1 = qRound( y1 * ph - py0 ); if ( yy1 < 0 ) yy1 = 0; } int yy2; if ( y1 == h - 1 ) { yy2 = sz.height(); } else { yy2 = qRound( ( y1 + 1 ) * ph - py0 ); if ( yy2 > sz.height() ) yy2 = sz.height(); } const uchar *line1 = image.scanLine( y1 ); for ( int x1 = 0; x1 < w; x1++ ) { int xx1; if ( x1 == 0 ) { xx1 = 0; } else { xx1 = qRound( x1 * pw - px0 ); if ( xx1 < 0 ) xx1 = 0; } int xx2; if ( x1 == w - 1 ) { xx2 = sz.width(); } else { xx2 = qRound( ( x1 + 1 ) * pw - px0 ); if ( xx2 > sz.width() ) xx2 = sz.width(); } for ( int y2 = yy1; y2 < yy2; y2++ ) { uchar *line2 = expanded.scanLine( y2 ); memset( line2 + xx1, line1[x1], xx2 - xx1 ); } } } break; } default: expanded = image; } return expanded; }
/*! Redraw the liquid in thermometer pipe. \param painter Painter \param pipeRect Bounding rectangle of the pipe without borders */ void QwtThermo::drawLiquid( QPainter *painter, const QRect &pipeRect ) const { painter->save(); painter->setClipRect( pipeRect, Qt::IntersectClip ); painter->setPen( Qt::NoPen ); const QwtScaleMap scaleMap = scaleDraw()->scaleMap(); QRect liquidRect = fillRect( pipeRect ); if ( d_data->colorMap != NULL ) { const QwtInterval interval = scaleDiv().interval().normalized(); // Because the positions of the ticks are rounded // we calculate the colors for the rounded tick values QVector<double> values = qwtTickList( scaleDraw()->scaleDiv() ); if ( scaleMap.isInverting() ) qSort( values.begin(), values.end(), qGreater<double>() ); else qSort( values.begin(), values.end(), qLess<double>() ); int from; if ( !values.isEmpty() ) { from = qRound( scaleMap.transform( values[0] ) ); qwtDrawLine( painter, from, d_data->colorMap->color( interval, values[0] ), pipeRect, liquidRect, d_data->orientation ); } for ( int i = 1; i < values.size(); i++ ) { const int to = qRound( scaleMap.transform( values[i] ) ); for ( int pos = from + 1; pos < to; pos++ ) { const double v = scaleMap.invTransform( pos ); qwtDrawLine( painter, pos, d_data->colorMap->color( interval, v ), pipeRect, liquidRect, d_data->orientation ); } qwtDrawLine( painter, to, d_data->colorMap->color( interval, values[i] ), pipeRect, liquidRect, d_data->orientation ); from = to; } } else { if ( !liquidRect.isEmpty() && d_data->alarmEnabled ) { const QRect r = alarmRect( liquidRect ); if ( !r.isEmpty() ) { painter->fillRect( r, palette().brush( QPalette::Highlight ) ); liquidRect = QRegion( liquidRect ).subtracted( r ).boundingRect(); } } painter->fillRect( liquidRect, palette().brush( QPalette::ButtonText ) ); } painter->restore(); }