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->baseLineDist();
00112 scaleWidget->setBaselineDist(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->baseLineDist();
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 QwtArray<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() - sDist);
00186 to = metricsMap.layoutToDeviceY(scaleRect.top() + eDist);
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->setBaselineDist(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 QwtScaleDraw::Alignment align;
00354 int x, y, w;
00355
00356 switch(axisId)
00357 {
00358 case yLeft:
00359 {
00360 x = rect.right() - baseDist + 1;
00361 y = rect.y() + startDist;
00362 w = rect.height() - startDist - endDist;
00363 align = QwtScaleDraw::LeftScale;
00364 break;
00365 }
00366 case yRight:
00367 {
00368 x = rect.left() + baseDist;
00369 y = rect.y() + startDist;
00370 w = rect.height() - startDist - endDist;
00371 align = QwtScaleDraw::RightScale;
00372 break;
00373 }
00374 case xTop:
00375 {
00376 x = rect.left() + startDist;
00377 y = rect.bottom() - baseDist + 1;
00378 w = rect.width() - startDist - endDist;
00379 align = QwtScaleDraw::TopScale;
00380 break;
00381 }
00382 case xBottom:
00383 {
00384 x = rect.left() + startDist;
00385 y = rect.top() + baseDist;
00386 w = rect.width() - startDist - endDist;
00387 align = QwtScaleDraw::BottomScale;
00388 break;
00389 }
00390 default:
00391 return;
00392 }
00393
00394 const QwtScaleWidget *scaleWidget = axisWidget(axisId);
00395 scaleWidget->drawTitle(painter, align, rect);
00396
00397 painter->save();
00398 painter->setFont(scaleWidget->font());
00399
00400 QwtScaleDraw *sd = (QwtScaleDraw *)scaleWidget->scaleDraw();
00401 const QPoint sdPos = sd->pos();
00402 const int sdLength = sd->length();
00403
00404 sd->move(x, y);
00405 sd->setLength(w);
00406
00407 #if QT_VERSION < 0x040000
00408 sd->draw(painter, scaleWidget->palette().active());
00409 #else
00410 QPalette palette = scaleWidget->palette();
00411 palette.setCurrentColorGroup(QPalette::Active);
00412 sd->draw(painter, palette);
00413 #endif
00414
00415 sd->move(sdPos);
00416 sd->setLength(sdLength);
00417
00418 painter->restore();
00419 }
00420
00431 void QwtPlot::printCanvas(QPainter *painter, const QRect &canvasRect,
00432 const QwtArray<QwtScaleMap> &map, const QwtPlotPrintFilter &pfilter) const
00433 {
00434 if ( pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground )
00435 {
00436 painter->setPen(Qt::NoPen);
00437
00438 QBrush bgBrush;
00439 #if QT_VERSION >= 0x040000
00440 bgBrush = canvas()->palette().brush(backgroundRole());
00441 #else
00442 QColorGroup::ColorRole role =
00443 QPalette::backgroundRoleFromMode( backgroundMode() );
00444 bgBrush = canvas()->colorGroup().brush( role );
00445 #endif
00446 painter->setBrush(bgBrush);
00447
00448 int x1 = 0;
00449 int x2 = 0;
00450 int y1 = 0;
00451 int y2 = 0;
00452
00453 #if QT_VERSION >= 0x040000
00454 switch(painter->device()->paintEngine()->type())
00455 {
00456 case QPaintEngine::PostScript:
00457 x2 = 1;
00458 y2 = 1;
00459 break;
00460 default:;
00461 }
00462 #endif
00463
00464 const QwtMetricsMap map = QwtPainter::metricsMap();
00465 x1 = map.screenToLayoutX(x1);
00466 x2 = map.screenToLayoutX(x2);
00467 y1 = map.screenToLayoutY(y1);
00468 y2 = map.screenToLayoutY(y2);
00469
00470 QwtPainter::drawRect(painter,
00471 canvasRect.x() + x1, canvasRect.y() + y1,
00472 canvasRect.width() - x2, canvasRect.height() - y2);
00473 }
00474 else
00475 {
00476
00477 painter->setPen(QPen(Qt::black));
00478 painter->setBrush(QBrush(Qt::NoBrush));
00479 QwtPainter::drawRect(painter, canvasRect);
00480 }
00481
00482
00483 painter->setClipping(true);
00484 QwtPainter::setClipRect(painter, canvasRect);
00485
00486 drawItems(painter, canvasRect, map, pfilter);
00487 }