Qwt User's Guide: qwt_plot_renderer.cpp Source File

Qwt User's Guide 6.2.0

qwt_plot_renderer.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_renderer.h"
11 #include "qwt_plot.h"
12 #include "qwt_painter.h"
13 #include "qwt_plot_layout.h"
14 #include "qwt_abstract_legend.h"
15 #include "qwt_scale_widget.h"
16 #include "qwt_scale_engine.h"
17 #include "qwt_scale_map.h"
18 #include "qwt_text.h"
19 #include "qwt_text_label.h"
20 #include "qwt_math.h"
21
22 #include <qpainter.h>
23 #include <qpainterpath.h>
24 #include <qtransform.h>
25 #include <qprinter.h>
26 #include <qfiledialog.h>
27 #include <qfileinfo.h>
28 #include <qimagewriter.h>
29 #include <qvariant.h>
30 #include <qmargins.h>
31
32 #ifndef QWT_NO_SVG
33 #ifdef QT_SVG_LIB
34 #define QWT_FORMAT_SVG 1
35 #endif
36 #endif
37
38 #ifndef QT_NO_PRINTER
39 #define QWT_FORMAT_PDF 1
40 #endif
41
42 #ifndef QT_NO_PDF
43
44 // QPdfWriter::setResolution() has been introduced with
45 // Qt 5.3. Guess it is o.k. to stay with QPrinter for older
46 // versions.
47
48 #if QT_VERSION >= 0x050300
49
50 #ifndef QWT_FORMAT_PDF
51 #define QWT_FORMAT_PDF 1
52 #endif
53
54 #define QWT_PDF_WRITER 1
55
56 #endif
57 #endif
58
59 #ifndef QT_NO_PRINTER
60 // postscript support has been dropped in Qt5
61 #if QT_VERSION < 0x050000
62 #define QWT_FORMAT_POSTSCRIPT 1
63 #endif
64 #endif
65
66 #if QWT_FORMAT_SVG
67 #include <qsvggenerator.h>
68 #endif
69
70 #if QWT_PDF_WRITER
71 #include <qpdfwriter.h>
72 #endif
73
74 static qreal qwtScalePenWidth( const QwtPlot* plot )
75 {
76 qreal pw = 0.0;
77
78 for ( int axisId = 0; axisId < QwtAxis::AxisPositions; axisId++ )
79 {
80 if ( plot->isAxisVisible( axisId ) )
81 pw = qMax( pw, plot->axisScaleDraw( axisId )->penWidthF() );
82 }
83
84 return pw;
85 }
86
87 static QColor qwtScalePenColor( const QwtPlot* plot )
88 {
89 const QPalette pal = plot->axisWidget( QwtAxis::YLeft )->palette();
90 return pal.color( QPalette::WindowText );
91 }
92
93 static QPainterPath qwtCanvasClip(
94 const QWidget* canvas, const QRectF& canvasRect )
95 {
96 // The clip region is calculated in integers
97 // To avoid too much rounding errors better
98 // calculate it in target device resolution
99
100 int x1 = qwtCeil( canvasRect.left() );
101 int x2 = qwtFloor( canvasRect.right() );
102 int y1 = qwtCeil( canvasRect.top() );
103 int y2 = qwtFloor( canvasRect.bottom() );
104
105 const QRect r( x1, y1, x2 - x1 - 1, y2 - y1 - 1 );
106
107 QPainterPath clipPath;
108
109 ( void ) QMetaObject::invokeMethod(
110 const_cast< QWidget* >( canvas ), "borderPath",
111 Qt::DirectConnection,
112 Q_RETURN_ARG( QPainterPath, clipPath ), Q_ARG( QRect, r ) );
113
114 return clipPath;
115 }
116
117 static inline QFont qwtResolvedFont( const QWidget* widget )
118 {
119 QFont font = widget->font();
120 #if QT_VERSION >= 0x060000
121 font.setResolveMask( QFont::AllPropertiesResolved );
122 #else
123 font.resolve( QFont::AllPropertiesResolved );
124 #endif
125
126 return font;
127 }
128
129 class QwtPlotRenderer::PrivateData
130 {
131 public:
132 PrivateData()
133 : discardFlags( QwtPlotRenderer::DiscardNone )
134 , layoutFlags( QwtPlotRenderer::DefaultLayout )
135 {
136 }
137
138 QwtPlotRenderer::DiscardFlags discardFlags;
139 QwtPlotRenderer::LayoutFlags layoutFlags;
140 };
141
146 QwtPlotRenderer::QwtPlotRenderer( QObject* parent )
147 : QObject( parent )
148 {
149 m_data = new PrivateData;
150 }
151
153 QwtPlotRenderer::~QwtPlotRenderer()
154 {
155 delete m_data;
156 }
157
166 void QwtPlotRenderer::setDiscardFlag( DiscardFlag flag, bool on )
167 {
168 if ( on )
169 m_data->discardFlags |= flag;
170 else
171 m_data->discardFlags &= ~flag;
172 }
173
179 bool QwtPlotRenderer::testDiscardFlag( DiscardFlag flag ) const
180 {
181 return m_data->discardFlags & flag;
182 }
183
190 void QwtPlotRenderer::setDiscardFlags( DiscardFlags flags )
191 {
192 m_data->discardFlags = flags;
193 }
194
199 QwtPlotRenderer::DiscardFlags QwtPlotRenderer::discardFlags() const
200 {
201 return m_data->discardFlags;
202 }
203
212 void QwtPlotRenderer::setLayoutFlag( LayoutFlag flag, bool on )
213 {
214 if ( on )
215 m_data->layoutFlags |= flag;
216 else
217 m_data->layoutFlags &= ~flag;
218 }
219
225 bool QwtPlotRenderer::testLayoutFlag( LayoutFlag flag ) const
226 {
227 return m_data->layoutFlags & flag;
228 }
229
236 void QwtPlotRenderer::setLayoutFlags( LayoutFlags flags )
237 {
238 m_data->layoutFlags = flags;
239 }
240
245 QwtPlotRenderer::LayoutFlags QwtPlotRenderer::layoutFlags() const
246 {
247 return m_data->layoutFlags;
248 }
249
261 void QwtPlotRenderer::renderDocument( QwtPlot* plot,
262 const QString& fileName, const QSizeF& sizeMM, int resolution )
263 {
264 renderDocument( plot, fileName,
265 QFileInfo( fileName ).suffix(), sizeMM, resolution );
266 }
267
293 void QwtPlotRenderer::renderDocument( QwtPlot* plot,
294 const QString& fileName, const QString& format,
295 const QSizeF& sizeMM, int resolution )
296 {
297 if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
298 return;
299
300 QString title = plot->title().text();
301 if ( title.isEmpty() )
302 title = "Plot Document";
303
304 const double mmToInch = 1.0 / 25.4;
305 const QSizeF size = sizeMM * mmToInch * resolution;
306
307 const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
308
309 const QString fmt = format.toLower();
310 if ( fmt == QLatin1String( "pdf" ) )
311 {
312 #if QWT_FORMAT_PDF
313
314 #if QWT_PDF_WRITER
315 QPdfWriter pdfWriter( fileName );
316 pdfWriter.setPageSize( QPageSize( sizeMM, QPageSize::Millimeter ) );
317 pdfWriter.setTitle( title );
318 pdfWriter.setPageMargins( QMarginsF() );
319 pdfWriter.setResolution( resolution );
320
321 QPainter painter( &pdfWriter );
322 render( plot, &painter, documentRect );
323 #else
324 QPrinter printer;
325 printer.setOutputFormat( QPrinter::PdfFormat );
326 printer.setColorMode( QPrinter::Color );
327 printer.setFullPage( true );
328 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
329 printer.setDocName( title );
330 printer.setOutputFileName( fileName );
331 printer.setResolution( resolution );
332
333 QPainter painter( &printer );
334 render( plot, &painter, documentRect );
335 #endif
336 #endif
337 }
338 else if ( fmt == QLatin1String( "ps" ) )
339 {
340 #if QWT_FORMAT_POSTSCRIPT
341 QPrinter printer;
342 printer.setOutputFormat( QPrinter::PostScriptFormat );
343 printer.setColorMode( QPrinter::Color );
344 printer.setFullPage( true );
345 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
346 printer.setDocName( title );
347 printer.setOutputFileName( fileName );
348 printer.setResolution( resolution );
349
350 QPainter painter( &printer );
351 render( plot, &painter, documentRect );
352 #endif
353 }
354 else if ( fmt == QLatin1String( "svg" ) )
355 {
356 #if QWT_FORMAT_SVG
357 QSvgGenerator generator;
358 generator.setTitle( title );
359 generator.setFileName( fileName );
360 generator.setResolution( resolution );
361 generator.setViewBox( documentRect );
362
363 QPainter painter( &generator );
364 render( plot, &painter, documentRect );
365 #endif
366 }
367 else
368 {
369 if ( QImageWriter::supportedImageFormats().indexOf(
370 format.toLatin1() ) >= 0 )
371 {
372 const QRect imageRect = documentRect.toRect();
373 const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
374
375 QImage image( imageRect.size(), QImage::Format_ARGB32 );
376 image.setDotsPerMeterX( dotsPerMeter );
377 image.setDotsPerMeterY( dotsPerMeter );
378 image.fill( QColor( Qt::white ).rgb() );
379
380 QPainter painter( &image );
381 render( plot, &painter, imageRect );
382 painter.end();
383
384 image.save( fileName, format.toLatin1() );
385 }
386 }
387 }
388
402 void QwtPlotRenderer::renderTo(
403 QwtPlot* plot, QPaintDevice& paintDevice ) const
404 {
405 int w = paintDevice.width();
406 int h = paintDevice.height();
407
408 QPainter p( &paintDevice );
409 render( plot, &p, QRectF( 0, 0, w, h ) );
410 }
411
425 #ifndef QT_NO_PRINTER
426
427 void QwtPlotRenderer::renderTo(
428 QwtPlot* plot, QPrinter& printer ) const
429 {
430 int w = printer.width();
431 int h = printer.height();
432
433 QRectF rect( 0, 0, w, h );
434 double aspect = rect.width() / rect.height();
435 if ( ( aspect < 1.0 ) )
436 rect.setHeight( aspect * rect.width() );
437
438 QPainter p( &printer );
439 render( plot, &p, rect );
440 }
441
442 #endif
443
444 #if QWT_FORMAT_SVG
445
457 void QwtPlotRenderer::renderTo(
458 QwtPlot* plot, QSvgGenerator& generator ) const
459 {
460 QRectF rect = generator.viewBoxF();
461 if ( rect.isEmpty() )
462 rect.setRect( 0, 0, generator.width(), generator.height() );
463
464 if ( rect.isEmpty() )
465 rect.setRect( 0, 0, 800, 600 ); // something
466
467 QPainter p( &generator );
468 render( plot, &p, rect );
469 }
470
471 #endif
472
482 void QwtPlotRenderer::render( QwtPlot* plot,
483 QPainter* painter, const QRectF& plotRect ) const
484 {
485 if ( painter == 0 || !painter->isActive() ||
486 !plotRect.isValid() || plot->size().isNull() )
487 {
488 return;
489 }
490
491 if ( !( m_data->discardFlags & DiscardBackground ) )
492 QwtPainter::drawBackgound( painter, plotRect, plot );
493
494 /*
495 The layout engine uses the same methods as they are used
496 by the Qt layout system. Therefore we need to calculate the
497 layout in screen coordinates and paint with a scaled painter.
498 */
499 QTransform transform;
500 transform.scale(
501 double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
502 double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
503
504 QRectF layoutRect = transform.inverted().mapRect( plotRect );
505
506 if ( !( m_data->discardFlags & DiscardBackground ) )
507 {
508 // subtract the contents margins
509
510 const QMargins m = plot->contentsMargins();
511 layoutRect.adjust( m.left(), m.top(), -m.right(), -m.bottom() );
512 }
513
514 QwtPlotLayout* layout = plot->plotLayout();
515
516 int baseLineDists[QwtAxis::AxisPositions];
517 int canvasMargins[QwtAxis::AxisPositions];
518
519 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
520 {
521 canvasMargins[axisPos] = layout->canvasMargin( axisPos );
522
523 if ( m_data->layoutFlags & FrameWithScales )
524 {
525 const QwtAxisId axisId( axisPos );
526
527 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
528 if ( scaleWidget )
529 {
530 baseLineDists[axisPos] = scaleWidget->margin();
531 scaleWidget->setMargin( 0 );
532 }
533
534 if ( !plot->isAxisVisible( axisId ) )
535 {
536 // When we have a scale the frame is painted on
537 // the position of the backbone - otherwise we
538 // need to introduce a margin around the canvas
539
540 const qreal fw = qwtScalePenWidth( plot );
541
542 switch( axisPos )
543 {
544 case QwtAxis::YLeft:
545 layoutRect.adjust( fw, 0, 0, 0 );
546 break;
547
548 case QwtAxis::YRight:
549 layoutRect.adjust( 0, 0, -fw, 0 );
550 break;
551
552 case QwtAxis::XTop:
553 layoutRect.adjust( 0, fw, 0, 0 );
554 break;
555
556 case QwtAxis::XBottom:
557 layoutRect.adjust( 0, 0, 0, -fw );
558 break;
559
560 default:
561 ;
562 }
563 }
564 }
565 }
566
567 // Calculate the layout for the document.
568
569 QwtPlotLayout::Options layoutOptions = QwtPlotLayout::IgnoreScrollbars;
570
571 if ( ( m_data->layoutFlags & FrameWithScales ) ||
572 ( m_data->discardFlags & DiscardCanvasFrame ) )
573 {
574 layoutOptions |= QwtPlotLayout::IgnoreFrames;
575 }
576
577 if ( m_data->discardFlags & DiscardLegend )
578 layoutOptions |= QwtPlotLayout::IgnoreLegend;
579
580 if ( m_data->discardFlags & DiscardTitle )
581 layoutOptions |= QwtPlotLayout::IgnoreTitle;
582
583 if ( m_data->discardFlags & DiscardFooter )
584 layoutOptions |= QwtPlotLayout::IgnoreFooter;
585
586 layout->activate( plot, layoutRect, layoutOptions );
587
588 // canvas
589
590 QwtScaleMap maps[QwtAxis::AxisPositions];
591 buildCanvasMaps( plot, layout->canvasRect(), maps );
592 if ( updateCanvasMargins( plot, layout->canvasRect(), maps ) )
593 {
594 // recalculate maps and layout, when the margins
595 // have been changed
596
597 layout->activate( plot, layoutRect, layoutOptions );
598 buildCanvasMaps( plot, layout->canvasRect(), maps );
599 }
600
601 // now start painting
602
603 painter->save();
604 painter->setWorldTransform( transform, true );
605
606 renderCanvas( plot, painter, layout->canvasRect(), maps );
607
608 if ( !( m_data->discardFlags & DiscardTitle )
609 && ( !plot->titleLabel()->text().isEmpty() ) )
610 {
611 renderTitle( plot, painter, layout->titleRect() );
612 }
613
614 if ( !( m_data->discardFlags & DiscardFooter )
615 && ( !plot->footerLabel()->text().isEmpty() ) )
616 {
617 renderFooter( plot, painter, layout->footerRect() );
618 }
619
620 if ( !( m_data->discardFlags & DiscardLegend )
621 && plot->legend() && !plot->legend()->isEmpty() )
622 {
623 renderLegend( plot, painter, layout->legendRect() );
624 }
625
626 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
627 {
628 {
629 const QwtAxisId axisId( axisPos );
630
631 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
632 if ( scaleWidget )
633 {
634 int baseDist = scaleWidget->margin();
635
636 int startDist, endDist;
637 scaleWidget->getBorderDistHint( startDist, endDist );
638
639 renderScale( plot, painter, axisId, startDist, endDist,
640 baseDist, layout->scaleRect( axisId ) );
641 }
642 }
643 }
644
645 painter->restore();
646
647 // restore all setting to their original attributes.
648 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
649 {
650 if ( m_data->layoutFlags & FrameWithScales )
651 {
652 const QwtAxisId axisId( axisPos );
653
654 QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
655 if ( scaleWidget )
656 scaleWidget->setMargin( baseLineDists[axisPos] );
657 }
658
659 layout->setCanvasMargin( canvasMargins[axisPos] );
660 }
661
662 layout->invalidate();
663
664 }
665
673 void QwtPlotRenderer::renderTitle( const QwtPlot* plot,
674 QPainter* painter, const QRectF& titleRect ) const
675 {
676 painter->setFont( qwtResolvedFont( plot->titleLabel() ) );
677
678 const QColor color = plot->titleLabel()->palette().color(
679 QPalette::Active, QPalette::Text );
680
681 painter->setPen( color );
682 plot->titleLabel()->text().draw( painter, titleRect );
683 }
684
692 void QwtPlotRenderer::renderFooter( const QwtPlot* plot,
693 QPainter* painter, const QRectF& footerRect ) const
694 {
695 painter->setFont( qwtResolvedFont( plot->footerLabel() ) );
696
697 const QColor color = plot->footerLabel()->palette().color(
698 QPalette::Active, QPalette::Text );
699
700 painter->setPen( color );
701 plot->footerLabel()->text().draw( painter, footerRect );
702 }
703
711 void QwtPlotRenderer::renderLegend( const QwtPlot* plot,
712 QPainter* painter, const QRectF& legendRect ) const
713 {
714 if ( plot->legend() )
715 {
716 bool fillBackground = !( m_data->discardFlags & DiscardBackground );
717 plot->legend()->renderLegend( painter, legendRect, fillBackground );
718 }
719 }
720
733 void QwtPlotRenderer::renderScale( const QwtPlot* plot, QPainter* painter,
734 QwtAxisId axisId, int startDist, int endDist, int baseDist,
735 const QRectF& scaleRect ) const
736 {
737 if ( !plot->isAxisVisible( axisId ) )
738 return;
739
740 const QwtScaleWidget* scaleWidget = plot->axisWidget( axisId );
741 if ( scaleWidget->isColorBarEnabled()
742 && scaleWidget->colorBarWidth() > 0 )
743 {
744 scaleWidget->drawColorBar( painter, scaleWidget->colorBarRect( scaleRect ) );
745 baseDist += scaleWidget->colorBarWidth() + scaleWidget->spacing();
746 }
747
748 painter->save();
749
750 QwtScaleDraw::Alignment align;
751 double x, y, w;
752
753 qreal off = 0.0;
754 if ( m_data->layoutFlags & FrameWithScales )
755 off = qwtScalePenWidth( plot );
756
757 switch ( axisId )
758 {
759 case QwtAxis::YLeft:
760 {
761 x = scaleRect.right() - 1.0 - baseDist - off;
762 y = scaleRect.y() + startDist;
763 w = scaleRect.height() - startDist - endDist;
764 align = QwtScaleDraw::LeftScale;
765 break;
766 }
767 case QwtAxis::YRight:
768 {
769 x = scaleRect.left() + baseDist + off;
770 y = scaleRect.y() + startDist;
771 w = scaleRect.height() - startDist - endDist;
772 align = QwtScaleDraw::RightScale;
773 break;
774 }
775 case QwtAxis::XTop:
776 {
777 x = scaleRect.left() + startDist;
778 y = scaleRect.bottom() - 1.0 - baseDist - off;
779 w = scaleRect.width() - startDist - endDist;
780 align = QwtScaleDraw::TopScale;
781 break;
782 }
783 case QwtAxis::XBottom:
784 {
785 x = scaleRect.left() + startDist;
786 y = scaleRect.top() + baseDist + off;
787 w = scaleRect.width() - startDist - endDist;
788 align = QwtScaleDraw::BottomScale;
789 break;
790 }
791 default:
792 return;
793 }
794
795 scaleWidget->drawTitle( painter, align, scaleRect );
796
797 painter->setFont( qwtResolvedFont( scaleWidget ) );
798
799 QwtScaleDraw* sd = const_cast< QwtScaleDraw* >( scaleWidget->scaleDraw() );
800 const QPointF sdPos = sd->pos();
801 const double sdLength = sd->length();
802
803 const bool hasBackbone = sd->hasComponent( QwtAbstractScaleDraw::Backbone );
804
805 if ( m_data->layoutFlags & FrameWithScales )
806 sd->enableComponent( QwtAbstractScaleDraw::Backbone, false );
807
808 sd->move( x, y );
809 sd->setLength( w );
810
811 QPalette palette = scaleWidget->palette();
812 palette.setCurrentColorGroup( QPalette::Active );
813 sd->draw( painter, palette );
814
815 // reset previous values
816 sd->move( sdPos );
817 sd->setLength( sdLength );
818 sd->enableComponent( QwtAbstractScaleDraw::Backbone, hasBackbone );
819
820 painter->restore();
821 }
822
831 void QwtPlotRenderer::renderCanvas( const QwtPlot* plot,
832 QPainter* painter, const QRectF& canvasRect,
833 const QwtScaleMap* maps ) const
834 {
835 const QWidget* canvas = plot->canvas();
836
837 QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );
838
839 if ( m_data->layoutFlags & FrameWithScales )
840 {
841 painter->save();
842
843 QPen pen;
844 pen.setColor( qwtScalePenColor( plot ) );
845 pen.setWidth( qwtScalePenWidth( plot ) );
846 pen.setJoinStyle( Qt::MiterJoin );
847
848 painter->setPen( pen );
849
850 const qreal pw2 = 0.5 * pen.widthF();
851 r.adjust( -pw2, -pw2, pw2, pw2 );
852
853 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
854 {
855 const QBrush bgBrush =
856 canvas->palette().brush( plot->backgroundRole() );
857 painter->setBrush( bgBrush );
858 }
859
860 QwtPainter::drawRect( painter, r );
861
862 painter->restore();
863 painter->save();
864
865 painter->setClipRect( canvasRect );
866 plot->drawItems( painter, canvasRect, maps );
867
868 painter->restore();
869 }
870 else if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
871 {
872 QPainterPath clipPath;
873
874 painter->save();
875
876 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
877 {
878 QwtPainter::drawBackgound( painter, r, canvas );
879 clipPath = qwtCanvasClip( canvas, canvasRect );
880 }
881
882 painter->restore();
883 painter->save();
884
885 if ( clipPath.isEmpty() )
886 painter->setClipRect( canvasRect );
887 else
888 painter->setClipPath( clipPath );
889
890 plot->drawItems( painter, canvasRect, maps );
891
892 painter->restore();
893 }
894 else
895 {
896 QPainterPath clipPath;
897
898 double frameWidth = 0.0;
899
900 if ( !( m_data->discardFlags & DiscardCanvasFrame ) )
901 {
902 const QVariant fw = canvas->property( "frameWidth" );
903 if ( fw.canConvert< double >() )
904 frameWidth = fw.value< double >();
905
906 clipPath = qwtCanvasClip( canvas, canvasRect );
907 }
908
909 QRectF innerRect = canvasRect.adjusted(
910 frameWidth, frameWidth, -frameWidth, -frameWidth );
911
912 painter->save();
913
914 if ( clipPath.isEmpty() )
915 {
916 painter->setClipRect( innerRect );
917 }
918 else
919 {
920 painter->setClipPath( clipPath );
921 }
922
923 if ( !( m_data->discardFlags & DiscardCanvasBackground ) )
924 {
925 QwtPainter::drawBackgound( painter, innerRect, canvas );
926 }
927
928 plot->drawItems( painter, innerRect, maps );
929
930 painter->restore();
931
932 if ( frameWidth > 0 )
933 {
934 painter->save();
935
936 const int frameStyle =
937 canvas->property( "frameShadow" ).toInt() |
938 canvas->property( "frameShape" ).toInt();
939
940 const QVariant borderRadius = canvas->property( "borderRadius" );
941 if ( borderRadius.canConvert< double >()
942 && borderRadius.value< double >() > 0.0 )
943 {
944 const double radius = borderRadius.value< double >();
945
946 QwtPainter::drawRoundedFrame( painter, canvasRect,
947 radius, radius, canvas->palette(), frameWidth, frameStyle );
948 }
949 else
950 {
951 const int midLineWidth = canvas->property( "midLineWidth" ).toInt();
952
953 QwtPainter::drawFrame( painter, canvasRect,
954 canvas->palette(), canvas->foregroundRole(),
955 frameWidth, midLineWidth, frameStyle );
956 }
957 painter->restore();
958 }
959 }
960 }
961
969 void QwtPlotRenderer::buildCanvasMaps( const QwtPlot* plot,
970 const QRectF& canvasRect, QwtScaleMap maps[] ) const
971 {
972 for ( int axisPos = 0; axisPos < QwtAxis::AxisPositions; axisPos++ )
973 {
974 {
975 const QwtAxisId axisId( axisPos );
976
977 QwtScaleMap& scaleMap = maps[axisId];
978
979 scaleMap.setTransformation(
980 plot->axisScaleEngine( axisId )->transformation() );
981
982 const QwtScaleDiv& scaleDiv = plot->axisScaleDiv( axisId );
983 scaleMap.setScaleInterval(
984 scaleDiv.lowerBound(), scaleDiv.upperBound() );
985
986 double from, to;
987 if ( plot->isAxisVisible( axisId ) )
988 {
989 const int sDist = plot->axisWidget( axisId )->startBorderDist();
990 const int eDist = plot->axisWidget( axisId )->endBorderDist();
991 const QRectF scaleRect = plot->plotLayout()->scaleRect( axisId );
992
993 if ( QwtAxis::isXAxis( axisPos ) )
994 {
995 from = scaleRect.left() + sDist;
996 to = scaleRect.right() - eDist;
997 }
998 else
999 {
1000 from = scaleRect.bottom() - eDist;
1001 to = scaleRect.top() + sDist;
1002 }
1003 }
1004 else
1005 {
1006 int margin = 0;
1007 if ( !plot->plotLayout()->alignCanvasToScale( axisPos ) )
1008 margin = plot->plotLayout()->canvasMargin( axisPos );
1009
1010 if ( QwtAxis::isYAxis( axisPos ) )
1011 {
1012 from = canvasRect.bottom() - margin;
1013 to = canvasRect.top() + margin;
1014 }
1015 else
1016 {
1017 from = canvasRect.left() + margin;
1018 to = canvasRect.right() - margin;
1019 }
1020 }
1021 scaleMap.setPaintInterval( from, to );
1022 }
1023 }
1024 }
1025
1026 bool QwtPlotRenderer::updateCanvasMargins( QwtPlot* plot,
1027 const QRectF& canvasRect, const QwtScaleMap maps[] ) const
1028 {
1029 using namespace QwtAxis;
1030
1031 double margins[AxisPositions];
1032 plot->getCanvasMarginsHint( maps, canvasRect,
1033 margins[YLeft], margins[XTop], margins[YRight], margins[XBottom] );
1034
1035 bool marginsChanged = false;
1036 for ( int axisId = 0; axisId < AxisPositions; axisId++ )
1037 {
1038 if ( margins[axisId] >= 0.0 )
1039 {
1040 const int m = qwtCeil( margins[axisId] );
1041 plot->plotLayout()->setCanvasMargin( m, axisId);
1042 marginsChanged = true;
1043 }
1044 }
1045
1046 return marginsChanged;
1047 }
1048
1060 bool QwtPlotRenderer::exportTo( QwtPlot* plot, const QString& documentName,
1061 const QSizeF& sizeMM, int resolution )
1062 {
1063 if ( plot == NULL )
1064 return false;
1065
1066 QString fileName = documentName;
1067
1068 // What about translation
1069
1070 #ifndef QT_NO_FILEDIALOG
1071 const QList< QByteArray > imageFormats =
1072 QImageWriter::supportedImageFormats();
1073
1074 QStringList filter;
1075 #if QWT_FORMAT_PDF
1076 filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
1077 #endif
1078 #if QWT_FORMAT_SVG
1079 filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
1080 #endif
1081 #if QWT_FORMAT_POSTSCRIPT
1082 filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
1083 #endif
1084
1085 if ( imageFormats.size() > 0 )
1086 {
1087 QString imageFilter( tr( "Images" ) );
1088 imageFilter += " (";
1089 for ( int i = 0; i < imageFormats.size(); i++ )
1090 {
1091 if ( i > 0 )
1092 imageFilter += " ";
1093 imageFilter += "*.";
1094 imageFilter += imageFormats[i];
1095 }
1096 imageFilter += ")";
1097
1098 filter += imageFilter;
1099 }
1100
1101 fileName = QFileDialog::getSaveFileName(
1102 NULL, tr( "Export File Name" ), fileName,
1103 filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
1104 #endif
1105 if ( fileName.isEmpty() )
1106 return false;
1107
1108 renderDocument( plot, fileName, sizeMM, resolution );
1109
1110 return true;
1111 }
1112
1113 #if QWT_MOC_INCLUDE
1114 #include "moc_qwt_plot_renderer.cpp"
1115 #endif
QList
Definition: qwt_abstract_legend.h:17
QwtAbstractLegend::renderLegend
virtual void renderLegend(QPainter *painter, const QRectF &rect, bool fillBackground) const =0
QwtAbstractLegend::isEmpty
virtual bool isEmpty() const =0
QwtAbstractScaleDraw::Backbone
@ Backbone
Backbone = the line where the ticks are located.
Definition: qwt_abstract_scale_draw.h:42
QwtAbstractScaleDraw::hasComponent
bool hasComponent(ScaleComponent) const
Definition: qwt_abstract_scale_draw.cpp:95
QwtAbstractScaleDraw::draw
virtual void draw(QPainter *, const QPalette &) const
Draw the scale.
Definition: qwt_abstract_scale_draw.cpp:169
QwtAbstractScaleDraw::penWidthF
qreal penWidthF() const
Definition: qwt_abstract_scale_draw.cpp:156
QwtAbstractScaleDraw::enableComponent
void enableComponent(ScaleComponent, bool enable=true)
Definition: qwt_abstract_scale_draw.cpp:79
QwtPainter::drawRoundedFrame
static void drawRoundedFrame(QPainter *, const QRectF &, qreal xRadius, qreal yRadius, const QPalette &, int lineWidth, int frameStyle)
Definition: qwt_painter.cpp:1065
QwtPainter::drawBackgound
static void drawBackgound(QPainter *, const QRectF &, const QWidget *)
Definition: qwt_painter.cpp:1351
QwtPainter::drawRect
static void drawRect(QPainter *, qreal x, qreal y, qreal w, qreal h)
Wrapper for QPainter::drawRect()
Definition: qwt_painter.cpp:347
QwtPainter::drawFrame
static void drawFrame(QPainter *, const QRectF &rect, const QPalette &palette, QPalette::ColorRole foregroundRole, int lineWidth, int midLineWidth, int frameStyle)
Definition: qwt_painter.cpp:911
QwtPlot
A 2-D plotting widget.
Definition: qwt_plot.h:79
QwtPlot::getCanvasMarginsHint
virtual void getCanvasMarginsHint(const QwtScaleMap maps[], const QRectF &canvasRect, double &left, double &top, double &right, double &bottom) const
Calculate the canvas margins.
Definition: qwt_plot.cpp:670
QwtPlot::axisScaleEngine
QwtScaleEngine * axisScaleEngine(QwtAxisId)
Definition: qwt_plot_axis.cpp:190
QwtPlot::drawItems
virtual void drawItems(QPainter *, const QRectF &, const QwtScaleMap maps[QwtAxis::AxisPositions]) const
Definition: qwt_plot.cpp:764
QwtPlot::canvas
QWidget * canvas()
Definition: qwt_plot.cpp:463
QwtPlot::footerLabel
QwtTextLabel * footerLabel()
Definition: qwt_plot.cpp:401
QwtPlot::isAxisVisible
bool isAxisVisible(QwtAxisId) const
Definition: qwt_plot_axis.cpp:225
QwtPlot::plotLayout
QwtPlotLayout * plotLayout()
Definition: qwt_plot.cpp:430
QwtPlot::legend
QwtAbstractLegend * legend()
Definition: qwt_plot.cpp:445
QwtPlot::axisWidget
const QwtScaleWidget * axisWidget(QwtAxisId) const
Definition: qwt_plot_axis.cpp:141
QwtPlot::titleLabel
QwtTextLabel * titleLabel()
Definition: qwt_plot.cpp:357
QwtPlot::axisScaleDiv
const QwtScaleDiv & axisScaleDiv(QwtAxisId) const
Return the scale division of a specified axis.
Definition: qwt_plot_axis.cpp:283
QwtPlot::axisScaleDraw
const QwtScaleDraw * axisScaleDraw(QwtAxisId) const
Return the scale draw of a specified axis.
Definition: qwt_plot_axis.cpp:294
QwtPlot::title
QwtText title() const
Definition: qwt_plot.cpp:351
QwtPlotLayout
Layout engine for QwtPlot.
Definition: qwt_plot_layout.h:28
QwtPlotLayout::titleRect
QRectF titleRect() const
Definition: qwt_plot_layout.cpp:1282
QwtPlotLayout::setCanvasMargin
void setCanvasMargin(int margin, int axis=-1)
Definition: qwt_plot_layout.cpp:1066
QwtPlotLayout::footerRect
QRectF footerRect() const
Definition: qwt_plot_layout.cpp:1304
QwtPlotLayout::canvasMargin
int canvasMargin(int axisId) const
Definition: qwt_plot_layout.cpp:1089
QwtPlotLayout::legendRect
QRectF legendRect() const
Definition: qwt_plot_layout.cpp:1328
QwtPlotLayout::invalidate
virtual void invalidate()
Definition: qwt_plot_layout.cpp:1389
QwtPlotLayout::alignCanvasToScale
bool alignCanvasToScale(int axisId) const
Definition: qwt_plot_layout.cpp:1141
QwtPlotLayout::scaleRect
QRectF scaleRect(QwtAxisId) const
Definition: qwt_plot_layout.cpp:1355
QwtPlotLayout::Options
QFlags< Option > Options
Definition: qwt_plot_layout.h:58
QwtPlotLayout::canvasRect
QRectF canvasRect() const
Definition: qwt_plot_layout.cpp:1380
QwtPlotLayout::IgnoreTitle
@ IgnoreTitle
Ignore the title.
Definition: qwt_plot_layout.h:52
QwtPlotLayout::IgnoreFooter
@ IgnoreFooter
Ignore the footer.
Definition: qwt_plot_layout.h:55
QwtPlotLayout::IgnoreScrollbars
@ IgnoreScrollbars
Definition: qwt_plot_layout.h:43
QwtPlotLayout::IgnoreFrames
@ IgnoreFrames
Ignore all frames.
Definition: qwt_plot_layout.h:46
QwtPlotLayout::IgnoreLegend
@ IgnoreLegend
Ignore the legend.
Definition: qwt_plot_layout.h:49
QwtPlotLayout::activate
virtual void activate(const QwtPlot *, const QRectF &plotRect, Options options=Options())
Recalculate the geometry of all components.
Definition: qwt_plot_layout.cpp:1508
QwtPlotRenderer
Renderer for exporting a plot to a document, a printer or anything else, that is supported by QPainte...
Definition: qwt_plot_renderer.h:40
QwtPlotRenderer::renderTo
void renderTo(QwtPlot *, QPrinter &) const
Render the plot to a QPrinter.
Definition: qwt_plot_renderer.cpp:427
QwtPlotRenderer::LayoutFlag
LayoutFlag
Layout flags.
Definition: qwt_plot_renderer.h:83
QwtPlotRenderer::DefaultLayout
@ DefaultLayout
Use the default layout as on screen.
Definition: qwt_plot_renderer.h:85
QwtPlotRenderer::FrameWithScales
@ FrameWithScales
Definition: qwt_plot_renderer.h:91
QwtPlotRenderer::renderCanvas
virtual void renderCanvas(const QwtPlot *, QPainter *, const QRectF &canvasRect, const QwtScaleMap *maps) const
Definition: qwt_plot_renderer.cpp:831
QwtPlotRenderer::renderFooter
virtual void renderFooter(const QwtPlot *, QPainter *, const QRectF &footerRect) const
Definition: qwt_plot_renderer.cpp:692
QwtPlotRenderer::setDiscardFlag
void setDiscardFlag(DiscardFlag flag, bool on=true)
Definition: qwt_plot_renderer.cpp:166
QwtPlotRenderer::DiscardFlag
DiscardFlag
Discard flags.
Definition: qwt_plot_renderer.h:46
QwtPlotRenderer::DiscardCanvasFrame
@ DiscardCanvasFrame
Definition: qwt_plot_renderer.h:72
QwtPlotRenderer::DiscardFooter
@ DiscardFooter
Don't render the footer of the plot.
Definition: qwt_plot_renderer.h:63
QwtPlotRenderer::DiscardTitle
@ DiscardTitle
Don't render the title of the plot.
Definition: qwt_plot_renderer.h:54
QwtPlotRenderer::DiscardBackground
@ DiscardBackground
Don't render the background of the plot.
Definition: qwt_plot_renderer.h:51
QwtPlotRenderer::DiscardCanvasBackground
@ DiscardCanvasBackground
Don't render the background of the canvas.
Definition: qwt_plot_renderer.h:60
QwtPlotRenderer::DiscardLegend
@ DiscardLegend
Don't render the legend of the plot.
Definition: qwt_plot_renderer.h:57
QwtPlotRenderer::DiscardNone
@ DiscardNone
Render all components of the plot.
Definition: qwt_plot_renderer.h:48
QwtPlotRenderer::renderLegend
virtual void renderLegend(const QwtPlot *, QPainter *, const QRectF &legendRect) const
Definition: qwt_plot_renderer.cpp:711
QwtPlotRenderer::setLayoutFlags
void setLayoutFlags(LayoutFlags flags)
Definition: qwt_plot_renderer.cpp:236
QwtPlotRenderer::~QwtPlotRenderer
virtual ~QwtPlotRenderer()
Destructor.
Definition: qwt_plot_renderer.cpp:153
QwtPlotRenderer::renderScale
virtual void renderScale(const QwtPlot *, QPainter *, QwtAxisId, int startDist, int endDist, int baseDist, const QRectF &scaleRect) const
Paint a scale into a given rectangle. Paint the scale into a given rectangle.
Definition: qwt_plot_renderer.cpp:733
QwtPlotRenderer::renderTitle
virtual void renderTitle(const QwtPlot *, QPainter *, const QRectF &titleRect) const
Definition: qwt_plot_renderer.cpp:673
QwtPlotRenderer::testLayoutFlag
bool testLayoutFlag(LayoutFlag flag) const
Definition: qwt_plot_renderer.cpp:225
QwtPlotRenderer::renderDocument
void renderDocument(QwtPlot *, const QString &fileName, const QSizeF &sizeMM, int resolution=85)
Definition: qwt_plot_renderer.cpp:261
QwtPlotRenderer::QwtPlotRenderer
QwtPlotRenderer(QObject *=NULL)
Definition: qwt_plot_renderer.cpp:146
QwtPlotRenderer::LayoutFlags
QFlags< LayoutFlag > LayoutFlags
Definition: qwt_plot_renderer.h:94
QwtPlotRenderer::setLayoutFlag
void setLayoutFlag(LayoutFlag flag, bool on=true)
Definition: qwt_plot_renderer.cpp:212
QwtPlotRenderer::DiscardFlags
QFlags< DiscardFlag > DiscardFlags
Definition: qwt_plot_renderer.h:76
QwtPlotRenderer::discardFlags
DiscardFlags discardFlags() const
Definition: qwt_plot_renderer.cpp:199
QwtPlotRenderer::exportTo
bool exportTo(QwtPlot *, const QString &documentName, const QSizeF &sizeMM=QSizeF(300, 200), int resolution=85)
Execute a file dialog and render the plot to the selected file.
Definition: qwt_plot_renderer.cpp:1060
QwtPlotRenderer::setDiscardFlags
void setDiscardFlags(DiscardFlags flags)
Definition: qwt_plot_renderer.cpp:190
QwtPlotRenderer::testDiscardFlag
bool testDiscardFlag(DiscardFlag flag) const
Definition: qwt_plot_renderer.cpp:179
QwtPlotRenderer::render
virtual void render(QwtPlot *, QPainter *, const QRectF &plotRect) const
Definition: qwt_plot_renderer.cpp:482
QwtPlotRenderer::layoutFlags
LayoutFlags layoutFlags() const
Definition: qwt_plot_renderer.cpp:245
QwtScaleDiv
A class representing a scale division.
Definition: qwt_scale_div.h:34
QwtScaleDiv::lowerBound
double lowerBound() const
Definition: qwt_scale_div.cpp:131
QwtScaleDiv::upperBound
double upperBound() const
Definition: qwt_scale_div.cpp:151
QwtScaleDraw
A class for drawing scales.
Definition: qwt_scale_draw.h:36
QwtScaleDraw::setLength
void setLength(double length)
Definition: qwt_scale_draw.cpp:732
QwtScaleDraw::move
void move(double x, double y)
Definition: qwt_scale_draw.h:118
QwtScaleDraw::length
double length() const
Definition: qwt_scale_draw.cpp:753
QwtScaleDraw::pos
QPointF pos() const
Definition: qwt_scale_draw.cpp:717
QwtScaleDraw::Alignment
Alignment
Definition: qwt_scale_draw.h:43
QwtScaleDraw::BottomScale
@ BottomScale
The scale is below.
Definition: qwt_scale_draw.h:45
QwtScaleDraw::TopScale
@ TopScale
The scale is above.
Definition: qwt_scale_draw.h:48
QwtScaleDraw::RightScale
@ RightScale
The scale is right.
Definition: qwt_scale_draw.h:54
QwtScaleDraw::LeftScale
@ LeftScale
The scale is left.
Definition: qwt_scale_draw.h:51
QwtScaleEngine::transformation
QwtTransform * transformation() const
Definition: qwt_scale_engine.cpp:265
QwtScaleMap
A scale map.
Definition: qwt_scale_map.h:27
QwtScaleMap::setPaintInterval
void setPaintInterval(double p1, double p2)
Specify the borders of the paint device interval.
Definition: qwt_scale_map.cpp:119
QwtScaleMap::setScaleInterval
void setScaleInterval(double s1, double s2)
Specify the borders of the scale interval.
Definition: qwt_scale_map.cpp:100
QwtScaleMap::setTransformation
void setTransformation(QwtTransform *)
Definition: qwt_scale_map.cpp:76
QwtScaleWidget
A Widget which contains a scale.
Definition: qwt_scale_widget.h:35
QwtScaleWidget::startBorderDist
int startBorderDist() const
Definition: qwt_scale_widget.cpp:380
QwtScaleWidget::drawColorBar
void drawColorBar(QPainter *, const QRectF &) const
Definition: qwt_scale_widget.cpp:624
QwtScaleWidget::scaleDraw
const QwtScaleDraw * scaleDraw() const
Definition: qwt_scale_widget.cpp:353
QwtScaleWidget::setMargin
void setMargin(int)
Specify the margin to the colorBar/base line.
Definition: qwt_scale_widget.cpp:265
QwtScaleWidget::isColorBarEnabled
bool isColorBarEnabled() const
Definition: qwt_scale_widget.cpp:907
QwtScaleWidget::drawTitle
void drawTitle(QPainter *, QwtScaleDraw::Alignment, const QRectF &rect) const
Definition: qwt_scale_widget.cpp:644
QwtScaleWidget::endBorderDist
int endBorderDist() const
Definition: qwt_scale_widget.cpp:389
QwtScaleWidget::spacing
int spacing() const
Definition: qwt_scale_widget.cpp:407
QwtScaleWidget::getBorderDistHint
void getBorderDistHint(int &start, int &end) const
Calculate a hint for the border distances.
Definition: qwt_scale_widget.cpp:814
QwtScaleWidget::colorBarRect
QRectF colorBarRect(const QRectF &) const
Definition: qwt_scale_widget.cpp:462
QwtScaleWidget::margin
int margin() const
Definition: qwt_scale_widget.cpp:398
QwtScaleWidget::colorBarWidth
int colorBarWidth() const
Definition: qwt_scale_widget.cpp:932
QwtText::isEmpty
bool isEmpty() const
Definition: qwt_text.cpp:739
QwtText::draw
void draw(QPainter *painter, const QRectF &rect) const
Definition: qwt_text.cpp:615
QwtText::text
QString text() const
Definition: qwt_text.cpp:289
QwtTextLabel::text
const QwtText & text() const
Return the text.
Definition: qwt_text_label.cpp:118
QwtAxis
Definition: qwt_axis.h:19
QwtAxis::isYAxis
bool isYAxis(int axisPos)
Definition: qwt_axis.h:57
QwtAxis::YRight
@ YRight
Y axis right of the canvas.
Definition: qwt_axis.h:27
QwtAxis::XTop
@ XTop
X axis above the canvas.
Definition: qwt_axis.h:33
QwtAxis::XBottom
@ XBottom
X axis below the canvas.
Definition: qwt_axis.h:30
QwtAxis::YLeft
@ YLeft
Y axis left of the canvas.
Definition: qwt_axis.h:24
QwtAxis::isXAxis
bool isXAxis(int axisPos)
Definition: qwt_axis.h:51