示例#1
0
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;
}
示例#4
0
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);
}
示例#6
0
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;
}
示例#7
0
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;
}
示例#8
0
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;
    }
}
示例#10
0
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;
}
示例#11
0
文件: dc.cpp 项目: catalinr/wxWidgets
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;
}
示例#12
0
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);
    }
}
示例#13
0
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;
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
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;
}
示例#18
0
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
}
示例#19
0
/// \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;
	}
}
示例#20
0
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 ) ) );
    }
示例#21
0
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;
}
示例#22
0
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);
}
示例#23
0
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());
}
示例#25
0
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;
    }
  }
}
示例#26
0
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;
}
示例#29
0
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();
}