summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/image/qpixmap_blitter.cpp106
-rw-r--r--src/gui/image/qpixmap_blitter_p.h87
-rw-r--r--src/gui/painting/qpaintengine_blitter.cpp97
-rw-r--r--src/gui/painting/qpaintengine_blitter_p.h10
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;
};