Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members | Related Pages

qwt_plot_print.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 // vim: expandtab
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     // All paint operations need to be scaled according to
00068     // the paint device metrics. 
00069 
00070     QwtPainter::setScaleMetrics(this, painter->device());
00071 
00072     // It is almost impossible to integrate into the Qt layout
00073     // framework, when using different fonts for printing
00074     // and screen. To avoid writing different and Qt unconform
00075     // layout engines we change the widget attributes, print and 
00076     // reset the widget attributes again. This way we produce a lot of
00077     // useless layout events ...
00078 
00079     pfilter.apply((QwtPlot *)this);
00080 
00081     // Calculate the layout for the print.
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     // When using QwtPainter all sizes where computed in pixel
00123     // coordinates and scaled by QwtPainter later. This limits
00124     // the precision to screen resolution. A much better solution
00125     // is to scale the maps and print in unlimited resolution.
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     // Disable scaling. The maps are still scaled.
00154     QwtPainter::resetScaleMetrics();
00155 
00156     printCanvas(painter, map, canvasRect, pfilter);
00157 
00158 
00159     d_layout->invalidate();
00160 
00161     // reset all widgets with their original attributes.
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); // acisColor ????
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); // reset previous values
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 }

Generated on Fri Nov 7 14:11:46 2003 for Qwt Developer's Guide by doxygen 1.3.2