Qwt User's Guide 6.3.0
Loading...
Searching...
No Matches
qwt_plot_rasteritem.cpp
1/******************************************************************************
2 * Qwt Widget Library
3 * Copyright (C) 1997 Josef Wilgen
4 * Copyright (C) 2002 Uwe Rathmann
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the Qwt License, Version 1.0
8 *****************************************************************************/
9
10#include "qwt_plot_rasteritem.h"
11#include "qwt_scale_map.h"
12#include "qwt_painter.h"
13#include "qwt_text.h"
14#include "qwt_interval.h"
15#include "qwt_math.h"
16
17#include <qpainter.h>
18#include <qpaintengine.h>
19#include <qthread.h>
20#include <qfuture.h>
21#include <qtconcurrentrun.h>
22
23#include <limits>
24
25class QwtPlotRasterItem::PrivateData
26{
27 public:
28 PrivateData()
29 : alpha( -1 )
30 , paintAttributes( QwtPlotRasterItem::PaintInDeviceResolution )
31 {
32 cache.policy = QwtPlotRasterItem::NoCache;
33 }
34
35 int alpha;
36
38
39 struct ImageCache
40 {
42 QRectF area;
43 QSizeF size;
44 QImage image;
45 } cache;
46};
47
48
49static QRectF qwtAlignRect(const QRectF& rect)
50{
51 QRectF r;
52 r.setLeft( qRound( rect.left() ) );
53 r.setRight( qRound( rect.right() ) );
54 r.setTop( qRound( rect.top() ) );
55 r.setBottom( qRound( rect.bottom() ) );
56
57 return r;
58}
59
60static QRectF qwtStripRect(const QRectF& rect, const QRectF& area,
61 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
62 const QwtInterval& xInterval, const QwtInterval& yInterval)
63{
64 QRectF r = rect;
65 if ( xInterval.borderFlags() & QwtInterval::ExcludeMinimum )
66 {
67 if ( area.left() <= xInterval.minValue() )
68 {
69 if ( xMap.isInverting() )
70 r.adjust(0, 0, -1, 0);
71 else
72 r.adjust(1, 0, 0, 0);
73 }
74 }
75
76 if ( xInterval.borderFlags() & QwtInterval::ExcludeMaximum )
77 {
78 if ( area.right() >= xInterval.maxValue() )
79 {
80 if ( xMap.isInverting() )
81 r.adjust(1, 0, 0, 0);
82 else
83 r.adjust(0, 0, -1, 0);
84 }
85 }
86
87 if ( yInterval.borderFlags() & QwtInterval::ExcludeMinimum )
88 {
89 if ( area.top() <= yInterval.minValue() )
90 {
91 if ( yMap.isInverting() )
92 r.adjust(0, 0, 0, -1);
93 else
94 r.adjust(0, 1, 0, 0);
95 }
96 }
97
98 if ( yInterval.borderFlags() & QwtInterval::ExcludeMaximum )
99 {
100 if ( area.bottom() >= yInterval.maxValue() )
101 {
102 if ( yMap.isInverting() )
103 r.adjust(0, 1, 0, 0);
104 else
105 r.adjust(0, 0, 0, -1);
106 }
107 }
108
109 return r;
110}
111
112static QImage qwtExpandImage(const QImage& image,
113 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
114 const QRectF& area, const QRectF& area2, const QRectF& paintRect,
115 const QwtInterval& xInterval, const QwtInterval& yInterval )
116{
117 const QRectF strippedRect = qwtStripRect(paintRect, area2,
118 xMap, yMap, xInterval, yInterval);
119 const QSize sz = strippedRect.toRect().size();
120
121 const int w = image.width();
122 const int h = image.height();
123
124 const QRectF r = QwtScaleMap::transform(xMap, yMap, area).normalized();
125 const double pw = ( r.width() - 1 ) / w;
126 const double ph = ( r.height() - 1 ) / h;
127
128 double px0, py0;
129 if ( !xMap.isInverting() )
130 {
131 px0 = xMap.transform( area2.left() );
132 px0 = qRound( px0 );
133 px0 = px0 - xMap.transform( area.left() );
134 }
135 else
136 {
137 px0 = xMap.transform( area2.right() );
138 px0 = qRound( px0 );
139 px0 -= xMap.transform( area.right() );
140
141 px0 -= 1.0;
142 }
143 px0 += strippedRect.left() - paintRect.left();
144
145 if ( !yMap.isInverting() )
146 {
147 py0 = yMap.transform( area2.top() );
148 py0 = qRound( py0 );
149 py0 -= yMap.transform( area.top() );
150 }
151 else
152 {
153 py0 = yMap.transform( area2.bottom() );
154 py0 = qRound( py0 );
155 py0 -= yMap.transform( area.bottom() );
156
157 py0 -= 1.0;
158 }
159 py0 += strippedRect.top() - paintRect.top();
160
161 QImage expanded( sz, image.format() );
162 if ( image.format() == QImage::Format_Indexed8 )
163 expanded.setColorTable( image.colorTable() );
164
165 switch( image.depth() )
166 {
167 case 32:
168 {
169 for ( int y1 = 0; y1 < h; y1++ )
170 {
171 int yy1;
172 if ( y1 == 0 )
173 {
174 yy1 = 0;
175 }
176 else
177 {
178 yy1 = qRound( y1 * ph - py0 );
179 if ( yy1 < 0 )
180 yy1 = 0;
181 }
182
183 int yy2;
184 if ( y1 == h - 1 )
185 {
186 yy2 = sz.height();
187 }
188 else
189 {
190 yy2 = qRound( ( y1 + 1 ) * ph - py0 );
191 if ( yy2 > sz.height() )
192 yy2 = sz.height();
193 }
194
195 const quint32* line1 =
196 reinterpret_cast< const quint32* >( image.scanLine( y1 ) );
197
198 for ( int x1 = 0; x1 < w; x1++ )
199 {
200 int xx1;
201 if ( x1 == 0 )
202 {
203 xx1 = 0;
204 }
205 else
206 {
207 xx1 = qRound( x1 * pw - px0 );
208 if ( xx1 < 0 )
209 xx1 = 0;
210 }
211
212 int xx2;
213 if ( x1 == w - 1 )
214 {
215 xx2 = sz.width();
216 }
217 else
218 {
219 xx2 = qRound( ( x1 + 1 ) * pw - px0 );
220 if ( xx2 > sz.width() )
221 xx2 = sz.width();
222 }
223
224 const quint32 rgb( line1[x1] );
225 for ( int y2 = yy1; y2 < yy2; y2++ )
226 {
227 quint32* line2 = reinterpret_cast< quint32* >(
228 expanded.scanLine( y2 ) );
229
230 for ( int x2 = xx1; x2 < xx2; x2++ )
231 line2[x2] = rgb;
232 }
233 }
234 }
235 break;
236 }
237 case 8:
238 {
239 for ( int y1 = 0; y1 < h; y1++ )
240 {
241 int yy1;
242 if ( y1 == 0 )
243 {
244 yy1 = 0;
245 }
246 else
247 {
248 yy1 = qRound( y1 * ph - py0 );
249 if ( yy1 < 0 )
250 yy1 = 0;
251 }
252
253 int yy2;
254 if ( y1 == h - 1 )
255 {
256 yy2 = sz.height();
257 }
258 else
259 {
260 yy2 = qRound( ( y1 + 1 ) * ph - py0 );
261 if ( yy2 > sz.height() )
262 yy2 = sz.height();
263 }
264
265 const uchar* line1 = image.scanLine( y1 );
266
267 for ( int x1 = 0; x1 < w; x1++ )
268 {
269 int xx1;
270 if ( x1 == 0 )
271 {
272 xx1 = 0;
273 }
274 else
275 {
276 xx1 = qRound( x1 * pw - px0 );
277 if ( xx1 < 0 )
278 xx1 = 0;
279 }
280
281 int xx2;
282 if ( x1 == w - 1 )
283 {
284 xx2 = sz.width();
285 }
286 else
287 {
288 xx2 = qRound( ( x1 + 1 ) * pw - px0 );
289 if ( xx2 > sz.width() )
290 xx2 = sz.width();
291 }
292
293 for ( int y2 = yy1; y2 < yy2; y2++ )
294 {
295 uchar* line2 = expanded.scanLine( y2 );
296 memset( line2 + xx1, line1[x1], xx2 - xx1 );
297 }
298 }
299 }
300 break;
301 }
302 default:
303 expanded = image;
304 }
305
306 return expanded;
307}
308
309static QRectF qwtExpandToPixels(const QRectF& rect, const QRectF& pixelRect)
310{
311 const double pw = pixelRect.width();
312 const double ph = pixelRect.height();
313
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();
318
319 QRectF r;
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 );
324
325 return r;
326}
327
328static void qwtTransformMaps( const QTransform& tr,
329 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
330 QwtScaleMap& xxMap, QwtScaleMap& yyMap )
331{
332 const QPointF p1 = tr.map( QPointF( xMap.p1(), yMap.p1() ) );
333 const QPointF p2 = tr.map( QPointF( xMap.p2(), yMap.p2() ) );
334
335 xxMap = xMap;
336 xxMap.setPaintInterval( p1.x(), p2.x() );
337
338 yyMap = yMap;
339 yyMap.setPaintInterval( p1.y(), p2.y() );
340}
341
342static void qwtAdjustMaps( QwtScaleMap& xMap, QwtScaleMap& yMap,
343 const QRectF& area, const QRectF& paintRect)
344{
345 double sx1 = area.left();
346 double sx2 = area.right();
347 if ( xMap.isInverting() )
348 qSwap(sx1, sx2);
349
350 double sy1 = area.top();
351 double sy2 = area.bottom();
352
353 if ( yMap.isInverting() )
354 qSwap(sy1, sy2);
355
356 xMap.setPaintInterval(paintRect.left(), paintRect.right() );
357 xMap.setScaleInterval(sx1, sx2);
358
359 yMap.setPaintInterval(paintRect.top(), paintRect.bottom() );
360 yMap.setScaleInterval(sy1, sy2);
361}
362
363static bool qwtUseCache( QwtPlotRasterItem::CachePolicy policy,
364 const QPainter* painter )
365{
366 bool doCache = false;
367
368 if ( policy == QwtPlotRasterItem::PaintCache )
369 {
370 // Caching doesn't make sense, when the item is
371 // not painted to screen
372
373 switch ( painter->paintEngine()->type() )
374 {
375 case QPaintEngine::SVG:
376 case QPaintEngine::Pdf:
377#if QT_VERSION < 0x060000
378 case QPaintEngine::PostScript:
379#endif
380 case QPaintEngine::MacPrinter:
381 case QPaintEngine::Picture:
382 break;
383 default:;
384 doCache = true;
385 }
386 }
387
388 return doCache;
389}
390
391static void qwtToRgba( const QImage* from, QImage* to,
392 const QRect& tile, int alpha )
393{
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 );
397
398 const int y0 = tile.top();
399 const int y1 = tile.bottom();
400 const int x0 = tile.left();
401 const int x1 = tile.right();
402
403 if ( from->depth() == 8 )
404 {
405 for ( int y = y0; y <= y1; y++ )
406 {
407 QRgb* alphaLine = reinterpret_cast< QRgb* >( to->scanLine( y ) );
408 const unsigned char* line = from->scanLine( y );
409
410 for ( int x = x0; x <= x1; x++ )
411 *alphaLine++ = ( from->color( *line++ ) & mask2 ) | mask1;
412 }
413 }
414 else if ( from->depth() == 32 )
415 {
416 for ( int y = y0; y <= y1; y++ )
417 {
418 QRgb* alphaLine = reinterpret_cast< QRgb* >( to->scanLine( y ) );
419 const QRgb* line = reinterpret_cast< const QRgb* >( from->scanLine( y ) );
420
421 for ( int x = x0; x <= x1; x++ )
422 {
423 const QRgb rgb = *line++;
424 if ( rgb & mask3 ) // alpha != 0
425 *alphaLine++ = ( rgb & mask2 ) | mask1;
426 else
427 *alphaLine++ = rgb;
428 }
429 }
430 }
431}
432
435 : QwtPlotItem( QwtText( title ) )
436{
437 init();
438}
439
442 : QwtPlotItem( title )
443{
444 init();
445}
446
449{
450 delete m_data;
451}
452
453void QwtPlotRasterItem::init()
454{
455 m_data = new PrivateData();
456
459
460 setZ( 8.0 );
461}
462
471{
472 if ( on )
473 m_data->paintAttributes |= attribute;
474 else
475 m_data->paintAttributes &= ~attribute;
476}
477
483{
484 return ( m_data->paintAttributes & attribute );
485}
486
511{
512 if ( alpha < 0 )
513 alpha = -1;
514
515 if ( alpha > 255 )
516 alpha = 255;
517
518 if ( alpha != m_data->alpha )
519 {
520 m_data->alpha = alpha;
521
522 itemChanged();
523 }
524}
525
531{
532 return m_data->alpha;
533}
534
545{
546 if ( m_data->cache.policy != policy )
547 {
548 m_data->cache.policy = policy;
549
551 itemChanged();
552 }
553}
554
560{
561 return m_data->cache.policy;
562}
563
569{
570 m_data->cache.image = QImage();
571 m_data->cache.area = QRect();
572 m_data->cache.size = QSize();
573}
574
601QRectF QwtPlotRasterItem::pixelHint( const QRectF& area ) const
602{
603 Q_UNUSED( area );
604 return QRectF();
605}
606
614void QwtPlotRasterItem::draw( QPainter* painter,
615 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
616 const QRectF& canvasRect ) const
617{
618 if ( canvasRect.isEmpty() || m_data->alpha == 0 )
619 return;
620
621 const bool doCache = qwtUseCache( m_data->cache.policy, painter );
622
623 const QwtInterval xInterval = interval( Qt::XAxis );
624 const QwtInterval yInterval = interval( Qt::YAxis );
625
626 /*
627 Scaling an image always results in a loss of
628 precision/quality. So we always render the image in
629 paint device resolution.
630 */
631
632 QwtScaleMap xxMap, yyMap;
633 qwtTransformMaps( painter->transform(), xMap, yMap, xxMap, yyMap );
634
635 QRectF paintRect = painter->transform().mapRect( canvasRect );
636 QRectF area = QwtScaleMap::invTransform( xxMap, yyMap, paintRect );
637
638 const QRectF br = boundingRect();
639 if ( br.isValid() && !br.contains( area ) )
640 {
641 area &= br;
642 if ( !area.isValid() )
643 return;
644
645 paintRect = QwtScaleMap::transform( xxMap, yyMap, area );
646 }
647
648 QRectF imageRect;
649 QImage image;
650
651 QRectF pixelRect = pixelHint(area);
652 if ( !pixelRect.isEmpty() )
653 {
654 // one pixel of the target device in plot coordinates
655 const double dx = qAbs( xxMap.invTransform( 1 ) - xxMap.invTransform( 0 ) );
656 const double dy = qAbs( yyMap.invTransform( 1 ) - yyMap.invTransform( 0 ) );
657
658 if ( dx > pixelRect.width() && dy > pixelRect.height() )
659 {
660 /*
661 When the resolution of the data pixels is higher than
662 the resolution of the target device we render in
663 target device resolution.
664 */
665 pixelRect = QRectF();
666 }
667 else
668 {
669 /*
670 If only one dimension is of the data pixel is higher
671 we expand the pixel rect to the resolution of the target device.
672 */
673
674 if ( dx > pixelRect.width() )
675 pixelRect.setWidth( dx );
676
677 if ( dy > pixelRect.height() )
678 pixelRect.setHeight( dy );
679 }
680 }
681
682 if ( pixelRect.isEmpty() )
683 {
684 if ( QwtPainter::roundingAlignment( painter ) )
685 {
686 // we want to have maps, where the boundaries of
687 // the aligned paint rectangle exactly match the area
688
689 paintRect = qwtAlignRect(paintRect);
690 qwtAdjustMaps(xxMap, yyMap, area, paintRect);
691 }
692
693 // When we have no information about position and size of
694 // data pixels we render in resolution of the paint device.
695
696 auto imageSize = paintRect.size();
697
698#if QT_VERSION >= 0x050000
699 const auto pixelRatio = QwtPainter::devicePixelRatio( painter->device() );
700 imageSize *= pixelRatio;
701#endif
702
703 image = compose(xxMap, yyMap,
704 area, paintRect, imageSize.toSize(), doCache);
705
706 if ( image.isNull() )
707 return;
708
709#if QT_VERSION >= 0x050000
710 image.setDevicePixelRatio( pixelRatio );
711#endif
712
713 // Remove pixels at the boundaries, when explicitly
714 // excluded in the intervals
715
716 imageRect = qwtStripRect(paintRect, area,
717 xxMap, yyMap, xInterval, yInterval);
718
719 if ( imageRect != paintRect )
720 {
721 const QRect r(
722 qRound( imageRect.x() - paintRect.x() ),
723 qRound( imageRect.y() - paintRect.y() ),
724 qRound( imageRect.width() ),
725 qRound( imageRect.height() ) );
726
727 image = image.copy(r);
728 }
729 }
730 else
731 {
732 if ( QwtPainter::roundingAlignment( painter ) )
733 paintRect = qwtAlignRect(paintRect);
734
735 // align the area to the data pixels
736 QRectF imageArea = qwtExpandToPixels(area, pixelRect);
737
738 if ( imageArea.right() == xInterval.maxValue() &&
739 !( xInterval.borderFlags() & QwtInterval::ExcludeMaximum ) )
740 {
741 imageArea.adjust(0, 0, pixelRect.width(), 0);
742 }
743 if ( imageArea.bottom() == yInterval.maxValue() &&
744 !( yInterval.borderFlags() & QwtInterval::ExcludeMaximum ) )
745 {
746 imageArea.adjust(0, 0, 0, pixelRect.height() );
747 }
748
749 QSize imageSize;
750 imageSize.setWidth( qRound( imageArea.width() / pixelRect.width() ) );
751 imageSize.setHeight( qRound( imageArea.height() / pixelRect.height() ) );
752
753 image = compose(xxMap, yyMap,
754 imageArea, paintRect, imageSize, doCache );
755
756 if ( image.isNull() )
757 return;
758
759 imageRect = qwtStripRect(paintRect, area,
760 xxMap, yyMap, xInterval, yInterval);
761
762 if ( ( image.width() > 1 || image.height() > 1 ) &&
764 {
765 // Because of rounding errors the pixels
766 // need to be expanded manually to rectangles of
767 // different sizes
768
769 image = qwtExpandImage(image, xxMap, yyMap,
770 imageArea, area, paintRect, xInterval, yInterval );
771 }
772 }
773
774 painter->save();
775 painter->setWorldTransform( QTransform() );
776
777 QwtPainter::drawImage( painter, imageRect, image );
778
779 painter->restore();
780}
781
791{
792 Q_UNUSED( axis );
793 return QwtInterval();
794}
795
801{
802 const QwtInterval intervalX = interval( Qt::XAxis );
803 const QwtInterval intervalY = interval( Qt::YAxis );
804
805 if ( !intervalX.isValid() && !intervalY.isValid() )
806 return QRectF(); // no bounding rect
807
808 QRectF r;
809
810 if ( intervalX.isValid() )
811 {
812 r.setLeft( intervalX.minValue() );
813 r.setRight( intervalX.maxValue() );
814 }
815 else
816 {
817 const qreal max = std::numeric_limits< float >::max();
818
819 r.setLeft( -0.5 * max );
820 r.setWidth( max );
821 }
822
823 if ( intervalY.isValid() )
824 {
825 r.setTop( intervalY.minValue() );
826 r.setBottom( intervalY.maxValue() );
827 }
828 else
829 {
830 const qreal max = std::numeric_limits< float >::max();
831
832 r.setTop( -0.5 * max );
833 r.setHeight( max );
834 }
835
836 return r.normalized();
837}
838
839QImage QwtPlotRasterItem::compose(
840 const QwtScaleMap& xMap, const QwtScaleMap& yMap,
841 const QRectF& imageArea, const QRectF& paintRect,
842 const QSize& imageSize, bool doCache) const
843{
844 QImage image;
845 if ( imageArea.isEmpty() || paintRect.isEmpty() || imageSize.isEmpty() )
846 return image;
847
848 if ( doCache )
849 {
850 if ( !m_data->cache.image.isNull()
851 && m_data->cache.area == imageArea
852 && m_data->cache.size == paintRect.size() )
853 {
854 image = m_data->cache.image;
855 }
856 }
857
858 if ( image.isNull() )
859 {
860 double dx = 0.0;
861 if ( paintRect.toRect().width() > imageSize.width() )
862 dx = imageArea.width() / imageSize.width();
863
864 const QwtScaleMap xxMap =
865 imageMap(Qt::Horizontal, xMap, imageArea, imageSize, dx);
866
867 double dy = 0.0;
868 if ( paintRect.toRect().height() > imageSize.height() )
869 dy = imageArea.height() / imageSize.height();
870
871 const QwtScaleMap yyMap =
872 imageMap(Qt::Vertical, yMap, imageArea, imageSize, dy);
873
874 image = renderImage( xxMap, yyMap, imageArea, imageSize );
875
876 if ( doCache )
877 {
878 m_data->cache.area = imageArea;
879 m_data->cache.size = paintRect.size();
880 m_data->cache.image = image;
881 }
882 }
883
884 if ( m_data->alpha >= 0 && m_data->alpha < 255 )
885 {
886 QImage alphaImage( image.size(), QImage::Format_ARGB32 );
887
888#if !defined( QT_NO_QFUTURE )
889 uint numThreads = renderThreadCount();
890
891 if ( numThreads <= 0 )
892 numThreads = QThread::idealThreadCount();
893
894 if ( numThreads <= 0 )
895 numThreads = 1;
896
897 const int numRows = image.height() / numThreads;
898
899 QVector< QFuture< void > > futures;
900 futures.reserve( numThreads - 1 );
901
902 for ( uint i = 0; i < numThreads; i++ )
903 {
904 QRect tile( 0, i * numRows, image.width(), numRows );
905 if ( i == numThreads - 1 )
906 {
907 tile.setHeight( image.height() - i * numRows );
908 qwtToRgba( &image, &alphaImage, tile, m_data->alpha );
909 }
910 else
911 {
912 futures += QtConcurrent::run(
913 &qwtToRgba, &image, &alphaImage, tile, m_data->alpha );
914 }
915 }
916 for ( int i = 0; i < futures.size(); i++ )
917 futures[i].waitForFinished();
918#else
919 const QRect tile( 0, 0, image.width(), image.height() );
920 qwtToRgba( &image, &alphaImage, tile, m_data->alpha );
921#endif
922 image = alphaImage;
923 }
924
925 return image;
926}
927
940 Qt::Orientation orientation,
941 const QwtScaleMap& map, const QRectF& area,
942 const QSize& imageSize, double pixelSize) const
943{
944 double p1, p2, s1, s2;
945
946 if ( orientation == Qt::Horizontal )
947 {
948 p1 = 0.0;
949 p2 = imageSize.width();
950 s1 = area.left();
951 s2 = area.right();
952 }
953 else
954 {
955 p1 = 0.0;
956 p2 = imageSize.height();
957 s1 = area.top();
958 s2 = area.bottom();
959 }
960
961 if ( pixelSize > 0.0 || p2 == 1.0 )
962 {
963 double off = 0.5 * pixelSize;
964 if ( map.isInverting() )
965 off = -off;
966
967 s1 += off;
968 s2 += off;
969 }
970 else
971 {
972 p2--;
973 }
974
975 if ( map.isInverting() && ( s1 < s2 ) )
976 qSwap( s1, s2 );
977
978 QwtScaleMap newMap = map;
979 newMap.setPaintInterval( p1, p2 );
980 newMap.setScaleInterval( s1, s2 );
981
982 return newMap;
983}
A class representing an interval.
double minValue() const
@ ExcludeMaximum
Max value is not included in the interval.
@ ExcludeMinimum
Min value is not included in the interval.
double maxValue() const
BorderFlags borderFlags() const
bool isValid() const
static void drawImage(QPainter *, const QRectF &, const QImage &)
Wrapper for QPainter::drawImage()
static qreal devicePixelRatio(const QPaintDevice *)
static bool roundingAlignment()
Base class for items on the plot canvas.
QRectF paintRect(const QwtScaleMap &, const QwtScaleMap &) const
Calculate the bounding paint rectangle of 2 maps.
void setZ(double z)
Set the z value.
void setItemAttribute(ItemAttribute, bool on=true)
virtual void itemChanged()
@ Legend
The item is represented on the legend.
uint renderThreadCount() const
A class, which displays raster data.
bool testPaintAttribute(PaintAttribute) const
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &canvasRect) const override
Draw the raster data.
virtual QRectF boundingRect() const override
void setAlpha(int alpha)
Set an alpha value for the raster data.
virtual QImage renderImage(const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &area, const QSize &imageSize) const =0
Render an image.
virtual ~QwtPlotRasterItem()
Destructor.
void setCachePolicy(CachePolicy)
void setPaintAttribute(PaintAttribute, bool on=true)
QFlags< PaintAttribute > PaintAttributes
virtual QRectF pixelHint(const QRectF &) const
Pixel hint.
CachePolicy
Cache policy The default policy is NoCache.
QwtPlotRasterItem(const QString &title=QString())
Constructor.
virtual QwtScaleMap imageMap(Qt::Orientation, const QwtScaleMap &map, const QRectF &area, const QSize &imageSize, double pixelSize) const
Calculate a scale map for painting to an image.
virtual QwtInterval interval(Qt::Axis) const
CachePolicy cachePolicy() const
A scale map.
bool isInverting() const
double p1() const
double transform(double s) const
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
double invTransform(double p) const
double p2() const
A class representing a text.
Definition qwt_text.h:52