diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-08-10 05:27:28 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-08-10 05:27:28 (GMT) |
commit | 3af33f5eddb3624654141b3f7b0cbb9a49e94438 (patch) | |
tree | e6335a3d37fc9572fe7b98c556970d241a6ad2b5 | |
parent | e0924b32b7323c355a00e6136c92a7eaf3819a35 (diff) | |
parent | cfc1658c68ee3b7227277a4549b60de545ec5f6f (diff) | |
download | Qt-3af33f5eddb3624654141b3f7b0cbb9a49e94438.zip Qt-3af33f5eddb3624654141b3f7b0cbb9a49e94438.tar.gz Qt-3af33f5eddb3624654141b3f7b0cbb9a49e94438.tar.bz2 |
Merge branch 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2 into master-integration
* 'master' of scm.dev.nokia.troll.no:qt/oslo-staging-2:
Added QPainter::clipBoundingRect() which is significantly faster
-rw-r--r-- | src/gui/painting/qpainter.cpp | 55 | ||||
-rw-r--r-- | src/gui/painting/qpainter.h | 2 | ||||
-rw-r--r-- | tests/auto/qpainter/tst_qpainter.cpp | 37 |
3 files changed, 94 insertions, 0 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index f24eafd..c4de7f0 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2702,6 +2702,61 @@ QPainterPath QPainter::clipPath() const } /*! + Returns the bounding rectangle of the current clip if there is a clip; + otherwise returns an empty rectangle. Note that the clip region is + given in logical coordinates. + + The bounding rectangle is not guaranteed to be tight. + + \sa setClipRect(), setClipPath(), setClipRegion() + + \since 4.8 + */ + +QRectF QPainter::clipBoundingRect() const +{ + Q_D(const QPainter); + + if (!d->engine) { + qWarning("QPainter::clipBoundingRect: Painter not active"); + return QRectF(); + } + + // Accumulate the bounding box in device space. This is not 100% + // precise, but it fits within the guarantee and it is resonably + // fast. + QRectF bounds; + for (int i=0; i<d->state->clipInfo.size(); ++i) { + QRectF r; + const QPainterClipInfo &info = d->state->clipInfo.at(i); + + if (info.clipType == QPainterClipInfo::RectClip) + r = info.rect; + else if (info.clipType == QPainterClipInfo::RegionClip) + r = info.region.boundingRect(); + else + r = info.path.boundingRect(); + + r = info.matrix.mapRect(r); + + if (i == 0) + bounds = r; + else if (info.operation == Qt::IntersectClip) + bounds &= r; + else if (info.operation == Qt::UniteClip) + bounds |= r; + } + + + // Map the rectangle back into logical space using the inverse + // matrix. + if (!d->txinv) + const_cast<QPainter *>(this)->d_ptr->updateInvMatrix(); + + return d->invMatrix.mapRect(bounds); +} + +/*! \fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation) Enables clipping, and sets the clip region to the given \a diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 85751a9..96305e3 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -222,6 +222,8 @@ public: void setClipping(bool enable); bool hasClipping() const; + QRectF clipBoundingRect() const; + void save(); void restore(); diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index f358681..9ed212f 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -168,6 +168,8 @@ private slots: void clippedText(); + void clipBoundingRect(); + void setOpacity_data(); void setOpacity(); @@ -4522,6 +4524,41 @@ void tst_QPainter::QTBUG5939_attachPainterPrivate() QCOMPARE(widget->deviceTransform, proxy->deviceTransform); } +void tst_QPainter::clipBoundingRect() +{ + QPixmap pix(500, 500); + + QPainter p(&pix); + + // Test a basic rectangle + p.setClipRect(100, 100, 200, 100); + QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200))); + p.setClipRect(120, 120, 20, 20, Qt::IntersectClip); + QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + + // Test a basic path + region + QPainterPath path; + path.addRect(100, 100, 200, 100); + p.setClipPath(path); + QVERIFY(p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(50, 50, 300, 200))); + p.setClipRegion(QRegion(120, 120, 20, 20), Qt::IntersectClip); + QVERIFY(p.clipBoundingRect().contains(QRect(120, 120, 20, 20))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(100, 100, 200, 100))); + + p.setClipRect(0, 0, 500, 500); + p.translate(250, 250); + for (int i=0; i<360; ++i) { + p.rotate(1); + p.setClipRect(-100, -100, 200, 200, Qt::IntersectClip); + } + QVERIFY(p.clipBoundingRect().contains(QRectF(-100, -100, 200, 200))); + QVERIFY(!p.clipBoundingRect().contains(QRectF(-250, -250, 500, 500))); + +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" |