qwt_plot_renderer.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_plot_renderer.h"
00011 #include "qwt_plot.h"
00012 #include "qwt_painter.h"
00013 #include "qwt_plot_layout.h"
00014 #include "qwt_abstract_legend.h"
00015 #include "qwt_scale_widget.h"
00016 #include "qwt_scale_engine.h"
00017 #include "qwt_text.h"
00018 #include "qwt_text_label.h"
00019 #include "qwt_math.h"
00020 #include <qpainter.h>
00021 #include <qpaintengine.h>
00022 #include <qtransform.h>
00023 #include <qprinter.h>
00024 #include <qprintdialog.h>
00025 #include <qfiledialog.h>
00026 #include <qfileinfo.h>
00027 #include <qstyle.h>
00028 #include <qstyleoption.h>
00029 #include <qimagewriter.h>
00030 
00031 #ifndef QWT_NO_SVG
00032 #ifdef QT_SVG_LIB
00033 #if QT_VERSION >= 0x040500
00034 #define QWT_FORMAT_SVG 1
00035 #endif
00036 #endif
00037 #endif
00038 
00039 #ifndef QT_NO_PRINTER
00040 #define QWT_FORMAT_PDF 1
00041 #endif
00042 
00043 #ifndef QT_NO_PDF
00044 
00045 // QPdfWriter::setResolution() has been introduced with
00046 // Qt 5.3. Guess it is o.k. to stay with QPrinter for older
00047 // versions.
00048 
00049 #if QT_VERSION >= 0x050300
00050 
00051 #ifndef QWT_FORMAT_PDF
00052 #define QWT_FORMAT_PDF 1
00053 #endif
00054 
00055 #define QWT_PDF_WRITER 1
00056 
00057 #endif
00058 #endif
00059 
00060 #ifndef QT_NO_PRINTER
00061 // postscript support has been dropped in Qt5
00062 #if QT_VERSION < 0x050000
00063 #define QWT_FORMAT_POSTSCRIPT 1
00064 #endif
00065 #endif
00066 
00067 #if QWT_FORMAT_SVG
00068 #include <qsvggenerator.h>
00069 #endif
00070 
00071 #if QWT_PDF_WRITER
00072 #include <qpdfwriter.h>
00073 #endif
00074 
00075 static QPainterPath qwtCanvasClip( 
00076     const QWidget* canvas, const QRectF &canvasRect )
00077 {
00078     // The clip region is calculated in integers
00079     // To avoid too much rounding errors better
00080     // calculate it in target device resolution
00081 
00082     int x1 = qCeil( canvasRect.left() );
00083     int x2 = qFloor( canvasRect.right() );
00084     int y1 = qCeil( canvasRect.top() );
00085     int y2 = qFloor( canvasRect.bottom() );
00086 
00087     const QRect r( x1, y1, x2 - x1 - 1, y2 - y1 - 1 );
00088 
00089     QPainterPath clipPath;
00090 
00091     ( void ) QMetaObject::invokeMethod(
00092         const_cast< QWidget *>( canvas ), "borderPath",
00093         Qt::DirectConnection,
00094         Q_RETURN_ARG( QPainterPath, clipPath ), Q_ARG( QRect, r ) );
00095 
00096     return clipPath;
00097 }
00098 
00099 class QwtPlotRenderer::PrivateData
00100 {
00101 public:
00102     PrivateData():
00103         discardFlags( QwtPlotRenderer::DiscardNone ),
00104         layoutFlags( QwtPlotRenderer::DefaultLayout )
00105     {
00106     }
00107 
00108     QwtPlotRenderer::DiscardFlags discardFlags;
00109     QwtPlotRenderer::LayoutFlags layoutFlags;
00110 };
00111 
00116 QwtPlotRenderer::QwtPlotRenderer( QObject *parent ):
00117     QObject( parent )
00118 {
00119     d_data = new PrivateData;
00120 }
00121 
00123 QwtPlotRenderer::~QwtPlotRenderer()
00124 {
00125     delete d_data;
00126 }
00127 
00136 void QwtPlotRenderer::setDiscardFlag( DiscardFlag flag, bool on )
00137 {
00138     if ( on )
00139         d_data->discardFlags |= flag;
00140     else
00141         d_data->discardFlags &= ~flag;
00142 }
00143 
00149 bool QwtPlotRenderer::testDiscardFlag( DiscardFlag flag ) const
00150 {
00151     return d_data->discardFlags & flag;
00152 }
00153 
00160 void QwtPlotRenderer::setDiscardFlags( DiscardFlags flags )
00161 {
00162     d_data->discardFlags = flags;
00163 }
00164 
00169 QwtPlotRenderer::DiscardFlags QwtPlotRenderer::discardFlags() const
00170 {
00171     return d_data->discardFlags;
00172 }
00173 
00182 void QwtPlotRenderer::setLayoutFlag( LayoutFlag flag, bool on )
00183 {
00184     if ( on )
00185         d_data->layoutFlags |= flag;
00186     else
00187         d_data->layoutFlags &= ~flag;
00188 }
00189 
00195 bool QwtPlotRenderer::testLayoutFlag( LayoutFlag flag ) const
00196 {
00197     return d_data->layoutFlags & flag;
00198 }
00199 
00206 void QwtPlotRenderer::setLayoutFlags( LayoutFlags flags )
00207 {
00208     d_data->layoutFlags = flags;
00209 }
00210 
00215 QwtPlotRenderer::LayoutFlags QwtPlotRenderer::layoutFlags() const
00216 {
00217     return d_data->layoutFlags;
00218 }
00219 
00231 void QwtPlotRenderer::renderDocument( QwtPlot *plot,
00232     const QString &fileName, const QSizeF &sizeMM, int resolution )
00233 {
00234     renderDocument( plot, fileName,
00235         QFileInfo( fileName ).suffix(), sizeMM, resolution );
00236 }
00237 
00263 void QwtPlotRenderer::renderDocument( QwtPlot *plot,
00264     const QString &fileName, const QString &format,
00265     const QSizeF &sizeMM, int resolution )
00266 {
00267     if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
00268         return;
00269 
00270     QString title = plot->title().text();
00271     if ( title.isEmpty() )
00272         title = "Plot Document";
00273 
00274     const double mmToInch = 1.0 / 25.4;
00275     const QSizeF size = sizeMM * mmToInch * resolution;
00276 
00277     const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
00278 
00279     const QString fmt = format.toLower();
00280     if ( fmt == "pdf" )
00281     {
00282 #if QWT_FORMAT_PDF
00283 
00284 #if QWT_PDF_WRITER
00285         QPdfWriter pdfWriter( fileName );
00286         pdfWriter.setPageSizeMM( sizeMM );
00287         pdfWriter.setTitle( title );
00288         pdfWriter.setPageMargins( QMarginsF() );
00289         pdfWriter.setResolution( resolution ); 
00290         
00291         QPainter painter( &pdfWriter );
00292         render( plot, &painter, documentRect );
00293 #else
00294         QPrinter printer;
00295         printer.setOutputFormat( QPrinter::PdfFormat );
00296         printer.setColorMode( QPrinter::Color );
00297         printer.setFullPage( true );
00298         printer.setPaperSize( sizeMM, QPrinter::Millimeter );
00299         printer.setDocName( title );
00300         printer.setOutputFileName( fileName );
00301         printer.setResolution( resolution );
00302 
00303         QPainter painter( &printer );
00304         render( plot, &painter, documentRect );
00305 #endif
00306 #endif
00307     }
00308     else if ( fmt == "ps" )
00309     {
00310 #if QWT_FORMAT_POSTSCRIPT
00311         QPrinter printer;
00312         printer.setOutputFormat( QPrinter::PostScriptFormat );
00313         printer.setColorMode( QPrinter::Color );
00314         printer.setFullPage( true );
00315         printer.setPaperSize( sizeMM, QPrinter::Millimeter );
00316         printer.setDocName( title );
00317         printer.setOutputFileName( fileName );
00318         printer.setResolution( resolution );
00319 
00320         QPainter painter( &printer );
00321         render( plot, &painter, documentRect );
00322 #endif
00323     }
00324     else if ( fmt == "svg" )
00325     {
00326 #if QWT_FORMAT_SVG
00327         QSvgGenerator generator;
00328         generator.setTitle( title );
00329         generator.setFileName( fileName );
00330         generator.setResolution( resolution );
00331         generator.setViewBox( documentRect );
00332 
00333         QPainter painter( &generator );
00334         render( plot, &painter, documentRect );
00335 #endif
00336     }
00337     else
00338     {
00339         if ( QImageWriter::supportedImageFormats().indexOf(
00340             format.toLatin1() ) >= 0 )
00341         {
00342             const QRect imageRect = documentRect.toRect();
00343             const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
00344 
00345             QImage image( imageRect.size(), QImage::Format_ARGB32 );
00346             image.setDotsPerMeterX( dotsPerMeter );
00347             image.setDotsPerMeterY( dotsPerMeter );
00348             image.fill( QColor( Qt::white ).rgb() );
00349 
00350             QPainter painter( &image );
00351             render( plot, &painter, imageRect );
00352             painter.end();
00353 
00354             image.save( fileName, format.toLatin1() );
00355         }
00356     }
00357 }
00358 
00372 void QwtPlotRenderer::renderTo(
00373     QwtPlot *plot, QPaintDevice &paintDevice ) const
00374 {
00375     int w = paintDevice.width();
00376     int h = paintDevice.height();
00377 
00378     QPainter p( &paintDevice );
00379     render( plot, &p, QRectF( 0, 0, w, h ) );
00380 }
00381 
00395 #ifndef QT_NO_PRINTER
00396 
00397 void QwtPlotRenderer::renderTo(
00398     QwtPlot *plot, QPrinter &printer ) const
00399 {
00400     int w = printer.width();
00401     int h = printer.height();
00402 
00403     QRectF rect( 0, 0, w, h );
00404     double aspect = rect.width() / rect.height();
00405     if ( ( aspect < 1.0 ) )
00406         rect.setHeight( aspect * rect.width() );
00407 
00408     QPainter p( &printer );
00409     render( plot, &p, rect );
00410 }
00411 
00412 #endif
00413 
00414 #if QWT_FORMAT_SVG
00415 
00427 void QwtPlotRenderer::renderTo(
00428     QwtPlot *plot, QSvgGenerator &generator ) const
00429 {
00430     QRectF rect = generator.viewBoxF();
00431     if ( rect.isEmpty() )
00432         rect.setRect( 0, 0, generator.width(), generator.height() );
00433 
00434     if ( rect.isEmpty() )
00435         rect.setRect( 0, 0, 800, 600 ); // something
00436 
00437     QPainter p( &generator );
00438     render( plot, &p, rect );
00439 }
00440 
00441 #endif
00442 
00452 void QwtPlotRenderer::render( QwtPlot *plot,
00453     QPainter *painter, const QRectF &plotRect ) const
00454 {
00455     if ( painter == 0 || !painter->isActive() ||
00456             !plotRect.isValid() || plot->size().isNull() )
00457     {
00458         return;
00459     }
00460 
00461     if ( !( d_data->discardFlags & DiscardBackground ) )
00462         QwtPainter::drawBackgound( painter, plotRect, plot );
00463 
00464     /*
00465       The layout engine uses the same methods as they are used
00466       by the Qt layout system. Therefore we need to calculate the
00467       layout in screen coordinates and paint with a scaled painter.
00468      */
00469     QTransform transform;
00470     transform.scale(
00471         double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
00472         double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
00473 
00474     QRectF layoutRect = transform.inverted().mapRect( plotRect );
00475 
00476     if ( !( d_data->discardFlags & DiscardBackground ) )
00477     {
00478         // subtract the contents margins
00479 
00480         int left, top, right, bottom;
00481         plot->getContentsMargins( &left, &top, &right, &bottom );
00482         layoutRect.adjust( left, top, -right, -bottom );
00483     }
00484 
00485     QwtPlotLayout *layout = plot->plotLayout();
00486 
00487     int baseLineDists[QwtPlot::axisCnt];
00488     int canvasMargins[QwtPlot::axisCnt];
00489 
00490     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00491     {
00492         canvasMargins[ axisId ] = layout->canvasMargin( axisId );
00493 
00494         if ( d_data->layoutFlags & FrameWithScales )
00495         {
00496             QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
00497             if ( scaleWidget )
00498             {
00499                 baseLineDists[axisId] = scaleWidget->margin();
00500                 scaleWidget->setMargin( 0 );
00501             }
00502 
00503             if ( !plot->axisEnabled( axisId ) )
00504             {
00505                 int left = 0;
00506                 int right = 0;
00507                 int top = 0;
00508                 int bottom = 0;
00509 
00510                 // When we have a scale the frame is painted on
00511                 // the position of the backbone - otherwise we
00512                 // need to introduce a margin around the canvas
00513 
00514                 switch( axisId )
00515                 {
00516                     case QwtPlot::yLeft:
00517                         layoutRect.adjust( 1, 0, 0, 0 );
00518                         break;
00519                     case QwtPlot::yRight:
00520                         layoutRect.adjust( 0, 0, -1, 0 );
00521                         break;
00522                     case QwtPlot::xTop:
00523                         layoutRect.adjust( 0, 1, 0, 0 );
00524                         break;
00525                     case QwtPlot::xBottom:
00526                         layoutRect.adjust( 0, 0, 0, -1 );
00527                         break;
00528                     default:
00529                         break;
00530                 }
00531                 layoutRect.adjust( left, top, right, bottom );
00532             }
00533         }
00534     }
00535 
00536     // Calculate the layout for the document.
00537 
00538     QwtPlotLayout::Options layoutOptions = QwtPlotLayout::IgnoreScrollbars;
00539 
00540     if ( ( d_data->layoutFlags & FrameWithScales ) ||
00541         ( d_data->discardFlags & DiscardCanvasFrame ) )
00542     {
00543         layoutOptions |= QwtPlotLayout::IgnoreFrames;
00544     } 
00545 
00546 
00547     if ( d_data->discardFlags & DiscardLegend )
00548         layoutOptions |= QwtPlotLayout::IgnoreLegend;
00549 
00550     if ( d_data->discardFlags & DiscardTitle )
00551         layoutOptions |= QwtPlotLayout::IgnoreTitle;
00552 
00553     if ( d_data->discardFlags & DiscardFooter )
00554         layoutOptions |= QwtPlotLayout::IgnoreFooter;
00555 
00556     layout->activate( plot, layoutRect, layoutOptions );
00557 
00558     // canvas
00559 
00560     QwtScaleMap maps[QwtPlot::axisCnt];
00561     buildCanvasMaps( plot, layout->canvasRect(), maps );
00562     if ( updateCanvasMargins( plot, layout->canvasRect(), maps ) )
00563     {
00564         // recalculate maps and layout, when the margins
00565         // have been changed
00566 
00567         layout->activate( plot, layoutRect, layoutOptions );
00568         buildCanvasMaps( plot, layout->canvasRect(), maps );
00569     }
00570 
00571     // now start painting
00572 
00573     painter->save();
00574     painter->setWorldTransform( transform, true );
00575 
00576     renderCanvas( plot, painter, layout->canvasRect(), maps );
00577 
00578     if ( !( d_data->discardFlags & DiscardTitle )
00579         && ( !plot->titleLabel()->text().isEmpty() ) )
00580     {
00581         renderTitle( plot, painter, layout->titleRect() );
00582     }
00583 
00584     if ( !( d_data->discardFlags & DiscardFooter )
00585         && ( !plot->footerLabel()->text().isEmpty() ) )
00586     {
00587         renderFooter( plot, painter, layout->footerRect() );
00588     }
00589 
00590     if ( !( d_data->discardFlags & DiscardLegend )
00591         && plot->legend() && !plot->legend()->isEmpty() )
00592     {
00593         renderLegend( plot, painter, layout->legendRect() );
00594     }
00595 
00596     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00597     {
00598         QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
00599         if ( scaleWidget )
00600         {
00601             int baseDist = scaleWidget->margin();
00602 
00603             int startDist, endDist;
00604             scaleWidget->getBorderDistHint( startDist, endDist );
00605 
00606             renderScale( plot, painter, axisId, startDist, endDist,
00607                 baseDist, layout->scaleRect( axisId ) );
00608         }
00609     }
00610 
00611     painter->restore();
00612 
00613     // restore all setting to their original attributes.
00614     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00615     {
00616         if ( d_data->layoutFlags & FrameWithScales )
00617         {
00618             QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
00619             if ( scaleWidget  )
00620                 scaleWidget->setMargin( baseLineDists[axisId] );
00621         }
00622 
00623         layout->setCanvasMargin( canvasMargins[axisId] );
00624     }
00625 
00626     layout->invalidate();
00627 
00628 }
00629 
00637 void QwtPlotRenderer::renderTitle( const QwtPlot *plot,
00638     QPainter *painter, const QRectF &rect ) const
00639 {
00640     painter->setFont( plot->titleLabel()->font() );
00641 
00642     const QColor color = plot->titleLabel()->palette().color(
00643             QPalette::Active, QPalette::Text );
00644 
00645     painter->setPen( color );
00646     plot->titleLabel()->text().draw( painter, rect );
00647 }
00648 
00656 void QwtPlotRenderer::renderFooter( const QwtPlot *plot,
00657     QPainter *painter, const QRectF &rect ) const
00658 {
00659     painter->setFont( plot->footerLabel()->font() );
00660 
00661     const QColor color = plot->footerLabel()->palette().color(
00662             QPalette::Active, QPalette::Text );
00663 
00664     painter->setPen( color );
00665     plot->footerLabel()->text().draw( painter, rect );
00666 }
00667 
00668 
00676 void QwtPlotRenderer::renderLegend( const QwtPlot *plot,
00677     QPainter *painter, const QRectF &rect ) const
00678 {
00679     if ( plot->legend() )
00680     {
00681         bool fillBackground = !( d_data->discardFlags & DiscardBackground );
00682         plot->legend()->renderLegend( painter, rect, fillBackground );
00683     }
00684 }
00685 
00698 void QwtPlotRenderer::renderScale( const QwtPlot *plot,
00699     QPainter *painter,
00700     int axisId, int startDist, int endDist, int baseDist,
00701     const QRectF &rect ) const
00702 {
00703     if ( !plot->axisEnabled( axisId ) )
00704         return;
00705 
00706     const QwtScaleWidget *scaleWidget = plot->axisWidget( axisId );
00707     if ( scaleWidget->isColorBarEnabled()
00708         && scaleWidget->colorBarWidth() > 0 )
00709     {
00710         scaleWidget->drawColorBar( painter, scaleWidget->colorBarRect( rect ) );
00711         baseDist += scaleWidget->colorBarWidth() + scaleWidget->spacing();
00712     }
00713 
00714     painter->save();
00715 
00716     QwtScaleDraw::Alignment align;
00717     double x, y, w;
00718 
00719     switch ( axisId )
00720     {
00721         case QwtPlot::yLeft:
00722         {
00723             x = rect.right() - 1.0 - baseDist;
00724             y = rect.y() + startDist;
00725             w = rect.height() - startDist - endDist;
00726             align = QwtScaleDraw::LeftScale;
00727             break;
00728         }
00729         case QwtPlot::yRight:
00730         {
00731             x = rect.left() + baseDist;
00732             y = rect.y() + startDist;
00733             w = rect.height() - startDist - endDist;
00734             align = QwtScaleDraw::RightScale;
00735             break;
00736         }
00737         case QwtPlot::xTop:
00738         {
00739             x = rect.left() + startDist;
00740             y = rect.bottom() - 1.0 - baseDist;
00741             w = rect.width() - startDist - endDist;
00742             align = QwtScaleDraw::TopScale;
00743             break;
00744         }
00745         case QwtPlot::xBottom:
00746         {
00747             x = rect.left() + startDist;
00748             y = rect.top() + baseDist;
00749             w = rect.width() - startDist - endDist;
00750             align = QwtScaleDraw::BottomScale;
00751             break;
00752         }
00753         default:
00754             return;
00755     }
00756 
00757     scaleWidget->drawTitle( painter, align, rect );
00758 
00759     painter->setFont( scaleWidget->font() );
00760 
00761     QwtScaleDraw *sd = const_cast<QwtScaleDraw *>( scaleWidget->scaleDraw() );
00762     const QPointF sdPos = sd->pos();
00763     const double sdLength = sd->length();
00764 
00765     sd->move( x, y );
00766     sd->setLength( w );
00767 
00768     QPalette palette = scaleWidget->palette();
00769     palette.setCurrentColorGroup( QPalette::Active );
00770     sd->draw( painter, palette );
00771 
00772     // reset previous values
00773     sd->move( sdPos );
00774     sd->setLength( sdLength );
00775 
00776     painter->restore();
00777 }
00778 
00787 void QwtPlotRenderer::renderCanvas( const QwtPlot *plot,
00788     QPainter *painter, const QRectF &canvasRect, 
00789     const QwtScaleMap *map ) const
00790 {
00791     const QWidget *canvas = plot->canvas();
00792 
00793     QRectF r = canvasRect.adjusted( 0.0, 0.0, -1.0, -1.0 );
00794 
00795     if ( d_data->layoutFlags & FrameWithScales )
00796     {
00797         painter->save();
00798 
00799         r.adjust( -1.0, -1.0, 1.0, 1.0 );
00800         painter->setPen( QPen( Qt::black ) );
00801 
00802         if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
00803         {
00804             const QBrush bgBrush =
00805                 canvas->palette().brush( plot->backgroundRole() );
00806             painter->setBrush( bgBrush );
00807         }
00808 
00809         QwtPainter::drawRect( painter, r );
00810 
00811         painter->restore();
00812         painter->save();
00813 
00814         painter->setClipRect( canvasRect );
00815         plot->drawItems( painter, canvasRect, map );
00816 
00817         painter->restore();
00818     }
00819     else if ( canvas->testAttribute( Qt::WA_StyledBackground ) )
00820     {
00821         QPainterPath clipPath;
00822 
00823         painter->save();
00824 
00825         if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
00826         {
00827             QwtPainter::drawBackgound( painter, r, canvas );
00828             clipPath = qwtCanvasClip( canvas, canvasRect );
00829         }
00830 
00831         painter->restore();
00832         painter->save();
00833 
00834         if ( clipPath.isEmpty() )
00835             painter->setClipRect( canvasRect );
00836         else
00837             painter->setClipPath( clipPath );
00838 
00839         plot->drawItems( painter, canvasRect, map );
00840 
00841         painter->restore();
00842     }
00843     else
00844     {
00845         QPainterPath clipPath;
00846 
00847         int frameWidth = 0;
00848 
00849         if ( !( d_data->discardFlags & DiscardCanvasFrame ) )
00850         {
00851             const QVariant fw = canvas->property( "frameWidth" );
00852             if ( fw.type() == QVariant::Int )
00853                 frameWidth = fw.toInt();
00854 
00855             clipPath = qwtCanvasClip( canvas, canvasRect );
00856         }
00857 
00858         QRectF innerRect = canvasRect.adjusted( 
00859             frameWidth, frameWidth, -frameWidth, -frameWidth );
00860 
00861         painter->save();
00862 
00863         if ( clipPath.isEmpty() )
00864         {
00865             painter->setClipRect( innerRect );
00866         }
00867         else
00868         {
00869             painter->setClipPath( clipPath );
00870         }
00871 
00872         if ( !( d_data->discardFlags & DiscardCanvasBackground ) )
00873         {
00874             QwtPainter::drawBackgound( painter, innerRect, canvas );
00875         }
00876 
00877         plot->drawItems( painter, innerRect, map );
00878 
00879         painter->restore();
00880 
00881         if ( frameWidth > 0 )
00882         {
00883             painter->save();
00884 
00885             const int frameStyle =
00886                 canvas->property( "frameShadow" ).toInt() |
00887                 canvas->property( "frameShape" ).toInt();
00888 
00889             const int frameWidth = canvas->property( "frameWidth" ).toInt();
00890 
00891 
00892             const QVariant borderRadius = canvas->property( "borderRadius" );
00893             if ( borderRadius.type() == QVariant::Double 
00894                 && borderRadius.toDouble() > 0.0 )
00895             {
00896                 const double r = borderRadius.toDouble();
00897 
00898                 QwtPainter::drawRoundedFrame( painter, canvasRect,
00899                     r, r, canvas->palette(), frameWidth, frameStyle );
00900             }
00901             else
00902             {
00903                 const int midLineWidth = canvas->property( "midLineWidth" ).toInt();
00904 
00905                 QwtPainter::drawFrame( painter, canvasRect,
00906                     canvas->palette(), canvas->foregroundRole(),
00907                     frameWidth, midLineWidth, frameStyle );
00908             }
00909             painter->restore();
00910         }
00911     }
00912 }
00913 
00921 void QwtPlotRenderer::buildCanvasMaps( const QwtPlot *plot,
00922     const QRectF &canvasRect, QwtScaleMap maps[] ) const
00923 {
00924     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00925     {
00926         maps[axisId].setTransformation(
00927             plot->axisScaleEngine( axisId )->transformation() );
00928 
00929         const QwtScaleDiv &scaleDiv = plot->axisScaleDiv( axisId );
00930         maps[axisId].setScaleInterval(
00931             scaleDiv.lowerBound(), scaleDiv.upperBound() );
00932 
00933         double from, to;
00934         if ( plot->axisEnabled( axisId ) )
00935         {
00936             const int sDist = plot->axisWidget( axisId )->startBorderDist();
00937             const int eDist = plot->axisWidget( axisId )->endBorderDist();
00938             const QRectF scaleRect = plot->plotLayout()->scaleRect( axisId );
00939 
00940             if ( axisId == QwtPlot::xTop || axisId == QwtPlot::xBottom )
00941             {
00942                 from = scaleRect.left() + sDist;
00943                 to = scaleRect.right() - eDist;
00944             }
00945             else
00946             {
00947                 from = scaleRect.bottom() - eDist;
00948                 to = scaleRect.top() + sDist;
00949             }
00950         }
00951         else
00952         {
00953             int margin = 0;
00954             if ( !plot->plotLayout()->alignCanvasToScale( axisId ) )
00955                 margin = plot->plotLayout()->canvasMargin( axisId );
00956 
00957             if ( axisId == QwtPlot::yLeft || axisId == QwtPlot::yRight )
00958             {
00959                 from = canvasRect.bottom() - margin;
00960                 to = canvasRect.top() + margin;
00961             }
00962             else
00963             {
00964                 from = canvasRect.left() + margin;
00965                 to = canvasRect.right() - margin;
00966             }
00967         }
00968         maps[axisId].setPaintInterval( from, to );
00969     }
00970 }
00971 
00972 bool QwtPlotRenderer::updateCanvasMargins( QwtPlot *plot,
00973     const QRectF &canvasRect, const QwtScaleMap maps[] ) const
00974 {
00975     double margins[QwtPlot::axisCnt];
00976     plot->getCanvasMarginsHint( maps, canvasRect,
00977         margins[QwtPlot::yLeft], margins[QwtPlot::xTop], 
00978         margins[QwtPlot::yRight], margins[QwtPlot::xBottom] );
00979 
00980     bool marginsChanged = false;
00981     for ( int axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00982     {
00983         if ( margins[axisId] >= 0.0 )
00984         {
00985             const int m = qCeil( margins[axisId] );
00986             plot->plotLayout()->setCanvasMargin( m, axisId);
00987             marginsChanged = true;
00988         }
00989     }
00990 
00991     return marginsChanged;
00992 }
00993 
01005 bool QwtPlotRenderer::exportTo( QwtPlot *plot, const QString &documentName,
01006      const QSizeF &sizeMM, int resolution )
01007 {       
01008     if ( plot == NULL )
01009         return false;
01010     
01011     QString fileName = documentName;
01012 
01013     // What about translation 
01014 
01015 #ifndef QT_NO_FILEDIALOG
01016     const QList<QByteArray> imageFormats =
01017         QImageWriter::supportedImageFormats();
01018         
01019     QStringList filter;
01020 #if QWT_FORMAT_PDF
01021     filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
01022 #endif
01023 #if QWT_FORMAT_SVG
01024     filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
01025 #endif
01026 #if QWT_FORMAT_POSTSCRIPT
01027     filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
01028 #endif
01029     
01030     if ( imageFormats.size() > 0 )
01031     {
01032         QString imageFilter( tr( "Images" ) );
01033         imageFilter += " (";
01034         for ( int i = 0; i < imageFormats.size(); i++ )
01035         {
01036             if ( i > 0 )
01037                 imageFilter += " ";
01038             imageFilter += "*."; 
01039             imageFilter += imageFormats[i];
01040         }   
01041         imageFilter += ")";
01042         
01043         filter += imageFilter;
01044     }   
01045     
01046     fileName = QFileDialog::getSaveFileName(
01047         NULL, tr( "Export File Name" ), fileName,
01048         filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
01049 #endif  
01050     if ( fileName.isEmpty() )
01051         return false;
01052 
01053     renderDocument( plot, fileName, sizeMM, resolution );
01054 
01055     return true;
01056 }   


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:56