diff options
-rw-r--r-- | src/gui/image/qpixmap_blitter.cpp | 106 | ||||
-rw-r--r-- | src/gui/image/qpixmap_blitter_p.h | 87 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_blitter.cpp | 97 | ||||
-rw-r--r-- | src/gui/painting/qpaintengine_blitter_p.h | 10 |
4 files changed, 236 insertions, 64 deletions
diff --git a/src/gui/image/qpixmap_blitter.cpp b/src/gui/image/qpixmap_blitter.cpp index 6e34fbd..f82a67d 100644 --- a/src/gui/image/qpixmap_blitter.cpp +++ b/src/gui/image/qpixmap_blitter.cpp @@ -1,6 +1,7 @@ #include "qpixmap_blitter_p.h" #include <qpainter.h> +#include <qimage.h> #include <private/qapplication_p.h> #include <private/qgraphicssystem_p.h> @@ -11,6 +12,9 @@ static int global_ser_no = 0; QBlittablePixmapData::QBlittablePixmapData(QPixmapData::PixelType type) : QPixmapData(type,BlitterClass), m_engine(0), m_blittable(0) +#ifdef QT_BLITTER_RASTEROVERLAY + ,m_rasterOverlay(0), m_unmergedCopy(0) +#endif //QT_BLITTER_RASTEROVERLAY { setSerialNumber(++global_ser_no); } @@ -19,6 +23,10 @@ QBlittablePixmapData::~QBlittablePixmapData() { delete m_blittable; delete m_engine; +#ifdef QT_BLITTER_RASTEROVERLAY + delete m_rasterOverlay; + delete m_unmergedCopy; +#endif //QT_BLITTER_RASTEROVERLAY } QBlittable *QBlittablePixmapData::blittable() const @@ -132,18 +140,13 @@ void QBlittablePixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags) { resize(image.width(),image.height()); + markRasterOverlay(QRect(0,0,w,h)); QImage *thisImg = buffer(); QImage correctFormatPic = image; if (correctFormatPic.format() != thisImg->format()) correctFormatPic = correctFormatPic.convertToFormat(thisImg->format(), flags); - //jl: This does not ALWAYS work as expected :( -// QPainter p(thisImg); -// p.setCompositionMode(QPainter::CompositionMode_Source); -// p.drawImage(0,0,image,flags); - - //So just copy strides by hand uchar *mem = thisImg->bits(); const uchar *bits = correctFormatPic.bits(); int bytesCopied = 0; @@ -163,3 +166,94 @@ QPaintEngine *QBlittablePixmapData::paintEngine() const } return m_engine; } + +#ifdef QT_BLITTER_RASTEROVERLAY + +static bool showRasterOverlay = !qgetenv("QT_BLITTER_RASTEROVERLAY").isEmpty(); + +void QBlittablePixmapData::mergeOverlay() +{ + if (m_unmergedCopy || !showRasterOverlay) + return; + m_unmergedCopy = new QImage(buffer()->copy()); + QPainter p(buffer()); + p.setCompositionMode(QPainter::CompositionMode_SourceOver); + p.drawImage(0,0,*overlay()); + p.end(); +} + +void QBlittablePixmapData::unmergeOverlay() +{ + if (!m_unmergedCopy || !showRasterOverlay) + return; + QPainter p(buffer()); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.drawImage(0,0,*m_unmergedCopy); + p.end(); + + delete m_unmergedCopy; + m_unmergedCopy = 0; +} + +QImage *QBlittablePixmapData::overlay() +{ + if (!m_rasterOverlay|| + m_rasterOverlay->size() != QSize(w,h)){ + m_rasterOverlay = new QImage(w,h,QImage::Format_ARGB32_Premultiplied); + m_rasterOverlay->fill(0x00000000); + uint color = (qrand() % 11)+7; + m_overlayColor = QColor(Qt::GlobalColor(color)); + m_overlayColor.setAlpha(0x88); + + } + return m_rasterOverlay; +} + +void QBlittablePixmapData::markRasterOverlayImpl(const QRectF &rect) +{ + if (!showRasterOverlay) + return; + QRectF transformationRect = clipAndTransformRect(rect); + if(!transformationRect.isEmpty()) { + QPainter p(overlay()); + p.setBrush(m_overlayColor); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(transformationRect,QBrush(m_overlayColor)); + } +} + +void QBlittablePixmapData::unmarkRasterOverlayImpl(const QRectF &rect) +{ + if (!showRasterOverlay) + return; + QRectF transformationRect = clipAndTransformRect(rect); + if (!transformationRect.isEmpty()) { + QPainter p(overlay()); + QColor color(0x00,0x00,0x00,0x00); + p.setBrush(color); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.fillRect(transformationRect,QBrush(color)); + } +} + +QRectF QBlittablePixmapData::clipAndTransformRect(const QRectF &rect) const +{ + QRectF transformationRect = rect; + paintEngine(); + if (m_engine->state()) { + transformationRect = m_engine->state()->matrix.mapRect(rect); + const QClipData *clipData = m_engine->clip(); + if (clipData) { + if (clipData->hasRectClip) { + transformationRect &= clipData->clipRect; + } else if (clipData->hasRegionClip) { + const QVector<QRect> rects = clipData->clipRegion.rects(); + for (int i = 0; i < rects.size(); i++) { + transformationRect &= rects.at(i); + } + } + } + } + return transformationRect; +} +#endif //QT_BLITTER_RASTEROVERLAY diff --git a/src/gui/image/qpixmap_blitter_p.h b/src/gui/image/qpixmap_blitter_p.h index ca834dc..73f80a8 100644 --- a/src/gui/image/qpixmap_blitter_p.h +++ b/src/gui/image/qpixmap_blitter_p.h @@ -23,10 +23,97 @@ public: void fromImage(const QImage &image, Qt::ImageConversionFlags flags); QPaintEngine *paintEngine() const; + + void markRasterOverlay(const QRectF &); + void markRasterOverlay(const QPointF &, const QTextItem &); + void markRasterOverlay(const QVectorPath &); + void markRasterOverlay(const QRect *rects, int rectCount); + void markRasterOverlay(const QRectF *rects, int rectCount); + void unmarkRasterOverlay(const QRectF &); + +#ifdef QT_BLITTER_RASTEROVERLAY + void mergeOverlay(); + void unmergeOverlay(); + QImage *overlay(); + +#endif //QT_BLITTER_RASTEROVERLAY protected: QBlitterPaintEngine *m_engine; QBlittable *m_blittable; +#ifdef QT_BLITTER_RASTEROVERLAY + QImage *m_rasterOverlay; + QImage *m_unmergedCopy; + QColor m_overlayColor; + + void markRasterOverlayImpl(const QRectF &); + void unmarkRasterOverlayImpl(const QRectF &); + QRectF clipAndTransformRect(const QRectF &) const; +#endif //QT_BLITTER_RASTEROVERLAY + }; +inline void QBlittablePixmapData::markRasterOverlay(const QRectF &rect) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + markRasterOverlayImpl(rect); +#else + Q_UNUSED(rect) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QVectorPath &path) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + markRasterOverlayImpl(path.convertToPainterPath().boundingRect()); +#else + Q_UNUSED(path) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QPointF &pos, const QTextItem &ti) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + QFontMetricsF fm(ti.font()); + QRectF rect = fm.tightBoundingRect(ti.text()); + rect.moveBottomLeft(pos); + markRasterOverlay(rect); +#else + Q_UNUSED(pos) + Q_UNUSED(ti) +#endif +} + +inline void QBlittablePixmapData::markRasterOverlay(const QRect *rects, int rectCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + for (int i = 0; i < rectCount; i++) { + markRasterOverlay(rects[i]); + } +#else + Q_UNUSED(rects) + Q_UNUSED(rectCount) +#endif +} +inline void QBlittablePixmapData::markRasterOverlay(const QRectF *rects, int rectCount) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + for (int i = 0; i < rectCount; i++) { + markRasterOverlay(rects[i]); + } +#else + Q_UNUSED(rects) + Q_UNUSED(rectCount) +#endif +} + +inline void QBlittablePixmapData::unmarkRasterOverlay(const QRectF &rect) +{ +#ifdef QT_BLITTER_RASTEROVERLAY + unmarkRasterOverlayImpl(rect); +#else + Q_UNUSED(rect) +#endif +} + #endif // QPIXMAP_BLITTER_P_H diff --git a/src/gui/painting/qpaintengine_blitter.cpp b/src/gui/painting/qpaintengine_blitter.cpp index 1a1d5e0..0e7c96a 100644 --- a/src/gui/painting/qpaintengine_blitter.cpp +++ b/src/gui/painting/qpaintengine_blitter.cpp @@ -19,12 +19,6 @@ #define STATE_CLIPSYS_COMPLEX 0x00010000 #define STATE_CLIP_COMPLEX 0x00020000 -//#define RASTEROVERLAY - -#ifdef RASTEROVERLAY -QColor rasterColor(255,0,0,100); -QBrush rasterBrush(rasterColor); -#endif static inline void updateStateBits(uint *state, uint mask, bool on) { @@ -107,9 +101,10 @@ public: updateStateBits(&fillRectMask, STATE_BRUSH_PATTERN, false); updateStateBits(&fillRectMask, STATE_BRUSH_ALPHA, false); - updateStateBits(&fillRectMask, STATE_PEN_ENABLED, false); + updateStateBits(&fillRectMask, STATE_PEN_ENABLED, true); - updateStateBits(&fillRectMask, STATE_ANTIALIASING, false); + //Sub-pixel aliasing should not be sent to the blitter + updateStateBits(&fillRectMask, STATE_ANTIALIASING, true); updateStateBits(&fillRectMask, STATE_ALPHA, false); updateStateBits(&fillRectMask, STATE_BLENDING_COMPLEX, false); @@ -152,30 +147,31 @@ class QBlitterPaintEnginePrivate : public QPaintEngineExPrivate public: QBlitterPaintEnginePrivate(QBlittablePixmapData *p) : QPaintEngineExPrivate(), + pmData(p), isBlitterLocked(false), hasXForm(false) { - blitter= p->blittable(); raster = new QRasterPaintEngine(p->buffer()); - capabillities = new CapabilitiesToStateMask(blitter->capabilities()); + capabillities = new CapabilitiesToStateMask(pmData->blittable()->capabilities()); } inline void lock() { if (!isBlitterLocked) { - raster->d_func()->rasterBuffer->prepare(blitter->lock()); + raster->d_func()->rasterBuffer->prepare(pmData->blittable()->lock()); isBlitterLocked = true; } } inline void unlock() { if (isBlitterLocked) { - blitter->unlock(); + pmData->blittable()->unlock(); isBlitterLocked = false; } } void fillRect(const QRectF &rect, const QColor &color) { + pmData->unmarkRasterOverlay(rect); QRectF targetRect = rect; if (hasXForm) { targetRect = state->matrix.mapRect(rect); @@ -184,14 +180,14 @@ public: if (clipData) { if (clipData->hasRectClip) { unlock(); - blitter->fillRect(targetRect & clipData->clipRect, color); + pmData->blittable()->fillRect(targetRect & clipData->clipRect, color); } else if (clipData->hasRegionClip) { QVector<QRect> rects = clipData->clipRegion.rects(); for ( int i = 0; i < rects.size(); i++ ) { QRect intersectRect = rects.at(i).intersected(targetRect.toRect()); if (!intersectRect.isEmpty()) { unlock(); - blitter->fillRect(intersectRect,color); + pmData->blittable()->fillRect(intersectRect,color); } } } @@ -200,11 +196,11 @@ public: && targetRect.width() <= raster->paintDevice()->width() && targetRect.height() <= raster->paintDevice()->height()) { unlock(); - blitter->fillRect(targetRect,color); + pmData->blittable()->fillRect(targetRect,color); } else { QRectF deviceRect(0,0,raster->paintDevice()->width(), raster->paintDevice()->height()); unlock(); - blitter->fillRect(deviceRect&targetRect,color); + pmData->blittable()->fillRect(deviceRect&targetRect,color); } } } @@ -222,7 +218,8 @@ public: qreal deltaRight = target.right() - intersectedRect.right(); source.adjust(-deltaLeft,-deltaTop,deltaRight,deltaBottom); } - blitter->drawPixmap(intersectedRect, pm, source); + pmData->unmarkRasterOverlay(intersectedRect); + pmData->blittable()->drawPixmap(intersectedRect, pm, source); } void updateClip() { @@ -235,11 +232,10 @@ public: raster->d_func()->systemStateChanged(); } - QPixmap pixmap; QRasterPaintEngine *raster; QRasterPaintEngineState *state; - QBlittable *blitter; + QBlittablePixmapData *pmData; bool isBlitterLocked; CapabilitiesToStateMask *capabillities; @@ -268,8 +264,11 @@ bool QBlitterPaintEngine::begin(QPaintDevice *pdev) d->raster->setSystemRect(systemRect()); d->raster->setSystemClip(systemClip()); - + setActive(true); bool ok = d->raster->begin(pdev); +#ifdef QT_BLITTER_RASTEROVERLAY + d->pmData->unmergeOverlay(); +#endif return ok; } @@ -280,6 +279,10 @@ bool QBlitterPaintEngine::end() d->raster->setPaintDevice(0); d->raster->setActive(false); + setActive(false); +#ifdef QT_BLITTER_RASTEROVERLAY + d->pmData->mergeOverlay(); +#endif return d->raster->end(); } @@ -287,16 +290,13 @@ bool QBlitterPaintEngine::end() void QBlitterPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QBlitterPaintEngine); - if (path.shape() == QVectorPath::RectangleHint) { QRectF rect(((QPointF *) path.points())[0], ((QPointF *) path.points())[2]); fillRect(rect, brush); } else { d->lock(); + d->pmData->markRasterOverlay(path); d->raster->fill(path, brush); -#ifdef RASTEROVERLAY - d->raster->fill(path,rasterBrush); -#endif } } @@ -307,10 +307,8 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QColor &color) d->fillRect(rect, color); } else { d->lock(); + d->pmData->markRasterOverlay(rect); d->raster->fillRect(rect, color); -#ifdef RASTEROVERLAY - d->raster->fillRect(rect,rasterColor); -#endif } } @@ -354,7 +352,7 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) int tmpSrcX = srcX + (targetRect.x() - x); int tmpSrcY = srcY + (targetRect.y() - y); QRect srcRect(tmpSrcX,tmpSrcY,targetRect.width(),targetRect.height()); - d->blitter->drawPixmap(targetRect,pm,srcRect); + d->pmData->blittable()->drawPixmap(targetRect,pm,srcRect); } } else if (clipData->hasRegionClip) { QVector<QRect> clipRects = clipData->clipRegion.rects(); @@ -368,9 +366,9 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) int tmpSrcX = srcX + (targetRect.x() - x); int tmpSrcY = srcY + (targetRect.y() - y); QRect srcRect(tmpSrcX,tmpSrcY,targetRect.width(),targetRect.height()); - d->blitter->drawPixmap(targetRect,pm,srcRect); + d->pmData->blittable()->drawPixmap(targetRect,pm,srcRect); } - } else Q_ASSERT(false);//should never happen + } x+=blitWidth; if (x>=transformedRect.right()) { x = transformedRect.x(); @@ -382,13 +380,10 @@ void QBlitterPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) } else srcX = 0; } - } else { d->lock(); + d->pmData->markRasterOverlay(rect); d->raster->fillRect(rect, brush); -#ifdef RASTEROVERLAY - d->raster->fillRect(rect,rasterBrush); -#endif } } @@ -397,10 +392,8 @@ void QBlitterPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QBlitterPaintEngine); d->lock(); + d->pmData->markRasterOverlay(path.convertToPainterPath().boundingRect()); d->raster->stroke(path, pen); -#ifdef RASTEROVERLAY - d->raster->stroke(path,QPen(rasterColor)); -#endif } void QBlitterPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) @@ -509,10 +502,8 @@ void QBlitterPaintEngine::drawRects(const QRect *rects, int rectCount) d->fillRect(rects[i], qbrush_color(d->state->brush)); } } else { + d->pmData->markRasterOverlay(rects,rectCount); QPaintEngineEx::drawRects(rects, rectCount); -#ifdef RASTEROVERLAY - d->raster->drawRects(rects,rectCount); -#endif } } @@ -524,10 +515,8 @@ void QBlitterPaintEngine::drawRects(const QRectF *rects, int rectCount) d->fillRect(rects[i], qbrush_color(d->state->brush)); } } else { + d->pmData->markRasterOverlay(rects,rectCount); QPaintEngineEx::drawRects(rects, rectCount); -#ifdef RASTEROVERLAY - d->raster->drawRects(rects,rectCount); -#endif } } @@ -557,10 +546,8 @@ void QBlitterPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const Q } }else { d->lock(); + d->pmData->markRasterOverlay(r); d->raster->drawPixmap(r, pm, sr); -#ifdef RASTEROVERLAY - d->raster->fillRect(r,rasterColor); -#endif } } @@ -569,10 +556,8 @@ void QBlitterPaintEngine::drawImage(const QRectF &r, const QImage &pm, const QRe { Q_D(QBlitterPaintEngine); d->lock(); + d->pmData->markRasterOverlay(r); d->raster->drawImage(r, pm, sr, flags); -#ifdef RASTEROVERLAY - d->raster->fillRect(r,rasterColor); -#endif } @@ -581,18 +566,14 @@ void QBlitterPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &ti) Q_D(QBlitterPaintEngine); d->lock(); d->raster->drawTextItem(pos, ti); -#ifdef RASTEROVERLAY - QFontMetricsF fm(ti.font()); - QRectF rect = fm.tightBoundingRect(ti.text()); - rect.moveBottomLeft(pos); - d->raster->fillRect(rect, rasterColor); -#endif + d->pmData->markRasterOverlay(pos,ti); } void QBlitterPaintEngine::drawEllipse(const QRectF &r) { Q_D(QBlitterPaintEngine); d->lock(); + d->pmData->markRasterOverlay(r); d->raster->drawEllipse(r); } @@ -616,6 +597,12 @@ void QBlitterPaintEngine::setState(QPainterState *s) d->updateClip(); } +inline QRasterPaintEngine *QBlitterPaintEngine::raster() const +{ + Q_D(const QBlitterPaintEngine); + return d->raster; +} + class QBlittablePrivate { public: diff --git a/src/gui/painting/qpaintengine_blitter_p.h b/src/gui/painting/qpaintengine_blitter_p.h index cebaf21..2d9add9 100644 --- a/src/gui/painting/qpaintengine_blitter_p.h +++ b/src/gui/painting/qpaintengine_blitter_p.h @@ -2,8 +2,8 @@ #define QPAINTENGINE_BLITTER_P_H #include "private/qpaintengineex_p.h" +#include "private/qpaintengine_raster_p.h" -class QRasterPaintEngine; class QBlittablePrivate; class QBlitterPaintEnginePrivate; class QBlittablePixmapData; @@ -89,8 +89,12 @@ public: virtual void setState(QPainterState *s); - inline QPainterState *state() { return static_cast<QPainterState *>(QPaintEngine::state); } - inline const QPainterState *state() const { return static_cast<const QPainterState *>(QPaintEngine::state); } + inline QPainterState *state() { return raster()->state(); } + inline const QPainterState *state() const { const QPainterState *state = raster()->state(); return state;} + inline const QClipData *clip(){return raster()->d_func()->clip();} + +private: + QRasterPaintEngine *raster() const; }; |