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 int margin = plotLayout()->canvasMargin(axisId);
00210 if ( axisId == yLeft || axisId == yRight )
00211 {
00212 margin = metricsMap.layoutToDeviceY(margin);
00213 from = canvasRect.bottom() - margin;
00214 to = canvasRect.top() + margin;
00215 }
00216 else
00217 {
00218 margin = metricsMap.layoutToDeviceX(margin);
00219 from = canvasRect.left() + margin;
00220 to = canvasRect.right() - margin;
00221 }
00222 }
00223 map[axisId].setPaintXInterval(from, to);
00224 }
00225
00226
00227 QwtPainter::setMetricsMap(painter->device(), painter->device());
00228 printCanvas(painter, boundingRect, canvasRect, map, pfilter);
00229 QwtPainter::resetMetricsMap();
00230
00231 ((QwtPlot *)this)->plotLayout()->invalidate();
00232
00233
00234 if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales )
00235 {
00236
00237
00238 for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00239 {
00240 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00241 if ( scaleWidget )
00242 scaleWidget->setMargin(baseLineDists[axisId]);
00243 }
00244 }
00245
00246 pfilter.reset((QwtPlot *)this);
00247
00248 painter->restore();
00249 }
00250
00258 void QwtPlot::printTitle(QPainter *painter, const QRect &rect) const
00259 {
00260 painter->setFont(titleLabel()->font());
00261
00262 const QColor color =
00263 #if QT_VERSION < 0x040000
00264 titleLabel()->palette().color(
00265 QPalette::Active, QColorGroup::Text);
00266 #else
00267 titleLabel()->palette().color(
00268 QPalette::Active, QPalette::Text);
00269 #endif
00270
00271 painter->setPen(color);
00272 titleLabel()->text().draw(painter, rect);
00273 }
00274
00282 void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const
00283 {
00284 if ( !legend() || legend()->isEmpty() )
00285 return;
00286
00287 QLayout *l = legend()->contentsWidget()->layout();
00288 if ( l == 0 || !l->inherits("QwtDynGridLayout") )
00289 return;
00290
00291 QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l;
00292
00293 uint numCols = legendLayout->columnsForWidth(rect.width());
00294 #if QT_VERSION < 0x040000
00295 QValueList<QRect> itemRects =
00296 legendLayout->layoutItems(rect, numCols);
00297 #else
00298 QList<QRect> itemRects =
00299 legendLayout->layoutItems(rect, numCols);
00300 #endif
00301
00302 int index = 0;
00303
00304 #if QT_VERSION < 0x040000
00305 QLayoutIterator layoutIterator = legendLayout->iterator();
00306 for ( QLayoutItem *item = layoutIterator.current();
00307 item != 0; item = ++layoutIterator)
00308 {
00309 #else
00310 for ( int i = 0; i < legendLayout->count(); i++ )
00311 {
00312 QLayoutItem *item = legendLayout->itemAt(i);
00313 #endif
00314 QWidget *w = item->widget();
00315 if ( w )
00316 {
00317 painter->save();
00318 painter->setClipping(true);
00319 QwtPainter::setClipRect(painter, itemRects[index]);
00320
00321 printLegendItem(painter, w, itemRects[index]);
00322
00323 index++;
00324 painter->restore();
00325 }
00326 }
00327 }
00328
00337 void QwtPlot::printLegendItem(QPainter *painter,
00338 const QWidget *w, const QRect &rect) const
00339 {
00340 if ( w->inherits("QwtLegendItem") )
00341 {
00342 QwtLegendItem *item = (QwtLegendItem *)w;
00343
00344 painter->setFont(item->font());
00345 item->drawItem(painter, rect);
00346 }
00347 }
00348
00361 void QwtPlot::printScale(QPainter *painter,
00362 int axisId, int startDist, int endDist, int baseDist,
00363 const QRect &rect) const
00364 {
00365 if (!axisEnabled(axisId))
00366 return;
00367
00368 const QwtScaleWidget *scaleWidget = axisWidget(axisId);
00369 if ( scaleWidget->isColorBarEnabled()
00370 && scaleWidget->colorBarWidth() > 0)
00371 {
00372 const QwtMetricsMap map = QwtPainter::metricsMap();
00373
00374 QRect r = map.layoutToScreen(rect);
00375 r.setWidth(r.width() - 1);
00376 r.setHeight(r.height() - 1);
00377
00378 scaleWidget->drawColorBar(painter, scaleWidget->colorBarRect(r));
00379
00380 const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing();
00381 if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal )
00382 baseDist += map.screenToLayoutY(off);
00383 else
00384 baseDist += map.screenToLayoutX(off);
00385 }
00386
00387 QwtScaleDraw::Alignment align;
00388 int x, y, w;
00389
00390 switch(axisId)
00391 {
00392 case yLeft:
00393 {
00394 x = rect.right() - baseDist;
00395 y = rect.y() + startDist;
00396 w = rect.height() - startDist - endDist;
00397 align = QwtScaleDraw::LeftScale;
00398 break;
00399 }
00400 case yRight:
00401 {
00402 x = rect.left() + baseDist;
00403 y = rect.y() + startDist;
00404 w = rect.height() - startDist - endDist;
00405 align = QwtScaleDraw::RightScale;
00406 break;
00407 }
00408 case xTop:
00409 {
00410 x = rect.left() + startDist;
00411 y = rect.bottom() - baseDist;
00412 w = rect.width() - startDist - endDist;
00413 align = QwtScaleDraw::TopScale;
00414 break;
00415 }
00416 case xBottom:
00417 {
00418 x = rect.left() + startDist;
00419 y = rect.top() + baseDist;
00420 w = rect.width() - startDist - endDist;
00421 align = QwtScaleDraw::BottomScale;
00422 break;
00423 }
00424 default:
00425 return;
00426 }
00427
00428 scaleWidget->drawTitle(painter, align, rect);
00429
00430 painter->save();
00431 painter->setFont(scaleWidget->font());
00432
00433 QPen pen = painter->pen();
00434 pen.setWidth(scaleWidget->penWidth());
00435 painter->setPen(pen);
00436
00437 QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw();
00438 const QPoint sdPos = sd->pos();
00439 const int sdLength = sd->length();
00440
00441 sd->move(x, y);
00442 sd->setLength(w);
00443
00444 #if QT_VERSION < 0x040000
00445 sd->draw(painter, scaleWidget->palette().active());
00446 #else
00447 QPalette palette = scaleWidget->palette();
00448 palette.setCurrentColorGroup(QPalette::Active);
00449 sd->draw(painter, palette);
00450 #endif
00451
00452 sd->move(sdPos);
00453 sd->setLength(sdLength);
00454
00455 painter->restore();
00456 }
00457
00469 void QwtPlot::printCanvas(QPainter *painter,
00470 const QRect &boundingRect, const QRect &canvasRect,
00471 const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const
00472 {
00473 if ( pfilter.options() & QwtPlotPrintFilter::PrintBackground )
00474 {
00475 QBrush bgBrush;
00476 #if QT_VERSION >= 0x040000
00477 bgBrush = canvas()->palette().brush(backgroundRole());
00478 #else
00479 QColorGroup::ColorRole role =
00480 QPalette::backgroundRoleFromMode( backgroundMode() );
00481 bgBrush = canvas()->colorGroup().brush( role );
00482 #endif
00483 QRect r = boundingRect;
00484 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales) )
00485 {
00486 r = canvasRect;
00487 #if QT_VERSION >= 0x040000
00488
00489 const QPaintEngine *pe = painter->paintEngine();
00490 if ( pe )
00491 {
00492 switch(painter->paintEngine()->type() )
00493 {
00494 case QPaintEngine::Raster:
00495 case QPaintEngine::X11:
00496 break;
00497 default:
00498 r.setWidth(r.width() - 1);
00499 r.setHeight(r.height() - 1);
00500 break;
00501 }
00502 }
00503 #else
00504 if ( painter->device()->isExtDev() )
00505 {
00506 r.setWidth(r.width() - 1);
00507 r.setHeight(r.height() - 1);
00508 }
00509 #endif
00510 }
00511
00512 QwtPainter::fillRect(painter, r, bgBrush);
00513 }
00514
00515 if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales )
00516 {
00517 painter->save();
00518 painter->setPen(QPen(Qt::black));
00519 painter->setBrush(QBrush(Qt::NoBrush));
00520 QwtPainter::drawRect(painter, boundingRect);
00521 painter->restore();
00522 }
00523
00524 painter->setClipping(true);
00525 QwtPainter::setClipRect(painter, canvasRect);
00526
00527 drawItems(painter, canvasRect, map, pfilter);
00528 }