⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwt_plot_print.cpp

📁 软件无线电的平台
💻 CPP
字号:
/* -*- mode: C++ ; c-file-style: "stroustrup" -*- ***************************** * Qwt Widget Library * Copyright (C) 1997   Josef Wilgen * Copyright (C) 2002   Uwe Rathmann * * This library is free software; you can redistribute it and/or * modify it under the terms of the Qwt License, Version 1.0 *****************************************************************************/// vim: expandtab#include <qlabel.h>#include <qpainter.h>#include <qpaintdevicemetrics.h>#include "qwt_painter.h"#include "qwt_legend.h"#include "qwt_plot.h"#include "qwt_plot_layout.h"#include "qwt_plot_dict.h"#include "qwt_rect.h"#include "qwt_dyngrid_layout.h"#include "qwt_scale.h"#include "qwt_text.h"#include "qwt_math.h"/*!  \brief Print the plot to a \c QPaintDevice (\c QPrinter)  This function prints the contents of a QwtPlot instance to  \c QPaintDevice object. The size is derived from its device  metrics.  \param paintDev device to paint on, often a printer  \param pfilter print filter  \sa QwtPlot::print  \sa QwtPlotPrintFilter  \warning Printing on a QPrinter(QPrinter::HighResolution) printer may  expose a nasty bug in Qt.  The problem concerns scaling of fonts: a given  font should use 8 times more pixels on a 600 dpi paint device than  on a 75 dpi paint device.  High resolution print tests on a Mandrake-8.2 system with a 75 dpi screen  show (test program available on request):  - Qt finds more fonts with the X Font Server enabled than disabled (use    qtconfig). On the test system this has no consequences for the print    quality.    - Qt-3.0.7 finds significantly more fonts than its successors and printing    works fine.  - Qt-3.1.2 finds less fonts than Qt-3.0.7 with the X Font Server enabled and    printing fine.  - Qt-3.2.0 finds less fonts than Qt-3.0.7 and printing only works for rich    text. All plain text is printed at 75 dpi instead of 600 dpi.  Some    standard X Window fonts as "Helvetica [Adobe]" do not print well as    rich text.  - Qt-3.2.1 finds a few more fonts than Qt-3.2.0 and some standard    non-scalable X Window fonts as "Helvetica [Adobe]" do not print well    as rich and plain text.  - Qt-3.2.2 still has problems with the same fonts as Qt-3.2.1, but there    is improvement (text printed with non-scalable X Windows fonts is barely    readable and looks ugly, because Qt gets the font metrics wrong).  Recommendations:  - Do not use Qt-3.2.0.  - Do not use non-scalable fonts for printing, especially if you print to    postscript files that are to be included in other documents.  We will continue to report the bug.*/void QwtPlot::print(QPaintDevice &paintDev,   const QwtPlotPrintFilter &pfilter) const{    QPaintDeviceMetrics mpr(&paintDev);    QRect rect(0, 0, mpr.width(), mpr.height());    double aspect = double(rect.width())/double(rect.height());    if ((aspect < 1.0))        rect.setHeight(int(aspect*rect.width()));    QPainter p(&paintDev);    print(&p, rect, pfilter);}/*!  \brief Paint the plot into a given rectangle.  Paint the contents of a QwtPlot instance into a given rectangle.  \param painter Painter  \param plotRect Bounding rectangle  \param pfilter Print filter  \sa QwtPlotPrintFilter*/void QwtPlot::print(QPainter *painter, const QRect &plotRect,        const QwtPlotPrintFilter &pfilter) const{    if ( painter == 0 || !painter->isActive() ||            !plotRect.isValid() || size().isNull() )       return;    painter->save();    // All paint operations need to be scaled according to    // the paint device metrics.     QwtPainter::setMetricsMap(this, painter->device());    const QwtMetricsMap &metricsMap = QwtPainter::metricsMap();    // It is almost impossible to integrate into the Qt layout    // framework, when using different fonts for printing    // and screen. To avoid writing different and Qt unconform    // layout engines we change the widget attributes, print and     // reset the widget attributes again. This way we produce a lot of    // useless layout events ...    pfilter.apply((QwtPlot *)this);    // Calculate the layout for the print.    int layoutOptions = QwtPlotLayout::IgnoreScrollbars         | QwtPlotLayout::IgnoreFrames | QwtPlotLayout::AlignScales;    if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) )        layoutOptions |= QwtPlotLayout::IgnoreMargin;    if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) )        layoutOptions |= QwtPlotLayout::IgnoreLegend;    d_layout->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect),         layoutOptions);    if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle)        && (!d_lblTitle->text().isEmpty()))    {        printTitle(painter, d_layout->titleRect());    }    if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend)        && !d_legend->isEmpty() )    {        printLegend(painter, d_layout->legendRect());    }    int axis;    for ( axis = 0; axis < axisCnt; axis++ )    {        if (d_scale[axis])        {            int startDist, endDist;            d_scale[axis]->minBorderDist(startDist, endDist);            int baseDist = d_scale[axis]->baseLineDist();            if ( !(pfilter.options() & QwtPlotPrintFilter::PrintBackground) )                baseDist = 0;            printScale(painter, axis, startDist, endDist,                baseDist, d_layout->scaleRect(axis));        }    }    // When using QwtPainter all sizes where computed in pixel    // coordinates and scaled by QwtPainter later. This limits    // the precision to screen resolution. A much better solution    // is to scale the maps and print in unlimited resolution.    QwtArray<QwtDiMap> map(axisCnt);    for (axis = 0; axis < axisCnt; axis++)    {        const QwtScaleDiv &scaleDiv = d_as[axis].scaleDiv();        map[axis].setDblRange(scaleDiv.lBound(),            scaleDiv.hBound(), scaleDiv.logScale());        const int sDist = d_scale[axis]->startBorderDist();        const int eDist = d_scale[axis]->endBorderDist();        const QRect &scaleRect = d_layout->scaleRect(axis);        double from, to;        if ( axis == xTop || axis == xBottom )        {            from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist);            to = metricsMap.layoutToDeviceX(scaleRect.right() - eDist);        }        else        {            from = metricsMap.layoutToDeviceY(scaleRect.bottom() - sDist);            to = metricsMap.layoutToDeviceY(scaleRect.top() + eDist);        }        map[axis].setIntRange(qwtInt(from), qwtInt(to));    }    const QRect canvasRect = metricsMap.layoutToDevice(d_layout->canvasRect());    // The maps are already scaled.     QwtPainter::setMetricsMap(painter->device(), painter->device());    printCanvas(painter, canvasRect, map, pfilter);    QwtPainter::resetMetricsMap();    d_layout->invalidate();    // reset all widgets with their original attributes.    pfilter.reset((QwtPlot *)this);    painter->restore();}/*!  Print the title into a given rectangle.  \param painter Painter  \param rect Bounding rectangle*/void QwtPlot::printTitle(QPainter *painter, const QRect &rect) const{    QwtText *text = QwtText::makeText(        d_lblTitle->text(), d_lblTitle->textFormat(), d_lblTitle->alignment(),        d_lblTitle->font(), painter->pen().color());     text->draw(painter, rect);    delete text;}/*!  Print the legend into a given rectangle.  \param painter Painter  \param rect Bounding rectangle*/void QwtPlot::printLegend(QPainter *painter, const QRect &rect) const{    if ( !d_legend || d_legend->isEmpty() )        return;    QLayout *l = d_legend->contentsWidget()->layout();    if ( l == 0 || !l->inherits("QwtDynGridLayout") )        return;    QwtDynGridLayout *legendLayout = (QwtDynGridLayout *)l;    uint numCols = legendLayout->columnsForWidth(rect.width());    QValueList<QRect> itemRects =         legendLayout->layoutItems(rect, numCols);    int index = 0;    QLayoutIterator layoutIterator = legendLayout->iterator();    for ( QLayoutItem *item = layoutIterator.current();         item != 0; item = ++layoutIterator)    {        QWidget *w = item->widget();        if ( w )        {            painter->save();            painter->setClipping(TRUE);            QwtPainter::setClipRect(painter, itemRects[index]);            printLegendItem(painter, w, itemRects[index]);            index++;            painter->restore();        }    }}void QwtPlot::printLegendItem(QPainter *painter,     const QWidget *w, const QRect &rect) const{    const QwtLegendItem *item = NULL;    if ( w->inherits("QwtLegendButton") )        item = (QwtLegendButton *)w;    if ( w->inherits("QwtLegendLabel") )        item = (QwtLegendLabel *)w;    if ( item )    {        painter->setFont(w->font());        item->drawItem(painter, rect);    }}/*!  \brief Paint a scale into a given rectangle.  Paint the scale into a given rectangle.  \param painter Painter  \param axis Axis  \param startDist Start border distance  \param endDist End border distance  \param baseDist Base distance  \param rect Bounding rectangle*/void QwtPlot::printScale(QPainter *painter,    int axis, int startDist, int endDist, int baseDist,     const QRect &rect) const{    if (!d_axisEnabled[axis])        return;    QwtScaleDraw::Orientation o;    int x, y, w;    switch(axis)    {        case yLeft:        {            x = rect.right() - baseDist + 1;            y = rect.y() + startDist;            w = rect.height() - startDist - endDist;            o = QwtScaleDraw::Left;            break;        }        case yRight:        {            x = rect.left() + baseDist;            y = rect.y() + startDist;            w = rect.height() - startDist - endDist;            o = QwtScaleDraw::Right;            break;        }        case xTop:        {            x = rect.left() + startDist;            y = rect.bottom() - baseDist + 1;            w = rect.width() - startDist - endDist;            o = QwtScaleDraw::Top;            break;        }        case xBottom:        {            x = rect.left() + startDist;            y = rect.top() + baseDist;            w = rect.width() - startDist - endDist;            o = QwtScaleDraw::Bottom;            break;        }        default:            return;    }    const QwtScale *scale = d_scale[axis];#if 0    painter->setPen(scale->titleColor());    painter->setFont(scale->titleFont());    QwtScale::drawTitle(painter, o, rect,        scale->titleAlignment(), scale->title());#endif    scale->drawTitle(painter, o, rect);#if 1    painter->setPen(Qt::black); // acisColor ????#endif    painter->setFont(scale->font());    QwtScaleDraw *sd = (QwtScaleDraw *)scale->scaleDraw();    int xSd = sd->x();    int ySd = sd->y();    int lengthSd = sd->length();    sd->setGeometry(x, y, w, o);    sd->draw(painter);    sd->setGeometry(xSd, ySd, lengthSd, o); // reset previous values}/*!  Print the canvas into a given rectangle.  \param painter Painter  \param map Maps mapping between plot and paint device coordinates  \param canvasRect Bounding rectangle  \param pfilter Print filter  \sa QwtPlotPrintFilter*/void QwtPlot::printCanvas(QPainter *painter, const QRect &canvasRect,    const QwtArray<QwtDiMap> &map, const QwtPlotPrintFilter &pfilter) const{    if ( pfilter.options() & QwtPlotPrintFilter::PrintBackground )        QwtPainter::fillRect(painter, canvasRect, canvasBackground());    else        QwtPainter::drawRect(painter, canvasRect);    painter->setClipping(TRUE);    QwtPainter::setClipRect(painter, QRect(canvasRect.x(), canvasRect.y(),        canvasRect.width() - 1, canvasRect.height() - 1));    drawCanvasItems(painter, canvasRect, map, pfilter);}// Local Variables:// mode: C++// c-file-style: "stroustrup"// indent-tabs-mode: nil// End:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -