18 #include <qpaintengine.h>
21 #include <qtconcurrentrun.h>
52 r.setLeft( qRound( rect.left() ) );
53 r.setRight( qRound( rect.right() ) );
54 r.setTop( qRound( rect.top() ) );
55 r.setBottom( qRound( rect.bottom() ) );
67 if ( area.left() <= xInterval.
minValue() )
70 r.adjust(0, 0, -1, 0);
78 if ( area.right() >= xInterval.
maxValue() )
83 r.adjust(0, 0, -1, 0);
89 if ( area.top() <= yInterval.
minValue() )
92 r.adjust(0, 0, 0, -1);
100 if ( area.bottom() >= yInterval.
maxValue() )
103 r.adjust(0, 1, 0, 0);
105 r.adjust(0, 0, 0, -1);
114 const QRectF& area,
const QRectF& area2,
const QRectF& paintRect,
117 const QRectF strippedRect =
qwtStripRect(paintRect, area2,
118 xMap, yMap, xInterval, yInterval);
119 const QSize sz = strippedRect.toRect().size();
121 const int w = image.width();
122 const int h = image.height();
125 const double pw = ( r.width() - 1 ) / w;
126 const double ph = ( r.height() - 1 ) / h;
133 px0 = px0 - xMap.
transform( area.left() );
143 px0 += strippedRect.left() - paintRect.left();
159 py0 += strippedRect.top() - paintRect.top();
161 QImage expanded( sz, image.format() );
162 if ( image.format() == QImage::Format_Indexed8 )
163 expanded.setColorTable( image.colorTable() );
165 switch( image.depth() )
169 for (
int y1 = 0; y1 < h; y1++ )
178 yy1 = qRound( y1 * ph - py0 );
190 yy2 = qRound( ( y1 + 1 ) * ph - py0 );
191 if ( yy2 > sz.height() )
195 const quint32* line1 =
196 reinterpret_cast< const quint32*
>( image.scanLine( y1 ) );
198 for (
int x1 = 0; x1 < w; x1++ )
207 xx1 = qRound( x1 * pw - px0 );
219 xx2 = qRound( ( x1 + 1 ) * pw - px0 );
220 if ( xx2 > sz.width() )
224 const quint32
rgb( line1[x1] );
225 for (
int y2 = yy1; y2 < yy2; y2++ )
227 quint32* line2 =
reinterpret_cast< quint32*
>(
228 expanded.scanLine( y2 ) );
230 for (
int x2 = xx1; x2 < xx2; x2++ )
239 for (
int y1 = 0; y1 < h; y1++ )
248 yy1 = qRound( y1 * ph - py0 );
260 yy2 = qRound( ( y1 + 1 ) * ph - py0 );
261 if ( yy2 > sz.height() )
265 const uchar* line1 = image.scanLine( y1 );
267 for (
int x1 = 0; x1 < w; x1++ )
276 xx1 = qRound( x1 * pw - px0 );
288 xx2 = qRound( ( x1 + 1 ) * pw - px0 );
289 if ( xx2 > sz.width() )
293 for (
int y2 = yy1; y2 < yy2; y2++ )
295 uchar* line2 = expanded.scanLine( y2 );
296 memset( line2 + xx1, line1[x1], xx2 - xx1 );
311 const double pw = pixelRect.width();
312 const double ph = pixelRect.height();
314 const double dx1 = pixelRect.left() - rect.left();
315 const double dx2 = pixelRect.right() - rect.right();
316 const double dy1 = pixelRect.top() - rect.top();
317 const double dy2 = pixelRect.bottom() - rect.bottom();
320 r.setLeft( pixelRect.left() -
qwtCeil( dx1 / pw ) * pw );
321 r.setTop( pixelRect.top() -
qwtCeil( dy1 / ph ) * ph );
322 r.setRight( pixelRect.right() -
qwtFloor( dx2 / pw ) * pw );
323 r.setBottom( pixelRect.bottom() -
qwtFloor( dy2 / ph ) * ph );
332 const QPointF p1 = tr.map( QPointF( xMap.
p1(), yMap.
p1() ) );
333 const QPointF p2 = tr.map( QPointF( xMap.
p2(), yMap.
p2() ) );
343 const QRectF& area,
const QRectF& paintRect)
345 double sx1 = area.left();
346 double sx2 = area.right();
350 double sy1 = area.top();
351 double sy2 = area.bottom();
364 const QPainter* painter )
366 bool doCache =
false;
373 switch ( painter->paintEngine()->type() )
375 case QPaintEngine::SVG:
376 case QPaintEngine::Pdf:
377 #if QT_VERSION < 0x060000
378 case QPaintEngine::PostScript:
380 case QPaintEngine::MacPrinter:
381 case QPaintEngine::Picture:
392 const QRect& tile,
int alpha )
394 const QRgb mask1 = qRgba( 0, 0, 0, alpha );
395 const QRgb mask2 = qRgba( 255, 255, 255, 0 );
396 const QRgb mask3 = qRgba( 0, 0, 0, 255 );
398 const int y0 = tile.top();
399 const int y1 = tile.bottom();
400 const int x0 = tile.left();
401 const int x1 = tile.right();
403 if ( from->depth() == 8 )
405 for (
int y = y0;
y <= y1;
y++ )
407 QRgb* alphaLine =
reinterpret_cast< QRgb*
>( to->scanLine(
y ) );
408 const unsigned char* line = from->scanLine(
y );
410 for (
int x = x0;
x <= x1;
x++ )
411 *alphaLine++ = ( from->color( *line++ ) & mask2 ) | mask1;
414 else if ( from->depth() == 32 )
416 for (
int y = y0;
y <= y1;
y++ )
418 QRgb* alphaLine =
reinterpret_cast< QRgb*
>( to->scanLine(
y ) );
419 const QRgb* line =
reinterpret_cast< const QRgb*
>( from->scanLine(
y ) );
421 for (
int x = x0;
x <= x1;
x++ )
423 const QRgb
rgb = *line++;
425 *alphaLine++ = (
rgb & mask2 ) | mask1;
616 const QRectF& canvasRect )
const
635 QRectF
paintRect = painter->transform().mapRect( canvasRect );
639 if ( br.isValid() && !br.contains( area ) )
642 if ( !area.isValid() )
652 if ( !pixelRect.isEmpty() )
658 if ( dx > pixelRect.width() && dy > pixelRect.height() )
665 pixelRect = QRectF();
674 if ( dx > pixelRect.width() )
675 pixelRect.setWidth( dx );
677 if ( dy > pixelRect.height() )
678 pixelRect.setHeight( dy );
682 if ( pixelRect.isEmpty() )
698 #if QT_VERSION >= 0x050000
700 imageSize *= pixelRatio;
704 area,
paintRect, imageSize.toSize(), doCache);
706 if ( image.isNull() )
709 #if QT_VERSION >= 0x050000
710 image.setDevicePixelRatio( pixelRatio );
717 xxMap, yyMap, xInterval, yInterval);
724 qRound( imageRect.width() ),
725 qRound( imageRect.height() ) );
727 image = image.copy(r);
738 if ( imageArea.right() == xInterval.
maxValue() &&
741 imageArea.adjust(0, 0, pixelRect.width(), 0);
743 if ( imageArea.bottom() == yInterval.
maxValue() &&
746 imageArea.adjust(0, 0, 0, pixelRect.height() );
750 imageSize.setWidth( qRound( imageArea.width() / pixelRect.width() ) );
751 imageSize.setHeight( qRound( imageArea.height() / pixelRect.height() ) );
754 imageArea,
paintRect, imageSize, doCache );
756 if ( image.isNull() )
760 xxMap, yyMap, xInterval, yInterval);
762 if ( ( image.width() > 1 || image.height() > 1 ) &&
770 imageArea, area,
paintRect, xInterval, yInterval );
775 painter->setWorldTransform( QTransform() );
817 const qreal max = std::numeric_limits< float >::max();
819 r.setLeft( -0.5 * max );
826 r.setBottom( intervalY.
maxValue() );
830 const qreal max = std::numeric_limits< float >::max();
832 r.setTop( -0.5 * max );
836 return r.normalized();
841 const QRectF& imageArea,
const QRectF& paintRect,
842 const QSize& imageSize,
bool doCache)
const
845 if ( imageArea.isEmpty() ||
paintRect.isEmpty() || imageSize.isEmpty() )
858 if ( image.isNull() )
861 if (
paintRect.toRect().width() > imageSize.width() )
862 dx = imageArea.width() / imageSize.width();
865 imageMap(Qt::Horizontal, xMap, imageArea, imageSize, dx);
868 if (
paintRect.toRect().height() > imageSize.height() )
869 dy = imageArea.height() / imageSize.height();
872 imageMap(Qt::Vertical, yMap, imageArea, imageSize, dy);
874 image =
renderImage( xxMap, yyMap, imageArea, imageSize );
886 QImage alphaImage( image.size(), QImage::Format_ARGB32 );
888 #if !defined( QT_NO_QFUTURE )
891 if ( numThreads <= 0 )
892 numThreads = QThread::idealThreadCount();
894 if ( numThreads <= 0 )
897 const int numRows = image.height() / numThreads;
900 futures.reserve( numThreads - 1 );
902 for ( uint i = 0; i < numThreads; i++ )
904 QRect tile( 0, i * numRows, image.width(), numRows );
905 if ( i == numThreads - 1 )
907 tile.setHeight( image.height() - i * numRows );
912 futures += QtConcurrent::run(
916 for (
int i = 0; i < futures.size(); i++ )
917 futures[i].waitForFinished();
919 const QRect tile( 0, 0, image.width(), image.height() );
940 Qt::Orientation orientation,
942 const QSize& imageSize,
double pixelSize)
const
944 double p1, p2, s1, s2;
946 if ( orientation == Qt::Horizontal )
949 p2 = imageSize.width();
956 p2 = imageSize.height();
961 if ( pixelSize > 0.0 || p2 == 1.0 )
963 double off = 0.5 * pixelSize;
964 if (
map.isInverting() )
975 if (
map.isInverting() && ( s1 < s2 ) )