00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qpainter.h>
00013 #if QT_VERSION < 0x040000
00014 #include <qpaintdevicemetrics.h>
00015 #else
00016 #include <qpaintengine.h>
00017 #endif
00018 #include "qwt_painter.h"
00019 #include "qwt_legend_item.h"
00020 #include "qwt_plot.h"
00021 #include "qwt_plot_canvas.h"
00022 #include "qwt_plot_layout.h"
00023 #include "qwt_legend.h"
00024 #include "qwt_dyngrid_layout.h"
00025 #include "qwt_scale_widget.h"
00026 #include "qwt_scale_engine.h"
00027 #include "qwt_text.h"
00028 #include "qwt_text_label.h"
00029 #include "qwt_math.h"
00030
00043 void QwtPlot::print(QPaintDevice &paintDev,
00044 const QwtPlotPrintFilter &pfilter) const
00045 {
00046 #if QT_VERSION < 0x040000
00047 QPaintDeviceMetrics mpr(&paintDev);
00048 int w = mpr.width();
00049 int h = mpr.height();
00050 #else
00051 int w = paintDev.width();
00052 int h = paintDev.height();
00053 #endif
00054
00055 QRect rect(0, 0, w, h);
00056 double aspect = double(rect.width())/double(rect.height());
00057 if ((aspect < 1.0))
00058 rect.setHeight(int(aspect*rect.width()));
00059
00060 QPainter p(&paintDev);
00061 print(&p, rect, pfilter);
00062 }
00063
00073 void QwtPlot::print(QPainter *painter, const QRect &plotRect,
00074 const QwtPlotPrintFilter &pfilter) const
00075 {
00076 int axisId;
00077
00078 if ( painter == 0 || !painter->isActive() ||
00079 !plotRect.isValid() || size().isNull() )
00080 return;
00081
00082 painter->save();
00083 #if 1
00084
00085
00086
00087
00088
00089 const QPen pen = painter->pen();
00090 painter->setPen(QPen(Qt::black, 1));
00091 painter->setPen(pen);
00092 #endif
00093
00094
00095
00096
00097 QwtPainter::setMetricsMap(this, painter->device());
00098 const QwtMetricsMap &metricsMap = QwtPainter::metricsMap();
00099
00100
00101
00102
00103
00104
00105
00106
00107 pfilter.apply((QwtPlot *)this);
00108
00109 int baseLineDists[QwtPlot::axisCnt];
00110 if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales )
00111 {
00112 for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00113 {
00114 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00115 if ( scaleWidget )
00116 {
00117 baseLineDists[axisId] = scaleWidget->margin();
00118 scaleWidget->setMargin(0);
00119 }
00120 }
00121 }
00122
00123
00124 int layoutOptions = QwtPlotLayout::IgnoreScrollbars
00125 | QwtPlotLayout::IgnoreFrames;
00126 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) )
00127 layoutOptions |= QwtPlotLayout::IgnoreMargin;
00128 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) )
00129 layoutOptions |= QwtPlotLayout::IgnoreLegend;
00130
00131 ((QwtPlot *)this)->plotLayout()->activate(this,
00132 QwtPainter::metricsMap().deviceToLayout(plotRect),
00133 layoutOptions);
00134
00135 if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle)
00136 && (!titleLabel()->text().isEmpty()))
00137 {
00138 printTitle(painter, plotLayout()->titleRect());
00139 }
00140
00141 if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend)
00142 && legend() && !legend()->isEmpty() )
00143 {
00144 printLegend(painter, plotLayout()->legendRect());
00145 }
00146
00147 for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00148 {
00149 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00150 if (scaleWidget)
00151 {
00152 int baseDist = scaleWidget->margin();
00153
00154 int startDist, endDist;
00155 scaleWidget->getBorderDistHint(startDist, endDist);
00156
00157 printScale(painter, axisId, startDist, endDist,
00158 baseDist, plotLayout()->scaleRect(axisId));
00159 }
00160 }
00161
00162 QRect canvasRect = plotLayout()->canvasRect();
00163
00164
00165
00166
00167
00168 QRect boundingRect( canvasRect.left() - 1, canvasRect.top() - 1,
00169 canvasRect.width() + 2, canvasRect.height() + 2);
00170 boundingRect = metricsMap.layoutToDevice(boundingRect);
00171 boundingRect.setWidth(boundingRect.width() - 1);
00172 boundingRect.setHeight(boundingRect.height() - 1);
00173
00174 canvasRect = metricsMap.layoutToDevice(canvasRect);
00175
00176
00177
00178
00179
00180
00181 QwtScaleMap map[axisCnt];
00182 for (axisId = 0; axisId < axisCnt; axisId++)
00183 {
00184 map[axisId].setTransformation(axisScaleEngine(axisId)->transformation());
00185
00186 const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId);
00187 map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound());
00188
00189 double from, to;
00190 if ( axisEnabled(axisId) )
00191 {
00192 const int sDist = axisWidget(axisId)->startBorderDist();
00193 const int eDist = axisWidget(axisId)->endBorderDist();
00194 const QRect &scaleRect = plotLayout()->scaleRect(axisId);
00195
00196 if ( axisId == xTop || axisId == xBottom )
00197 {
00198 from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist);
00199 to = metricsMap.layoutToDeviceX(scaleRect.right() + 1 - eDist);
00200 }
00201 else
00202 {
00203 from = metricsMap.layoutToDeviceY(scaleRect.bottom() + 1 - eDist );
00204 to = metricsMap.layoutToDeviceY(scaleRect.top() + sDist);
00205 }
00206 }
00207 else
00208 {
00209 const int margin = plotLayout()->canvasMargin(axisId);
00210 if ( axisId == yLeft || axisId == yRight )
00211 {
00212 from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin);
00213 to = metricsMap.layoutToDeviceX(canvasRect.top() + margin);
00214 }
00215 else
00216 {
00217 from = metricsMap.layoutToDeviceY(canvasRect.left() + margin);
00218 to = metricsMap.layoutToDeviceY(canvasRect.right() - margin);
00219 }
00220 }
00221 map[axisId].setPaintXInterval(from, to);
00222 }
00223
00224
00225 QwtPainter::setMetricsMap(painter->device(), painter->device());
00226 printCanvas(painter, boundingRect, canvasRect, map, pfilter);
00227 QwtPainter::resetMetricsMap();
00228
00229 ((QwtPlot *)this)->plotLayout()->invalidate();
00230
00231
00232 if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales )
00233 {
00234
00235
00236 for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00237 {
00238 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00239 if ( scaleWidget )
00240 scaleWidget->setMargin(baseLineDists[axisId]);
00241 }
00242 }
00243
00244 pfilter.reset((QwtPlot *)this);
00245
00246 painter->restore();
00247 }
00248
00256 void QwtPlot::printTitle(QPainter *painter, const QRect &rect) const
00257 {
00258 painter->setFont(titleLabel()->font());
00259
00260 const QColor color =
00261 #if QT_VERSION < 0x040000
00262 titleLabel()->palette().color(
00263 QPalette::Active, QColorGroup::Text);
00264 #else
00265 titleLabel()->palette().color(
00266 QPalette::Active, QPalette::Text);
00267 #endif
00268
00269 painter->setPen(color);
00270 titleLabel()->text().draw(painter, rect);
00271 }
00272
00280 void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const
00281 {
00282 if ( !legend() || legend()->isEmpty() )
00283 return;
00284
00285 QLayout *l = legend()->contentsWidget()->layout();
00286 if ( l == 0 || !l->inherits("QwtDynGridLayout") )
00287 return;
00288
00289 QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l;
00290
00291 uint numCols = legendLayout->columnsForWidth(rect.width());
00292 #if QT_VERSION < 0x040000
00293 QValueList<QRect> itemRects =
00294 legendLayout->layoutItems(rect, numCols);
00295 #else
00296 QList<QRect> itemRects =
00297 legendLayout->layoutItems(rect, numCols);
00298 #endif
00299
00300 int index = 0;
00301
00302 #if QT_VERSION < 0x040000
00303 QLayoutIterator layoutIterator = legendLayout->iterator();
00304 for ( QLayoutItem *item = layoutIterator.current();
00305 item != 0; item = ++layoutIterator)
00306 {
00307 #else
00308 for ( int i = 0; i < legendLayout->count(); i++ )
00309 {
00310 QLayoutItem *item = legendLayout->itemAt(i);
00311 #endif
00312 QWidget *w = item->widget();
00313 if ( w )
00314 {
00315 painter->save();
00316 painter->setClipping(true);
00317 QwtPainter::setClipRect(painter, itemRects[index]);
00318
00319 printLegendItem(painter, w, itemRects[index]);
00320
00321 index++;
00322 painter->restore();
00323 }
00324 }
00325 }
00326
00335 void QwtPlot::printLegendItem(QPainter *painter,
00336 const QWidget *w, const QRect &rect) const
00337 {
00338 if ( w->inherits("QwtLegendItem") )
00339 {
00340 QwtLegendItem *item = (QwtLegendItem *)w;
00341
00342 painter->setFont(item->font());
00343 item->drawItem(painter, rect);
00344 }
00345 }
00346
00359 void QwtPlot::printScale(QPainter *painter,
00360 int axisId, int startDist, int endDist, int baseDist,
00361 const QRect &rect) const
00362 {
00363 if (!axisEnabled(axisId))
00364 return;
00365
00366 const QwtScaleWidget *scaleWidget = axisWidget(axisId);
00367 if ( scaleWidget->isColorBarEnabled()
00368 && scaleWidget->colorBarWidth() > 0)
00369 {
00370 const QwtMetricsMap map = QwtPainter::metricsMap();
00371
00372 QRect r = map.layoutToScreen(rect);
00373 r.setWidth(r.width() - 1);
00374 r.setHeight(r.height() - 1);
00375
00376 scaleWidget->drawColorBar(painter, scaleWidget->colorBarRect(r));
00377
00378 const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing();
00379 if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal )
00380 baseDist += map.screenToLayoutY(off);
00381 else
00382 baseDist += map.screenToLayoutX(off);
00383 }
00384
00385 QwtScaleDraw::Alignment align;
00386 int x, y, w;
00387
00388 switch(axisId)
00389 {
00390 case yLeft:
00391 {
00392 x = rect.right() - baseDist;
00393 y = rect.y() + startDist;
00394 w = rect.height() - startDist - endDist;
00395 align = QwtScaleDraw::LeftScale;
00396 break;
00397 }
00398 case yRight:
00399 {
00400 x = rect.left() + baseDist;
00401 y = rect.y() + startDist;
00402 w = rect.height() - startDist - endDist;
00403 align = QwtScaleDraw::RightScale;
00404 break;
00405 }
00406 case xTop:
00407 {
00408 x = rect.left() + startDist;
00409 y = rect.bottom() - baseDist;
00410 w = rect.width() - startDist - endDist;
00411 align = QwtScaleDraw::TopScale;
00412 break;
00413 }
00414 case xBottom:
00415 {
00416 x = rect.left() + startDist;
00417 y = rect.top() + baseDist;
00418 w = rect.width() - startDist - endDist;
00419 align = QwtScaleDraw::BottomScale;
00420 break;
00421 }
00422 default:
00423 return;
00424 }
00425
00426 scaleWidget->drawTitle(painter, align, rect);
00427
00428 painter->save();
00429 painter->setFont(scaleWidget->font());
00430
00431 QPen pen = painter->pen();
00432 pen.setWidth(scaleWidget->penWidth());
00433 painter->setPen(pen);
00434
00435 QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw();
00436 const QPoint sdPos = sd->pos();
00437 const int sdLength = sd->length();
00438
00439 sd->move(x, y);
00440 sd->setLength(w);
00441
00442 #if QT_VERSION < 0x040000
00443 sd->draw(painter, scaleWidget->palette().active());
00444 #else
00445 QPalette palette = scaleWidget->palette();
00446 palette.setCurrentColorGroup(QPalette::Active);
00447 sd->draw(painter, palette);
00448 #endif
00449
00450 sd->move(sdPos);
00451 sd->setLength(sdLength);
00452
00453 painter->restore();
00454 }
00455
00467 void QwtPlot::printCanvas(QPainter *painter,
00468 const QRect &boundingRect, const QRect &canvasRect,
00469 const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const
00470 {
00471 if ( pfilter.options() & QwtPlotPrintFilter::PrintBackground )
00472 {
00473 QBrush bgBrush;
00474 #if QT_VERSION >= 0x040000
00475 bgBrush = canvas()->palette().brush(backgroundRole());
00476 #else
00477 QColorGroup::ColorRole role =
00478 QPalette::backgroundRoleFromMode( backgroundMode() );
00479 bgBrush = canvas()->colorGroup().brush( role );
00480 #endif
00481 QRect r = boundingRect;
00482 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales) )
00483 {
00484 r = canvasRect;
00485 #if QT_VERSION >= 0x040000
00486
00487 switch(painter->paintEngine()->type() )
00488 {
00489 case QPaintEngine::Raster:
00490 case QPaintEngine::X11:
00491 break;
00492 default:
00493 r.setWidth(r.width() - 1);
00494 r.setHeight(r.height() - 1);
00495 break;
00496 }
00497 #else
00498 if ( painter->device()->isExtDev() )
00499 {
00500 r.setWidth(r.width() - 1);
00501 r.setHeight(r.height() - 1);
00502 }
00503 #endif
00504 }
00505
00506 QwtPainter::fillRect(painter, r, bgBrush);
00507 }
00508
00509 if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales )
00510 {
00511 painter->save();
00512 painter->setPen(QPen(Qt::black));
00513 painter->setBrush(QBrush(Qt::NoBrush));
00514 QwtPainter::drawRect(painter, boundingRect);
00515 painter->restore();
00516 }
00517
00518 painter->setClipping(true);
00519 QwtPainter::setClipRect(painter, canvasRect);
00520
00521 drawItems(painter, canvasRect, map, pfilter);
00522 }