00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <qlabel.h>
00013 #include <qpainter.h>
00014 #include <qpaintdevicemetrics.h>
00015 #include "qwt_painter.h"
00016 #include "qwt_legend.h"
00017 #include "qwt_plot.h"
00018 #include "qwt_plot_layout.h"
00019 #include "qwt_plot_dict.h"
00020 #include "qwt_rect.h"
00021 #include "qwt_dyngrid_layout.h"
00022 #include "qwt_scale.h"
00023 #include "qwt_math.h"
00024
00037 void QwtPlot::print(QPaintDevice &paintDev,
00038 const QwtPlotPrintFilter &pfilter) const
00039 {
00040 QPaintDeviceMetrics mpr(&paintDev);
00041
00042 QRect rect(0, 0, mpr.width(), mpr.height());
00043 rect.setHeight(qwtMin(rect.height(), int(0.66 * double(rect.width()))));
00044
00045 QPainter p(&paintDev);
00046 print(&p, rect, pfilter);
00047 }
00048
00058 void QwtPlot::print(QPainter *painter, const QRect &plotRect,
00059 const QwtPlotPrintFilter &pfilter) const
00060 {
00061 if ( painter == 0 || !painter->isActive() ||
00062 !plotRect.isValid() || size().isNull() )
00063 return;
00064
00065 painter->save();
00066
00067
00068
00069
00070 QwtPainter::setScaleMetrics(this, painter->device());
00071
00072
00073
00074
00075
00076
00077
00078
00079 pfilter.apply((QwtPlot *)this);
00080
00081
00082
00083 int layoutOptions = QwtPlotLayout::IgnoreScrollbars
00084 | QwtPlotLayout::IgnoreFrames | QwtPlotLayout::AlignScales;
00085 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) )
00086 layoutOptions |= QwtPlotLayout::IgnoreMargin;
00087 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) )
00088 layoutOptions |= QwtPlotLayout::IgnoreLegend;
00089
00090 d_layout->activate(this, QwtPainter::invScale(plotRect),
00091 layoutOptions);
00092
00093 if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle)
00094 && (!d_lblTitle->text().isEmpty()))
00095 {
00096 printTitle(painter, d_layout->titleRect());
00097 }
00098
00099 if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend)
00100 && !d_legend->isEmpty() )
00101 {
00102 printLegend(painter, d_layout->legendRect());
00103 }
00104
00105 int axis;
00106 for ( axis = 0; axis < axisCnt; axis++ )
00107 {
00108 if (d_scale[axis])
00109 {
00110 int startDist, endDist;
00111 d_scale[axis]->minBorderDist(startDist, endDist);
00112
00113 int baseDist = d_scale[axis]->baseLineDist();
00114 if ( !(pfilter.options() & QwtPlotPrintFilter::PrintBackground) )
00115 baseDist = 0;
00116
00117 printScale(painter, axis, startDist, endDist,
00118 baseDist, d_layout->scaleRect(axis));
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127 QwtDiMap map[axisCnt];
00128 for (axis = 0; axis < axisCnt; axis++)
00129 {
00130 map[axis].setDblRange(d_sdiv[axis].lBound(),
00131 d_sdiv[axis].hBound(), d_sdiv[axis].logScale());
00132
00133 const int sDist = d_scale[axis]->startBorderDist();
00134 const int eDist = d_scale[axis]->endBorderDist();
00135
00136 const QRect &scaleRect = d_layout->scaleRect(axis);
00137 double from, to;
00138 if ( axis == xTop || axis == xBottom )
00139 {
00140 from = (scaleRect.left() + sDist) * QwtPainter::scaleMetricsX();
00141 to = (scaleRect.right() - eDist) * QwtPainter::scaleMetricsX();
00142 }
00143 else
00144 {
00145 from = (scaleRect.bottom() - sDist) * QwtPainter::scaleMetricsY();
00146 to = (scaleRect.top() + eDist) * QwtPainter::scaleMetricsY();
00147 }
00148 map[axis].setIntRange(qwtInt(from), qwtInt(to));
00149 }
00150
00151 const QRect canvasRect = QwtPainter::scale(d_layout->canvasRect());
00152
00153
00154 QwtPainter::resetScaleMetrics();
00155
00156 printCanvas(painter, map, canvasRect, pfilter);
00157
00158
00159 d_layout->invalidate();
00160
00161
00162 pfilter.reset((QwtPlot *)this);
00163
00164 painter->restore();
00165 }
00166
00174 void QwtPlot::printTitle(QPainter *painter, const QRect &rect) const
00175 {
00176 painter->setFont(d_lblTitle->font());
00177 QwtPainter::drawText(painter, rect,
00178 d_lblTitle->alignment(), d_lblTitle->text());
00179 }
00180
00188 void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const
00189 {
00190 if ( !d_legend || d_legend->isEmpty() )
00191 return;
00192
00193 QLayout *l = d_legend->contentsWidget()->layout();
00194 if ( l == 0 || !l->inherits("QwtDynGridLayout") )
00195 return;
00196
00197 QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l;
00198
00199 uint numCols = legendLayout->columnsForWidth(rect.width());
00200 QValueList<QRect> itemRects =
00201 legendLayout->layoutItems(rect, numCols);
00202
00203 int index = 0;
00204
00205 QLayoutIterator layoutIterator = legendLayout->iterator();
00206 for ( QLayoutItem *item = layoutIterator.current();
00207 item != 0; item = ++layoutIterator)
00208 {
00209 QWidget *w = item->widget();
00210 if ( w )
00211 {
00212 painter->save();
00213 painter->setClipping(TRUE);
00214 QwtPainter::setClipRect(painter, itemRects[index]);
00215
00216 printLegendItem(painter, w, itemRects[index]);
00217
00218 index++;
00219 painter->restore();
00220 }
00221 }
00222 }
00223
00224 void QwtPlot::printLegendItem(QPainter *painter,
00225 const QWidget *w, const QRect &rect) const
00226 {
00227 if ( w->inherits("QwtLegendButton") )
00228 {
00229 QwtLegendButton *btn = (QwtLegendButton *)w;
00230
00231 painter->setFont(btn->font());
00232 btn->drawContents(painter, rect);
00233 }
00234 }
00235
00248 void QwtPlot::printScale(QPainter *painter,
00249 int axis, int startDist, int endDist, int baseDist,
00250 const QRect &rect) const
00251 {
00252 if (!d_axisEnabled[axis])
00253 return;
00254
00255 QwtScaleDraw::Orientation o;
00256 int x, y, w;
00257
00258 switch(axis)
00259 {
00260 case yLeft:
00261 {
00262 x = rect.right() - baseDist + 1;
00263 y = rect.y() + startDist;
00264 w = rect.height() - startDist - endDist;
00265 o = QwtScaleDraw::Left;
00266 break;
00267 }
00268 case yRight:
00269 {
00270 x = rect.left() + baseDist;
00271 y = rect.y() + startDist;
00272 w = rect.height() - startDist - endDist;
00273 o = QwtScaleDraw::Right;
00274 break;
00275 }
00276 case xTop:
00277 {
00278 x = rect.left() + startDist;
00279 y = rect.bottom() - baseDist + 1;
00280 w = rect.width() - startDist - endDist;
00281 o = QwtScaleDraw::Top;
00282 break;
00283 }
00284 case xBottom:
00285 {
00286 x = rect.left() + startDist;
00287 y = rect.top() + baseDist;
00288 w = rect.width() - startDist - endDist;
00289 o = QwtScaleDraw::Bottom;
00290 break;
00291 }
00292 default:
00293 return;
00294 }
00295
00296 const QwtScale *scale = d_scale[axis];
00297
00298 painter->setPen(scale->titleColor());
00299 painter->setFont(scale->titleFont());
00300 QwtScale::drawTitle(painter, o, rect,
00301 scale->titleAlignment(), scale->title());
00302
00303 #if 1
00304 painter->setPen(Qt::black);
00305 #endif
00306 painter->setFont(scale->font());
00307
00308 QwtScaleDraw *sd = (QwtScaleDraw *)scale->scaleDraw();
00309 int xSd = sd->x();
00310 int ySd = sd->y();
00311 int lengthSd = sd->length();
00312
00313 sd->setGeometry(x, y, w, o);
00314 sd->draw(painter);
00315 sd->setGeometry(xSd, ySd, lengthSd, o);
00316 }
00317
00328 void QwtPlot::printCanvas(QPainter *painter, const QwtDiMap map[],
00329 const QRect &canvasRect, const QwtPlotPrintFilter &pfilter) const
00330 {
00331 if ( pfilter.options() & QwtPlotPrintFilter::PrintBackground )
00332 QwtPainter::fillRect(painter, canvasRect, canvasBackground());
00333 else
00334 QwtPainter::drawRect(painter, canvasRect);
00335
00336 painter->setClipping(TRUE);
00337 QwtPainter::setClipRect(painter, QRect(canvasRect.x(), canvasRect.y(),
00338 canvasRect.width() - 1, canvasRect.height() - 1));
00339
00340 drawCanvasItems(painter, canvasRect, map, pfilter);
00341 }