static bool heightMediaFeatureEval(CSSValueImpl* value, RenderStyle* style, KHTMLPart* part, MediaFeaturePrefix op) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; int height; if (printing) height = pd->height(); else { height = part->view()->visibleHeight(); doc = static_cast<DOM::DocumentImpl*>(part->document().handle()); } int logicalDpiY = doc->logicalDpiY(); if (value) return value->isPrimitiveValue() && compareValue(height, static_cast<CSSPrimitiveValueImpl*>(value)->computeLength(style, logicalDpiY), op); return height > 0; }
void QwtPlot::print(QPaintDevice &paintDev, const QwtPlotPrintFilter &pfilter) const { #if QT_VERSION < 0x040000 QPaintDeviceMetrics mpr(&paintDev); int w = mpr.width(); int h = mpr.height(); #else int w = paintDev.width(); int h = paintDev.height(); #endif QRect rect(0, 0, w, h); 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); }
static QSize getPixmapSize(QTextDocument *doc, const QTextImageFormat &format) { QPixmap pm; const bool hasWidth = format.hasProperty(QTextFormat::ImageWidth); const int width = qRound(format.width()); const bool hasHeight = format.hasProperty(QTextFormat::ImageHeight); const int height = qRound(format.height()); QSize size(width, height); if (!hasWidth || !hasHeight) { pm = getPixmap(doc, format); const int pmWidth = pm.width() / pm.devicePixelRatio(); const int pmHeight = pm.height() / pm.devicePixelRatio(); if (!hasWidth) { if (!hasHeight) size.setWidth(pmWidth); else size.setWidth(qRound(height * (pmWidth / (qreal) pmHeight))); } if (!hasHeight) { if (!hasWidth) size.setHeight(pmHeight); else size.setHeight(qRound(width * (pmHeight / (qreal) pmWidth))); } } qreal scale = 1.0; QPaintDevice *pdev = doc->documentLayout()->paintDevice(); if (pdev) { if (pm.isNull()) pm = getPixmap(doc, format); if (!pm.isNull()) scale = qreal(pdev->logicalDpiY()) / qreal(qt_defaultDpi()); } size *= scale; return size; }
static cairo_image_surface_t * _cairo_qt_surface_map_to_image (void *abstract_surface, const cairo_rectangle_int_t *extents) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; QImage *qimg = NULL; D(fprintf(stderr, "q[%p] acquire_dest_image\n", abstract_surface)); if (qs->image_equiv) return _cairo_image_surface_map_to_image (qs->image_equiv, extents); QPoint offset; if (qs->pixmap) { qimg = new QImage(qs->pixmap->toImage()); } else { // Try to figure out what kind of QPaintDevice we have, and // how we can grab an image from it QPaintDevice *pd = qs->p->device(); if (!pd) return (cairo_image_surface_t *) _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY); QPaintDevice *rpd = QPainter::redirected(pd, &offset); if (rpd) pd = rpd; if (pd->devType() == QInternal::Image) { qimg = new QImage(((QImage*) pd)->copy()); } else if (pd->devType() == QInternal::Pixmap) { qimg = new QImage(((QPixmap*) pd)->toImage()); } else if (pd->devType() == QInternal::Widget) { qimg = new QImage(QPixmap::grabWindow(((QWidget*)pd)->winId()).toImage()); } } return (cairo_image_surface_t *) map_qimage_to_image (qimg, extents); }
void printerStream::printPixmap(const QPixmap &pm, bool newLine) { #if 0 QPaintDevice *dev = pr.device(); if (fwbdebug) { qDebug("printPixmap: width=%d height=%d", pm.width(), pm.height()); qDebug("printPixmap: printer->resolution()=%d", printer->resolution()); if (dev) { qDebug("printPixmap: device parameters:"); qDebug(" height=%d width=%d", dev->height(), dev->width()); qDebug(" logicalDpiY=%d logicalDpiX=%d", dev->logicalDpiY(), dev->logicalDpiX()); qDebug(" physicalDpiY=%d physicalDpiX=%d", dev->physicalDpiY(), dev->physicalDpiX()); } } #endif int target_w = (int)(pm.width() * pixmap_scaling_ratio); int target_h = (int)(pm.height() * pixmap_scaling_ratio); int pmYOffset = 0; while ( getYSpace()<(pm.height()-pmYOffset) ) { int yFrag = pageBody.height() - yPos; if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 1: yPos=%d pmYOffset=%d " "yFrag=%d target_w=%d target_h=%d", yPos, pmYOffset, yFrag, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, yFrag); } pmYOffset = pmYOffset + yFrag; flushPage(); beginPage(); // resets yPos } if (pageNo>=fromPage && pageNo<=toPage) { if (fwbdebug) qDebug("Print pixmap 2: yPos=%d pmYOffset=%d target_w=%d target_h=%d", yPos, pmYOffset, target_w, target_h); pr.drawPixmap(xmargin, yPos, target_w, target_h, pm, 0, pmYOffset, -1, -1); } if (newLine) yPos = yPos + (target_h - pmYOffset); }
static bool device_widthMediaFeatureEval(CSSValueImpl* value, RenderStyle* style, KHTMLPart* part, MediaFeaturePrefix op) { if (value) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; int width; if (printing) width = pd->width(); else { width = QApplication::desktop()->screen(QApplication::desktop()->screenNumber( rootPart->view() ))->rect().width(); doc = static_cast<DOM::DocumentImpl*>(part->document().handle()); } int logicalDpiY = doc->logicalDpiY(); return value->isPrimitiveValue() && compareValue(width, static_cast<CSSPrimitiveValueImpl*>(value)->computeLength(style,logicalDpiY), op); } // ({,min-,max-}device-width) // assume if we have a device, assume non-zero return true; }
static bool aspect_ratioMediaFeatureEval(CSSValueImpl* value, RenderStyle*, KHTMLPart* part, MediaFeaturePrefix op) { if (value) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; QSize vs; int h = 0, v = 0; if (printing) { vs= QSize(pd->width(), pd->height()); } else { vs= QSize(part->view()->visibleWidth(), part->view()->visibleHeight()); } if (parseAspectRatio(value, h, v)) return v != 0 && compareValue(vs.width()*v, vs.height()*h, op); return false; } // ({,min-,max-}aspect-ratio) // assume if we have a viewport, its aspect ratio is non-zero return true; }
void StylePainter::init(GraphicsContext* context, QStyle* themeStyle) { painter = static_cast<QPainter*>(context->platformContext()); widget = 0; QPaintDevice* dev = 0; if (painter) dev = painter->device(); if (dev && dev->devType() == QInternal::Widget) widget = static_cast<QWidget*>(dev); style = themeStyle; if (painter) { // the styles often assume being called with a pristine painter where no brush is set, // so reset it manually oldBrush = painter->brush(); painter->setBrush(Qt::NoBrush); // painting the widget with anti-aliasing will make it blurry // disable it here and restore it later oldAntialiasing = painter->testRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing, false); } }
/*! Flush the internal pixmap buffer to the device. */ void QwtPaintBuffer::flush() { if ( d_enabled && d_device != 0 && d_rect.isValid()) { // We need a painter to find out if // there is a painter redirection for d_device. QPainter *p; if ( d_devicePainter == 0 ) p = new QPainter(d_device); else p = d_devicePainter; QPaintDevice *device = p->device(); if ( device->isExtDev() ) d_devicePainter->drawPixmap(d_rect.topLeft(), d_pixBuffer); else bitBlt(device, d_rect.topLeft(), &d_pixBuffer ); if ( d_devicePainter == 0 ) delete p; } }
static bool widthMediaFeatureEval(CSSValueImpl *value, RenderStyle *style, KHTMLPart *part, MediaFeaturePrefix op) { KHTMLPart *rootPart = part; while (rootPart->parentPart()) { rootPart = rootPart->parentPart(); } DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl *>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; int width; if (printing) { width = pd->width(); } else { width = part->view()->visibleWidth(); doc = static_cast<DOM::DocumentImpl *>(part->document().handle()); } int logicalDpiY = doc->logicalDpiY(); if (value) { return value->isPrimitiveValue() && compareValue(width, static_cast<CSSPrimitiveValueImpl *>(value)->computeLength(style, style, logicalDpiY), op); } return width > 0; }
void wxQtDCImpl::DoGetSizeMM(int* width, int* height) const { QPaintDevice *pDevice = m_qtPainter->device(); int deviceWidthMM; int deviceHeightMM; if ( pDevice ) { deviceWidthMM = pDevice->widthMM(); deviceHeightMM = pDevice->heightMM(); } else { deviceWidthMM = 0; deviceHeightMM = 0; } if ( width ) *width = deviceWidthMM; if ( height ) *height = deviceHeightMM; }
StylePainter::StylePainter(const RenderObject::PaintInfo& paintInfo) { painter = (paintInfo.context ? static_cast<QPainter*>(paintInfo.context->platformContext()) : 0); widget = 0; QPaintDevice* dev = 0; if (painter) dev = painter->device(); if (dev && dev->devType() == QInternal::Widget) widget = static_cast<QWidget*>(dev); style = (widget ? widget->style() : QApplication::style()); if (painter) { // the styles often assume being called with a pristine painter where no brush is set, // so reset it manually oldBrush = painter->brush(); painter->setBrush(Qt::NoBrush); // painting the widget with anti-aliasing will make it blurry // disable it here and restore it later oldAntialiasing = painter->testRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::Antialiasing, false); } }
static bool colorMediaFeatureEval(CSSValueImpl* value, RenderStyle*, KHTMLPart* part, MediaFeaturePrefix op) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; int bitsPerComponent = 0; if (printing) { if (pd->numColors() > 2) bitsPerComponent = pd->depth()/3; // assume printer is either b&w or color. } else { int sn = QApplication::desktop()->screenNumber( rootPart->view() ); if (QColormap::instance(sn).mode() != QColormap::Gray ) bitsPerComponent = QApplication::desktop()->screen(sn)->depth()/3; } if (value && bitsPerComponent) { float number = 0; return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op); } return bitsPerComponent; }
static bool orientationMediaFeatureEval(CSSValueImpl* value, RenderStyle*, KHTMLPart* part, MediaFeaturePrefix /*op*/) { if (value) { CSSPrimitiveValueImpl* pv = static_cast<CSSPrimitiveValueImpl*>(value); if (!value->isPrimitiveValue() || pv->primitiveType() != CSSPrimitiveValue::CSS_IDENT || (pv->getIdent() != CSS_VAL_PORTRAIT && pv->getIdent() != CSS_VAL_LANDSCAPE)) return false; KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; if (printing) { if (pd->width() > pd->height()) return (pv->getIdent() == CSS_VAL_LANDSCAPE); } else { if (part->view()->visibleWidth() > part->view()->visibleHeight()) return (pv->getIdent() == CSS_VAL_LANDSCAPE); } return (pv->getIdent() == CSS_VAL_PORTRAIT); } return false; }
static bool color_indexMediaFeatureEval(CSSValueImpl* value, RenderStyle*, KHTMLPart* part, MediaFeaturePrefix op) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; unsigned int numColors = 0; if (printing) { numColors = pd->numColors(); } else { int sn = QApplication::desktop()->screenNumber( rootPart->view() ); numColors = QApplication::desktop()->screen(sn)->numColors(); } if (numColors == INT_MAX) numColors = UINT_MAX; if (value) { float number = 0; return numberValue(value, number) && compareValue(numColors, static_cast<unsigned int>(number), op); } return numColors; }
static bool device_aspect_ratioMediaFeatureEval(CSSValueImpl* value, RenderStyle*, KHTMLPart* part, MediaFeaturePrefix op) { if (value) { KHTMLPart* rootPart = part; while (rootPart->parentPart()) rootPart = rootPart->parentPart(); DOM::DocumentImpl *doc = static_cast<DOM::DocumentImpl*>(rootPart->document().handle()); QPaintDevice *pd = doc->paintDevice(); bool printing = pd ? (pd->devType() == QInternal::Printer) : false; QRect sg; int h = 0, v = 0; if (printing) { sg = QRect(0, 0, pd->width(), pd->height()); } else { sg = QApplication::desktop()->screen(QApplication::desktop()->screenNumber( rootPart->view() ))->rect(); } if (parseAspectRatio(value, h, v)) return v != 0 && compareValue(sg.width()*v, sg.height()*h, op); return false; } // ({,min-,max-}device-aspect-ratio) // assume if we have a device, its aspect ratio is non-zero return true; }
void QgsComposerLegend::drawPointSymbol( QPainter* p, QgsSymbol* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int opacity ) const { if ( !s ) { return; } QImage pointImage; double rasterScaleFactor = 1.0; if ( p ) { QPaintDevice* paintDevice = p->device(); if ( !paintDevice ) { return; } rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4; } //width scale is 1.0 pointImage = s->getPointSymbolAsImage( 1.0, false, Qt::yellow, 1.0, 0.0, rasterScaleFactor, opacity / 255.0 ); if ( p ) { p->save(); p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); QPointF imageTopLeft( currentXPosition * rasterScaleFactor, currentYCoord * rasterScaleFactor ); p->drawImage( imageTopLeft, pointImage ); p->restore(); } currentXPosition += s->pointSize(); //pointImage.width() / rasterScaleFactor; symbolHeight = s->pointSize(); //pointImage.height() / rasterScaleFactor; }
void Style::drawTabBar(const QStyleOption *option, QPainter *painter, const QWidget *widget) const { ASSURE_OPTION(tbb, TabBarBase); if (!config.invert.headers) { if (tbb->selectedTabRect.isEmpty()) return; // only paint tab shapes if HAVE_OPTION(tbb2, TabBarBaseV2) { if (tbb2->documentMode) { return; // useless and adds confliciting horizintal lines } } SAVE_PAINTER(Pen|Alias); painter->setRenderHint(QPainter::Antialiasing, false); painter->setPen(QPen(FRAME_COLOR, FRAME_STROKE_WIDTH)); switch (tbb->shape) { case QTabBar::RoundedNorth: case QTabBar::TriangularNorth: painter->drawLine(RECT.x(), RECT.bottom(), tbb->selectedTabRect.x(), RECT.bottom()); painter->drawLine(tbb->selectedTabRect.right(), RECT.bottom(), RECT.right(), RECT.bottom()); break; case QTabBar::RoundedSouth: case QTabBar::TriangularSouth: painter->drawLine(RECT.x(), RECT.top(), tbb->selectedTabRect.x(), RECT.top()); painter->drawLine(tbb->selectedTabRect.right(), RECT.top(), RECT.right(), RECT.top()); break; case QTabBar::RoundedEast: case QTabBar::TriangularEast: painter->drawLine(RECT.x(), RECT.y(), RECT.x(), tbb->selectedTabRect.y()); painter->drawLine(RECT.x(), tbb->selectedTabRect.bottom(), RECT.x(), RECT.bottom()); break; case QTabBar::RoundedWest: case QTabBar::TriangularWest: painter->drawLine(RECT.right(), RECT.y(), RECT.right(), tbb->selectedTabRect.y()); painter->drawLine(RECT.right(), tbb->selectedTabRect.bottom(), RECT.right(), RECT.bottom()); break; } RESTORE_PAINTER return; } QWidget *win = 0; if (widget) { if (widget->parentWidget() && qobject_cast<QTabWidget*>(widget->parentWidget())) { if (widget->parentWidget()->style() == this) { return; // otherwise it's a proxystyle like on konqueror / kdevelop... } } else if (qobject_cast<const QTabBar*>(widget) || (appType == KDevelop && widget->inherits("QLabel"))) { return; // usually we alter the paintevent by eventfiltering } win = widget->window(); } else { if (painter->device()->devType() == QInternal::Widget) widget = static_cast<QWidget*>(painter->device()); else { QPaintDevice *dev = QPainter::redirected(painter->device()); if (dev && dev->devType() == QInternal::Widget) widget = static_cast<QWidget*>(dev); } if ( widget ) win = widget->window(); } QRect winRect; if (win) { winRect = win->rect(); winRect.moveTopLeft(widget->mapFrom(win, winRect.topLeft())); } // else // winRect = tbb->tabBarRect; // we set this from the eventfilter QEvent::Paint SAVE_PAINTER(Pen|Brush|Alias); painter->setBrush(PAL.color(QPalette::Active, QPalette::WindowText)); painter->setPen(Qt::NoPen); // TODO: half rounded rect? if (RECT.x() == winRect.x() || RECT.y() == winRect.y() || RECT.right() == winRect.right() || RECT.bottom() == winRect.bottom()) { painter->setRenderHint(QPainter::Antialiasing, false); painter->drawRect(RECT); } else { painter->setRenderHint(QPainter::Antialiasing, true); const int rnd = qMin(config.frame.roundness, verticalTabs(tbb->shape) ? RECT.width()/2 : RECT.height()/2); painter->drawRoundedRect(RECT, rnd, rnd); } RESTORE_PAINTER }
/// \brief Print the document (May be a file too) bool Exporter::doExport() { if(this->format < EXPORT_FORMAT_CSV) { // Choose the color values we need DsoSettingsColorValues *colorValues; if(this->format == EXPORT_FORMAT_IMAGE && this->settings->view.screenColorImages) colorValues = &(this->settings->view.color.screen); else colorValues = &(this->settings->view.color.print); QPaintDevice *paintDevice; if(this->format < EXPORT_FORMAT_IMAGE) { // We need a QPrinter for printing, pdf- and ps-export paintDevice = new QPrinter(QPrinter::HighResolution); static_cast<QPrinter *>(paintDevice)->setOrientation(this->settings->view.zoom ? QPrinter::Portrait : QPrinter::Landscape); static_cast<QPrinter *>(paintDevice)->setPageMargins(20, 20, 20, 20, QPrinter::Millimeter); if(this->format == EXPORT_FORMAT_PRINTER) { // Show the printing dialog QPrintDialog dialog(static_cast<QPrinter *>(paintDevice), static_cast<QWidget *>(this->parent())); dialog.setWindowTitle(tr("Print oscillograph")); if(dialog.exec() != QDialog::Accepted) { delete paintDevice; return false; } } else { // Configure the QPrinter static_cast<QPrinter *>(paintDevice)->setOutputFileName(this->filename); static_cast<QPrinter *>(paintDevice)->setOutputFormat((this->format == EXPORT_FORMAT_PDF) ? QPrinter::PdfFormat : QPrinter::PostScriptFormat); } } else { // We need a QPixmap for image-export paintDevice = new QPixmap(this->settings->options.imageSize); static_cast<QPixmap *>(paintDevice)->fill(colorValues->background); } // Create a painter for our device QPainter painter(paintDevice); // Get line height QFont font; QFontMetrics fontMetrics(font, paintDevice); double lineHeight = fontMetrics.height(); painter.setBrush(Qt::SolidPattern); this->dataAnalyzer->mutex()->lock(); // Draw the settings table double stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4; // Print trigger details painter.setPen(colorValues->voltage[this->settings->scope.trigger.source]); QString levelString = Helper::valueToString(this->settings->scope.voltage[this->settings->scope.trigger.source].trigger, Helper::UNIT_VOLTS, 3); QString pretriggerString = tr("%L1%").arg((int) (this->settings->scope.trigger.position * 100 + 0.5)); painter.drawText(QRectF(0, 0, lineHeight * 10, lineHeight), tr("%1 %2 %3 %4").arg(this->settings->scope.voltage[this->settings->scope.trigger.source].name, Dso::slopeString(this->settings->scope.trigger.slope), levelString, pretriggerString)); // Print sample count painter.setPen(colorValues->text); painter.drawText(QRectF(lineHeight * 10, 0, stretchBase, lineHeight), tr("%1 S").arg(this->dataAnalyzer->sampleCount()), QTextOption(Qt::AlignRight)); // Print samplerate painter.drawText(QRectF(lineHeight * 10 + stretchBase, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.samplerate, Helper::UNIT_SAMPLES) + tr("/s"), QTextOption(Qt::AlignRight)); // Print timebase painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.timebase, Helper::UNIT_SECONDS, 0) + tr("/div"), QTextOption(Qt::AlignRight)); // Print frequencybase painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, 0, stretchBase, lineHeight), Helper::valueToString(this->settings->scope.horizontal.frequencybase, Helper::UNIT_HERTZ, 0) + tr("/div"), QTextOption(Qt::AlignRight)); // Draw the measurement table stretchBase = (double) (paintDevice->width() - lineHeight * 6) / 10; int channelCount = 0; for(int channel = this->settings->scope.voltage.count() - 1; channel >= 0; channel--) { if((this->settings->scope.voltage[channel].used || this->settings->scope.spectrum[channel].used) && this->dataAnalyzer->data(channel)) { ++channelCount; double top = (double) paintDevice->height() - channelCount * lineHeight; // Print label painter.setPen(colorValues->voltage[channel]); painter.drawText(QRectF(0, top, lineHeight * 4, lineHeight), this->settings->scope.voltage[channel].name); // Print coupling/math mode if((unsigned int) channel < this->settings->scope.physicalChannels) painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::couplingString((Dso::Coupling) this->settings->scope.voltage[channel].misc)); else painter.drawText(QRectF(lineHeight * 4, top, lineHeight * 2, lineHeight), Dso::mathModeString((Dso::MathMode) this->settings->scope.voltage[channel].misc)); // Print voltage gain painter.drawText(QRectF(lineHeight * 6, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.voltage[channel].gain, Helper::UNIT_VOLTS, 0) + tr("/div"), QTextOption(Qt::AlignRight)); // Print spectrum magnitude painter.setPen(colorValues->spectrum[channel]); painter.drawText(QRectF(lineHeight * 6 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(this->settings->scope.spectrum[channel].magnitude, Helper::UNIT_DECIBEL, 0) + tr("/div"), QTextOption(Qt::AlignRight)); // Amplitude string representation (4 significant digits) painter.setPen(colorValues->text); painter.drawText(QRectF(lineHeight * 6 + stretchBase * 4, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->amplitude, Helper::UNIT_VOLTS, 4), QTextOption(Qt::AlignRight)); // Frequency string representation (5 significant digits) painter.drawText(QRectF(lineHeight * 6 + stretchBase * 7, top, stretchBase * 3, lineHeight), Helper::valueToString(this->dataAnalyzer->data(channel)->frequency, Helper::UNIT_HERTZ, 5), QTextOption(Qt::AlignRight)); } } // Draw the marker table double scopeHeight; stretchBase = (double) (paintDevice->width() - lineHeight * 10) / 4; painter.setPen(colorValues->text); // Calculate variables needed for zoomed scope double divs = fabs(this->settings->scope.horizontal.marker[1] - this->settings->scope.horizontal.marker[0]); double time = divs * this->settings->scope.horizontal.timebase; double zoomFactor = DIVS_TIME / divs; double zoomOffset = (this->settings->scope.horizontal.marker[0] + this->settings->scope.horizontal.marker[1]) / 2; if(this->settings->view.zoom) { scopeHeight = (double) (paintDevice->height() - (channelCount + 5) * lineHeight) / 2; double top = 2.5 * lineHeight + scopeHeight; painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Zoom x%L1").arg(DIVS_TIME / divs, -1, 'g', 3)); painter.drawText(QRectF(lineHeight * 10, top, stretchBase, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight)); painter.drawText(QRectF(lineHeight * 10 + stretchBase, top, stretchBase, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight)); painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase, lineHeight), Helper::valueToString(time / DIVS_TIME, Helper::UNIT_SECONDS, 3) + tr("/div"), QTextOption(Qt::AlignRight)); painter.drawText(QRectF(lineHeight * 10 + stretchBase * 3, top, stretchBase, lineHeight), Helper::valueToString(divs * this->settings->scope.horizontal.frequencybase / DIVS_TIME, Helper::UNIT_HERTZ, 3) + tr("/div"), QTextOption(Qt::AlignRight)); } else { scopeHeight = (double) paintDevice->height() - (channelCount + 4) * lineHeight; double top = 2.5 * lineHeight + scopeHeight; painter.drawText(QRectF(0, top, stretchBase, lineHeight), tr("Marker 1/2")); painter.drawText(QRectF(lineHeight * 10, top, stretchBase * 2, lineHeight), Helper::valueToString(time, Helper::UNIT_SECONDS, 4), QTextOption(Qt::AlignRight)); painter.drawText(QRectF(lineHeight * 10 + stretchBase * 2, top, stretchBase * 2, lineHeight), Helper::valueToString(1.0 / time, Helper::UNIT_HERTZ, 4), QTextOption(Qt::AlignRight)); } // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) / 2 + lineHeight * 1.5), false); // Draw the graphs painter.setRenderHint(QPainter::Antialiasing); painter.setBrush(Qt::NoBrush); for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); ++zoomed) { switch(this->settings->scope.horizontal.format) { case Dso::GRAPHFORMAT_TY: // Add graphs for channels for(int channel = 0 ; channel < this->settings->scope.voltage.count(); ++channel) { if(this->settings->scope.voltage[channel].used && this->dataAnalyzer->data(channel)) { painter.setPen(colorValues->voltage[channel]); // What's the horizontal distance between sampling points? double horizontalFactor = this->dataAnalyzer->data(channel)->samples.voltage.interval / this->settings->scope.horizontal.timebase; // How many samples are visible? double centerPosition, centerOffset; if(zoomed) { centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor; centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2; } else { centerPosition = DIVS_TIME / 2 / horizontalFactor; centerOffset = DIVS_TIME / horizontalFactor / 2; } unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0); unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.voltage.sample.size() - 1); // Draw graph QPointF *graph = new QPointF[lastPosition - firstPosition + 1]; for(unsigned int position = firstPosition; position <= lastPosition; ++position) graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.voltage.sample[position] / this->settings->scope.voltage[channel].gain + this->settings->scope.voltage[channel].offset); painter.drawPolyline(graph, lastPosition - firstPosition + 1); delete[] graph; } } // Add spectrum graphs for (int channel = 0; channel < this->settings->scope.spectrum.count(); ++channel) { if(this->settings->scope.spectrum[channel].used && this->dataAnalyzer->data(channel)) { painter.setPen(colorValues->spectrum[channel]); // What's the horizontal distance between sampling points? double horizontalFactor = this->dataAnalyzer->data(channel)->samples.spectrum.interval / this->settings->scope.horizontal.frequencybase; // How many samples are visible? double centerPosition, centerOffset; if(zoomed) { centerPosition = (zoomOffset + DIVS_TIME / 2) / horizontalFactor; centerOffset = DIVS_TIME / horizontalFactor / zoomFactor / 2; } else { centerPosition = DIVS_TIME / 2 / horizontalFactor; centerOffset = DIVS_TIME / horizontalFactor / 2; } unsigned int firstPosition = qMax((int) (centerPosition - centerOffset), 0); unsigned int lastPosition = qMin((int) (centerPosition + centerOffset), (int) this->dataAnalyzer->data(channel)->samples.spectrum.sample.size() - 1); // Draw graph QPointF *graph = new QPointF[lastPosition - firstPosition + 1]; for(unsigned int position = firstPosition; position <= lastPosition; ++position) graph[position - firstPosition] = QPointF(position * horizontalFactor - DIVS_TIME / 2, this->dataAnalyzer->data(channel)->samples.spectrum.sample[position] / this->settings->scope.spectrum[channel].magnitude + this->settings->scope.spectrum[channel].offset); painter.drawPolyline(graph, lastPosition - firstPosition + 1); delete[] graph; } } break; case Dso::GRAPHFORMAT_XY: break; default: break; } // Set DIVS_TIME / zoomFactor x DIVS_VOLTAGE matrix for zoomed oscillograph painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME * zoomFactor, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2 - zoomOffset * zoomFactor * (paintDevice->width() - 1) / DIVS_TIME, (scopeHeight - 1) * 1.5 + lineHeight * 4), false); } this->dataAnalyzer->mutex()->unlock(); // Draw grids painter.setRenderHint(QPainter::Antialiasing, false); for(int zoomed = 0; zoomed < (this->settings->view.zoom ? 2 : 1); ++zoomed) { // Set DIVS_TIME x DIVS_VOLTAGE matrix for oscillograph painter.setMatrix(QMatrix((paintDevice->width() - 1) / DIVS_TIME, 0, 0, -(scopeHeight - 1) / DIVS_VOLTAGE, (double) (paintDevice->width() - 1) / 2, (scopeHeight - 1) * (zoomed + 0.5) + lineHeight * 1.5 + lineHeight * 2.5 * zoomed), false); // Grid lines painter.setPen(colorValues->grid); if(this->format < EXPORT_FORMAT_IMAGE) { // Draw vertical lines for(int div = 1; div < DIVS_TIME / 2; ++div) { for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) { painter.drawLine(QPointF((double) -div - 0.02, (double) -dot / 5), QPointF((double) -div + 0.02, (double) -dot / 5)); painter.drawLine(QPointF((double) -div - 0.02, (double) dot / 5), QPointF((double) -div + 0.02, (double) dot / 5)); painter.drawLine(QPointF((double) div - 0.02, (double) -dot / 5), QPointF((double) div + 0.02, (double) -dot / 5)); painter.drawLine(QPointF((double) div - 0.02, (double) dot / 5), QPointF((double) div + 0.02, (double) dot / 5)); } } // Draw horizontal lines for(int div = 1; div < DIVS_VOLTAGE / 2; ++div) { for(int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) { painter.drawLine(QPointF((double) -dot / 5, (double) -div - 0.02), QPointF((double) -dot / 5, (double) -div + 0.02)); painter.drawLine(QPointF((double) dot / 5, (double) -div - 0.02), QPointF((double) dot / 5, (double) -div + 0.02)); painter.drawLine(QPointF((double) -dot / 5, (double) div - 0.02), QPointF((double) -dot / 5, (double) div + 0.02)); painter.drawLine(QPointF((double) dot / 5, (double) div - 0.02), QPointF((double) dot / 5, (double) div + 0.02)); } } } else { // Draw vertical lines for(int div = 1; div < DIVS_TIME / 2; ++div) { for(int dot = 1; dot < DIVS_VOLTAGE / 2 * 5; ++dot) { painter.drawPoint(QPointF(-div, (double) -dot / 5)); painter.drawPoint(QPointF(-div, (double) dot / 5)); painter.drawPoint(QPointF(div, (double) -dot / 5)); painter.drawPoint(QPointF(div, (double) dot / 5)); } } // Draw horizontal lines for(int div = 1; div < DIVS_VOLTAGE / 2; ++div) { for(int dot = 1; dot < DIVS_TIME / 2 * 5; ++dot) { if(dot % 5 == 0) continue; // Already done by vertical lines painter.drawPoint(QPointF((double) -dot / 5, -div)); painter.drawPoint(QPointF((double) dot / 5, -div)); painter.drawPoint(QPointF((double) -dot / 5, div)); painter.drawPoint(QPointF((double) dot / 5, div)); } } } // Axes painter.setPen(colorValues->axes); painter.drawLine(QPointF(-DIVS_TIME / 2, 0), QPointF(DIVS_TIME / 2, 0)); painter.drawLine(QPointF(0, -DIVS_VOLTAGE / 2), QPointF(0, DIVS_VOLTAGE / 2)); for(double div = 0.2; div <= DIVS_TIME / 2; div += 0.2) { painter.drawLine(QPointF(div, -0.05), QPointF(div, 0.05)); painter.drawLine(QPointF(-div, -0.05), QPointF(-div, 0.05)); } for(double div = 0.2; div <= DIVS_VOLTAGE / 2; div += 0.2) { painter.drawLine(QPointF(-0.05, div), QPointF(0.05, div)); painter.drawLine(QPointF(-0.05, -div), QPointF(0.05, -div)); } // Borders painter.setPen(colorValues->border); painter.drawRect(QRectF(-DIVS_TIME / 2, -DIVS_VOLTAGE / 2, DIVS_TIME, DIVS_VOLTAGE)); } painter.end(); if(this->format == EXPORT_FORMAT_IMAGE) static_cast<QPixmap *>(paintDevice)->save(this->filename); delete paintDevice; return true; } else { QFile csvFile(this->filename); if(!csvFile.open(QIODevice::WriteOnly | QIODevice::Text)) return false; QTextStream csvStream(&csvFile); for(int channel = 0 ; channel < this->settings->scope.voltage.count(); ++channel) { if(this->dataAnalyzer->data(channel)) { if(this->settings->scope.voltage[channel].used) { // Start with channel name and the sample interval csvStream << "\"" << this->settings->scope.voltage[channel].name << "\"," << this->dataAnalyzer->data(channel)->samples.voltage.interval; // And now all sample values in volts for(unsigned int position = 0; position < this->dataAnalyzer->data(channel)->samples.voltage.sample.size(); ++position) csvStream << "," << this->dataAnalyzer->data(channel)->samples.voltage.sample[position]; // Finally a newline csvStream << '\n'; } if(this->settings->scope.spectrum[channel].used) { // Start with channel name and the sample interval csvStream << "\"" << this->settings->scope.spectrum[channel].name << "\"," << this->dataAnalyzer->data(channel)->samples.spectrum.interval; // And now all magnitudes in dB for(unsigned int position = 0; position < this->dataAnalyzer->data(channel)->samples.spectrum.sample.size(); ++position) csvStream << "," << this->dataAnalyzer->data(channel)->samples.spectrum.sample[position]; // Finally a newline csvStream << '\n'; } } } csvFile.close(); return true; } }
void QgsMapRenderer::render( QPainter* painter, double* forceWidthScale ) { //Lock render method for concurrent threads (e.g. from globe) QMutexLocker renderLock( &mRenderMutex ); //flag to see if the render context has changed //since the last time we rendered. If it hasnt changed we can //take some shortcuts with rendering bool mySameAsLastFlag = true; QgsDebugMsg( "========== Rendering ==========" ); if ( mExtent.isEmpty() ) { QgsDebugMsg( "empty extent... not rendering" ); return; } if ( mSize.width() == 1 && mSize.height() == 1 ) { QgsDebugMsg( "size 1x1... not rendering" ); return; } QPaintDevice* thePaintDevice = painter->device(); if ( !thePaintDevice ) { return; } // wait if ( mDrawing ) { QgsDebugMsg( "already rendering" ); QCoreApplication::processEvents(); } if ( mDrawing ) { QgsDebugMsg( "still rendering - skipping" ); return; } mDrawing = true; const QgsCoordinateTransform *ct; #ifdef QGISDEBUG QgsDebugMsg( "Starting to render layer stack." ); QTime renderTime; renderTime.start(); #endif if ( mOverview ) mRenderContext.setDrawEditingInformation( !mOverview ); mRenderContext.setPainter( painter ); mRenderContext.setCoordinateTransform( 0 ); //this flag is only for stopping during the current rendering progress, //so must be false at every new render operation mRenderContext.setRenderingStopped( false ); // set selection color QgsProject* prj = QgsProject::instance(); int myRed = prj->readNumEntry( "Gui", "/SelectionColorRedPart", 255 ); int myGreen = prj->readNumEntry( "Gui", "/SelectionColorGreenPart", 255 ); int myBlue = prj->readNumEntry( "Gui", "/SelectionColorBluePart", 0 ); int myAlpha = prj->readNumEntry( "Gui", "/SelectionColorAlphaPart", 255 ); mRenderContext.setSelectionColor( QColor( myRed, myGreen, myBlue, myAlpha ) ); //calculate scale factor //use the specified dpi and not those from the paint device //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene) double sceneDpi = mScaleCalculator->dpi(); double scaleFactor = 1.0; if ( mOutputUnits == QgsMapRenderer::Millimeters ) { if ( forceWidthScale ) { scaleFactor = *forceWidthScale; } else { scaleFactor = sceneDpi / 25.4; } } double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi; if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor ) { mRenderContext.setRasterScaleFactor( rasterScaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.scaleFactor() != scaleFactor ) { mRenderContext.setScaleFactor( scaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.rendererScale() != mScale ) { //add map scale to render context mRenderContext.setRendererScale( mScale ); mySameAsLastFlag = false; } if ( mLastExtent != mExtent ) { mLastExtent = mExtent; mySameAsLastFlag = false; } mRenderContext.setLabelingEngine( mLabelingEngine ); if ( mLabelingEngine ) mLabelingEngine->init( this ); // know we know if this render is just a repeat of the last time, we // can clear caches if it has changed if ( !mySameAsLastFlag ) { //clear the cache pixmap if we changed resolution / extent QSettings mySettings; if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { QgsMapLayerRegistry::instance()->clearAllLayerCaches(); } } // render all layers in the stack, starting at the base QListIterator<QString> li( mLayerSet ); li.toBack(); QgsRectangle r1, r2; while ( li.hasPrevious() ) { if ( mRenderContext.renderingStopped() ) { break; } // Store the painter in case we need to swap it out for the // cache painter QPainter * mypContextPainter = mRenderContext.painter(); // Flattened image for drawing when a blending mode is set QImage * mypFlattenedImage = 0; QString layerId = li.previous(); QgsDebugMsg( "Rendering at layer item " + layerId ); // This call is supposed to cause the progress bar to // advance. However, it seems that updating the progress bar is // incompatible with having a QPainter active (the one that is // passed into this function), as Qt produces a number of errors // when try to do so. I'm (Gavin) not sure how to fix this, but // added these comments and debug statement to help others... QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" ); //emit drawingProgress(myRenderCounter++, mLayerSet.size()); QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( !ml ) { QgsDebugMsg( "Layer not found in registry!" ); continue; } QgsDebugMsg( QString( "layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 extent:%5 blendmode:%6" ) .arg( ml->name() ) .arg( ml->minimumScale() ) .arg( ml->maximumScale() ) .arg( ml->hasScaleBasedVisibility() ) .arg( ml->extent().toString() ) .arg( ml->blendMode() ) ); if ( mRenderContext.useAdvancedEffects() ) { // Set the QPainter composition mode so that this layer is rendered using // the desired blending mode mypContextPainter->setCompositionMode( ml->blendMode() ); } if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() <= mScale && mScale < ml->maximumScale() ) || mOverview ) { connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); // // Now do the call to the layer that actually does // the rendering work! // bool split = false; if ( hasCrsTransformEnabled() ) { r1 = mExtent; split = splitLayersExtent( ml, r1, r2 ); ct = transformation( ml ); mRenderContext.setExtent( r1 ); QgsDebugMsg( " extent 1: " + r1.toString() ); QgsDebugMsg( " extent 2: " + r2.toString() ); if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer { continue; } } else { ct = NULL; } mRenderContext.setCoordinateTransform( ct ); //decide if we have to scale the raster //this is necessary in case QGraphicsScene is used bool scaleRaster = false; QgsMapToPixel rasterMapToPixel; QgsMapToPixel bk_mapToPixel; if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 ) { scaleRaster = true; } // Force render of layers that are being edited // or if there's a labeling engine that needs the layer to register features if ( ml->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->isEditable() || ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) ) { ml->setCacheImage( 0 ); } } QSettings mySettings; bool useRenderCaching = false; if ( ! split )//render caching does not yet cater for split extents { if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { useRenderCaching = true; if ( !mySameAsLastFlag || ml->cacheImage() == 0 ) { QgsDebugMsg( "Caching enabled but layer redraw forced by extent change or empty cache" ); QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); if ( mypImage->isNull() ) { QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) ); emit drawError( ml ); painter->end(); // drawError is not caught by anyone, so we end painting to notify caller return; } mypImage->fill( 0 ); ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you QPainter * mypPainter = new QPainter( ml->cacheImage() ); // Changed to enable anti aliasing by default in QGIS 1.7 if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mRenderContext.setPainter( mypPainter ); } else if ( mySameAsLastFlag ) { //draw from cached image QgsDebugMsg( "Caching enabled --- drawing layer from cached image" ); mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); //short circuit as there is nothing else to do... continue; } } } // If we are drawing with an alternative blending mode then we need to render to a separate image // before compositing this on the map. This effectively flattens the layer and prevents // blending occuring between objects on the layer // (this is not required for raster layers or when layer caching is enabled, since that has the same effect) bool flattenedLayer = false; if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if (( !useRenderCaching ) && (( vl->blendMode() != QPainter::CompositionMode_SourceOver ) || ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver ) || ( vl->layerTransparency() != 0 ) ) ) { flattenedLayer = true; mypFlattenedImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); if ( mypFlattenedImage->isNull() ) { QgsDebugMsg( "insufficient memory for image " + QString::number( mRenderContext.painter()->device()->width() ) + "x" + QString::number( mRenderContext.painter()->device()->height() ) ); emit drawError( ml ); painter->end(); // drawError is not caught by anyone, so we end painting to notify caller return; } mypFlattenedImage->fill( 0 ); QPainter * mypPainter = new QPainter( mypFlattenedImage ); if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mypPainter->scale( rasterScaleFactor, rasterScaleFactor ); mRenderContext.setPainter( mypPainter ); } } // Per feature blending mode if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->featureBlendMode() != QPainter::CompositionMode_SourceOver ) { // set the painter to the feature blend mode, so that features drawn // on this layer will interact and blend with each other mRenderContext.painter()->setCompositionMode( vl->featureBlendMode() ); } } if ( scaleRaster ) { bk_mapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor ); rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor ); mRenderContext.setMapToPixel( rasterMapToPixel ); mRenderContext.painter()->save(); mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); } if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } else { QgsDebugMsg( "Layer rendered without issues" ); } if ( split ) { mRenderContext.setExtent( r2 ); if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } } if ( scaleRaster ) { mRenderContext.setMapToPixel( bk_mapToPixel ); mRenderContext.painter()->restore(); } //apply layer transparency for vector layers if (( mRenderContext.useAdvancedEffects() ) && ( ml->type() == QgsMapLayer::VectorLayer ) ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->layerTransparency() != 0 ) { // a layer transparency has been set, so update the alpha for the flattened layer // by combining it with the layer transparency QColor transparentFillColor = QColor( 0, 0, 0, 255 - ( 255 * vl->layerTransparency() / 100 ) ); // use destination in composition mode to merge source's alpha with destination mRenderContext.painter()->setCompositionMode( QPainter::CompositionMode_DestinationIn ); mRenderContext.painter()->fillRect( 0, 0, mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), transparentFillColor ); } } if ( useRenderCaching ) { // composite the cached image into our view and then clean up from caching // by reinstating the painter as it was swapped out for caching renders delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); //draw from cached image that we created further up if ( ml->cacheImage() ) mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); } else if ( flattenedLayer ) { // If we flattened this layer for alternate blend modes, composite it now delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); mypContextPainter->save(); mypContextPainter->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); mypContextPainter->drawImage( 0, 0, *( mypFlattenedImage ) ); mypContextPainter->restore(); delete mypFlattenedImage; mypFlattenedImage = 0; } disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); }
bool printerStream::begin() { if( !pr.begin(printer) ) // paint on printer return false; active=true; pageWidth = printer->width(); pageHeight = printer->height(); if (fwbdebug) { qDebug("printer dimensions: %dx%d",pageWidth,pageHeight); qDebug("Margin: %.1f", margin); } dpiy = printer->logicalDpiY(); ymargin = (int) ( (margin/2.54)*dpiy ); // assuming printer's resolutions by X and Y axes are the same xmargin = ymargin; pageBody = QRect( xmargin, ymargin, printer->width() - 2 * xmargin, printer->height() - 2 * ymargin ); yHeaderHeight = int((headerHeight / 2.54) * dpiy); yHeaderLine = int(((headerHeight - 0.5) / 2.54) * dpiy); pr.setFont(headerFont); QFontMetrics fm = pr.fontMetrics(); QRect br = fm.boundingRect("Page 999"); headerTextBox = QRect(xmargin, ymargin + yHeaderLine - fm.lineSpacing() - 1, printer->width() - 2 * xmargin, fm.lineSpacing() + 1); headerBox = QRect(xmargin, ymargin, printer->width() - 2 * xmargin, yHeaderHeight); if (fwbdebug) { qDebug("dpiy=%d", dpiy); qDebug("yHeaderHeight=%d", yHeaderHeight); qDebug("yHeaderLine=%d", yHeaderLine); qDebug("fm.lineSpacing()=%d", fm.lineSpacing()); qDebug("bounding rect for the header text: l=%d,t=%d,w=%d,h=%d", br.left(), br.top(), br.width(), br.height()); qDebug("headerBox: l=%d,t=%d,w=%d,h=%d", headerBox.left(), headerBox.top(), headerBox.width(), headerBox.height()); qDebug("headerTextBox: l=%d,t=%d,w=%d,h=%d", headerTextBox.left(), headerTextBox.top(), headerTextBox.width(), headerTextBox.height()); } yPos = 0; pageNo = 1; QPaintDevice *dev = pr.device(); // lets table with width 1000 pixels be drawn 80% of the page width pixmap_scaling_ratio = float(dev->width()) * 0.8 / 1000 * table_scaling; return true; }
void PluginView::paint(GraphicsContext* context, const IntRect& rect) { if (!m_isStarted) { paintMissingPluginIcon(context, rect); return; } if (context->paintingDisabled()) return; setNPWindowIfNeeded(); if (m_isWindowed || !m_drawable) return; const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display(); QPainter* painter = context->platformContext(); IntRect exposedRect(rect); exposedRect.intersect(frameRect()); exposedRect.move(-frameRect().x(), -frameRect().y()); QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared); const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth; ASSERT(drawableDepth == qtDrawable.depth()); // When printing, Qt uses a QPicture to capture the output in preview mode. The // QPicture holds a reference to the X Pixmap. As a result, the print preview would // update itself when the X Pixmap changes. To prevent this, we create a copy. if (m_element->document()->printing()) qtDrawable = qtDrawable.copy(); if (m_isTransparent && drawableDepth != 32) { // Attempt content propagation for drawable with no alpha by copying over from the backing store QPoint offset; QPaintDevice* backingStoreDevice = QPainter::redirected(painter->device(), &offset); offset = -offset; // negating the offset gives us the offset of the view within the backing store pixmap const bool hasValidBackingStore = backingStoreDevice && backingStoreDevice->devType() == QInternal::Pixmap; QPixmap* backingStorePixmap = static_cast<QPixmap*>(backingStoreDevice); // We cannot grab contents from the backing store when painting on QGraphicsView items // (because backing store contents are already transformed). What we really mean to do // here is to check if we are painting on QWebView, but let's be a little permissive :) QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient(); const bool backingStoreHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent()); if (hasValidBackingStore && backingStorePixmap->depth() == drawableDepth && backingStoreHasUntransformedContents) { GC gc = XDefaultGC(QX11Info::display(), QX11Info::appScreen()); XCopyArea(QX11Info::display(), backingStorePixmap->handle(), m_drawable, gc, offset.x() + m_windowRect.x() + exposedRect.x(), offset.y() + m_windowRect.y() + exposedRect.y(), exposedRect.width(), exposedRect.height(), exposedRect.x(), exposedRect.y()); } else { // no backing store, clean the pixmap because the plugin thinks its transparent QPainter painter(&qtDrawable); painter.fillRect(exposedRect, Qt::white); } if (syncX) QApplication::syncX(); } XEvent xevent; memset(&xevent, 0, sizeof(XEvent)); XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose; exposeEvent.type = GraphicsExpose; exposeEvent.display = QX11Info::display(); exposeEvent.drawable = qtDrawable.handle(); exposeEvent.x = exposedRect.x(); exposeEvent.y = exposedRect.y(); exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode dispatchNPEvent(xevent); if (syncX) XSync(m_pluginDisplay, False); // sync changes by plugin painter->drawPixmap(QPoint(frameRect().x() + exposedRect.x(), frameRect().y() + exposedRect.y()), qtDrawable, exposedRect); }
MainPage::MainPage(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { ui.setupUi(this); this->LoadQSS(); m_mousePressed = false; QObject::connect(ui.toolButtonHardware, SIGNAL(clicked()), this, SLOT(HardwareInforClicked())); QObject::connect(ui.toolButtonTempManagement, SIGNAL(clicked()), this, SLOT(TemperatureClicked())); QObject::connect(ui.toolButtonTestItem, SIGNAL(clicked()), this, SLOT(TestItemClicked())); QObject::connect(ui.pushButtonMin, SIGNAL(clicked()), this, SLOT(MinButtonClicked())); QObject::connect(ui.pushButtonClose, SIGNAL(clicked()), this, SLOT(CloseButtonClicked())); QObject::connect(ui.pushButtonUpdate, SIGNAL(clicked()), this, SLOT(UpdateButtonClicked())); QObject::connect(&m_checkNewTimer, SIGNAL(timeout()), this, SLOT(CheckNewTimerTimeout())); QObject::connect(&m_downloadNewTimer, SIGNAL(timeout()), this, SLOT(DownloadNewTimerTimeout())); // 隐藏默认窗口边框和标题栏 this->setWindowFlags(Qt::Window|Qt::FramelessWindowHint|Qt::WindowSystemMenuHint |Qt::WindowMinimizeButtonHint|Qt::WindowMaximizeButtonHint); this->setWindowIcon(QIcon(":/ControlImage/Main.png")); QString title = MAIN_TITLE; title += LAppParam::GetAppVersion(); this->ui.labelTitle->setText(title); this->ui.pushButtonUpdate->setVisible(false); // 获取当前系统DPI, 当前系统DPI除以设计时DPI值, 则得到UI放大系数 const float DESIGN_DPI = 96.0f; // 设计时DPI QPainter painter(this); QPaintDevice* pDevice = painter.device(); PrintLogW(L"System DPI X: %d, Y: %d", pDevice->logicalDpiX(), pDevice->logicalDpiY()); float ratioX = pDevice->logicalDpiX()/DESIGN_DPI; float ratioY = pDevice->logicalDpiY()/DESIGN_DPI; m_uiRatio = ratioX > ratioY ? ratioX : ratioY; if (m_uiRatio < 1.0f) m_uiRatio = 1.0f; PrintLogW(L"UI Ratio: %f", m_uiRatio); // 根据比例重新调整主UI大小, 并居中显示 int width = this->geometry().width() * m_uiRatio; int height = this->geometry().height() * m_uiRatio; this->setFixedSize(width, height); QDesktopWidget* pDesk = QApplication::desktop(); this->move((pDesk->width() - width) / 2, (pDesk->height() - height) / 2); // 显示启动画面 QPixmap originalImage(".\\Image\\Background\\splash.png"); QSize imageSize(originalImage.width() * m_uiRatio, originalImage.height() * m_uiRatio); QPixmap scaledImage = originalImage.scaled(imageSize, Qt::KeepAspectRatio); QFont splashFont("Microsoft YaHei UI", 10); m_splashScreen.setFont(splashFont); m_splashScreen.setPixmap(scaledImage); m_splashScreen.show(); width = ui.stackedWidget->width() * m_uiRatio; height = ui.stackedWidget->height() * m_uiRatio; m_splashScreen.showMessage(QObject::tr("Creating Hardware Page..."), Qt::AlignLeft | Qt::AlignTop, Qt::red); m_pHardwareInforPage = new HardwareInforPage(m_uiRatio); m_pHardwareInforPage->SetSplashScreen(&m_splashScreen); m_pHardwareInforPage->setFixedSize(width, height); m_pHardwareInforPage->InitHardwareInfor(); ui.stackedWidget->addWidget(m_pHardwareInforPage); m_splashScreen.showMessage(QObject::tr("Creating Temperature Page..."), Qt::AlignLeft | Qt::AlignTop, Qt::red); m_pTempManagementPage = new TempManagementPage(); m_pTempManagementPage->setFixedSize(width, height); ui.stackedWidget->addWidget(m_pTempManagementPage); m_splashScreen.showMessage(QObject::tr("Creating Test Item Page..."), Qt::AlignLeft | Qt::AlignTop, Qt::red); m_pTestItemPage = new TestItemPage(m_uiRatio); m_pTestItemPage->setFixedSize(width, height); ui.stackedWidget->addWidget(m_pTestItemPage); if (APP_NORMAL == LAppParam::GetStartMode()) ui.stackedWidget->setCurrentWidget(m_pHardwareInforPage); else if (APP_RESTARTAGING == LAppParam::GetStartMode()) ui.stackedWidget->setCurrentWidget(m_pTestItemPage); else ui.stackedWidget->setCurrentWidget(m_pTestItemPage); }
QRect QGLPainterSurface::viewportGL() const { QPaintDevice *device = m_painter->device(); return QRect(0, 0, device->width(), device->height()); }
void DrawWidget::drawChannel(QPaintDevice &pd, Channel *ch, QPainter &p, double leftTime, double currentTime, double zoomX, double viewBottom, double zoomY, int viewType) { ZoomLookup *z; if(viewType == DRAW_VIEW_SUMMARY) z = &ch->summaryZoomLookup; else z = &ch->normalZoomLookup; ChannelLocker channelLocker(ch); QColor current = ch->color; QColor invert(255 - current.red(), 255 - current.green(), 255 - current.blue()); p.setPen(current); int viewBottomOffset = toInt(viewBottom / zoomY); printf("viewBottomOffset=%d, %f, %f\n", viewBottomOffset, viewBottom, zoomY); viewBottom = double(viewBottomOffset) * zoomY; // baseX is the no. of chunks a pixel must represent. double baseX = zoomX / ch->timePerChunk(); z->setZoomLevel(baseX); double currentChunk = ch->chunkFractionAtTime(currentTime); double leftFrameTime = currentChunk - ((currentTime - leftTime) / ch->timePerChunk()); //double leftFrameTime = leftTime / ch->timePerChunk(); double frameTime = leftFrameTime; //if(frameTime < 0.0) frameTime = 0.0; int n = 0; int baseElement = int(floor(frameTime / baseX)); if(baseElement < 0) { n -= baseElement; baseElement = 0; } int lastBaseElement = int(floor(double(ch->totalChunks()) / baseX)); Q3PointArray pointArray(pd.width()*2); //QPointArray topPoints(width()*2); //QPointArray bottomPoints(width()*2); //int pointIndex = 0; //int pointIndex = 0; if (baseX > 1) { // More samples than pixels int theWidth = pd.width(); //if(baseElement + theWidth > z->size()) z->setSize(baseElement + theWidth); if(lastBaseElement > z->size()) z->setSize(lastBaseElement); for(; n < theWidth && baseElement < lastBaseElement; n++, baseElement++) { myassert(baseElement >= 0); ZoomElement &ze = z->at(baseElement); if(!ze.isValid()) { if(calcZoomElement(ch, ze, baseElement, baseX)) continue; } if(ze.high() != 0.0f && ze.high() - ze.low() < 1.0) { //if range is closer than one semi-tone then draw a line between them //if(ze.noteLow > 0) { p.setPen(ze.color()); //p.setPen(QPen(ze.color(), lineWidth)); //Note: lineTo doen't draw a pixel on the last point of the line p.drawLine(n, pd.height() - lineTopHalfWidth - toInt(ze.high() / zoomY) + viewBottomOffset, n, pd.height() + lineBottomHalfWidth - toInt(ze.low() / zoomY) + viewBottomOffset); //pointArray.setPoint(pointIndex++, n, height() - lineTopHalfWidth - toInt(ze.high / zoomY) + viewBottomOffset); //pointArray.setPoint(pointIndex++, n, height() + lineBottomHalfWidth - toInt(ze.low / zoomY) + viewBottomOffset); } } //myassert(pointIndex <= width()*2); //p.setPen(ch->color); //p.drawLineSegments(pointArray, 0, pointIndex/2); } else { // More pixels than samples float err = 0.0, pitch = 0.0, prevPitch = 0.0, vol; int intChunk = (int) floor(frameTime); // Integer version of frame time if(intChunk < 0) intChunk = 0; double stepSize = 1.0 / baseX; // So we skip some pixels int x = 0, y; //double start = 0 - stepSize; double start = (double(intChunk) - frameTime) * stepSize; double stop = pd.width() + (2 * stepSize); int squareSize = (int(sqrt(stepSize)) / 2) * 2 + 1; //make it an odd number int halfSquareSize = squareSize/2; int penX=0, penY=0; //topPoints.setPoint(pointIndex, toInt(start), 0); //bottomPoints.setPoint(pointIndex++, toInt(start), height()); for (double n = start; n < stop && intChunk < (int)ch->totalChunks(); n += stepSize, intChunk++) { myassert(intChunk >= 0); //if (intChunk < 0) continue; // So we don't go off the beginning of the array AnalysisData *data = ch->dataAtChunk(intChunk); err = data->getCorrelation(); //vol = dB2ViewVal(data->logrms(), ch->rmsCeiling, ch->rmsFloor); vol = dB2Normalised(data->getLogRms(), ch->rmsCeiling, ch->rmsFloor); //if (err >= CERTAIN_THRESHOLD) { //float val = MIN(ch->dataAtChunk(intChunk)->volumeValue, 1.0); if(gdata->pitchContourMode() == 0) //p.setPen(QPen(colorBetween(colorGroup().background(), ch->color, err*2.0-1.0), lineWidth)); //p.setPen(QPen(colorBetween(gdata->backgroundColor(), ch->color, err*sqrt(data->rms)*10.0), lineWidth)); if(viewType == DRAW_VIEW_PRINT) p.setPen(QPen(colorBetween(QColor(255, 255, 255), ch->color, err*vol), lineWidth)); else p.setPen(QPen(colorBetween(gdata->backgroundColor(), ch->color, err*vol), lineWidth)); else p.setPen(QPen(ch->color, lineWidth)); x = toInt(n); //note = (data->isValid()) ? data->note : 0.0f; //note = (ch->isVisibleNote(data->noteIndex)) ? data->note : 0.0f; pitch = (ch->isVisibleChunk(data)) ? data->getPitch() : 0.0f; myassert(pitch >= 0.0 && pitch <= gdata->topPitch()); //pitch = bound(pitch, 0, gdata->topPitch()); y = pd.height() - 1 - toInt(pitch / zoomY) + viewBottomOffset; //y = height() - 1 - int((note / zoomY) - (viewBottom / zoomY)); if(pitch > 0.0f) { if(fabs(prevPitch - pitch) < 1.0 && n != start) { //if closer than one semi-tone from previous then draw a line between them //p.lineTo(x, y); p.drawLine(penX, penY, x, y); penX = x; penY = y; } else { p.drawPoint(x, y); //p.moveTo(x, y); penX = x; penY = y; } if(stepSize > 10) { //draw squares on the data points //p.setPen(invert); p.setBrush(Qt::NoBrush); p.drawRect(x - halfSquareSize, y - halfSquareSize, squareSize, squareSize); //p.setPen(QPen(current, 2)); } //} else { // p.moveTo(x, height()-1-int(((note-viewBottom) / zoomY))); //} } prevPitch = pitch; } } }
void QgsMapRenderer::render( QPainter* painter ) { //flag to see if the render context has changed //since the last time we rendered. If it hasnt changed we can //take some shortcuts with rendering bool mySameAsLastFlag = true; QgsDebugMsg( "========== Rendering ==========" ); if ( mExtent.isEmpty() ) { QgsDebugMsg( "empty extent... not rendering" ); return; } if ( mSize.width() == 1 && mSize.height() == 1 ) { QgsDebugMsg( "size 1x1... not rendering" ); return; } QPaintDevice* thePaintDevice = painter->device(); if ( !thePaintDevice ) { return; } // wait if ( mDrawing ) { QgsDebugMsg( "already rendering" ); QCoreApplication::processEvents(); } if ( mDrawing ) { QgsDebugMsg( "still rendering - skipping" ); return; } mDrawing = true; QgsCoordinateTransform* ct; #ifdef QGISDEBUG QgsDebugMsg( "Starting to render layer stack." ); QTime renderTime; renderTime.start(); #endif if ( mOverview ) mRenderContext.setDrawEditingInformation( !mOverview ); mRenderContext.setPainter( painter ); mRenderContext.setCoordinateTransform( 0 ); //this flag is only for stopping during the current rendering progress, //so must be false at every new render operation mRenderContext.setRenderingStopped( false ); //calculate scale factor //use the specified dpi and not those from the paint device //because sometimes QPainter units are in a local coord sys (e.g. in case of QGraphicsScene) double sceneDpi = mScaleCalculator->dpi(); double scaleFactor = 1.0; if ( mOutputUnits == QgsMapRenderer::Millimeters ) { scaleFactor = sceneDpi / 25.4; } double rasterScaleFactor = ( thePaintDevice->logicalDpiX() + thePaintDevice->logicalDpiY() ) / 2.0 / sceneDpi; if ( mRenderContext.rasterScaleFactor() != rasterScaleFactor ) { mRenderContext.setRasterScaleFactor( rasterScaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.scaleFactor() != scaleFactor ) { mRenderContext.setScaleFactor( scaleFactor ); mySameAsLastFlag = false; } if ( mRenderContext.rendererScale() != mScale ) { //add map scale to render context mRenderContext.setRendererScale( mScale ); mySameAsLastFlag = false; } if ( mLastExtent != mExtent ) { mLastExtent = mExtent; mySameAsLastFlag = false; } mRenderContext.setLabelingEngine( mLabelingEngine ); if ( mLabelingEngine ) mLabelingEngine->init( this ); // know we know if this render is just a repeat of the last time, we // can clear caches if it has changed if ( !mySameAsLastFlag ) { //clear the cache pixmap if we changed resolution / extent QSettings mySettings; if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { QgsMapLayerRegistry::instance()->clearAllLayerCaches(); } } QgsOverlayObjectPositionManager* overlayManager = overlayManagerFromSettings(); QList<QgsVectorOverlay*> allOverlayList; //list of all overlays, used to draw them after layers have been rendered // render all layers in the stack, starting at the base QListIterator<QString> li( mLayerSet ); li.toBack(); QgsRectangle r1, r2; while ( li.hasPrevious() ) { if ( mRenderContext.renderingStopped() ) { break; } // Store the painter in case we need to swap it out for the // cache painter QPainter * mypContextPainter = mRenderContext.painter(); QString layerId = li.previous(); QgsDebugMsg( "Rendering at layer item " + layerId ); // This call is supposed to cause the progress bar to // advance. However, it seems that updating the progress bar is // incompatible with having a QPainter active (the one that is // passed into this function), as Qt produces a number of errors // when try to do so. I'm (Gavin) not sure how to fix this, but // added these comments and debug statement to help others... QgsDebugMsg( "If there is a QPaintEngine error here, it is caused by an emit call" ); //emit drawingProgress(myRenderCounter++, mLayerSet.size()); QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( !ml ) { QgsDebugMsg( "Layer not found in registry!" ); continue; } QgsDebugMsg( "Rendering layer " + ml->name() ); QgsDebugMsg( " Layer minscale " + QString( "%1" ).arg( ml->minimumScale() ) ); QgsDebugMsg( " Layer maxscale " + QString( "%1" ).arg( ml->maximumScale() ) ); QgsDebugMsg( " Scale dep. visibility enabled? " + QString( "%1" ).arg( ml->hasScaleBasedVisibility() ) ); QgsDebugMsg( " Input extent: " + ml->extent().toString() ); if ( !ml->hasScaleBasedVisibility() || ( ml->minimumScale() < mScale && mScale < ml->maximumScale() ) || mOverview ) { connect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); // // Now do the call to the layer that actually does // the rendering work! // bool split = false; if ( hasCrsTransformEnabled() ) { r1 = mExtent; split = splitLayersExtent( ml, r1, r2 ); ct = new QgsCoordinateTransform( ml->crs(), *mDestCRS ); mRenderContext.setExtent( r1 ); QgsDebugMsg( " extent 1: " + r1.toString() ); QgsDebugMsg( " extent 2: " + r2.toString() ); if ( !r1.isFinite() || !r2.isFinite() ) //there was a problem transforming the extent. Skip the layer { continue; } } else { ct = NULL; } mRenderContext.setCoordinateTransform( ct ); //decide if we have to scale the raster //this is necessary in case QGraphicsScene is used bool scaleRaster = false; QgsMapToPixel rasterMapToPixel; QgsMapToPixel bk_mapToPixel; if ( ml->type() == QgsMapLayer::RasterLayer && qAbs( rasterScaleFactor - 1.0 ) > 0.000001 ) { scaleRaster = true; } //create overlay objects for features within the view extent if ( ml->type() == QgsMapLayer::VectorLayer && overlayManager ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl ) { QList<QgsVectorOverlay*> thisLayerOverlayList; vl->vectorOverlays( thisLayerOverlayList ); QList<QgsVectorOverlay*>::iterator overlayIt = thisLayerOverlayList.begin(); for ( ; overlayIt != thisLayerOverlayList.end(); ++overlayIt ) { if (( *overlayIt )->displayFlag() ) { ( *overlayIt )->createOverlayObjects( mRenderContext ); allOverlayList.push_back( *overlayIt ); } } overlayManager->addLayer( vl, thisLayerOverlayList ); } } // Force render of layers that are being edited // or if there's a labeling engine that needs the layer to register features if ( ml->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( ml ); if ( vl->isEditable() || ( mRenderContext.labelingEngine() && mRenderContext.labelingEngine()->willUseLayer( vl ) ) ) { ml->setCacheImage( 0 ); } } QSettings mySettings; if ( ! split )//render caching does not yet cater for split extents { if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { if ( !mySameAsLastFlag || ml->cacheImage() == 0 ) { QgsDebugMsg( "\n\n\nCaching enabled but layer redraw forced by extent change or empty cache\n\n\n" ); QImage * mypImage = new QImage( mRenderContext.painter()->device()->width(), mRenderContext.painter()->device()->height(), QImage::Format_ARGB32 ); mypImage->fill( 0 ); ml->setCacheImage( mypImage ); //no need to delete the old one, maplayer does it for you QPainter * mypPainter = new QPainter( ml->cacheImage() ); // Changed to enable anti aliasing by default in QGIS 1.7 if ( mySettings.value( "/qgis/enable_anti_aliasing", true ).toBool() ) { mypPainter->setRenderHint( QPainter::Antialiasing ); } mRenderContext.setPainter( mypPainter ); } else if ( mySameAsLastFlag ) { //draw from cached image QgsDebugMsg( "\n\n\nCaching enabled --- drawing layer from cached image\n\n\n" ); mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); //short circuit as there is nothing else to do... continue; } } } if ( scaleRaster ) { bk_mapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel = mRenderContext.mapToPixel(); rasterMapToPixel.setMapUnitsPerPixel( mRenderContext.mapToPixel().mapUnitsPerPixel() / rasterScaleFactor ); rasterMapToPixel.setYMaximum( mSize.height() * rasterScaleFactor ); mRenderContext.setMapToPixel( rasterMapToPixel ); mRenderContext.painter()->save(); mRenderContext.painter()->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); } if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } else { QgsDebugMsg( "Layer rendered without issues" ); } if ( split ) { mRenderContext.setExtent( r2 ); if ( !ml->draw( mRenderContext ) ) { emit drawError( ml ); } } if ( scaleRaster ) { mRenderContext.setMapToPixel( bk_mapToPixel ); mRenderContext.painter()->restore(); } if ( mySettings.value( "/qgis/enable_render_caching", false ).toBool() ) { if ( !split ) { // composite the cached image into our view and then clean up from caching // by reinstating the painter as it was swapped out for caching renders delete mRenderContext.painter(); mRenderContext.setPainter( mypContextPainter ); //draw from cached image that we created further up mypContextPainter->drawImage( 0, 0, *( ml->cacheImage() ) ); } } disconnect( ml, SIGNAL( drawingProgress( int, int ) ), this, SLOT( onDrawingProgress( int, int ) ) ); } else // layer not visible due to scale {
void WindowSurfaceImpl::updateSurfaceData() { // If painting is active, i.e. beginPaint has been called // surface data is not updated if(mPaintingStarted) { return; } QWindowSurface* surface = mMainSurface.widget->windowSurface(); // If window surface is null it means that the widget has been // sent to background and widget's window surface has been deleted, // in such case create own QImage as local surface in order to support // rendering in background if(surface == NULL) { // check if we already have local surface with valid size if(!isLocalSurfaceValid()) { // incase we have invalid surface delete the current one // and create new if(mMainSurface.localSurfaceInUse) { deleteLocalSurface(); } createLocalSurface(); // set info mMainSurface.qSurface = NULL; mMainSurface.device = mMainSurface.localSurface; mMainSurface.type = WsTypeQtImage; mMainSurface.localSurfaceInUse = true; return; } else { // We have valid local surface so make sure its active and return mMainSurface.localSurfaceInUse = true; return; } } else { // We got Qt's window surface, so in case we had local surface in use // delete it as it's not used anymore if(mMainSurface.localSurfaceInUse) { // in case we have needed the local surface as temp // buffer for a client, it is not deleted as we most likely // will need it again. In any case the local surface // stops to be the main surface and is atleast demoted to // temp surface. if(!mPreserveLocalSurface) { deleteLocalSurface(); } } } // We got window surface so extract information QPaintDevice* device = surface->paintDevice(); QPaintEngine* engine = NULL; // If the device is active it means that some painter is attached to the widget, // if not then we attach our own painter to do the job if(device->paintingActive()) { engine = device->paintEngine(); } else { mPainter.begin(device); engine = mPainter.paintEngine(); } // determine the surface type based on the engine used // as Qt does not provide exact info of the surface type switch (engine->type()) { case QPaintEngine::OpenVG: // surface is EGL window surface mMainSurface.type = WsTypeEglSurface; break; case QPaintEngine::Raster: mMainSurface.type = WsTypeSymbianBitmap; if(device->devType() == QInternal::Pixmap) { QPixmap* pixmap = static_cast<QPixmap*>(device); mMainSurface.symbianBitmap = pixmap->toSymbianCFbsBitmap(); } else { throw GfxException(EGfxErrorIllegalArgument, "Unsupported device type"); } break; default: throw GfxException(EGfxErrorIllegalArgument, "Unsupported widget window surface type"); } // release painter if its active if(mPainter.isActive()) { mPainter.end(); } mMainSurface.qSurface = surface; mMainSurface.device = device; mMainSurface.localSurfaceInUse = false; }
void QgsComposerLegend::drawSymbolV2( QPainter* p, QgsSymbolV2* s, double currentYCoord, double& currentXPosition, double& symbolHeight, int layerOpacity ) const { if ( !p || !s ) { return; } double rasterScaleFactor = 1.0; if ( p ) { QPaintDevice* paintDevice = p->device(); if ( !paintDevice ) { return; } rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4; } //consider relation to composer map for symbol sizes in mm bool sizeInMapUnits = s->outputUnit() == QgsSymbolV2::MapUnit; double mmPerMapUnit = 1; if ( mComposerMap ) { mmPerMapUnit = mComposerMap->mapUnitsToMM(); } QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( s ); //Consider symbol size for point markers double height = mSymbolHeight; double width = mSymbolWidth; double size = 0; //Center small marker symbols double widthOffset = 0; double heightOffset = 0; if ( markerSymbol ) { size = markerSymbol->size(); height = size; width = size; if ( mComposerMap && sizeInMapUnits ) { height *= mmPerMapUnit; width *= mmPerMapUnit; markerSymbol->setSize( width ); } if ( width < mSymbolWidth ) { widthOffset = ( mSymbolWidth - width ) / 2.0; } if ( height < mSymbolHeight ) { heightOffset = ( mSymbolHeight - height ) / 2.0; } } p->save(); p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset ); p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor ); if ( markerSymbol && sizeInMapUnits ) { s->setOutputUnit( QgsSymbolV2::MM ); } s->drawPreviewIcon( p, QSize( width * rasterScaleFactor, height * rasterScaleFactor ) ); if ( markerSymbol && sizeInMapUnits ) { s->setOutputUnit( QgsSymbolV2::MapUnit ); markerSymbol->setSize( size ); } p->restore(); currentXPosition += width; currentXPosition += 2 * widthOffset; symbolHeight = height + 2 * heightOffset; }
static cairo_status_t _cairo_qt_surface_acquire_dest_image (void *abstract_surface, cairo_rectangle_int_t *interest_rect, cairo_image_surface_t **image_out, cairo_rectangle_int_t *image_rect, void **image_extra) { cairo_qt_surface_t *qs = (cairo_qt_surface_t *) abstract_surface; QImage *qimg = NULL; D(fprintf(stderr, "q[%p] acquire_dest_image\n", abstract_surface)); *image_extra = NULL; if (qs->image_equiv) { *image_out = (cairo_image_surface_t*) cairo_surface_reference (qs->image_equiv); image_rect->x = qs->window.x(); image_rect->y = qs->window.y(); image_rect->width = qs->window.width(); image_rect->height = qs->window.height(); return CAIRO_STATUS_SUCCESS; } QPoint offset; if (qs->pixmap) { qimg = new QImage(qs->pixmap->toImage()); } else { // Try to figure out what kind of QPaintDevice we have, and // how we can grab an image from it QPaintDevice *pd = qs->p->device(); if (!pd) return _cairo_error (CAIRO_STATUS_NO_MEMORY); QPaintDevice *rpd = QPainter::redirected(pd, &offset); if (rpd) pd = rpd; if (pd->devType() == QInternal::Image) { qimg = new QImage(((QImage*) pd)->copy()); } else if (pd->devType() == QInternal::Pixmap) { qimg = new QImage(((QPixmap*) pd)->toImage()); } else if (pd->devType() == QInternal::Widget) { qimg = new QImage(QPixmap::grabWindow(((QWidget*)pd)->winId()).toImage()); } } if (qimg == NULL) return _cairo_error (CAIRO_STATUS_NO_MEMORY); *image_out = (cairo_image_surface_t*) cairo_image_surface_create_for_data (qimg->bits(), _cairo_format_from_qimage_format (qimg->format()), qimg->width(), qimg->height(), qimg->bytesPerLine()); *image_extra = qimg; image_rect->x = qs->window.x() + offset.x(); image_rect->y = qs->window.y() + offset.y(); image_rect->width = qs->window.width() - offset.x(); image_rect->height = qs->window.height() - offset.y(); return CAIRO_STATUS_SUCCESS; }
void QgsDecorationCopyright::render( const QgsMapSettings &mapSettings, QgsRenderContext &context ) { Q_UNUSED( mapSettings ); if ( !enabled() ) return; context.painter()->save(); context.painter()->setRenderHint( QPainter::Antialiasing, true ); QString displayString = QgsExpression::replaceExpressionText( mLabelText, &context.expressionContext() ); QStringList displayStringList = displayString.split( QStringLiteral( "\n" ) ); QFontMetricsF fm( mTextFormat.scaledFont( context ) ); double textWidth = QgsTextRenderer::textWidth( context, mTextFormat, displayStringList, &fm ); double textHeight = QgsTextRenderer::textHeight( context, mTextFormat, displayStringList, QgsTextRenderer::Point, &fm ); QPaintDevice *device = context.painter()->device(); int deviceHeight = device->height() / device->devicePixelRatioF(); int deviceWidth = device->width() / device->devicePixelRatioF(); float xOffset( 0 ), yOffset( 0 ); // Set margin according to selected units switch ( mMarginUnit ) { case QgsUnitTypes::RenderMillimeters: { int pixelsInchX = context.painter()->device()->logicalDpiX(); int pixelsInchY = context.painter()->device()->logicalDpiY(); xOffset = pixelsInchX * INCHES_TO_MM * mMarginHorizontal; yOffset = pixelsInchY * INCHES_TO_MM * mMarginVertical; break; } case QgsUnitTypes::RenderPixels: { xOffset = mMarginHorizontal; yOffset = mMarginVertical; break; } case QgsUnitTypes::RenderPercentage: { xOffset = ( ( deviceWidth - textWidth ) / 100. ) * mMarginHorizontal; yOffset = ( ( deviceHeight - textHeight ) / 100. ) * mMarginVertical; break; } case QgsUnitTypes::RenderMapUnits: case QgsUnitTypes::RenderPoints: case QgsUnitTypes::RenderInches: case QgsUnitTypes::RenderUnknownUnit: case QgsUnitTypes::RenderMetersInMapUnits: break; } // Determine placement of label from form combo box QgsTextRenderer::HAlignment horizontalAlignment = QgsTextRenderer::AlignLeft; switch ( mPlacement ) { case BottomLeft: // Bottom Left, xOffset is set above yOffset = deviceHeight - yOffset; break; case TopLeft: // Top left, xOffset is set above yOffset = yOffset + textHeight; break; case TopRight: // Top Right yOffset = yOffset + textHeight; xOffset = deviceWidth - xOffset; horizontalAlignment = QgsTextRenderer::AlignRight; break; case BottomRight: // Bottom Right yOffset = deviceHeight - yOffset; xOffset = deviceWidth - xOffset; horizontalAlignment = QgsTextRenderer::AlignRight; break; default: QgsDebugMsg( QStringLiteral( "Unknown placement index of %1" ).arg( static_cast<int>( mPlacement ) ) ); } //Paint label to canvas QgsTextRenderer::drawText( QPointF( xOffset, yOffset ), 0.0, horizontalAlignment, displayStringList, context, mTextFormat ); context.painter()->restore(); }