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 /src/openvg | |
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
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
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) |