summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2010-06-02 17:57:06 +1000
committerRhys Weatherley <rhys.weatherley@nokia.com>2010-06-02 17:57:06 +1000
commitd374883cd9f5a773787c2907be3d8d7b31fd0f2b (patch)
tree5c52a2fb3c0e9d9459f3b24552ccd1469b216c67
parentbcafe4a3dde9986ecfdeea43dc592b6f54134893 (diff)
Clipping with rounded rectangles and QVG_SCISSOR_CLIP
WebKit draws rounded rectangles by setting a rounded rect path as a clip and then filling the clip. This had problems when QVG_SCISSOR_CLIP was enabled because the scissor would only clip to the bounding box of complex paths. Thus, rounded rectangle clips were turned into normal rectangle clips. This change will make the scissor clipping code subdivide complex paths into rectangles and use a tighter clip if the number of rectangles is less than or equal to VG_MAX_SCISSOR_RECTS. If it is greater, then it will fall back to the bounding box of the path. Task-number: QT-3372 Reviewed-by: Jason Barron
-rw-r--r--doc/src/howtos/openvg.qdoc5
-rw-r--r--doc/src/platforms/emb-openvg.qdocinc4
-rw-r--r--src/openvg/qpaintengine_vg.cpp45
3 files changed, 48 insertions, 6 deletions
diff --git a/doc/src/howtos/openvg.qdoc b/doc/src/howtos/openvg.qdoc
index e448d9cd5d..f4a34cda30 100644
--- a/doc/src/howtos/openvg.qdoc
+++ b/doc/src/howtos/openvg.qdoc
@@ -262,7 +262,10 @@
The QVG_SCISSOR_CLIP define will disable clipping with vgMask() or
vgRenderToMask() and instead use the scissor rectangle list to perform
- clipping. Clipping with an arbitrary QPainterPath will not be supported.
+ clipping. Clipping with an arbitrary QPainterPath will need to convert
+ the path into a series of rectangles. If the number of rectangles
+ exceeds VG_MAX_SCISSOR_RECTS, then the results will not be exact.
+
The QVG_SCISSOR_CLIP define should only be used if the OpenVG engine
does not support vgMask() or vgRenderToMask().
diff --git a/doc/src/platforms/emb-openvg.qdocinc b/doc/src/platforms/emb-openvg.qdocinc
index 579af6719b..877d70cc91 100644
--- a/doc/src/platforms/emb-openvg.qdocinc
+++ b/doc/src/platforms/emb-openvg.qdocinc
@@ -225,7 +225,9 @@ The QVG_NO_RENDER_TO_MASK define will disable the use of vgRenderToMask().
The QVG_SCISSOR_CLIP define will disable clipping with vgMask() or
vgRenderToMask() and instead use the scissor rectangle list to perform
-clipping. Clipping with an arbitrary QPainterPath will not be supported.
+clipping. Clipping with an arbitrary QPainterPath will need to convert
+the path into a series of rectangles. If the number of rectangles
+exceeds VG_MAX_SCISSOR_RECTS, then the results will not be exact.
The QVG_SCISSOR_CLIP define should only be used if the OpenVG engine does
not support vgMask() or vgRenderToMask().
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp
index 07f841590a..cfc481e2ea 100644
--- a/src/openvg/qpaintengine_vg.cpp
+++ b/src/openvg/qpaintengine_vg.cpp
@@ -1626,11 +1626,48 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op)
QRectF rect(points[0], points[1], points[2] - points[0],
points[5] - points[1]);
clip(rect.toRect(), op);
- } else {
- // The best we can do is clip to the bounding rectangle
- // of all control points.
- clip(path.controlPointRect().toRect(), op);
+ return;
+ }
+
+ // Try converting the path into a QRegion that tightly follows
+ // the outline of the path we want to clip with.
+ QRegion region(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon());
+ switch (op) {
+ case Qt::NoClip:
+ {
+ region = defaultClipRegion();
+ }
+ break;
+
+ case Qt::ReplaceClip:
+ {
+ region = d->transform.map(region);
+ }
+ break;
+
+ case Qt::IntersectClip:
+ {
+ region = s->clipRegion.intersect(d->transform.map(region));
+ }
+ break;
+
+ case Qt::UniteClip:
+ {
+ region = s->clipRegion.unite(d->transform.map(region));
+ }
+ break;
}
+ if (region.numRects() <= d->maxScissorRects) {
+ // We haven't reached the maximum scissor count yet, so we can
+ // still make use of this region.
+ s->clipRegion = region;
+ updateScissor();
+ return;
+ }
+
+ // The best we can do is clip to the bounding rectangle
+ // of all control points.
+ clip(path.controlPointRect().toRect(), op);
}
void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op)