qwt_graphic.cpp
Go to the documentation of this file.
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_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  : m_scalablePen( false )
221  {
222  // QVector needs a default constructor
223  }
224 
225  PathInfo( const QRectF& pointRect,
226  const QRectF& boundingRect, bool scalablePen )
227  : m_pointRect( pointRect )
228  , m_boundingRect( boundingRect )
229  , m_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 m_boundingRect;
237 
238  QTransform transform;
239  transform.scale( sx, sy );
240 
241  QRectF rect;
242  if ( scalePens && m_scalablePen )
243  {
244  rect = transform.mapRect( m_boundingRect );
245  }
246  else
247  {
248  rect = transform.mapRect( m_pointRect );
249 
250  const qreal l = qAbs( m_pointRect.left() - m_boundingRect.left() );
251  const qreal r = qAbs( m_pointRect.right() - m_boundingRect.right() );
252  const qreal t = qAbs( m_pointRect.top() - m_boundingRect.top() );
253  const qreal b = qAbs( m_pointRect.bottom() - m_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 = m_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 && m_scalablePen )
277  {
278  sx = w / m_boundingRect.width();
279  }
280  else
281  {
282  const qreal pw = qwtMaxF(
283  qAbs( m_boundingRect.left() - m_pointRect.left() ),
284  qAbs( m_boundingRect.right() - m_pointRect.right() ) );
285 
286  sx = ( w - 2 * pw ) / m_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 = m_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 && m_scalablePen )
308  {
309  sy = h / m_boundingRect.height();
310  }
311  else
312  {
313  const qreal pw = qwtMaxF(
314  qAbs( m_boundingRect.top() - m_pointRect.top() ),
315  qAbs( m_boundingRect.bottom() - m_pointRect.bottom() ) );
316 
317  sy = ( h - 2 * pw ) / m_pointRect.height();
318  }
319 
320  return sy;
321  }
322 
323  private:
324  QRectF m_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 
345  QwtGraphic::CommandTypes commandTypes;
346  QwtGraphic::RenderHints renderHints;
347 };
348 
356 {
358  m_data = new PrivateData;
359 }
360 
368 {
369  setMode( other.mode() );
370  m_data = new PrivateData( *other.m_data );
371 }
372 
375 {
376  delete m_data;
377 }
378 
386 {
387  setMode( other.mode() );
388  *m_data = *other.m_data;
389 
390  return *this;
391 }
392 
398 {
399  m_data->commands.clear();
400  m_data->pathInfos.clear();
401 
402  m_data->commandTypes = CommandTypes();
403 
404  m_data->boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
405  m_data->pointRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
406  m_data->defaultSize = QSizeF();
407 }
408 
413 bool QwtGraphic::isNull() const
414 {
415  return m_data->commands.isEmpty();
416 }
417 
423 {
424  return m_data->boundingRect.isEmpty();
425 }
426 
430 QwtGraphic::CommandTypes QwtGraphic::commandTypes() const
431 {
432  return m_data->commandTypes;
433 }
434 
444 {
445  if ( on )
446  m_data->renderHints |= hint;
447  else
448  m_data->renderHints &= ~hint;
449 }
450 
459 {
460  return m_data->renderHints.testFlag( hint );
461 }
462 
464 QwtGraphic::RenderHints QwtGraphic::renderHints() const
465 {
466  return m_data->renderHints;
467 }
468 
478 {
479  if ( m_data->boundingRect.width() < 0 )
480  return QRectF();
481 
482  return m_data->boundingRect;
483 }
484 
494 {
495  if ( m_data->pointRect.width() < 0 )
496  return QRectF();
497 
498  return m_data->pointRect;
499 }
500 
514 QRectF QwtGraphic::scaledBoundingRect( qreal sx, qreal sy ) const
515 {
516  if ( sx == 1.0 && sy == 1.0 )
517  return m_data->boundingRect;
518 
519  const bool scalePens = !( m_data->renderHints & RenderPensUnscaled );
520 
521  QTransform transform;
522  transform.scale( sx, sy );
523 
524  QRectF rect = transform.mapRect( m_data->pointRect );
525 
526  for ( int i = 0; i < m_data->pathInfos.size(); i++ )
527  rect |= m_data->pathInfos[i].scaledBoundingRect( sx, sy, scalePens );
528 
529  return rect;
530 }
531 
534 {
535  const QSizeF sz = defaultSize();
536  return QSize( qwtCeil( sz.width() ), qwtCeil( sz.height() ) );
537 }
538 
553 void QwtGraphic::setDefaultSize( const QSizeF& size )
554 {
555  const double w = qwtMaxF( 0.0, size.width() );
556  const double h = qwtMaxF( 0.0, size.height() );
557 
558  m_data->defaultSize = QSizeF( w, h );
559 }
560 
575 {
576  if ( !m_data->defaultSize.isEmpty() )
577  return m_data->defaultSize;
578 
579  return boundingRect().size();
580 }
581 
592 qreal QwtGraphic::heightForWidth( qreal width ) const
593 {
594  const QSizeF sz = defaultSize();
595  if ( sz.isEmpty() )
596  return 0.0;
597 
598  return sz.height() * width / sz.width();
599 }
600 
611 qreal QwtGraphic::widthForHeight( qreal height ) const
612 {
613  const QSizeF sz = defaultSize();
614  if ( sz.isEmpty() )
615  return 0.0;
616 
617  return sz.width() * height / sz.height();
618 }
619 
624 void QwtGraphic::render( QPainter* painter ) const
625 {
626  renderGraphic( painter, NULL );
627 }
628 
629 void QwtGraphic::renderGraphic( QPainter* painter, QTransform* initialTransform ) const
630 {
631  if ( isNull() )
632  return;
633 
634  const int numCommands = m_data->commands.size();
635  const QwtPainterCommand* commands = m_data->commands.constData();
636 
637  const QTransform transform = painter->transform();
638 
639  painter->save();
640 
641  for ( int i = 0; i < numCommands; i++ )
642  {
643  qwtExecCommand( painter, commands[i],
644  m_data->renderHints, transform, initialTransform );
645  }
646 
647  painter->restore();
648 }
649 
660 void QwtGraphic::render( QPainter* painter, const QSizeF& size,
661  Qt::AspectRatioMode aspectRatioMode ) const
662 {
663  const QRectF r( 0.0, 0.0, size.width(), size.height() );
664  render( painter, r, aspectRatioMode );
665 }
666 
676 void QwtGraphic::render( QPainter* painter, const QRectF& rect,
677  Qt::AspectRatioMode aspectRatioMode ) const
678 {
679  if ( isEmpty() || rect.isEmpty() )
680  return;
681 
682  double sx = 1.0;
683  double sy = 1.0;
684 
685  if ( m_data->pointRect.width() > 0.0 )
686  sx = rect.width() / m_data->pointRect.width();
687 
688  if ( m_data->pointRect.height() > 0.0 )
689  sy = rect.height() / m_data->pointRect.height();
690 
691  const bool scalePens = !m_data->renderHints.testFlag( RenderPensUnscaled );
692 
693  for ( int i = 0; i < m_data->pathInfos.size(); i++ )
694  {
695  const PathInfo& info = m_data->pathInfos[i];
696 
697  const double ssx = info.scaleFactorX(
698  m_data->pointRect, rect, scalePens );
699 
700  if ( ssx > 0.0 )
701  sx = qwtMinF( sx, ssx );
702 
703  const double ssy = info.scaleFactorY(
704  m_data->pointRect, rect, scalePens );
705 
706  if ( ssy > 0.0 )
707  sy = qwtMinF( sy, ssy );
708  }
709 
710  if ( aspectRatioMode == Qt::KeepAspectRatio )
711  {
712  const qreal s = qwtMinF( sx, sy );
713  sx = s;
714  sy = s;
715  }
716  else if ( aspectRatioMode == Qt::KeepAspectRatioByExpanding )
717  {
718  const qreal s = qwtMaxF( sx, sy );
719  sx = s;
720  sy = s;
721  }
722 
723  QTransform tr;
724  tr.translate( rect.center().x() - 0.5 * sx * m_data->pointRect.width(),
725  rect.center().y() - 0.5 * sy * m_data->pointRect.height() );
726  tr.scale( sx, sy );
727  tr.translate( -m_data->pointRect.x(), -m_data->pointRect.y() );
728 
729  const QTransform transform = painter->transform();
730 
731  painter->setTransform( tr, true );
732 
733  if ( !scalePens && transform.isScaling() )
734  {
735  // we don't want to scale pens according to sx/sy,
736  // but we want to apply the scaling from the
737  // painter transformation later
738 
739  QTransform initialTransform;
740  initialTransform.scale( transform.m11(), transform.m22() );
741 
742  renderGraphic( painter, &initialTransform );
743  }
744  else
745  {
746  renderGraphic( painter, NULL );
747  }
748 
749  painter->setTransform( transform );
750 }
751 
762 void QwtGraphic::render( QPainter* painter,
763  const QPointF& pos, Qt::Alignment alignment ) const
764 {
765  QRectF r( pos, defaultSize() );
766 
767  if ( alignment & Qt::AlignLeft )
768  {
769  r.moveLeft( pos.x() );
770  }
771  else if ( alignment & Qt::AlignHCenter )
772  {
773  r.moveCenter( QPointF( pos.x(), r.center().y() ) );
774  }
775  else if ( alignment & Qt::AlignRight )
776  {
777  r.moveRight( pos.x() );
778  }
779 
780  if ( alignment & Qt::AlignTop )
781  {
782  r.moveTop( pos.y() );
783  }
784  else if ( alignment & Qt::AlignVCenter )
785  {
786  r.moveCenter( QPointF( r.center().x(), pos.y() ) );
787  }
788  else if ( alignment & Qt::AlignBottom )
789  {
790  r.moveBottom( pos.y() );
791  }
792 
793  render( painter, r );
794 }
795 
812 QPixmap QwtGraphic::toPixmap( qreal devicePixelRatio ) const
813 {
814  if ( isNull() )
815  return QPixmap();
816 
817  const QSizeF sz = defaultSize();
818 
819  const int w = qwtCeil( sz.width() );
820  const int h = qwtCeil( sz.height() );
821 
822  QPixmap pixmap( w, h );
823 
824 #if QT_VERSION >= 0x050000
825  if ( devicePixelRatio <= 0.0 )
826  devicePixelRatio = qwtDevicePixelRatio();
827 
828  pixmap.setDevicePixelRatio( devicePixelRatio );
829 #else
830  Q_UNUSED( devicePixelRatio )
831 #endif
832 
833  pixmap.fill( Qt::transparent );
834 
835  const QRectF r( 0.0, 0.0, sz.width(), sz.height() );
836 
837  QPainter painter( &pixmap );
838  render( &painter, r, Qt::KeepAspectRatio );
839  painter.end();
840 
841  return pixmap;
842 }
843 
859 QPixmap QwtGraphic::toPixmap( const QSize& size,
860  Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio ) const
861 {
862  QPixmap pixmap( size );
863 
864 #if QT_VERSION >= 0x050000
865  if ( devicePixelRatio <= 0.0 )
866  devicePixelRatio = qwtDevicePixelRatio();
867 
868  pixmap.setDevicePixelRatio( devicePixelRatio );
869 #else
870  Q_UNUSED( devicePixelRatio )
871 #endif
872  pixmap.fill( Qt::transparent );
873 
874  const QRect r( 0, 0, size.width(), size.height() );
875 
876  QPainter painter( &pixmap );
877  render( &painter, r, aspectRatioMode );
878  painter.end();
879 
880  return pixmap;
881 }
882 
900 QImage QwtGraphic::toImage( const QSize& size,
901  Qt::AspectRatioMode aspectRatioMode, qreal devicePixelRatio ) const
902 {
903 #if QT_VERSION >= 0x050000
904  if ( devicePixelRatio <= 0.0 )
905  devicePixelRatio = qwtDevicePixelRatio();
906 
907  QImage image( size* devicePixelRatio, QImage::Format_ARGB32_Premultiplied );
908  image.setDevicePixelRatio( devicePixelRatio );
909 #else
910  Q_UNUSED( devicePixelRatio )
911  QImage image( size, QImage::Format_ARGB32_Premultiplied );
912 #endif
913 
914  image.fill( 0 );
915 
916  const QRect r( 0, 0, size.width(), size.height() );
917 
918  QPainter painter( &image );
919  render( &painter, r, aspectRatioMode );
920  painter.end();
921 
922  return image;
923 }
924 
943 QImage QwtGraphic::toImage( qreal devicePixelRatio ) const
944 {
945  if ( isNull() )
946  return QImage();
947 
948  const QSizeF sz = defaultSize();
949 
950  int w = qwtCeil( sz.width() );
951  int h = qwtCeil( sz.height() );
952 
953 #if QT_VERSION >= 0x050000
954  if ( devicePixelRatio <= 0.0 )
955  devicePixelRatio = qwtDevicePixelRatio();
956 
957  w *= devicePixelRatio;
958  h *= devicePixelRatio;
959 
960  QImage image( w, h, QImage::Format_ARGB32 );
961  image.setDevicePixelRatio( devicePixelRatio );
962 #else
963  Q_UNUSED( devicePixelRatio )
964  QImage image( w, h, QImage::Format_ARGB32 );
965 #endif
966 
967  image.fill( 0 );
968 
969  const QRect r( 0, 0, sz.width(), sz.height() );
970 
971  QPainter painter( &image );
972  render( &painter, r, Qt::KeepAspectRatio );
973  painter.end();
974 
975  return image;
976 }
977 
984 void QwtGraphic::drawPath( const QPainterPath& path )
985 {
986  const QPainter* painter = paintEngine()->painter();
987  if ( painter == NULL )
988  return;
989 
990  m_data->commands += QwtPainterCommand( path );
992 
993  if ( !path.isEmpty() )
994  {
995  const QPainterPath scaledPath = painter->transform().map( path );
996 
997  QRectF pointRect = scaledPath.boundingRect();
998  QRectF boundingRect = pointRect;
999 
1000  if ( painter->pen().style() != Qt::NoPen
1001  && painter->pen().brush().style() != Qt::NoBrush )
1002  {
1003  boundingRect = qwtStrokedPathRect( painter, path );
1004  }
1005 
1006  updateControlPointRect( pointRect );
1007  updateBoundingRect( boundingRect );
1008 
1009  m_data->pathInfos += PathInfo( pointRect,
1010  boundingRect, qwtHasScalablePen( painter ) );
1011  }
1012 }
1013 
1023 void QwtGraphic::drawPixmap( const QRectF& rect,
1024  const QPixmap& pixmap, const QRectF& subRect )
1025 {
1026  const QPainter* painter = paintEngine()->painter();
1027  if ( painter == NULL )
1028  return;
1029 
1030  m_data->commands += QwtPainterCommand( rect, pixmap, subRect );
1032 
1033  const QRectF r = painter->transform().mapRect( rect );
1035  updateBoundingRect( r );
1036 }
1037 
1048 void QwtGraphic::drawImage( const QRectF& rect, const QImage& image,
1049  const QRectF& subRect, Qt::ImageConversionFlags flags )
1050 {
1051  const QPainter* painter = paintEngine()->painter();
1052  if ( painter == NULL )
1053  return;
1054 
1055  m_data->commands += QwtPainterCommand( rect, image, subRect, flags );
1057 
1058  const QRectF r = painter->transform().mapRect( rect );
1059 
1061  updateBoundingRect( r );
1062 }
1063 
1070 void QwtGraphic::updateState( const QPaintEngineState& state )
1071 {
1072  m_data->commands += QwtPainterCommand( state );
1073 
1074  if ( state.state() & QPaintEngine::DirtyTransform )
1075  {
1077  {
1078  /*
1079  QTransform::isScaling() returns true for all type
1080  of transformations beside simple translations
1081  even if it is f.e a rotation
1082  */
1083  if ( state.transform().isScaling() )
1085  }
1086  }
1087 }
1088 
1089 void QwtGraphic::updateBoundingRect( const QRectF& rect )
1090 {
1091  QRectF br = rect;
1092 
1093  const QPainter* painter = paintEngine()->painter();
1094  if ( painter && painter->hasClipping() )
1095  {
1096  QRectF cr = painter->clipRegion().boundingRect();
1097  cr = painter->transform().mapRect( cr );
1098 
1099  br &= cr;
1100  }
1101 
1102  if ( m_data->boundingRect.width() < 0 )
1103  m_data->boundingRect = br;
1104  else
1105  m_data->boundingRect |= br;
1106 }
1107 
1108 void QwtGraphic::updateControlPointRect( const QRectF& rect )
1109 {
1110  if ( m_data->pointRect.width() < 0.0 )
1111  m_data->pointRect = rect;
1112  else
1113  m_data->pointRect |= rect;
1114 }
1115 
1121 {
1122  return m_data->commands;
1123 }
1124 
1132 {
1133  reset();
1134 
1135  const int numCommands = commands.size();
1136  if ( numCommands <= 0 )
1137  return;
1138 
1139  // to calculate a proper bounding rectangle we don't simply copy
1140  // the commands.
1141 
1142  const QwtPainterCommand* cmds = commands.constData();
1143 
1144  const QTransform noTransform;
1145  const RenderHints noRenderHints;
1146 
1147  QPainter painter( this );
1148  for ( int i = 0; i < numCommands; i++ )
1149  qwtExecCommand( &painter, cmds[i], noRenderHints, noTransform, NULL );
1150 
1151  painter.end();
1152 }
QwtGraphic & operator=(const QwtGraphic &)
Assignment operator.
QRectF boundingRect() const
Qt::ImageConversionFlags flags
QRectF scaledBoundingRect(qreal sx, qreal sy) const
Calculate the target rectangle for scaling the graphic.
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)
RenderHints renderHints() const
XmlRpcServer s
bool testRenderHint(RenderHint) const
QWT_CONSTEXPR float qwtMinF(float a, float b)
Definition: qwt_math.h:99
const QVector< QwtPainterCommand > & commands() const
QPixmap toPixmap(qreal devicePixelRatio=0.0) const
Convert the graphic to a QPixmap.
The graphic contains scalable vector data.
Definition: qwt_graphic.h:108
CommandTypes commandTypes() const
void setRenderHint(RenderHint, bool on=true)
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.
bool isEmpty() const
virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) QWT_OVERRIDE
Store a pixmap command in the command list.
void renderGraphic(QPainter *, QTransform *) const
QPainter::CompositionMode compositionMode
QPainter::RenderHints renderHints
QwtGraphic()
Constructor.
qreal widthForHeight(qreal height) const
void reset()
Clear all stored commands.
double scaleFactorX(const QRectF &pathRect, const QRectF &targetRect, bool scalePens) const
A paint device for scalable graphics.
Definition: qwt_graphic.h:75
The graphic contains transformations beyond simple translations.
Definition: qwt_graphic.h:114
Draw a QPainterPath.
QwtGraphic::CommandTypes commandTypes
void updateControlPointRect(const QRectF &)
QVector< QwtPainterCommand > commands
QImage toImage(qreal devicePixelRatio=0.0) const
Convert the graphic to a QImage.
Attributes of a state change.
QPaintEngine::DirtyFlags flags
static QRectF qwtStrokedPathRect(const QPainter *painter, const QPainterPath &path)
Definition: qwt_graphic.cpp:54
The graphic contains raster data ( QPixmap or QImage )
Definition: qwt_graphic.h:111
Attributes how to paint a QImage.
void render(QPainter *) const
Replay all recorded painter commands.
virtual void updateState(const QPaintEngineState &) QWT_OVERRIDE
Store a state command in the command list.
static bool qwtHasScalablePen(const QPainter *painter)
Definition: qwt_graphic.cpp:32
QwtGraphic::RenderHints renderHints
QRectF scaledBoundingRect(qreal sx, qreal sy, bool scalePens) const
virtual QSize sizeMetrics() const QWT_OVERRIDE
virtual QPaintEngine * paintEngine() const QWT_OVERRIDE
See QPaintDevice::paintEngine()
bool isNull() const
span_constexpr std::size_t size(span< T, Extent > const &spn)
Definition: span.hpp:1485
void updateBoundingRect(const QRectF &)
virtual void drawPath(const QPainterPath &) QWT_OVERRIDE
QPainter state change.
PrivateData * m_data
Definition: qwt_graphic.h:196
QVector< QwtGraphic::PathInfo > pathInfos
QSizeF defaultSize() const
Default size.
double scaleFactorY(const QRectF &pathRect, const QRectF &targetRect, bool scalePens) const
int qwtCeil(qreal value)
Definition: qwt_math.h:262
qreal heightForWidth(qreal width) const
QRectF controlPointRect() const
Definition: format.h:895
void setCommands(const QVector< QwtPainterCommand > &)
Append paint commands.
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 Mon Jun 19 2023 03:01:38