aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
diff options
context:
space:
mode:
authorCharles Yin <yinyunqiao@gmail.com>2011-09-22 20:01:29 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-30 10:37:05 +0200
commit8f69461c480e10424401e95b16b507eec3e28e54 (patch)
tree58e13d4c7a470485ab5e14642a55bc35bd0ae2c3 /src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
parent20fb62f6040ad8415828092a2b09bd374433505f (diff)
tests for canvas and a few bug fixes
Change-Id: Icbbc7f2a0fe3b908963ce18afef51e25ea0170a0 Reviewed-on: http://codereview.qt-project.org/5805 Reviewed-by: Charles Yin <charles.yin@nokia.com>
Diffstat (limited to 'src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp')
-rw-r--r--src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp91
1 files changed, 79 insertions, 12 deletions
diff --git a/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp b/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
index 550ad77515..51730d41ec 100644
--- a/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
+++ b/src/declarative/items/context2d/qsgcontext2dcommandbuffer.cpp
@@ -54,7 +54,7 @@ static QImage makeShadowImage(const QImage& image, qreal offsetX, qreal offsetY,
{
QImage shadowImg(image.width() + blur + qAbs(offsetX),
image.height() + blur + qAbs(offsetY),
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
shadowImg.fill(0);
QPainter tmpPainter(&shadowImg);
tmpPainter.setCompositionMode(QPainter::CompositionMode_Source);
@@ -80,7 +80,7 @@ static void fillRectShadow(QPainter* p, QRectF shadowRect, qreal offsetX, qreal
QRectF r = shadowRect;
r.moveTo(0, 0);
- QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32);
+ QImage shadowImage(r.size().width() + 1, r.size().height() + 1, QImage::Format_ARGB32_Premultiplied);
QPainter tp;
tp.begin(&shadowImage);
tp.fillRect(r, p->brush());
@@ -99,7 +99,7 @@ static void fillShadowPath(QPainter* p, const QPainterPath& path, qreal offsetX,
QRectF r = path.boundingRect();
QImage img(r.size().width() + r.left() + 1,
r.size().height() + r.top() + 1,
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter tp(&img);
tp.fillPath(path.translated(0, 0), p->brush());
@@ -118,7 +118,7 @@ static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offset
QRectF r = path.boundingRect();
QImage img(r.size().width() + r.left() + 1,
r.size().height() + r.top() + 1,
- QImage::Format_ARGB32);
+ QImage::Format_ARGB32_Premultiplied);
img.fill(0);
QPainter tp(&img);
tp.strokePath(path, p->pen());
@@ -130,6 +130,72 @@ static void strokeShadowPath(QPainter* p, const QPainterPath& path, qreal offset
p->drawImage(dx, dy, shadowImage);
p->strokePath(path, p->pen());
}
+static inline void drawRepeatPattern(QPainter* p, const QImage& image, const QRectF& rect, const bool repeatX, const bool repeatY)
+{
+ // Patterns must be painted so that the top left of the first image is anchored at
+ // the origin of the coordinate space
+ if (!image.isNull()) {
+ int w = image.width();
+ int h = image.height();
+ int startX, startY;
+ QRect r(static_cast<int>(rect.x()), static_cast<int>(rect.y()), static_cast<int>(rect.width()), static_cast<int>(rect.height()));
+
+ // startX, startY is the coordinate of the first image we need to put on the left-top of the rect
+ if (repeatX && repeatY) {
+ // repeat
+ // startX, startY is at the left top side of the left-top of the rect
+ startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w);
+ startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h);
+ } else {
+ if (!repeatX && !repeatY) {
+ // no-repeat
+ // only draw the image once at orgin once, check if need to draw
+ QRect imageRect(0, 0, w, h);
+ if (imageRect.intersects(r)) {
+ startX = 0;
+ startY = 0;
+ } else
+ return;
+ } else if (repeatX && !repeatY) {
+ // repeat-x
+ // startY is fixed, but startX change based on the left-top of the rect
+ QRect imageRect(r.x(), 0, r.width(), h);
+ if (imageRect.intersects(r)) {
+ startX = r.x() >=0 ? r.x() - (r.x() % w) : r.x() - (w - qAbs(r.x()) % w);
+ startY = 0;
+ } else
+ return;
+ } else {
+ // repeat-y
+ // startX is fixed, but startY change based on the left-top of the rect
+ QRect imageRect(0, r.y(), w, r.height());
+ if (imageRect.intersects(r)) {
+ startX = 0;
+ startY = r.y() >=0 ? r.y() - (r.y() % h) : r.y() - (h - qAbs(r.y()) % h);
+ } else
+ return;
+ }
+ }
+
+ int x = startX;
+ int y = startY;
+ do {
+ // repeat Y
+ do {
+ // repeat X
+ QRect imageRect(x, y, w, h);
+ QRect intersectRect = imageRect.intersected(r);
+ QPoint destStart(intersectRect.x(), intersectRect.y());
+ QRect sourceRect(intersectRect.x() - imageRect.x(), intersectRect.y() - imageRect.y(), intersectRect.width(), intersectRect.height());
+
+ p->drawImage(destStart, image, sourceRect);
+ x += w;
+ } while (repeatX && x < r.x() + r.width());
+ x = startX;
+ y += h;
+ } while (repeatY && y < r.y() + r.height());
+ }
+}
QPen QSGContext2DCommandBuffer::makePen(QSGContext2D::State state)
{
@@ -186,7 +252,7 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
}
case QSGContext2D::ClearRect:
{
- p->eraseRect(takeRect());
+ p->fillRect(takeRect(), QColor(qRgba(0, 0, 0, 0)));
break;
}
case QSGContext2D::FillRect:
@@ -221,12 +287,16 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
case QSGContext2D::FillStyle:
{
state.fillStyle = takeFillStyle();
+ state.fillPatternRepeatX = takeBool();
+ state.fillPatternRepeatY = takeBool();
p->setBrush(state.fillStyle);
break;
}
case QSGContext2D::StrokeStyle:
{
state.strokeStyle = takeStrokeStyle();
+ state.strokePatternRepeatX = takeBool();
+ state.strokePatternRepeatY = takeBool();
pen.setBrush(state.strokeStyle);
p->setPen(pen);
break;
@@ -264,6 +334,7 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
break;
case QSGContext2D::Fill:
{
+ bool hasPattern = p->brush().style() == Qt::TexturePattern;
if (HAS_SHADOW(state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor))
fillShadowPath(p,takePath(), state.shadowOffsetX, state.shadowOffsetY, state.shadowBlur, state.shadowColor);
else
@@ -289,13 +360,6 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
p->setClipPath(clipPath);
break;
}
- case QSGContext2D::UpdateBrush:
- {
- state.fillStyle = takeBrush();
- p->setBrush(state.fillStyle);
- break;
- }
-
case QSGContext2D::GlobalAlpha:
{
state.globalAlpha = takeGlobalAlpha();
@@ -357,6 +421,7 @@ QSGContext2D::State QSGContext2DCommandBuffer::replay(QPainter* p, QSGContext2D:
QSGContext2DCommandBuffer::QSGContext2DCommandBuffer()
: cmdIdx(0)
, intIdx(0)
+ , boolIdx(0)
, realIdx(0)
, colorIdx(0)
, matrixIdx(0)
@@ -375,6 +440,7 @@ void QSGContext2DCommandBuffer::clear()
{
commands.clear();
ints.clear();
+ bools.clear();
reals.clear();
colors.clear();
matrixes.clear();
@@ -388,6 +454,7 @@ void QSGContext2DCommandBuffer::reset()
{
cmdIdx = 0;
intIdx = 0;
+ boolIdx = 0;
realIdx = 0;
colorIdx = 0;
matrixIdx = 0;