qwt_polar_renderer.cpp
Go to the documentation of this file.
1 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
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 
76 {
77 public:
79  plot( NULL )
80  {
81  }
82 
84 };
85 
91  QObject( parent )
92 {
93  d_data = new PrivateData;
94 }
95 
98 {
99  delete d_data;
100 }
101 
114  const QString &fileName, const QSizeF &sizeMM, int resolution )
115 {
116  renderDocument( plot, fileName,
117  QFileInfo( fileName ).suffix(), sizeMM, resolution );
118 }
119 
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 
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 
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 
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 
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  d_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 =
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  d_data->plot = NULL;
382 }
383 
391 void QwtPolarRenderer::renderTitle( QPainter *painter, const QRectF &rect ) const
392 {
393  QwtTextLabel *title = d_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 
412  QPainter *painter, const QRectF &rect ) const
413 {
414  if ( plot->legend() )
415  plot->legend()->renderLegend( painter, rect, true );
416 }
417 
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
const QRectF & legendRect() const
A plotting widget, displaying a polar coordinate system.
const QRectF & canvasRect() const
virtual ~QwtPolarRenderer()
Destructor.
FMT_INLINE std::basic_string< Char > format(const S &format_str, Args &&...args)
Definition: core.h:2081
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.
QwtPolarLayout * plotLayout()
A Widget which displays a QwtText.
QwtText title() const
const QRectF & titleRect() const
virtual void drawCanvas(QPainter *, const QRectF &) const
virtual void activate(const QwtPolarPlot *, const QRectF &rect, Options options=Options())
Recalculate the geometry of all components.
void draw(QPainter *painter, const QRectF &rect) const
Definition: qwt_text.cpp:592
const QwtText & text() const
Return the text.
QFlags< Option > Options
Options to configure the plot layout engine.
void renderTo(QwtPolarPlot *, QPrinter &) const
Render the plot to a QPrinter.
virtual void invalidate()
PrivateData * d_data
QwtTextLabel * titleLabel()
virtual void renderLegend(const QwtPolarPlot *, QPainter *, const QRectF &) const
QString text() const
Definition: qwt_text.cpp:266
virtual void renderTitle(QPainter *, const QRectF &) const
static double qwtDistance(const QPointF &p1, const QPointF &p2)
virtual void renderLegend(QPainter *painter, const QRectF &rect, bool fillBackground) const =0
QwtAbstractLegend * legend()
QwtPolarRenderer(QObject *parent=NULL)
virtual void render(QwtPolarPlot *, QPainter *, const QRectF &rect) const
Render the plot to a given rectangle ( f.e QPrinter, QSvgRenderer )
Ignore the dimension of the scrollbars.
Layout class for QwtPolarPlot.
void renderDocument(QwtPolarPlot *, const QString &format, const QSizeF &sizeMM, int resolution=85)


plotjuggler
Author(s): Davide Faconti
autogenerated on Sun Dec 6 2020 03:48:10