Qwt User's Guide: qwt_polar_renderer.cpp Source File

Qwt User's Guide 6.2.0

qwt_polar_renderer.cpp
1 /******************************************************************************
2 * QwtPolar Widget Library
3 * Copyright (C) 2008 Uwe Rathmann
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the Qwt License, Version 1.0
7 *****************************************************************************/
8
9 #include "qwt_polar_renderer.h"
10 #include "qwt_polar_plot.h"
11 #include "qwt_polar_layout.h"
12 #include "qwt_legend.h"
13 #include "qwt_dyngrid_layout.h"
14 #include "qwt_text_label.h"
15 #include "qwt_text.h"
16
17 #include <qpainter.h>
18 #include <qprinter.h>
19 #include <qprintdialog.h>
20 #include <qfiledialog.h>
21 #include <qimagewriter.h>
22 #include <qfileinfo.h>
23 #include <qmath.h>
24
25 #ifndef QWT_NO_SVG
26 #ifdef QT_SVG_LIB
27 #define QWT_FORMAT_SVG 1
28 #endif
29 #endif
30
31 #ifndef QT_NO_PRINTER
32 #define QWT_FORMAT_PDF 1
33 #endif
34
35 #ifndef QT_NO_PDF
36
37 // QPdfWriter::setResolution() has been introduced with
38 // Qt 5.3. Guess it is o.k. to stay with QPrinter for older
39 // versions.
40
41 #if QT_VERSION >= 0x050300
42
43 #ifndef QWT_FORMAT_PDF
44 #define QWT_FORMAT_PDF 1
45 #endif
46
47 #define QWT_PDF_WRITER 1
48
49 #endif
50 #endif
51
52 #ifndef QT_NO_PRINTER
53 // postscript support has been dropped in Qt5
54 #if QT_VERSION < 0x050000
55 #define QWT_FORMAT_POSTSCRIPT 1
56 #endif
57 #endif
58
59 #if QWT_FORMAT_SVG
60 #include <qsvggenerator.h>
61 #endif
62
63 #if QWT_PDF_WRITER
64 #include <qpdfwriter.h>
65 #endif
66
67 static inline double qwtDistance(
68 const QPointF& p1, const QPointF& p2 )
69 {
70 double dx = p2.x() - p1.x();
71 double dy = p2.y() - p1.y();
72 return qSqrt( dx * dx + dy * dy );
73 }
74
75 class QwtPolarRenderer::PrivateData
76 {
77 public:
78 PrivateData()
79 : plot( NULL )
80 {
81 }
82
83 QwtPolarPlot* plot;
84 };
85
90 QwtPolarRenderer::QwtPolarRenderer( QObject* parent )
91 : QObject( parent )
92 {
93 m_data = new PrivateData;
94 }
95
97 QwtPolarRenderer::~QwtPolarRenderer()
98 {
99 delete m_data;
100 }
101
113 void QwtPolarRenderer::renderDocument( QwtPolarPlot* plot,
114 const QString& fileName, const QSizeF& sizeMM, int resolution )
115 {
116 renderDocument( plot, fileName,
117 QFileInfo( fileName ).suffix(), sizeMM, resolution );
118 }
119
138 void QwtPolarRenderer::renderDocument( QwtPolarPlot* plot,
139 const QString& fileName, const QString& format,
140 const QSizeF& sizeMM, int resolution )
141 {
142 if ( plot == NULL || sizeMM.isEmpty() || resolution <= 0 )
143 return;
144
145 QString title = plot->title().text();
146 if ( title.isEmpty() )
147 title = "Plot Document";
148
149 const double mmToInch = 1.0 / 25.4;
150 const QSizeF size = sizeMM * mmToInch * resolution;
151
152 const QRectF documentRect( 0.0, 0.0, size.width(), size.height() );
153
154 const QString fmt = format.toLower();
155 if ( format == "pdf" )
156 {
157 #if QWT_FORMAT_PDF
158 #if QWT_PDF_WRITER
159 QPdfWriter pdfWriter( fileName );
160 pdfWriter.setPageSize( QPageSize( sizeMM, QPageSize::Millimeter ) );
161 pdfWriter.setTitle( title );
162 pdfWriter.setPageMargins( QMarginsF() );
163 pdfWriter.setResolution( resolution );
164
165 QPainter painter( &pdfWriter );
166 render( plot, &painter, documentRect );
167
168 #else
169 QPrinter printer;
170 printer.setOutputFormat( QPrinter::PdfFormat );
171 printer.setColorMode( QPrinter::Color );
172 printer.setFullPage( true );
173 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
174 printer.setDocName( title );
175 printer.setOutputFileName( fileName );
176 printer.setResolution( resolution );
177
178 QPainter painter( &printer );
179 render( plot, &painter, documentRect );
180 #endif
181 #endif
182 }
183 else if ( format == "ps" )
184 {
185 #if QWT_FORMAT_POSTSCRIPT
186 QPrinter printer;
187 printer.setColorMode( QPrinter::Color );
188 printer.setFullPage( true );
189 printer.setPaperSize( sizeMM, QPrinter::Millimeter );
190 printer.setDocName( title );
191 printer.setOutputFileName( fileName );
192 printer.setOutputFormat( QPrinter::PostScriptFormat );
193 printer.setResolution( resolution );
194
195 QPainter painter( &printer );
196 render( plot, &painter, documentRect );
197 #endif
198 }
199 else if ( format == "svg" )
200 {
201 #ifdef QWT_FORMAT_SVG
202 QSvgGenerator generator;
203 generator.setTitle( title );
204 generator.setFileName( fileName );
205 generator.setResolution( resolution );
206 generator.setViewBox( documentRect );
207
208 QPainter painter( &generator );
209 render( plot, &painter, documentRect );
210 #endif
211 }
212 else
213 {
214 if ( QImageWriter::supportedImageFormats().indexOf(
215 format.toLatin1() ) >= 0 )
216 {
217 const QRect imageRect = documentRect.toRect();
218 const int dotsPerMeter = qRound( resolution * mmToInch * 1000.0 );
219
220 QImage image( imageRect.size(), QImage::Format_ARGB32 );
221 image.setDotsPerMeterX( dotsPerMeter );
222 image.setDotsPerMeterY( dotsPerMeter );
223 image.fill( QColor( Qt::white ).rgb() );
224
225 QPainter painter( &image );
226 render( plot, &painter, imageRect );
227 painter.end();
228
229 image.save( fileName, format.toLatin1() );
230 }
231 }
232 }
233
247 void QwtPolarRenderer::renderTo(
248 QwtPolarPlot* plot, QPaintDevice& paintDevice ) const
249 {
250 int w = paintDevice.width();
251 int h = paintDevice.height();
252
253 QPainter p( &paintDevice );
254 render( plot, &p, QRectF( 0, 0, w, h ) );
255 }
256
257
271 #ifndef QT_NO_PRINTER
272
273 void QwtPolarRenderer::renderTo(
274 QwtPolarPlot* plot, QPrinter& printer ) const
275 {
276 int w = printer.width();
277 int h = printer.height();
278
279 QRectF rect( 0, 0, w, h );
280 double aspect = rect.width() / rect.height();
281 if ( ( aspect < 1.0 ) )
282 rect.setHeight( aspect * rect.width() );
283
284 QPainter p( &printer );
285 render( plot, &p, rect );
286 }
287
288 #endif
289
290 #ifdef QWT_FORMAT_SVG
291
303 void QwtPolarRenderer::renderTo(
304 QwtPolarPlot* plot, QSvgGenerator& generator ) const
305 {
306 QRectF rect = generator.viewBoxF();
307 if ( rect.isEmpty() )
308 rect.setRect( 0, 0, generator.width(), generator.height() );
309
310 if ( rect.isEmpty() )
311 rect.setRect( 0, 0, 800, 600 ); // something
312
313 QPainter p( &generator );
314 render( plot, &p, rect );
315 }
316
317 #endif
318
326 void QwtPolarRenderer::render( QwtPolarPlot* plot,
327 QPainter* painter, const QRectF& plotRect ) const
328 {
329 if ( plot == NULL || painter == NULL || !painter->isActive() ||
330 !plotRect.isValid() || plot->size().isNull() )
331 {
332 return;
333 }
334
335 m_data->plot = plot;
336
337 /*
338 The layout engine uses the same methods as they are used
339 by the Qt layout system. Therefore we need to calculate the
340 layout in screen coordinates and paint with a scaled painter.
341 */
342 QTransform transform;
343 transform.scale(
344 double( painter->device()->logicalDpiX() ) / plot->logicalDpiX(),
345 double( painter->device()->logicalDpiY() ) / plot->logicalDpiY() );
346
347 const QRectF layoutRect = transform.inverted().mapRect( plotRect );
348
349 QwtPolarLayout* layout = plot->plotLayout();
350
351 // All paint operations need to be scaled according to
352 // the paint device metrics.
353
354 QwtPolarLayout::Options layoutOptions =
355 QwtPolarLayout::IgnoreScrollbars | QwtPolarLayout::IgnoreFrames;
356
357 layout->activate( plot, layoutRect, layoutOptions );
358
359 painter->save();
360 painter->setWorldTransform( transform, true );
361
362 painter->save();
363 renderTitle( painter, layout->titleRect() );
364 painter->restore();
365
366 painter->save();
367 renderLegend( plot, painter, layout->legendRect() );
368 painter->restore();
369
370 const QRectF canvasRect = layout->canvasRect();
371
372 painter->save();
373 painter->setClipRect( canvasRect );
374 plot->drawCanvas( painter, canvasRect );
375 painter->restore();
376
377 painter->restore();
378
379 layout->invalidate();
380
381 m_data->plot = NULL;
382 }
383
391 void QwtPolarRenderer::renderTitle( QPainter* painter, const QRectF& rect ) const
392 {
393 QwtTextLabel* title = m_data->plot->titleLabel();
394
395 painter->setFont( title->font() );
396
397 const QColor color = title->palette().color(
398 QPalette::Active, QPalette::Text );
399
400 painter->setPen( color );
401 title->text().draw( painter, rect );
402 }
403
411 void QwtPolarRenderer::renderLegend( const QwtPolarPlot* plot,
412 QPainter* painter, const QRectF& rect ) const
413 {
414 if ( plot->legend() )
415 plot->legend()->renderLegend( painter, rect, true );
416 }
417
430 bool QwtPolarRenderer::exportTo( QwtPolarPlot* plot,
431 const QString& documentName, const QSizeF& sizeMM, int resolution )
432 {
433 if ( plot == NULL )
434 return false;
435
436 QString fileName = documentName;
437
438 // What about translation
439
440 #ifndef QT_NO_FILEDIALOG
441 const QList< QByteArray > imageFormats =
442 QImageWriter::supportedImageFormats();
443
444 QStringList filter;
445 #ifndef QT_NO_PRINTER
446 filter += QString( "PDF " ) + tr( "Documents" ) + " (*.pdf)";
447 #endif
448 #ifndef QWT_NO_SVG
449 filter += QString( "SVG " ) + tr( "Documents" ) + " (*.svg)";
450 #endif
451 #ifndef QT_NO_PRINTER
452 filter += QString( "Postscript " ) + tr( "Documents" ) + " (*.ps)";
453 #endif
454
455 if ( imageFormats.size() > 0 )
456 {
457 QString imageFilter( tr( "Images" ) );
458 imageFilter += " (";
459 for ( int i = 0; i < imageFormats.size(); i++ )
460 {
461 if ( i > 0 )
462 imageFilter += " ";
463 imageFilter += "*.";
464 imageFilter += imageFormats[i];
465 }
466 imageFilter += ")";
467
468 filter += imageFilter;
469 }
470
471 fileName = QFileDialog::getSaveFileName(
472 NULL, tr( "Export File Name" ), fileName,
473 filter.join( ";;" ), NULL, QFileDialog::DontConfirmOverwrite );
474 #endif
475 if ( fileName.isEmpty() )
476 return false;
477
478 renderDocument( plot, fileName, sizeMM, resolution );
479
480 return true;
481 }
482
483 #if QWT_MOC_INCLUDE
484 #include "moc_qwt_polar_renderer.cpp"
485 #endif
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
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