qwt_graphic.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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_graphic.h"
11 #include "qwt_painter_command.h"
12 #include "qwt_math.h"
13 
14 #include <qvector.h>
15 #include <qpainter.h>
16 #include <qpaintengine.h>
17 #include <qimage.h>
18 #include <qpixmap.h>
19 #include <qpainterpath.h>
20 
21 #if QT_VERSION >= 0x050000
22 
23 #include <qguiapplication.h>
24 
25 static inline qreal qwtDevicePixelRatio()
26 {
27  return qGuiApp ? qGuiApp->devicePixelRatio() : 1.0;
28 }
29 
30 #endif
31 
32 static bool qwtHasScalablePen( const QPainter *painter )
33 {
34  const QPen pen = painter->pen();
35 
36  bool scalablePen = false;
37 
38  if ( pen.style() != Qt::NoPen && pen.brush().style() != Qt::NoBrush )
39  {
40  scalablePen = !pen.isCosmetic();
41 #if QT_VERSION < 0x050000
42  if ( !scalablePen && pen.widthF() == 0.0 )
43  {
44  const QPainter::RenderHints hints = painter->renderHints();
45  if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) )
46  scalablePen = true;
47  }
48 #endif
49  }
50 
51  return scalablePen;
52 }
53 
54 static QRectF qwtStrokedPathRect(
55  const QPainter *painter, const QPainterPath &path )
56 {
57  QPainterPathStroker stroker;
58  stroker.setWidth( painter->pen().widthF() );
59  stroker.setCapStyle( painter->pen().capStyle() );
60  stroker.setJoinStyle( painter->pen().joinStyle() );
61  stroker.setMiterLimit( painter->pen().miterLimit() );
62 
63  QRectF rect;
64  if ( qwtHasScalablePen( painter ) )
65  {
66  QPainterPath stroke = stroker.createStroke( path );
67  rect = painter->transform().map( stroke ).boundingRect();
68  }
69  else
70  {
71  QPainterPath mappedPath = painter->transform().map( path );
72  mappedPath = stroker.createStroke( mappedPath );
73 
74  rect = mappedPath.boundingRect();
75  }
76 
77  return rect;
78 }
79 
80 static inline void qwtExecCommand(
81  QPainter *painter, const QwtPainterCommand &cmd,
82  QwtGraphic::RenderHints renderHints,
83  const QTransform &transform,
84  const QTransform *initialTransform )
85 {
86  switch( cmd.type() )
87  {
89  {
90  bool doMap = false;
91 
92  if ( painter->transform().isScaling() )
93  {
94  bool isCosmetic = painter->pen().isCosmetic();
95 #if QT_VERSION < 0x050000
96  if ( isCosmetic && painter->pen().widthF() == 0.0 )
97  {
98  QPainter::RenderHints hints = painter->renderHints();
99  if ( hints.testFlag( QPainter::NonCosmeticDefaultPen ) )
100  isCosmetic = false;
101  }
102 #endif
103 
104  if ( isCosmetic )
105  {
106  // OpenGL2 seems to be buggy for cosmetic pens.
107  // It interpolates curves in too rough steps then
108 
109  doMap = painter->paintEngine()->type() == QPaintEngine::OpenGL2;
110  }
111  else
112  {
113  doMap = renderHints.testFlag( QwtGraphic::RenderPensUnscaled );
114  }
115  }
116 
117  if ( doMap )
118  {
119  const QTransform tr = painter->transform();
120 
121  painter->resetTransform();
122 
123  QPainterPath path = tr.map( *cmd.path() );
124  if ( initialTransform )
125  {
126  painter->setTransform( *initialTransform );
127  path = initialTransform->inverted().map( path );
128  }
129 
130  painter->drawPath( path );
131 
132  painter->setTransform( tr );
133  }
134  else
135  {
136  painter->drawPath( *cmd.path() );
137  }
138  break;
139  }
141  {
143  painter->drawPixmap( data->rect, data->pixmap, data->subRect );
144  break;
145  }
147  {
149  painter->drawImage( data->rect, data->image,
150  data->subRect, data->flags );
151  break;
152  }
154  {
156 
157  if ( data->flags & QPaintEngine::DirtyPen )
158  painter->setPen( data->pen );
159 
160  if ( data->flags & QPaintEngine::DirtyBrush )
161  painter->setBrush( data->brush );
162 
163  if ( data->flags & QPaintEngine::DirtyBrushOrigin )
164  painter->setBrushOrigin( data->brushOrigin );
165 
166  if ( data->flags & QPaintEngine::DirtyFont )
167  painter->setFont( data->font );
168 
169  if ( data->flags & QPaintEngine::DirtyBackground )
170  {
171  painter->setBackgroundMode( data->backgroundMode );
172  painter->setBackground( data->backgroundBrush );
173  }
174 
175  if ( data->flags & QPaintEngine::DirtyTransform )
176  {
177  painter->setTransform( data->transform * transform );
178  }
179 
180  if ( data->flags & QPaintEngine::DirtyClipEnabled )
181  painter->setClipping( data->isClipEnabled );
182 
183  if ( data->flags & QPaintEngine::DirtyClipRegion )
184  {
185  painter->setClipRegion( data->clipRegion,
186  data->clipOperation );
187  }
188 
189  if ( data->flags & QPaintEngine::DirtyClipPath )
190  {
191  painter->setClipPath( data->clipPath, data->clipOperation );
192  }
193 
194  if ( data->flags & QPaintEngine::DirtyHints )
195  {
196  for ( int i = 0; i < 8; i++ )
197  {
198  const QPainter::RenderHint hint = static_cast< QPainter::RenderHint >( 1 << i );
199  painter->setRenderHint( hint, data->renderHints.testFlag( hint ) );
200  }
201  }
202 
203  if ( data->flags & QPaintEngine::DirtyCompositionMode )
204  painter->setCompositionMode( data->compositionMode );
205 
206  if ( data->flags & QPaintEngine::DirtyOpacity )
207  painter->setOpacity( data->opacity );
208 
209  break;
210  }
211  default:
212  break;
213  }
214 }
215 
217 {
218 public:
220  d_scalablePen( false )
221  {
222  // QVector needs a default constructor
223  }
224 
225  PathInfo( const QRectF &pointRect,
226  const QRectF &boundingRect, bool scalablePen ):
227  d_pointRect( pointRect ),
228  d_boundingRect( boundingRect ),
229  d_scalablePen( scalablePen )
230  {
231  }
232 
233  inline QRectF scaledBoundingRect( qreal sx, qreal sy, bool scalePens ) const
234  {
235  if ( sx == 1.0 && sy == 1.0 )
236  return d_boundingRect;
237 
238  QTransform transform;
239  transform.scale( sx, sy );
240 
241  QRectF rect;
242  if ( scalePens && d_scalablePen )
243  {
244  rect = transform.mapRect( d_boundingRect );
245  }
246  else
247  {
248  rect = transform.mapRect( d_pointRect );
249 
250  const qreal l = qAbs( d_pointRect.left() - d_boundingRect.left() );
251  const qreal r = qAbs( d_pointRect.right() - d_boundingRect.right() );
252  const qreal t = qAbs( d_pointRect.top() - d_boundingRect.top() );
253  const qreal b = qAbs( d_pointRect.bottom() - d_boundingRect.bottom() );
254 
255  rect.adjust( -l, -t, r, b );
256  }
257 
258  return rect;
259  }
260 
261  inline double scaleFactorX( const QRectF& pathRect,
262  const QRectF &targetRect, bool scalePens ) const
263  {
264  if ( pathRect.width() <= 0.0 )
265  return 0.0;
266 
267  const QPointF p0 = d_pointRect.center();
268 
269  const qreal l = qAbs( pathRect.left() - p0.x() );
270  const qreal r = qAbs( pathRect.right() - p0.x() );
271 
272  const double w = 2.0 * qwtMinF( l, r )
273  * targetRect.width() / pathRect.width();
274 
275  double sx;
276  if ( scalePens && d_scalablePen )
277  {
278  sx = w / d_boundingRect.width();
279  }
280  else
281  {
282  const qreal pw = qwtMaxF(
283  qAbs( d_boundingRect.left() - d_pointRect.left() ),
284  qAbs( d_boundingRect.right() - d_pointRect.right() ) );
285 
286  sx = ( w - 2 * pw ) / d_pointRect.width();
287  }
288 
289  return sx;
290  }
291 
292  inline double scaleFactorY( const QRectF& pathRect,
293  const QRectF &targetRect, bool scalePens ) const
294  {
295  if ( pathRect.height() <= 0.0 )
296  return 0.0;
297 
298  const QPointF p0 = d_pointRect.center();
299 
300  const qreal t = qAbs( pathRect.top() - p0.y() );
301  const qreal b = qAbs( pathRect.bottom() - p0.y() );
302 
303  const qreal h = 2.0 * qwtMinF( t, b )
304  * targetRect.height() / pathRect.height();
305 
306  double sy;
307  if ( scalePens && d_scalablePen )
308  {
309  sy = h / d_boundingRect.height();
310  }
311  else
312  {
313  const qreal pw = qwtMaxF(
314  qAbs( d_boundingRect.top() - d_pointRect.top() ),
315  qAbs( d_boundingRect.bottom() - d_pointRect.bottom() ) );
316 
317  sy = ( h - 2 * pw ) / d_pointRect.height();
318  }
319 
320  return sy;
321  }
322 
323 private:
324  QRectF d_pointRect;
327 };
328 
330 {
331 public:
333  boundingRect( 0.0, 0.0, -1.0, -1.0 ),
334  pointRect( 0.0, 0.0, -1.0, -1.0 )
335  {
336  }
337 
338  QSizeF defaultSize;
341 
342  QRectF boundingRect;
343  QRectF pointRect;
344 
347 };
348 
357 {
359  d_data = new PrivateData;
360 }
361 
370 {
371  setMode( other.mode() );
372  d_data = new PrivateData( *other.d_data );
373 }
374 
377 {
378  delete d_data;
379 }
380 
388 {
389  setMode( other.mode() );
390  *d_data = *other.d_data;
391 
392  return *this;
393 }
394 
400 {
401  d_data->commands.clear();
402  d_data->pathInfos.clear();
403 
405 
406  d_data->boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
407  d_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
408  d_data->defaultSize = QSizeF();
409 }
410 
415 bool QwtGraphic::isNull() const
416 {
417  return d_data->commands.isEmpty();
418 }
419 
425 {
426  return d_data->boundingRect.isEmpty();
427 }
428 
433 {
434  return d_data->commandTypes;
435 }
436 
446 {
447  if ( on )
448  d_data->renderHints |= hint;
449  else
450  d_data->renderHints &= ~hint;
451 }
452 
461 {
462  return d_data->renderHints.testFlag( hint );
463 }
464 
467 {
468  return d_data->renderHints;
469 }
470 
480 {
481  if ( d_data->boundingRect.width() < 0 )
482  return QRectF();
483 
484  return d_data->boundingRect;
485 }
486 
496 {
497  if ( d_data->pointRect.width() < 0 )
498  return QRectF();
499 
500  return d_data->pointRect;
501 }
502 
516 QRectF QwtGraphic::scaledBoundingRect( qreal sx, qreal sy ) const
517 {
518  if ( sx == 1.0 && sy == 1.0 )
519  return d_data->boundingRect;
520 
521  const bool scalePens = !( d_data->renderHints & RenderPensUnscaled );
522 
523  QTransform transform;
524  transform.scale( sx, sy );
525 
526  QRectF rect = transform.mapRect( d_data->pointRect );
527 
528  for ( int i = 0; i < d_data->pathInfos.size(); i++ )
529  rect |= d_data->pathInfos[i].scaledBoundingRect( sx, sy, scalePens );
530 
531  return rect;
532 }
533 
536 {
537  const QSizeF sz = defaultSize();
538  return QSize( qwtCeil( sz.width() ), qwtCeil( sz.height() ) );
539 }
540 
555 void QwtGraphic::setDefaultSize( const QSizeF &size )
556 {
557  const double w = qwtMaxF( 0.0, size.width() );
558  const double h = qwtMaxF( 0.0, size.height() );
559 
560  d_data->defaultSize = QSizeF( w, h );
561 }
562 
577 {
578  if ( !d_data->defaultSize.isEmpty() )
579  return d_data->defaultSize;
580 
581  return boundingRect().size();
582 }
583 
594 qreal QwtGraphic::heightForWidth( qreal width ) const
595 {
596  const QSizeF sz = defaultSize();
597  if ( sz.isEmpty() )
598  return 0.0;
599 
600  return sz.height() * width / sz.width();
601 }
602 
613 qreal QwtGraphic::widthForHeight( qreal height ) const
614 {
615  const QSizeF sz = defaultSize();
616  if ( sz.isEmpty() )
617  return 0.0;
618 
619  return sz.width() * height / sz.height();
620 }
621 
626 void QwtGraphic::render( QPainter *painter ) const
627 {
628  renderGraphic( painter, NULL );
629 }
630 
631 void QwtGraphic::renderGraphic( QPainter* painter, QTransform *initialTransform ) const
632 {
633  if ( isNull() )
634  return;
635 
636  const int numCommands = d_data->commands.size();
637  const QwtPainterCommand *commands = d_data->commands.constData();
638 
639  const QTransform transform = painter->transform();
640 
641  painter->save();
642 
643  for ( int i = 0; i < numCommands; i++ )
644  {
645  qwtExecCommand( painter, commands[i],
646  d_data->renderHints, transform, initialTransform );
647  }
648 
649  painter->restore();
650 }
651 
662 void QwtGraphic::render( QPainter *painter, const QSizeF &size,
663  Qt::AspectRatioMode aspectRatioMode ) const
664 {
665  const QRectF r( 0.0, 0.0, size.width(), size.height() );
666  render( painter, r, aspectRatioMode );
667 }
668 
678 void QwtGraphic::render( QPainter *painter, const QRectF &rect,
679  Qt::AspectRatioMode aspectRatioMode ) const
680 {
681  if ( isEmpty() || rect.isEmpty() )
682  return;
683 
684  double sx = 1.0;
685  double sy = 1.0;
686 
687  if ( d_data->pointRect.width() > 0.0 )
688  sx = rect.width() / d_data->pointRect.width();
689 
690  if ( d_data->pointRect.height() > 0.0 )
691  sy = rect.height() / d_data->pointRect.height();
692 
693  const bool scalePens = !d_data->renderHints.testFlag( RenderPensUnscaled );
694 
695  for ( int i = 0; i < d_data->pathInfos.size(); i++ )
696  {
697  const PathInfo &info = d_data->pathInfos[i];
698 
699  const double ssx = info.scaleFactorX(
700  d_data->pointRect, rect, scalePens );
701 
702  if ( ssx > 0.0 )
703  sx = qwtMinF( sx, ssx );
704 
705  const double ssy = info.scaleFactorY(
706  d_data->pointRect, rect, scalePens );
707 
708  if ( ssy > 0.0 )
709  sy = qwtMinF( sy, ssy );
710  }
711 
712  if ( aspectRatioMode == Qt::KeepAspectRatio )
713  {
714  const qreal s = qwtMinF( sx, sy );
715  sx = s;
716  sy = s;
717  }
718  else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding )
719  {
720  const qreal s = qwtMaxF( sx, sy );
721  sx = s;
722  sy = s;
723  }
724 
725  QTransform tr;
726  tr.translate( rect.center().x() - 0.5 * sx * d_data->pointRect.width(),
727  rect.center().y() - 0.5 * sy * d_data->pointRect.height() );
728  tr.scale( sx, sy );
729  tr.translate( -d_data->pointRect.x(), -d_data->pointRect.y() );
730 
731  const QTransform transform = painter->transform();
732 
733  painter->setTransform( tr, true );
734 
735  if ( !scalePens && transform.isScaling() )
736  {
737  // we don't want to scale pens according to sx/sy,
738  // but we want to apply the scaling from the
739  // painter transformation later
740 
741  QTransform initialTransform;
742  initialTransform.scale( transform.m11(), transform.m22() );
743 
744  renderGraphic( painter, &initialTransform );
745  }
746  else
747  {
748  renderGraphic( painter, NULL );
749  }
750 
751  painter->setTransform( transform );
752 }
753 
764 void QwtGraphic::render( QPainter *painter,
765  const QPointF &pos, Qt::Alignment alignment ) const
766 {
767  QRectF r( pos, defaultSize() );
768 
769  if ( alignment & Qt::AlignLeft )
770  {
771  r.moveLeft( pos.x() );
772  }
773  else if ( alignment & Qt::AlignHCenter )
774  {
775  r.moveCenter( QPointF( pos.x(), r.center().y() ) );
776  }
777  else if ( alignment & Qt::AlignRight )
778  {
779  r.moveRight( pos.x() );
780  }
781 
782  if ( alignment & Qt::AlignTop )
783  {
784  r.moveTop( pos.y() );
785  }
786  else if ( alignment & Qt::AlignVCenter )
787  {
788  r.moveCenter( QPointF( r.center().x(), pos.y() ) );
789  }
790  else if ( alignment & Qt::AlignBottom )
791  {
792  r.moveBottom( pos.y() );
793  }
794 
795  render( painter, r );
796 }
797 
814 QPixmap QwtGraphic::toPixmap( qreal devicePixelRatio ) const
815 {
816  if ( isNull() )
817  return QPixmap();
818 
819  const QSizeF sz = defaultSize();
820 
821  const int w = qwtCeil( sz.width() );
822  const int h = qwtCeil( sz.height() );
823 
824  QPixmap pixmap( w, h );
825 
826 #if QT_VERSION >= 0x050000
827  if ( devicePixelRatio <= 0.0 )
828  devicePixelRatio = qwtDevicePixelRatio();
829 
830  pixmap.setDevicePixelRatio( devicePixelRatio );
831 #else
832  Q_UNUSED( devicePixelRatio )
833 #endif
834 
835  pixmap.fill( Qt::transparent );
836 
837  const QRectF r( 0.0, 0.0, sz.width(), sz.height() );
838 
839  QPainter painter( &pixmap );
840  render( &painter, r, Qt::KeepAspectRatio );
841  painter.end();
842 
843  return pixmap;
844 }
845 
861 QPixmap QwtGraphic::toPixmap( const QSize &size,
862  Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio ) const
863 {
864  QPixmap pixmap( size );
865 
866 #if QT_VERSION >= 0x050000
867  if ( devicePixelRatio <= 0.0 )
868  devicePixelRatio = qwtDevicePixelRatio();
869 
870  pixmap.setDevicePixelRatio( devicePixelRatio );
871 #else
872  Q_UNUSED( devicePixelRatio )
873 #endif
874  pixmap.fill( Qt::transparent );
875 
876  const QRect r( 0, 0, size.width(), size.height() );
877 
878  QPainter painter( &pixmap );
879  render( &painter, r, aspectRatioMode );
880  painter.end();
881 
882  return pixmap;
883 }
884 
902 QImage QwtGraphic::toImage( const QSize &size,
903  Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio ) const
904 {
905 #if QT_VERSION >= 0x050000
906  if ( devicePixelRatio <= 0.0 )
907  devicePixelRatio = qwtDevicePixelRatio();
908 
909  QImage image( size * devicePixelRatio, QImage::Format_ARGB32_Premultiplied );
910  image.setDevicePixelRatio( devicePixelRatio );
911 #else
912  Q_UNUSED( devicePixelRatio )
913  QImage image( size, QImage::Format_ARGB32_Premultiplied );
914 #endif
915 
916  image.fill( 0 );
917 
918  const QRect r( 0, 0, size.width(), size.height() );
919 
920  QPainter painter( &image );
921  render( &painter, r, aspectRatioMode );
922  painter.end();
923 
924  return image;
925 }
926 
945 QImage QwtGraphic::toImage( qreal devicePixelRatio ) const
946 {
947  if ( isNull() )
948  return QImage();
949 
950  const QSizeF sz = defaultSize();
951 
952  int w = qwtCeil( sz.width() );
953  int h = qwtCeil( sz.height() );
954 
955 #if QT_VERSION >= 0x050000
956  if ( devicePixelRatio <= 0.0 )
957  devicePixelRatio = qwtDevicePixelRatio();
958 
959  w *= devicePixelRatio;
960  h *= devicePixelRatio;
961 
962  QImage image( w, h, QImage::Format_ARGB32 );
963  image.setDevicePixelRatio( devicePixelRatio );
964 #else
965  Q_UNUSED( devicePixelRatio )
966  QImage image( w, h, QImage::Format_ARGB32 );
967 #endif
968 
969  image.fill( 0 );
970 
971  const QRect r( 0, 0, sz.width(), sz.height() );
972 
973  QPainter painter( &image );
974  render( &painter, r, Qt::KeepAspectRatio );
975  painter.end();
976 
977  return image;
978 }
979 
986 void QwtGraphic::drawPath( const QPainterPath &path )
987 {
988  const QPainter *painter = paintEngine()->painter();
989  if ( painter == NULL )
990  return;
991 
992  d_data->commands += QwtPainterCommand( path );
994 
995  if ( !path.isEmpty() )
996  {
997  const QPainterPath scaledPath = painter->transform().map( path );
998 
999  QRectF pointRect = scaledPath.boundingRect();
1000  QRectF boundingRect = pointRect;
1001 
1002  if ( painter->pen().style() != Qt::NoPen
1003  && painter->pen().brush().style() != Qt::NoBrush )
1004  {
1005  boundingRect = qwtStrokedPathRect( painter, path );
1006  }
1007 
1008  updateControlPointRect( pointRect );
1009  updateBoundingRect( boundingRect );
1010 
1011  d_data->pathInfos += PathInfo( pointRect,
1012  boundingRect, qwtHasScalablePen( painter ) );
1013  }
1014 }
1015 
1025 void QwtGraphic::drawPixmap( const QRectF &rect,
1026  const QPixmap &pixmap, const QRectF &subRect )
1027 {
1028  const QPainter *painter = paintEngine()->painter();
1029  if ( painter == NULL )
1030  return;
1031 
1032  d_data->commands += QwtPainterCommand( rect, pixmap, subRect );
1034 
1035  const QRectF r = painter->transform().mapRect( rect );
1037  updateBoundingRect( r );
1038 }
1039 
1050 void QwtGraphic::drawImage( const QRectF &rect, const QImage &image,
1051  const QRectF &subRect, Qt::ImageConversionFlags flags )
1052 {
1053  const QPainter *painter = paintEngine()->painter();
1054  if ( painter == NULL )
1055  return;
1056 
1057  d_data->commands += QwtPainterCommand( rect, image, subRect, flags );
1059 
1060  const QRectF r = painter->transform().mapRect( rect );
1061 
1063  updateBoundingRect( r );
1064 }
1065 
1072 void QwtGraphic::updateState( const QPaintEngineState &state )
1073 {
1074  d_data->commands += QwtPainterCommand( state );
1075 
1076  if ( state.state() & QPaintEngine::DirtyTransform )
1077  {
1079  {
1080  /*
1081  QTransform::isScaling() returns true for all type
1082  of transformations beside simple translations
1083  even if it is f.e a rotation
1084  */
1085  if ( state.transform().isScaling() )
1087  }
1088  }
1089 }
1090 
1091 void QwtGraphic::updateBoundingRect( const QRectF &rect )
1092 {
1093  QRectF br = rect;
1094 
1095  const QPainter *painter = paintEngine()->painter();
1096  if ( painter && painter->hasClipping() )
1097  {
1098  QRectF cr = painter->clipRegion().boundingRect();
1099  cr = painter->transform().mapRect( cr );
1100 
1101  br &= cr;
1102  }
1103 
1104  if ( d_data->boundingRect.width() < 0 )
1105  d_data->boundingRect = br;
1106  else
1107  d_data->boundingRect |= br;
1108 }
1109 
1110 void QwtGraphic::updateControlPointRect( const QRectF &rect )
1111 {
1112  if ( d_data->pointRect.width() < 0.0 )
1113  d_data->pointRect = rect;
1114  else
1115  d_data->pointRect |= rect;
1116 }
1117 
1123 {
1124  return d_data->commands;
1125 }
1126 
1134 {
1135  reset();
1136 
1137  const int numCommands = commands.size();
1138  if ( numCommands <= 0 )
1139  return;
1140 
1141  // to calculate a proper bounding rectangle we don't simply copy
1142  // the commands.
1143 
1144  const QwtPainterCommand *cmds = commands.constData();
1145 
1146  const QTransform noTransform;
1147  const RenderHints noRenderHints;
1148 
1149  QPainter painter( this );
1150  for ( int i = 0; i < numCommands; i++ )
1151  qwtExecCommand( &painter, cmds[i], noRenderHints, noTransform, NULL );
1152 
1153  painter.end();
1154 }
QImage toImage(qreal devicePixelRatio=0.0) const
Convert the graphic to a QImage.
QwtGraphic & operator=(const QwtGraphic &)
Assignment operator.
QRectF scaledBoundingRect(qreal sx, qreal sy, bool scalePens) const
static heap_info state
Definition: Heap.c:58
void render(QPainter *) const
Replay all recorded painter commands.
Qt::ImageConversionFlags flags
double scaleFactorX(const QRectF &pathRect, const QRectF &targetRect, bool scalePens) const
CommandTypes commandTypes() const
qreal heightForWidth(qreal width) const
Attributes how to paint a QPixmap.
QWT_CONSTEXPR float qwtMaxF(float a, float b)
Definition: qwt_math.h:123
PathInfo(const QRectF &pointRect, const QRectF &boundingRect, bool scalablePen)
QRectF scaledBoundingRect(qreal sx, qreal sy) const
Calculate the target rectangle for scaling the graphic.
A null paint device doing nothing.
QSizeF defaultSize() const
Default size.
QRectF boundingRect() const
QWT_CONSTEXPR float qwtMinF(float a, float b)
Definition: qwt_math.h:99
The graphic contains scalable vector data.
Definition: qwt_graphic.h:113
void setRenderHint(RenderHint, bool on=true)
QRectF controlPointRect() const
static void qwtExecCommand(QPainter *painter, const QwtPainterCommand &cmd, QwtGraphic::RenderHints renderHints, const QTransform &transform, const QTransform *initialTransform)
Definition: qwt_graphic.cpp:80
void setDefaultSize(const QSizeF &)
Set a default size.
virtual ~QwtGraphic()
Destructor.
virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) QWT_OVERRIDE
Store a pixmap command in the command list.
QFlags< CommandType > CommandTypes
Definition: qwt_graphic.h:126
QPainter::CompositionMode compositionMode
RenderHints renderHints() const
QPainter::RenderHints renderHints
QwtGraphic()
Constructor.
void renderGraphic(QPainter *, QTransform *) const
void reset()
Clear all stored commands.
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
The graphic contains transformations beyond simple translations.
Definition: qwt_graphic.h:119
Draw a QPainterPath.
PrivateData * d_data
Definition: qwt_graphic.h:205
QwtGraphic::CommandTypes commandTypes
void updateControlPointRect(const QRectF &)
QVector< QwtPainterCommand > commands
Attributes of a state change.
QPaintEngine::DirtyFlags flags
double scaleFactorY(const QRectF &pathRect, const QRectF &targetRect, bool scalePens) const
static QRectF qwtStrokedPathRect(const QPainter *painter, const QPainterPath &path)
Definition: qwt_graphic.cpp:54
static const char * noTransform
Definition: plotwidget.cpp:116
The graphic contains raster data ( QPixmap or QImage )
Definition: qwt_graphic.h:116
QPixmap toPixmap(qreal devicePixelRatio=0.0) const
Convert the graphic to a QPixmap.
Attributes how to paint a QImage.
bool testRenderHint(RenderHint) const
virtual void updateState(const QPaintEngineState &) QWT_OVERRIDE
Store a state command in the command list.
qreal widthForHeight(qreal height) const
static bool qwtHasScalablePen(const QPainter *painter)
Definition: qwt_graphic.cpp:32
const QVector< QwtPainterCommand > & commands() const
QwtGraphic::RenderHints renderHints
bool isEmpty() const
virtual QSize sizeMetrics() const QWT_OVERRIDE
virtual QPaintEngine * paintEngine() const QWT_OVERRIDE
See QPaintDevice::paintEngine()
void updateBoundingRect(const QRectF &)
virtual void drawPath(const QPainterPath &) QWT_OVERRIDE
QPainter state change.
bool isNull() const
dictionary data
Definition: mqtt_test.py:22
QVector< QwtGraphic::PathInfo > pathInfos
int qwtCeil(qreal value)
Definition: qwt_math.h:262
void setCommands(const QVector< QwtPainterCommand > &)
Append paint commands.
QFlags< RenderHint > RenderHints
Render hints.
Definition: qwt_graphic.h:104
virtual void drawImage(const QRectF &, const QImage &, const QRectF &, Qt::ImageConversionFlags) QWT_OVERRIDE
Store a image command in the command list.


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10