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_rect.h"
00025 #include "qwt_dyngrid_layout.h"
00026 #include "qwt_scale_widget.h"
00027 #include "qwt_scale_engine.h"
00028 #include "qwt_text.h"
00029 #include "qwt_text_label.h"
00030 #include "qwt_math.h"
00031
00044 void QwtPlot::print(QPaintDevice &paintDev,
00045 const QwtPlotPrintFilter &pfilter) const
00046 {
00047 #if QT_VERSION < 0x040000
00048 QPaintDeviceMetrics mpr(&paintDev);
00049 int w = mpr.width();
00050 int h = mpr.height();
00051 #else
00052 int w = paintDev.width();
00053 int h = paintDev.height();
00054 #endif
00055
00056 QRect rect(0, 0, w, h);
00057 double aspect = double(rect.width())/double(rect.height());
00058 if ((aspect < 1.0))
00059 rect.setHeight(int(aspect*rect.width()));
00060
00061 QPainter p(&paintDev);
00062 print(&p, rect, pfilter);
00063 }
00064
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
00085
00086
00087
00088 QwtPainter::setMetricsMap(this, painter->device());
00089 const QwtMetricsMap &metricsMap = QwtPainter::metricsMap();
00090
00091
00092
00093
00094
00095
00096
00097
00098 pfilter.apply((QwtPlot *)this);
00099
00100 int baseLineDists[QwtPlot::axisCnt];
00101 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) )
00102 {
00103
00104
00105
00106 for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00107 {
00108 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00109 if ( scaleWidget )
00110 {
00111 baseLineDists[axisId] = scaleWidget->margin();
00112 scaleWidget->setMargin(0);
00113 }
00114 }
00115 }
00116
00117
00118 int layoutOptions = QwtPlotLayout::IgnoreScrollbars
00119 | QwtPlotLayout::IgnoreFrames;
00120 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) )
00121 layoutOptions |= QwtPlotLayout::IgnoreMargin;
00122 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) )
00123 layoutOptions |= QwtPlotLayout::IgnoreLegend;
00124
00125 ((QwtPlot *)this)->plotLayout()->activate(this,
00126 QwtPainter::metricsMap().deviceToLayout(plotRect),
00127 layoutOptions);
00128
00129 if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle)
00130 && (!titleLabel()->text().isEmpty()))
00131 {
00132 printTitle(painter, plotLayout()->titleRect());
00133 }
00134
00135 if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend)
00136 && legend() && !legend()->isEmpty() )
00137 {
00138 printLegend(painter, plotLayout()->legendRect());
00139 }
00140
00141 for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00142 {
00143 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00144 if (scaleWidget)
00145 {
00146 int baseDist = scaleWidget->margin();
00147
00148 int startDist, endDist;
00149 scaleWidget->getBorderDistHint(startDist, endDist);
00150
00151 printScale(painter, axisId, startDist, endDist,
00152 baseDist, plotLayout()->scaleRect(axisId));
00153 }
00154 }
00155
00156 const QRect canvasRect = metricsMap.layoutToDevice(plotLayout()->canvasRect());
00157
00158
00159
00160
00161
00162
00163 QwtScaleMap map[axisCnt];
00164 for (axisId = 0; axisId < axisCnt; axisId++)
00165 {
00166 map[axisId].setTransformation(axisScaleEngine(axisId)->transformation());
00167
00168 const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId);
00169 map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound());
00170
00171 double from, to;
00172 if ( axisEnabled(axisId) )
00173 {
00174 const int sDist = axisWidget(axisId)->startBorderDist();
00175 const int eDist = axisWidget(axisId)->endBorderDist();
00176 const QRect &scaleRect = plotLayout()->scaleRect(axisId);
00177
00178 if ( axisId == xTop || axisId == xBottom )
00179 {
00180 from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist);
00181 to = metricsMap.layoutToDeviceX(scaleRect.right() - eDist);
00182 }
00183 else
00184 {
00185 from = metricsMap.layoutToDeviceY(scaleRect.bottom() - eDist);
00186 to = metricsMap.layoutToDeviceY(scaleRect.top() + sDist);
00187 }
00188 }
00189 else
00190 {
00191 const int margin = plotLayout()->canvasMargin(axisId);
00192
00193 const QRect &canvasRect = plotLayout()->canvasRect();
00194 if ( axisId == yLeft || axisId == yRight )
00195 {
00196 from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin);
00197 to = metricsMap.layoutToDeviceX(canvasRect.top() + margin);
00198 }
00199 else
00200 {
00201 from = metricsMap.layoutToDeviceY(canvasRect.left() + margin);
00202 to = metricsMap.layoutToDeviceY(canvasRect.right() - margin);
00203 }
00204 }
00205 map[axisId].setPaintXInterval(from, to);
00206 }
00207
00208
00209
00210 QwtPainter::setMetricsMap(painter->device(), painter->device());
00211
00212 printCanvas(painter, canvasRect, map, pfilter);
00213
00214 QwtPainter::resetMetricsMap();
00215
00216 ((QwtPlot *)this)->plotLayout()->invalidate();
00217
00218
00219 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) )
00220 {
00221
00222
00223 for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ )
00224 {
00225 QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId);
00226 if ( scaleWidget )
00227 scaleWidget->setMargin(baseLineDists[axisId]);
00228 }
00229 }
00230
00231 pfilter.reset((QwtPlot *)this);
00232
00233 painter->restore();
00234 }
00235
00243 void QwtPlot::printTitle(QPainter *painter, const QRect &rect) const
00244 {
00245 painter->setFont(titleLabel()->font());
00246
00247 const QColor color =
00248 #if QT_VERSION < 0x040000
00249 titleLabel()->palette().color(
00250 QPalette::Active, QColorGroup::Text);
00251 #else
00252 titleLabel()->palette().color(
00253 QPalette::Active, QPalette::Text);
00254 #endif
00255
00256 painter->setPen(color);
00257 titleLabel()->text().draw(painter, rect);
00258 }
00259
00267 void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const
00268 {
00269 if ( !legend() || legend()->isEmpty() )
00270 return;
00271
00272 QLayout *l = legend()->contentsWidget()->layout();
00273 if ( l == 0 || !l->inherits("QwtDynGridLayout") )
00274 return;
00275
00276 QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l;
00277
00278 uint numCols = legendLayout->columnsForWidth(rect.width());
00279 #if QT_VERSION < 0x040000
00280 QValueList<QRect> itemRects =
00281 legendLayout->layoutItems(rect, numCols);
00282 #else
00283 QList<QRect> itemRects =
00284 legendLayout->layoutItems(rect, numCols);
00285 #endif
00286
00287 int index = 0;
00288
00289 #if QT_VERSION < 0x040000
00290 QLayoutIterator layoutIterator = legendLayout->iterator();
00291 for ( QLayoutItem *item = layoutIterator.current();
00292 item != 0; item = ++layoutIterator)
00293 {
00294 #else
00295 for ( int i = 0; i < legendLayout->count(); i++ )
00296 {
00297 QLayoutItem *item = legendLayout->itemAt(i);
00298 #endif
00299 QWidget *w = item->widget();
00300 if ( w )
00301 {
00302 painter->save();
00303 painter->setClipping(true);
00304 QwtPainter::setClipRect(painter, itemRects[index]);
00305
00306 printLegendItem(painter, w, itemRects[index]);
00307
00308 index++;
00309 painter->restore();
00310 }
00311 }
00312 }
00313
00322 void QwtPlot::printLegendItem(QPainter *painter,
00323 const QWidget *w, const QRect &rect) const
00324 {
00325 if ( w->inherits("QwtLegendItem") )
00326 {
00327 QwtLegendItem *item = (QwtLegendItem *)w;
00328
00329 painter->setFont(item->font());
00330 item->drawItem(painter, rect);
00331 }
00332 }
00333
00346 void QwtPlot::printScale(QPainter *painter,
00347 int axisId, int startDist, int endDist, int baseDist,
00348 const QRect &rect) const
00349 {
00350 if (!axisEnabled(axisId))
00351 return;
00352
00353 const QwtScaleWidget *scaleWidget = axisWidget(axisId);
00354 if ( scaleWidget->isColorBarEnabled()
00355 && scaleWidget->colorBarWidth() > 0)
00356 {
00357 const QwtMetricsMap map = QwtPainter::metricsMap();
00358
00359 const QRect r = map.layoutToScreen(rect);
00360 scaleWidget->drawColorBar(painter, scaleWidget->colorBarRect(r));
00361
00362 const int off = scaleWidget->colorBarWidth() + scaleWidget->spacing();
00363 if ( scaleWidget->scaleDraw()->orientation() == Qt::Horizontal )
00364 baseDist += map.screenToLayoutY(off);
00365 else
00366 baseDist += map.screenToLayoutX(off);
00367 }
00368
00369 QwtScaleDraw::Alignment align;
00370 int x, y, w;
00371
00372 switch(axisId)
00373 {
00374 case yLeft:
00375 {
00376 x = rect.right() - baseDist + 1;
00377 y = rect.y() + startDist;
00378 w = rect.height() - startDist - endDist;
00379 align = QwtScaleDraw::LeftScale;
00380 break;
00381 }
00382 case yRight:
00383 {
00384 x = rect.left() + baseDist;
00385 y = rect.y() + startDist;
00386 w = rect.height() - startDist - endDist;
00387 align = QwtScaleDraw::RightScale;
00388 break;
00389 }
00390 case xTop:
00391 {
00392 x = rect.left() + startDist;
00393 y = rect.bottom() - baseDist + 1;
00394 w = rect.width() - startDist - endDist;
00395 align = QwtScaleDraw::TopScale;
00396 break;
00397 }
00398 case xBottom:
00399 {
00400 x = rect.left() + startDist;
00401 y = rect.top() + baseDist;
00402 w = rect.width() - startDist - endDist;
00403 align = QwtScaleDraw::BottomScale;
00404 break;
00405 }
00406 default:
00407 return;
00408 }
00409
00410 scaleWidget->drawTitle(painter, align, rect);
00411
00412 painter->save();
00413 painter->setFont(scaleWidget->font());
00414
00415 QPen pen = painter->pen();
00416 pen.setWidth(scaleWidget->penWidth());
00417 painter->setPen(pen);
00418
00419 QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw();
00420 const QPoint sdPos = sd->pos();
00421 const int sdLength = sd->length();
00422
00423 sd->move(x, y);
00424 sd->setLength(w);
00425
00426 #if QT_VERSION < 0x040000
00427 sd->draw(painter, scaleWidget->palette().active());
00428 #else
00429 QPalette palette = scaleWidget->palette();
00430 palette.setCurrentColorGroup(QPalette::Active);
00431 sd->draw(painter, palette);
00432 #endif
00433
00434 sd->move(sdPos);
00435 sd->setLength(sdLength);
00436
00437 painter->restore();
00438 }
00439
00450 void QwtPlot::printCanvas(QPainter *painter, const QRect &canvasRect,
00451 const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const
00452 {
00453 if ( pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground )
00454 {
00455 painter->setPen(Qt::NoPen);
00456
00457 QBrush bgBrush;
00458 #if QT_VERSION >= 0x040000
00459 bgBrush = canvas()->palette().brush(backgroundRole());
00460 #else
00461 QColorGroup::ColorRole role =
00462 QPalette::backgroundRoleFromMode( backgroundMode() );
00463 bgBrush = canvas()->colorGroup().brush( role );
00464 #endif
00465 painter->setBrush(bgBrush);
00466
00467 int x1 = 0;
00468 int x2 = 0;
00469 int y1 = 0;
00470 int y2 = 0;
00471
00472 #if QT_VERSION >= 0x040000
00473 switch(painter->device()->paintEngine()->type())
00474 {
00475 case QPaintEngine::PostScript:
00476 x2 = 1;
00477 y2 = 1;
00478 break;
00479 default:;
00480 }
00481 #endif
00482
00483 const QwtMetricsMap map = QwtPainter::metricsMap();
00484 x1 = map.screenToLayoutX(x1);
00485 x2 = map.screenToLayoutX(x2);
00486 y1 = map.screenToLayoutY(y1);
00487 y2 = map.screenToLayoutY(y2);
00488
00489 QwtPainter::drawRect(painter,
00490 canvasRect.x() + x1, canvasRect.y() + y1,
00491 canvasRect.width() - x2, canvasRect.height() - y2);
00492 }
00493 else
00494 {
00495
00496 painter->setPen(QPen(Qt::black));
00497 painter->setBrush(QBrush(Qt::NoBrush));
00498 QwtPainter::drawRect(painter, canvasRect);
00499 }
00500
00501
00502 painter->setClipping(true);
00503 QwtPainter::setClipRect(painter, canvasRect);
00504
00505 drawItems(painter, canvasRect, map, pfilter);
00506 }