void QwtPlot::drawItems(QPainter *painter, const QRect &rect, const QwtScaleMap map[axisCnt], const QwtPlotPrintFilter &pfilter) const { const QwtPlotItemList& itmList = itemList(); for ( QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); ++it ) { QwtPlotItem *item = *it; if ( item && item->isVisible() ) { if ( !(pfilter.options() & QwtPlotPrintFilter::PrintGrid) && item->rtti() == QwtPlotItem::Rtti_PlotGrid ) { continue; } painter->save(); #if QT_VERSION >= 0x040000 painter->setRenderHint(QPainter::Antialiasing, item->testRenderHint(QwtPlotItem::RenderAntialiased) ); #endif item->draw(painter, map[item->xAxis()], map[item->yAxis()], rect); painter->restore(); } } }
void QwtPlot::printCanvas(QPainter *painter, const QRect &canvasRect, const QwtArray<QwtDiMap> &map, const QwtPlotPrintFilter &pfilter) const { if ( pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground ) { QwtPainter::fillRect(painter, QRect(canvasRect.x(), canvasRect.y(), canvasRect.width() - 1, canvasRect.height() - 1), canvasBackground()); } else QwtPainter::drawRect(painter, canvasRect.x() - 1, canvasRect.y() - 1, canvasRect.width() + 1, canvasRect.height() + 1); painter->setClipping(TRUE); QwtPainter::setClipRect(painter, canvasRect); drawCanvasItems(painter, canvasRect, map, pfilter); }
void QwtPlot::drawCanvasItems(QPainter *painter, const QRect &rect, const QwtArray<QwtDiMap> &map, const QwtPlotPrintFilter &pfilter) const { // // draw grid // if ( pfilter.options() & QwtPlotPrintFilter::PrintGrid ) { if ( d_grid->enabled() ) { d_grid->draw(painter, rect, map[d_grid->xAxis()], map[d_grid->yAxis()]); } } // // draw curves // QwtPlotCurveIterator itc = curveIterator(); for (QwtPlotCurve *curve = itc.toFirst(); curve != 0; curve = ++itc ) { if ( curve->enabled() ) { curve->draw(painter, map[curve->xAxis()], map[curve->yAxis()]); } } // // draw markers // QwtPlotMarkerIterator itm = markerIterator(); for (QwtPlotMarker *marker = itm.toFirst(); marker != 0; marker = ++itm ) { if ( marker->enabled() ) { marker->draw(painter, map[marker->xAxis()].transform(marker->xValue()), map[marker->yAxis()].transform(marker->yValue()), rect); } } }
void QwtPlot::drawItems(QPainter *painter, const QRect &rect, const QwtArray<QwtScaleMap> &map, const QwtPlotPrintFilter &pfilter) const { painter->save(); const QwtPlotItemList& itmList = itemList(); for ( QwtPlotItemIterator it = itmList.begin(); it != itmList.end(); ++it ) { QwtPlotItem *item = *it; if ( item && item->isVisible() ) { if ( !(pfilter.options() & QwtPlotPrintFilter::PrintGrid) && item->rtti() == QwtPlotItem::Rtti_PlotGrid ) { continue; } #if QT_VERSION >= 0x040000 const QPaintEngine *pe = painter->device()->paintEngine(); if (pe->hasFeature(QPaintEngine::Antialiasing) ) { painter->setRenderHint(QPainter::Antialiasing, item->testRenderHint(QwtPlotItem::RenderAntialiased) ); } #endif item->draw(painter, map[item->xAxis()], map[item->yAxis()], rect); } } painter->restore(); }
void QwtPlot::findLayout( #ifndef QWT_NO_LEGEND bool printing, #else bool, #endif const QRect &rect, int hDist, int vDist, const QwtPlotPrintFilter &pfilter, QRect &rTitle, QRect &rLegend, QRect rAxis[axisCnt], QRect &rPixmap) const { rLegend = rTitle = rPixmap = QRect(); for ( int i = 0; i < axisCnt; i++ ) rAxis[i] = QRect(); QwtRect rPlot = rect; ///////////// // rLegend ///////////// #ifndef QWT_NO_LEGEND if ((pfilter.options() & QwtPlotPrintFilter::PrintLegend) && d_legend->itemCnt() > 0) { int border = 2 * d_legend->frameWidth(); QSize cell = d_legend->cellSizeHint(pfilter.font(d_legend->font(), QwtPlotPrintFilter::Legend)); QSize hint; hint.setWidth(d_legend->numCols() * cell.width() + border); hint.setHeight(d_legend->numRows() * cell.height() + border); cell.setWidth(cell.width() + border); cell.setHeight(cell.height() + border); switch(d_legendPos) { case Qwt::Left: { int w = qwtMin(hint.width(), rPlot.width() / 2); if ( !printing && hint.height() > rPlot.height() ) w += ScrBarWidth; rLegend = rPlot.cutLeft(w); break; } case Qwt::Right: { int w = qwtMin(hint.width(), rPlot.width() / 2); if ( !printing && hint.height() > rPlot.height() ) w += ScrBarWidth; rLegend = rPlot.cutRight(w); break; } case Qwt::Top: { int h = qwtMin(hint.height(), rPlot.height() / 4); h = qwtMax(h, cell.height()); // at least one cell high rLegend = rPlot.cutTop(h); break; } case Qwt::Bottom: default: { int h = qwtMin(hint.height(), rPlot.height() / 4); h = qwtMax(h, cell.height()); // at least one cell high rLegend = rPlot.cutBottom(h); break; } } } #endif /////////////////// // rTitle, rPixmap /////////////////// int dimTitle = 0; int dim[axisCnt]; int hSpacing = qwtMax( 0, hDist - vDist ); int vSpacing = qwtMax( 0, vDist - hDist ); dim[yLeft] = dim[yRight] = hSpacing; dim[xTop] = dim[xBottom] = vSpacing; bool done = FALSE; while (!done) { done = TRUE; // the size for the 4 axis depend on each other. Expanding // the height of a horizontal axis will shrink the height // for the verical axis, shrinking the height of a vertical // axis will result in a line break what will expand the // width and results in shrinking the width of a horizontal // axis what might result in a line break of a horizonatal // axis ... . So we loop as long as no size has to be changed. for ( int axis = 0; axis < axisCnt; axis++ ) { if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && !d_lblTitle->text().isEmpty()) { QFont f = d_lblTitle->font(); d_lblTitle->setFont(pfilter.font(f, QwtPlotPrintFilter::Title)); int w = rPlot.width(); if ( d_axisEnabled[yLeft] != d_axisEnabled[yRight] ) w -= dim[yLeft] + dim[yRight]; // centered to the pixmap dimTitle = d_lblTitle->heightForWidth(w); d_lblTitle->setFont(f); } if (d_axisEnabled[axis]) { int length; if ( axis == xTop || axis == xBottom ) { length = rPlot.width() - dim[yLeft] - dim[yRight] + 2 * hSpacing; } else { length = rPlot.height() - dim[xTop] - dim[xBottom] + 2 * vSpacing; if ( dimTitle > 0 ) length -= dimTitle + d_spacing; } const QwtScale *scale = d_scale[axis]; QFontMetrics titleFm(pfilter.font(scale->titleFont(), QwtPlotPrintFilter::AxisTitle)); QFontMetrics scaleFm(pfilter.font(scale->font(), QwtPlotPrintFilter::AxisScale)); int d = scale->dimForLength(length, titleFm, scaleFm); if ( !(pfilter.options() & QwtPlotPrintFilter::PrintBackground) ) { int baseDist = scale->baseLineDist(); d -= baseDist; } if ( d > dim[axis] ) { dim[axis] = d; done = FALSE; } } } } if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && !d_lblTitle->text().isEmpty()) { rTitle = QRect(rPlot.x(), rPlot.y(), rPlot.width(), dimTitle); if ( d_axisEnabled[yLeft] != d_axisEnabled[yRight] ) { // if one of the y axes is missing we align // the title centered to the pixmap rTitle.setX(rPlot.x() + dim[yLeft]); rTitle.setWidth(rPlot.width() - dim[yLeft] - dim[yRight]); } } int spacing = 0; if ( dimTitle > 0 ) spacing = d_spacing; // space between titel and canvas rPixmap = QRect( rPlot.x() + dim[yLeft], rPlot.y() + dimTitle + spacing + dim[xTop], rPlot.width() - dim[yRight] - dim[yLeft], rPlot.height() - dimTitle - spacing - dim[xBottom] - dim[xTop]); if (d_scale[xTop]) { rAxis[xTop] = QRect(rPixmap.x() - hSpacing, rPixmap.y() - dim[xTop], rPixmap.width() + 2 * hSpacing, dim[xTop]); if ( !(pfilter.options() & QwtPlotPrintFilter::PrintBackground) ) rAxis[xTop].setBottom(rAxis[xTop].bottom() + 1); } if (d_scale[xBottom]) { rAxis[xBottom] = QRect(rPixmap.x() - hSpacing, rPixmap.y() + rPixmap.height(), rPixmap.width() + 2 * hSpacing, dim[xBottom]); } if (d_scale[yLeft]) { rAxis[yLeft] = QRect(rPixmap.x() - dim[yLeft], rPixmap.y() - vSpacing, dim[yLeft], rPixmap.height() + 2 * vSpacing); if ( !(pfilter.options() & QwtPlotPrintFilter::PrintBackground) ) rAxis[yLeft].setRight(rAxis[yLeft].right() + 1); } if (d_scale[yRight]) { rAxis[yRight] = QRect(rPixmap.x() + rPixmap.width(), rPixmap.y() - vSpacing, dim[yRight], rPixmap.height() + 2 * vSpacing); } #ifndef QWT_NO_LEGEND if (!printing && (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && d_legend->itemCnt() > 0) { QSize hint = d_legend->sizeHint(); if ( d_legendPos == Qwt::Right || d_legendPos == Qwt::Left ) { if (rLegend.height() > hint.height() + ScrBarWidth) { // adjust the height; prevent scrollbars where possible if (rLegend.width() >= hint.width()) // has no hor. scrollbar rLegend.setHeight(hint.height()); else rLegend.setHeight(hint.height() + ScrBarWidth); // put it at same the y position as rPixmap if useful; // center otherwise if (rLegend.height() <= rPixmap.height()) rLegend.moveBy(0, rPixmap.y() - rLegend.y()); else rLegend.moveBy(0, contentsRect().center().y() - rLegend.center().y()); } } else { if (rLegend.width() > (hint.width() + ScrBarWidth)) { // adjust the width if (rLegend.height() >= hint.height()) // has novert. scrollbar rLegend.setWidth(hint.width()); else rLegend.setWidth(hint.width() + ScrBarWidth); // put it in the center if (rLegend.width() <= (rPixmap.width() + 2 * qwtMin(rAxis[yLeft].width() , rAxis[yRight].width()))) { rLegend.moveBy(rPixmap.center().x() - rLegend.center().x(), 0); } else { rLegend.moveBy(contentsRect().center().x() - rLegend.center().x(), 0); } } } } #endif }
/*! \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 { int axisId; if ( painter == 0 || !painter->isActive() || !plotRect.isValid() || size().isNull() ) return; painter->save(); #if 1 /* PDF: In Qt4 ( <= 4.3.2 ) the scales are painted in gray instead of black. See http://trolltech.com/developer/task-tracker/index_html?id=184671&method=entry The dummy lines below work around the problem. */ const QPen pen = painter->pen(); painter->setPen(QPen(Qt::black, 1)); painter->setPen(pen); #endif // 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); int baseLineDists[QwtPlot::axisCnt]; if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales ) { for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) { baseLineDists[axisId] = scaleWidget->margin(); scaleWidget->setMargin(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) ) layoutOptions |= QwtPlotLayout::IgnoreMargin; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) ) layoutOptions |= QwtPlotLayout::IgnoreLegend; ((QwtPlot *)this)->plotLayout()->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect), layoutOptions); if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && (!titleLabel()->text().isEmpty())) { printTitle(painter, plotLayout()->titleRect()); } if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && legend() && !legend()->isEmpty() ) { printLegend(painter, plotLayout()->legendRect()); } for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if (scaleWidget) { int baseDist = scaleWidget->margin(); int startDist, endDist; scaleWidget->getBorderDistHint(startDist, endDist); printScale(painter, axisId, startDist, endDist, baseDist, plotLayout()->scaleRect(axisId)); } } QRect canvasRect = plotLayout()->canvasRect(); /* The border of the bounding rect needs to ba scaled to layout coordinates, so that it is aligned to the axes */ QRect boundingRect( canvasRect.left() - 1, canvasRect.top() - 1, canvasRect.width() + 2, canvasRect.height() + 2); boundingRect = metricsMap.layoutToDevice(boundingRect); boundingRect.setWidth(boundingRect.width() - 1); boundingRect.setHeight(boundingRect.height() - 1); canvasRect = metricsMap.layoutToDevice(canvasRect); // When using QwtPainter all sizes where computed in pixel // coordinates and scaled by QwtPainter later. This limits // the precision to screen resolution. A better solution // is to scale the maps and print in unlimited resolution. QwtScaleMap map[axisCnt]; for (axisId = 0; axisId < axisCnt; axisId++) { map[axisId].setTransformation(axisScaleEngine(axisId)->transformation()); const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId); map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound()); double from, to; if ( axisEnabled(axisId) ) { const int sDist = axisWidget(axisId)->startBorderDist(); const int eDist = axisWidget(axisId)->endBorderDist(); const QRect &scaleRect = plotLayout()->scaleRect(axisId); if ( axisId == xTop || axisId == xBottom ) { from = metricsMap.layoutToDeviceX(scaleRect.left() + sDist); to = metricsMap.layoutToDeviceX(scaleRect.right() + 1 - eDist); } else { from = metricsMap.layoutToDeviceY(scaleRect.bottom() + 1 - eDist ); to = metricsMap.layoutToDeviceY(scaleRect.top() + sDist); } } else { int margin = plotLayout()->canvasMargin(axisId); if ( axisId == yLeft || axisId == yRight ) { margin = metricsMap.layoutToDeviceY(margin); from = canvasRect.bottom() - margin; to = canvasRect.top() + margin; } else { margin = metricsMap.layoutToDeviceX(margin); from = canvasRect.left() + margin; to = canvasRect.right() - margin; } } map[axisId].setPaintXInterval(from, to); } // The canvas maps are already scaled. QwtPainter::setMetricsMap(painter->device(), painter->device()); printCanvas(painter, boundingRect, canvasRect, map, pfilter); QwtPainter::resetMetricsMap(); ((QwtPlot *)this)->plotLayout()->invalidate(); // reset all widgets with their original attributes. if ( pfilter.options() & QwtPlotPrintFilter::PrintFrameWithScales ) { // restore the previous base line dists for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) scaleWidget->setMargin(baseLineDists[axisId]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }
/*! \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 { int axisId; 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); int baseLineDists[QwtPlot::axisCnt]; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // In case of no background we set the backbone of // the scale on the frame of the canvas. for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) { baseLineDists[axisId] = scaleWidget->baseLineDist(); scaleWidget->setBaselineDist(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintMargin) ) layoutOptions |= QwtPlotLayout::IgnoreMargin; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintLegend) ) layoutOptions |= QwtPlotLayout::IgnoreLegend; ((QwtPlot *)this)->plotLayout()->activate(this, QwtPainter::metricsMap().deviceToLayout(plotRect), layoutOptions); if ((pfilter.options() & QwtPlotPrintFilter::PrintTitle) && (!titleLabel()->text().isEmpty())) { printTitle(painter, plotLayout()->titleRect()); } if ( (pfilter.options() & QwtPlotPrintFilter::PrintLegend) && legend() && !legend()->isEmpty() ) { printLegend(painter, plotLayout()->legendRect()); } for ( axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if (scaleWidget) { int baseDist = scaleWidget->baseLineDist(); int startDist, endDist; scaleWidget->getBorderDistHint(startDist, endDist); printScale(painter, axisId, startDist, endDist, baseDist, plotLayout()->scaleRect(axisId)); } } const QRect canvasRect = metricsMap.layoutToDevice(plotLayout()->canvasRect()); // 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<QwtScaleMap> map(axisCnt); for (axisId = 0; axisId < axisCnt; axisId++) { map[axisId].setTransformation(axisScaleEngine(axisId)->transformation()); const QwtScaleDiv &scaleDiv = *axisScaleDiv(axisId); map[axisId].setScaleInterval(scaleDiv.lBound(), scaleDiv.hBound()); double from, to; if ( axisEnabled(axisId) ) { const int sDist = axisWidget(axisId)->startBorderDist(); const int eDist = axisWidget(axisId)->endBorderDist(); const QRect &scaleRect = plotLayout()->scaleRect(axisId); if ( axisId == xTop || axisId == 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); } } else { const int margin = plotLayout()->canvasMargin(axisId); const QRect &canvasRect = plotLayout()->canvasRect(); if ( axisId == yLeft || axisId == yRight ) { from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin); to = metricsMap.layoutToDeviceX(canvasRect.top() + margin); } else { from = metricsMap.layoutToDeviceY(canvasRect.left() + margin); to = metricsMap.layoutToDeviceY(canvasRect.right() - margin); } } map[axisId].setPaintXInterval(from, to); } // The canvas maps are already scaled. QwtPainter::setMetricsMap(painter->device(), painter->device()); printCanvas(painter, canvasRect, map, pfilter); QwtPainter::resetMetricsMap(); ((QwtPlot *)this)->plotLayout()->invalidate(); // reset all widgets with their original attributes. if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // restore the previous base line dists for (axisId = 0; axisId < QwtPlot::axisCnt; axisId++ ) { QwtScaleWidget *scaleWidget = (QwtScaleWidget *)axisWidget(axisId); if ( scaleWidget ) scaleWidget->setBaselineDist(baseLineDists[axisId]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }
/*! \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 { int axis; 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()); #if QT_VERSION < 300 if ( painter->device()->isExtDev() ) { QPaintDeviceMetrics metrics(painter->device()); if ( metrics.logicalDpiX() == 72 && metrics.logicalDpiY() == 72 ) { // In Qt 2.x QPrinter returns hardcoded wrong metrics. // So scaling won´t work: we reset to screen resolution QwtPainter::setMetricsMap(this, this); } } #endif 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); int baseLineDists[QwtPlot::axisCnt]; if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // In case of no background we set the backbone of // the scale on the frame of the canvas. for (axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( d_scale[axis] ) { baseLineDists[axis] = d_scale[axis]->baseLineDist(); d_scale[axis]->setBaselineDist(0); } } } // Calculate the layout for the print. int layoutOptions = QwtPlotLayout::IgnoreScrollbars | QwtPlotLayout::IgnoreFrames; 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()); } for ( axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if (d_scale[axis]) { int baseDist = d_scale[axis]->baseLineDist(); int startDist, endDist; d_scale[axis]->minBorderDist(startDist, endDist); printScale(painter, axis, startDist, endDist, baseDist, d_layout->scaleRect(axis)); } } const QRect canvasRect = metricsMap.layoutToDevice(d_layout->canvasRect()); // 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()); double from, to; if ( axisEnabled(axis) ) { const int sDist = d_scale[axis]->startBorderDist(); const int eDist = d_scale[axis]->endBorderDist(); const QRect &scaleRect = d_layout->scaleRect(axis); 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); } } else { const int margin = plotLayout()->canvasMargin(axis); const QRect &canvasRect = plotLayout()->canvasRect(); if ( axis == yLeft || axis == yRight ) { from = metricsMap.layoutToDeviceX(canvasRect.bottom() - margin); to = metricsMap.layoutToDeviceX(canvasRect.top() + margin); } else { from = metricsMap.layoutToDeviceY(canvasRect.left() + margin); to = metricsMap.layoutToDeviceY(canvasRect.right() - margin); } } map[axis].setIntRange( qwtInt(from), qwtInt(to)); } // 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. if ( !(pfilter.options() & QwtPlotPrintFilter::PrintCanvasBackground) ) { // restore the previous base line dists for (axis = 0; axis < QwtPlot::axisCnt; axis++ ) { if ( d_scale[axis] ) d_scale[axis]->setBaselineDist(baseLineDists[axis]); } } pfilter.reset((QwtPlot *)this); painter->restore(); }