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