Loading...
Searching...
No Matches
qwt_polar_renderer.cpp
/******************************************************************************
* QwtPolar Widget Library
* Copyright (C) 2008 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
#include "qwt_polar_renderer.h"
#include "qwt_polar_plot.h"
#include "qwt_polar_layout.h"
#include "qwt_legend.h"
#include "qwt_dyngrid_layout.h"
#include "qwt_text_label.h"
#include "qwt_text.h"
#include <qpainter.h>
#include <qprinter.h>
#include <qprintdialog.h>
#include <qfiledialog.h>
#include <qimagewriter.h>
#include <qfileinfo.h>
#include <qmath.h>
#ifndef QWT_NO_SVG
#ifdef QT_SVG_LIB
#define QWT_FORMAT_SVG 1
#endif
#endif
#ifndef QT_NO_PRINTER
#define QWT_FORMAT_PDF 1
#endif
#ifndef QT_NO_PDF
// QPdfWriter::setResolution() has been introduced with
// Qt 5.3. Guess it is o.k. to stay with QPrinter for older
// versions.
#if QT_VERSION >= 0x050300
#ifndef QWT_FORMAT_PDF
#define QWT_FORMAT_PDF 1
#endif
#define QWT_PDF_WRITER 1
#endif
#endif
#ifndef QT_NO_PRINTER
// postscript support has been dropped in Qt5
#if QT_VERSION < 0x050000
#define QWT_FORMAT_POSTSCRIPT 1
#endif
#endif
#if QWT_FORMAT_SVG
#include <qsvggenerator.h>
#endif
#if QWT_PDF_WRITER
#include <qpdfwriter.h>
#endif
static inline double qwtDistance(
const QPointF& p1, const QPointF& p2 )
{
double dx = p2.x() - p1.x();
double dy = p2.y() - p1.y();
return qSqrt( dx * dx + dy * dy );
}
class QwtPolarRenderer::PrivateData
{
public:
PrivateData()
: plot( NULL )
{
}
QwtPolarPlot* plot;
};
QwtPolarRenderer::QwtPolarRenderer( QObject* parent )
: QObject( parent )
{
m_data = new PrivateData;
}
QwtPolarRenderer::~QwtPolarRenderer()
{
delete m_data;
}
void QwtPolarRenderer::renderDocument( QwtPolarPlot* plot,
const QString& fileName, const QSizeF& sizeMM, int resolution )
{
renderDocument( plot, fileName,
QFileInfo( fileName ).suffix(), sizeMM, resolution );
}
void QwtPolarRenderer::renderDocument( QwtPolarPlot* plot,
const QString& fileName, const QString& format,
const QSizeF& sizeMM, int resolution )
{
if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
return;
QString title = plot->title().text();
if ( title.isEmpty() )
title = "Plot Document";
const double mmToInch = 1.0 / 25.4;
const QSizeF size = sizeMM * mmToInch * resolution;
const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
const QString fmt = format.toLower();
if ( format == "pdf" )
{
#if QWT_FORMAT_PDF
#if QWT_PDF_WRITER
QPdfWriter pdfWriter( fileName );
pdfWriter.setPageSize( QPageSize( sizeMM, QPageSize::Millimeter ) );
pdfWriter.setTitle( title );
pdfWriter.setPageMargins( QMarginsF() );
pdfWriter.setResolution( resolution );
QPainter painter( &pdfWriter );
render( plot, &painter, documentRect );
#else
QPrinter printer;
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setColorMode( QPrinter::Color );
printer.setFullPage( true );
printer.setPaperSize( sizeMM, QPrinter::Millimeter );
printer.setDocName( title );
printer.setOutputFileName( fileName );
printer.setResolution( resolution );
QPainter painter( &printer );
render( plot, &painter, documentRect );
#endif
#endif
}
else if ( format == "ps" )
{
#if QWT_FORMAT_POSTSCRIPT
QPrinter printer;
printer.setColorMode( QPrinter::Color );
printer.setFullPage( true );
printer.setPaperSize( sizeMM, QPrinter::Millimeter );
printer.setDocName( title );
printer.setOutputFileName( fileName );
printer.setOutputFormat( QPrinter::PostScriptFormat );
printer.setResolution( resolution );
QPainter painter( &printer );
render( plot, &painter, documentRect );
#endif
}
else if ( format == "svg" )
{
#ifdef QWT_FORMAT_SVG
QSvgGenerator generator;
generator.setTitle( title );
generator.setFileName( fileName );
generator.setResolution( resolution );
generator.setViewBox( documentRect );
QPainter painter( &generator );
render( plot, &painter, documentRect );
#endif
}
else
{
if ( QImageWriter::supportedImageFormats().indexOf(
format.toLatin1() ) >= 0 )
{
const QRect imageRect = documentRect.toRect();
const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
QImage image( imageRect.size(), QImage::Format_ARGB32 );
image.setDotsPerMeterX( dotsPerMeter );
image.setDotsPerMeterY( dotsPerMeter );
image.fill( QColor( Qt::white ).rgb() );
QPainter painter( &image );
render( plot, &painter, imageRect );
painter.end();
image.save( fileName, format.toLatin1() );
}
}
}
void QwtPolarRenderer::renderTo(
QwtPolarPlot* plot, QPaintDevice& paintDevice ) const
{
int w = paintDevice.width();
int h = paintDevice.height();
QPainter p( &paintDevice );
render( plot, &p, QRectF( 0, 0, w, h ) );
}
#ifndef QT_NO_PRINTER
void QwtPolarRenderer::renderTo(
QwtPolarPlot* plot, QPrinter& printer ) const
{
int w = printer.width();
int h = printer.height();
QRectF rect( 0, 0, w, h );
double aspect = rect.width() / rect.height();
if ( ( aspect < 1.0 ) )
rect.setHeight( aspect * rect.width() );
QPainter p( &printer );
render( plot, &p, rect );
}
#endif
#ifdef QWT_FORMAT_SVG
void QwtPolarRenderer::renderTo(
QwtPolarPlot* plot, QSvgGenerator& generator ) const
{
QRectF rect = generator.viewBoxF();
if ( rect.isEmpty() )
rect.setRect( 0, 0, generator.width(), generator.height() );
if ( rect.isEmpty() )
rect.setRect( 0, 0, 800, 600 ); // something
QPainter p( &generator );
render( plot, &p, rect );
}
#endif
void QwtPolarRenderer::render( QwtPolarPlot* plot,
QPainter* painter, const QRectF& plotRect ) const
{
if ( plot == NULL || painter == NULL || !painter->isActive() ||
!plotRect.isValid() || plot->size().isNull() )
{
return;
}
m_data->plot = plot;
/*
The layout engine uses the same methods as they are used
by the Qt layout system. Therefore we need to calculate the
layout in screen coordinates and paint with a scaled painter.
*/
QTransform transform;
transform.scale(
double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
const QRectF layoutRect = transform.inverted().mapRect( plotRect );
QwtPolarLayout* layout = plot->plotLayout();
// All paint operations need to be scaled according to
// the paint device metrics.
QwtPolarLayout::Options layoutOptions =
QwtPolarLayout::IgnoreScrollbars | QwtPolarLayout::IgnoreFrames;
layout->activate( plot, layoutRect, layoutOptions );
painter->save();
painter->setWorldTransform( transform, true );
painter->save();
renderTitle( painter, layout->titleRect() );
painter->restore();
painter->save();
renderLegend( plot, painter, layout->legendRect() );
painter->restore();
const QRectF canvasRect = layout->canvasRect();
painter->save();
painter->setClipRect( canvasRect );
plot->drawCanvas( painter, canvasRect );
painter->restore();
painter->restore();
layout->invalidate();
m_data->plot = NULL;
}
void QwtPolarRenderer::renderTitle( QPainter* painter, const QRectF& rect ) const
{
QwtTextLabel* title = m_data->plot->titleLabel();
painter->setFont( title->font() );
const QColor color = title->palette().color(
QPalette::Active, QPalette::Text );
painter->setPen( color );
title->text().draw( painter, rect );
}
void QwtPolarRenderer::renderLegend( const QwtPolarPlot* plot,
QPainter* painter, const QRectF& rect ) const
{
if ( plot->legend() )
plot->legend()->renderLegend( painter, rect, true );
}
bool QwtPolarRenderer::exportTo( QwtPolarPlot* plot,
const QString& documentName, const QSizeF& sizeMM, int resolution )
{
if ( plot == NULL )
return false;
QString fileName = documentName;
// What about translation
#ifndef QT_NO_FILEDIALOG
const QList< QByteArray > imageFormats =
QImageWriter::supportedImageFormats();
QStringList filter;
#ifndef QT_NO_PRINTER
filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
#endif
#ifndef QWT_NO_SVG
filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
#endif
#ifndef QT_NO_PRINTER
filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
#endif
if ( imageFormats.size() > 0 )
{
QString imageFilter( tr( "Images" ) );
imageFilter += " (";
for ( int i = 0; i < imageFormats.size(); i++ )
{
if ( i > 0 )
imageFilter += " ";
imageFilter += "*.";
imageFilter += imageFormats[i];
}
imageFilter += ")";
filter += imageFilter;
}
fileName = QFileDialog::getSaveFileName(
NULL, tr( "Export File Name" ), fileName,
filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
#endif
if ( fileName.isEmpty() )
return false;
renderDocument( plot, fileName, sizeMM, resolution );
return true;
}
#include "moc_qwt_polar_renderer.cpp"
QList
Definition qwt_abstract_legend.h:17
QwtAbstractLegend::renderLegend
virtual void renderLegend(QPainter *painter, const QRectF &rect, bool fillBackground) const =0
QwtPolarLayout
Layout class for QwtPolarPlot.
Definition qwt_polar_layout.h:24
QwtPolarLayout::legendRect
const QRectF & legendRect() const
Definition qwt_polar_layout.cpp:239
QwtPolarLayout::invalidate
virtual void invalidate()
Definition qwt_polar_layout.cpp:257
QwtPolarLayout::activate
virtual void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
Definition qwt_polar_layout.cpp:344
QwtPolarLayout::titleRect
const QRectF & titleRect() const
Definition qwt_polar_layout.cpp:229
QwtPolarLayout::IgnoreScrollbars
@ IgnoreScrollbars
Ignore the dimension of the scrollbars.
Definition qwt_polar_layout.h:31
QwtPolarLayout::IgnoreFrames
@ IgnoreFrames
Ignore all frames.
Definition qwt_polar_layout.h:34
QwtPolarLayout::Options
QFlags< Option > Options
Definition qwt_polar_layout.h:43
QwtPolarLayout::canvasRect
const QRectF & canvasRect() const
Definition qwt_polar_layout.cpp:248
QwtPolarPlot
A plotting widget, displaying a polar coordinate system.
Definition qwt_polar_plot.h:47
QwtPolarPlot::plotLayout
QwtPolarLayout * plotLayout()
Definition qwt_polar_plot.cpp:1274
QwtPolarPlot::drawCanvas
virtual void drawCanvas(QPainter *, const QRectF &) const
Definition qwt_polar_plot.cpp:930
QwtPolarPlot::title
QwtText title() const
Definition qwt_polar_plot.cpp:147
QwtPolarPlot::legend
QwtAbstractLegend * legend()
Definition qwt_polar_plot.cpp:286
QwtPolarPlot::titleLabel
QwtTextLabel * titleLabel()
Definition qwt_polar_plot.cpp:153
QwtPolarRenderer::exportTo
bool exportTo(QwtPolarPlot *, const QString &documentName, const QSizeF &sizeMM=QSizeF(200, 200), int resolution=85)
Execute a file dialog and render the plot to the selected file.
Definition qwt_polar_renderer.cpp:430
QwtPolarRenderer::renderTitle
virtual void renderTitle(QPainter *, const QRectF &) const
Definition qwt_polar_renderer.cpp:391
QwtPolarRenderer::QwtPolarRenderer
QwtPolarRenderer(QObject *parent=NULL)
Definition qwt_polar_renderer.cpp:90
QwtPolarRenderer::render
virtual void render(QwtPolarPlot *, QPainter *, const QRectF &rect) const
Render the plot to a given rectangle ( f.e QPrinter, QSvgRenderer )
Definition qwt_polar_renderer.cpp:326
QwtPolarRenderer::renderDocument
void renderDocument(QwtPolarPlot *, const QString &format, const QSizeF &sizeMM, int resolution=85)
Definition qwt_polar_renderer.cpp:113
QwtPolarRenderer::~QwtPolarRenderer
virtual ~QwtPolarRenderer()
Destructor.
Definition qwt_polar_renderer.cpp:97
QwtPolarRenderer::renderLegend
virtual void renderLegend(const QwtPolarPlot *, QPainter *, const QRectF &) const
Definition qwt_polar_renderer.cpp:411
QwtPolarRenderer::renderTo
void renderTo(QwtPolarPlot *, QPrinter &) const
Render the plot to a QPrinter.
Definition qwt_polar_renderer.cpp:273
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
A Widget which displays a QwtText.
Definition qwt_text_label.h:27
QwtTextLabel::text
const QwtText & text() const
Return the text.
Definition qwt_text_label.cpp:118