📄 qpaintengine_raster.cpp
字号:
delete d->rasterBuffer; delete d->outlineMapper;#ifdef Q_WS_WIN delete d->fontRasterBuffer;#endif delete d->dashStroker;}/*! \reimp*/bool QRasterPaintEngine::begin(QPaintDevice *device){ Q_D(QRasterPaintEngine); // ####### move to QApp qInitDrawhelperAsm(); d->deviceDepth = device->depth(); d->antialiased = false; d->bilinear = false; d->mono_surface = false; d->fast_pen = true; d->int_xform = true; d->user_clip_enabled = false; d->opacity = 256; d->fast_text = true; d->paint_unclipped = false; d->tx_noshear = true; const QPaintDevice *originalDevice = painter()->d_ptr->original_device; if (originalDevice->devType() == QInternal::Widget) { const QWidget *widget = static_cast<const QWidget *>(originalDevice); if (widget->testAttribute(Qt::WA_PaintUnclipped)) d->paint_unclipped = true; } painter()->d_func()->fillrect_func = static_cast<QPainterPrivate::FillRectBackdoor>(&QRasterPaintEngine::fastFillRect); d->inverseScale = qreal(1);#if defined(Q_WS_WIN) d->isPlain45DegreeRotation = true; d->clear_type_text = false; QT_WA({ UINT result; BOOL ok; ok = SystemParametersInfoW(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); if (ok) d->clear_type_text = (result == FE_FONTSMOOTHINGCLEARTYPE); }, { UINT result; BOOL ok; ok = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0); if (ok) d->clear_type_text = (result == FE_FONTSMOOTHINGCLEARTYPE); });#endif d->rasterBuffer->init(); d->deviceRect = QRect(0, 0, device->width(), device->height()); gccaps &= ~PorterDuff; // reset paintevent clip d->baseClip = QPainterPath(); if (device->devType() == QInternal::Widget) { if (!d->paint_unclipped) { QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) { d->baseClip.addRegion(sysClip); d->deviceRect = sysClip.boundingRect(); // Shift the baseclip to absolute d->baseClip = d->baseClip * QMatrix(1, 0, 0, 1, -d->deviceRect.x(), -d->deviceRect.y()); } } gccaps &= ~PaintOutsidePaintEvent; }#if defined(Q_WS_QWS) else if (device->devType() == QInternal::Pixmap) { if (!d->paint_unclipped) { // Only embedded uses system clipping on pixmaps QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) d->baseClip.addRegion(sysClip); } }#endif else if (!d->paint_unclipped) { QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) { d->baseClip.addRegion(sysClip); } }#if defined(Q_WS_WIN) || defined(Q_WS_QWS) if (device->devType() == QInternal::Pixmap) { QPixmap *pixmap = static_cast<QPixmap *>(device); if (pixmap->isNull()) { qWarning("Cannot paint on a null pixmap"); return false; } QPixmapData *data = static_cast<QPixmap *>(device)->data; device = &data->image; }#elif defined(Q_WS_MAC) if (device->devType() == QInternal::Pixmap) { QPixmap *pixmap = static_cast<QPixmap *>(device); if (pixmap->isNull()) { qWarning("Cannot paint on a null pixmap"); return false; } d->rasterBuffer->prepare(pixmap); }#endif if (device->devType() == QInternal::Image) { QImage *image = static_cast<QImage *>(device); int format = image->format(); d->flushOnEnd = false; d->rasterBuffer->prepare(image); if (format == QImage::Format_MonoLSB) { d->mono_surface = true; } else if (format == QImage::Format_Mono) { d->mono_surface = true; } else if (format == QImage::Format_RGB32) { ; } else if (format == QImage::Format_ARGB32_Premultiplied) { gccaps |= PorterDuff; } else if (format == QImage::Format_ARGB32) { gccaps |= PorterDuff; } else if (format == QImage::Format_RGB16) { ; } else { qWarning("QRasterPaintEngine::begin: Unsupported image format (%d)", format); return false; }#ifdef Q_WS_QWS } else if (device->devType() == QInternal::CustomRaster) { QCustomRasterPaintDevice *dev = static_cast<QCustomRasterPaintDevice*>(device); d->rasterBuffer->prepare(dev);#endif } else { d->rasterBuffer->prepare(d->deviceRect.width(), d->deviceRect.height()); } d->matrix = QTransform(); d->txop = QTransform::TxNone; d->txscale = 1; d->outlineMapper->setMatrix(d->matrix, d->txop); d->outlineMapper->m_clipper.setBoundingRect(d->deviceRect.adjusted(-10, -10, 10, 10)); d->rasterizer.setDeviceRect(d->deviceRect); if (device->depth() == 1) { d->pen = QPen(Qt::color1); d->brush = QBrush(Qt::color0); } else { d->pen = QPen(Qt::black); d->brush = QBrush(Qt::NoBrush); } d->penData.init(d->rasterBuffer, this); d->penData.setup(d->pen.brush(), d->opacity); d->stroker = &d->basicStroker; d->basicStroker.setClipRect(d->deviceRect); d->brushData.init(d->rasterBuffer, this); d->brushData.setup(d->brush, d->opacity); if (!d->paint_unclipped) updateClipRegion(QRegion(), Qt::NoClip); setDirty(DirtyBrushOrigin); setActive(true); return true;}/*! \reimp*/bool QRasterPaintEngine::end(){ Q_D(QRasterPaintEngine); if (d->flushOnEnd) flush(d->pdev, QPoint()); if (d->rasterBuffer->disabled_clip) { delete d->rasterBuffer->disabled_clip; d->rasterBuffer->disabled_clip = 0; } setActive(false); return true;}/*! \internal*/void QRasterPaintEngine::releaseBuffer(){ Q_D(QRasterPaintEngine); delete d->rasterBuffer; d->rasterBuffer = new QRasterBuffer;}/*! \internal*/QSize QRasterPaintEngine::size() const{ Q_D(const QRasterPaintEngine); return QSize(d->rasterBuffer->width(), d->rasterBuffer->height());}/*! \internal*/#ifndef QT_NO_DEBUGvoid QRasterPaintEngine::saveBuffer(const QString &s) const{ Q_D(const QRasterPaintEngine); d->rasterBuffer->bufferImage().save(s, "PNG");}#endif/*! \internal*/void QRasterPaintEngine::setFlushOnEnd(bool flushOnEnd){ Q_D(QRasterPaintEngine); d->flushOnEnd = flushOnEnd;}/*! \internal Force the contents of the buffer out on the underlying device.*/void QRasterPaintEngine::flush(QPaintDevice *device, const QPoint &offset){ Q_D(QRasterPaintEngine); Q_ASSERT(device);#if defined(Q_WS_WIN) if (!d->rasterBuffer->hdc()) return; if (device->devType() == QInternal::Widget) { HDC hdc = device->getDC(); QRegion sysClip = systemClip(); if (sysClip.isEmpty()) { BitBlt(hdc, d->deviceRect.x() + offset.x(), d->deviceRect.y() + offset.y(), d->deviceRect.width(), d->deviceRect.height(), d->rasterBuffer->hdc(), 0, 0, SRCCOPY); } else { QVector<QRect> rects = sysClip.rects(); for (int i=0; i<rects.size(); ++i) { QRect r = rects.at(i); BitBlt(hdc, r.x() + offset.x(), r.y() + offset.y(), r.width(), r.height(), d->rasterBuffer->hdc(), r.x() - d->deviceRect.x(), r.y() - d->deviceRect.y(), SRCCOPY); } } device->releaseDC(hdc); }#elif defined(Q_WS_MAC) extern CGContextRef qt_mac_cg_context(const QPaintDevice *); //qpaintdevice_mac.cpp extern void qt_mac_clip_cg(CGContextRef, const QRegion &, const QPoint *, CGAffineTransform *); //qpaintengine_mac.cpp if(CGContextRef ctx = qt_mac_cg_context(device)) { qt_mac_clip_cg(ctx, systemClip(), 0, 0); const CGRect source = CGRectMake(0, 0, d->deviceRect.width(), d->deviceRect.height()); QCFType<CGImageRef> subimage;#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4) if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) { subimage = CGImageCreateWithImageInRect(d->rasterBuffer->m_data, source); } else#endif { int dw = d->deviceRect.width(); int dh = d->deviceRect.height(); QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData( d->rasterBuffer->buffer(), d->rasterBuffer->buffer(), dw*dh*sizeof(uint), 0); subimage = CGImageCreate(dw, dh, 8, 32, d->rasterBuffer->width() * sizeof(uint), QCFType<CGColorSpaceRef>(CGColorSpaceCreateDeviceRGB()), kCGImageAlphaPremultipliedFirst, provider, 0, 0, kCGRenderingIntentDefault); } const CGRect dest = CGRectMake(offset.x(), offset.y(), d->deviceRect.width(), d->deviceRect.height()); HIViewDrawCGImage(ctx, &dest, subimage); //top left CGContextRelease(ctx); CGImageRelease(subimage); }#else Q_UNUSED(d); Q_UNUSED(device); Q_UNUSED(offset);#endif}/*! \internal*/void QRasterPaintEngine::updateMatrix(const QTransform &matrix){ Q_D(QRasterPaintEngine); if (d->matrix == matrix) return; d->matrix = matrix; d->int_xform = false; d->txop = static_cast<int>(d->matrix.type()); switch (d->txop) { case QTransform::TxScale: d->int_xform = qreal(int(d->matrix.dx())) == d->matrix.dx() && qreal(int(d->matrix.dy())) == d->matrix.dy() && qreal(int(d->matrix.m11())) == d->matrix.m11() && qreal(int(d->matrix.m22())) == d->matrix.m22(); break; case QTransform::TxTranslate: d->int_xform = qreal(int(d->matrix.dx())) == d->matrix.dx() && qreal(int(d->matrix.dy())) == d->matrix.dy(); break; case QTransform::TxNone: d->int_xform = true; break; } if (d->txop < QTransform::TxScale) { d->tx_noshear = true; } else if (d->txop < QTransform::TxRotate) { d->tx_noshear = qFuzzyCompare(qAbs(d->matrix.m11()), qAbs(d->matrix.m22())); } else if (d->txop < QTransform::TxShear) { const qreal xAxis = d->matrix.m11() * d->matrix.m11() + d->matrix.m21() * d->matrix.m21(); const qreal yAxis = d->matrix.m12() * d->matrix.m12() + d->matrix.m22() * d->matrix.m22(); d->tx_noshear = qFuzzyCompare(xAxis, yAxis); } else { d->tx_noshear = false; } d->txscale = d->txop > QTransform::TxTranslate ? qSqrt(qMax(d->matrix.m11() * d->matrix.m11() + d->matrix.m21() * d->matrix.m21(), d->matrix.m12() * d->matrix.m12() + d->matrix.m22() * d->matrix.m22())) : 1.0; // 1/10000 == 0.0001, so we have good enough res to cover curves // that span the entire widget... d->inverseScale = d->txop <= QTransform::TxTranslate ? 1 : qMax(1 / qMax( qMax(qAbs(matrix.m11()), qAbs(matrix.m22())), qMax(qAbs(matrix.m12()), qAbs(matrix.m21())) ), qreal(0.0001)); d->outlineMapper->setMatrix(d->matrix, d->txop); d->updateMatrixData(&d->penData, d->pen.brush(), matrix); d->updateMatrixData(&d->brushData, d->brush, d->brushMatrix());#ifdef Q_WS_WIN d->isPlain45DegreeRotation = false; if (d->txop >= QTransform::TxRotate) { d->isPlain45DegreeRotation = (qFuzzyCompare(matrix.m11(), qreal(0)) && qFuzzyCompare(matrix.m12(), qreal(1)) && qFuzzyCompare(matrix.m21(), qreal(-1)) && qFuzzyCompare(matrix.m22(), qreal(0)) ) || (qFuzzyCompare(matrix.m11(), qreal(-1)) && qFuzzyCompare(matrix.m12(), qreal(0)) && qFuzzyCompare(matrix.m21(), qreal(0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -