diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-06-02 07:57:06 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2010-06-02 07:57:06 (GMT) |
commit | d374883cd9f5a773787c2907be3d8d7b31fd0f2b (patch) | |
tree | 5c52a2fb3c0e9d9459f3b24552ccd1469b216c67 | |
parent | bcafe4a3dde9986ecfdeea43dc592b6f54134893 (diff) | |
download | Qt-d374883cd9f5a773787c2907be3d8d7b31fd0f2b.zip Qt-d374883cd9f5a773787c2907be3d8d7b31fd0f2b.tar.gz Qt-d374883cd9f5a773787c2907be3d8d7b31fd0f2b.tar.bz2 |
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.qdoc | 5 | ||||
-rw-r--r-- | doc/src/platforms/emb-openvg.qdocinc | 4 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 45 |
3 files changed, 48 insertions, 6 deletions
diff --git a/doc/src/howtos/openvg.qdoc b/doc/src/howtos/openvg.qdoc index e448d9c..f4a34cd 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 579af67..877d70c 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 07f8415..cfc481e 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) |