diff options
author | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-20 23:22:07 (GMT) |
---|---|---|
committer | Rhys Weatherley <rhys.weatherley@nokia.com> | 2009-09-20 23:22:07 (GMT) |
commit | 1b8d92b1ae453bd2d395658c7086d0049916e88f (patch) | |
tree | 5d2c7f6e879af1b029653ae6c73ab10a9e696cab /src/openvg | |
parent | cd48ed92670a0d086589b202364f38f14e7221c9 (diff) | |
download | Qt-1b8d92b1ae453bd2d395658c7086d0049916e88f.zip Qt-1b8d92b1ae453bd2d395658c7086d0049916e88f.tar.gz Qt-1b8d92b1ae453bd2d395658c7086d0049916e88f.tar.bz2 |
Accelerate drawRoundedRect() for the OpenVG paint engine
Previously rounded rectangles were converted into a QVectorPath
and then a VGPath. This change creates the VGPath directly without
an intermediate step and was made possible by change dd3e4308.
Reviewed-by: trustme
Diffstat (limited to 'src/openvg')
-rw-r--r-- | src/openvg/qpaintengine_vg.cpp | 98 | ||||
-rw-r--r-- | src/openvg/qpaintengine_vg_p.h | 2 |
2 files changed, 100 insertions, 0 deletions
diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 3ae3fe4..46abbea 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -52,6 +52,7 @@ #include <QtGui/private/qtextureglyphcache_p.h> #include <QtGui/private/qtextengine_p.h> #include <QtGui/private/qfontengine_p.h> +#include <QtGui/private/qpainterpath_p.h> #include <QDebug> #include <QSet> @@ -131,6 +132,7 @@ public: void fill(VGPath path, const QBrush& brush, VGint rule = VG_EVEN_ODD); VGPath vectorPathToVGPath(const QVectorPath& path); VGPath painterPathToVGPath(const QPainterPath& path); + VGPath roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode); VGPaintType setBrush (VGPaint paint, const QBrush& brush, VGMatrixMode mode, VGPaintType prevPaintType); @@ -172,6 +174,7 @@ public: #if !defined(QVG_NO_MODIFY_PATH) VGPath rectPath; // Cached path for quick drawing of rectangles. VGPath linePath; // Cached path for quick drawing of lines. + VGPath roundRectPath; // Cached path for quick drawing of rounded rects. #endif QTransform transform; // Currently active transform. @@ -341,6 +344,7 @@ void QVGPaintEnginePrivate::init() #if !defined(QVG_NO_MODIFY_PATH) rectPath = 0; linePath = 0; + roundRectPath = 0; #endif simpleTransform = true; @@ -453,6 +457,8 @@ void QVGPaintEnginePrivate::destroy() vgDestroyPath(rectPath); if (linePath) vgDestroyPath(linePath); + if (roundRectPath) + vgDestroyPath(roundRectPath); #endif #if !defined(QVG_NO_DRAW_GLYPHS) @@ -879,6 +885,83 @@ VGPath QVGPaintEnginePrivate::painterPathToVGPath(const QPainterPath& path) return vgpath; } +VGPath QVGPaintEnginePrivate::roundedRectPath(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode) +{ + static VGubyte roundedrect_types[] = { + VG_MOVE_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_LINE_TO_ABS, + VG_CUBIC_TO_ABS, + VG_CLOSE_PATH + }; + + qreal x1 = rect.left(); + qreal x2 = rect.right(); + qreal y1 = rect.top(); + qreal y2 = rect.bottom(); + + if (mode == Qt::RelativeSize) { + xRadius = xRadius * rect.width() / 200.; + yRadius = yRadius * rect.height() / 200.; + } + + xRadius = qMin(xRadius, rect.width() / 2); + yRadius = qMin(yRadius, rect.height() / 2); + + VGfloat pts[] = { + x1 + xRadius, y1, // MoveTo + x2 - xRadius, y1, // LineTo + x2 - (1 - KAPPA) * xRadius, y1, // CurveTo + x2, y1 + (1 - KAPPA) * yRadius, + x2, y1 + yRadius, + x2, y2 - yRadius, // LineTo + x2, y2 - (1 - KAPPA) * yRadius, // CurveTo + x2 - (1 - KAPPA) * xRadius, y2, + x2 - xRadius, y2, + x1 + xRadius, y2, // LineTo + x1 + (1 - KAPPA) * xRadius, y2, // CurveTo + x1, y2 - (1 - KAPPA) * yRadius, + x1, y2 - yRadius, + x1, y1 + yRadius, // LineTo + x1, y1 + KAPPA * yRadius, // CurveTo + x1 + (1 - KAPPA) * xRadius, y1, + x1 + xRadius, y1 + }; + +#if !defined(QVG_NO_MODIFY_PATH) + VGPath vgpath = roundRectPath; + if (!vgpath) { + vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 10, // segmentCapacityHint + 17 * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + vgAppendPathData(vgpath, 10, roundedrect_types, pts); + roundRectPath = vgpath; + } else { + vgModifyPathCoords(vgpath, 0, 9, pts); + } +#else + VGPath vgpath = vgCreatePath(VG_PATH_FORMAT_STANDARD, + VG_PATH_DATATYPE_F, + 1.0f, // scale + 0.0f, // bias + 10, // segmentCapacityHint + 17 * 2, // coordCapacityHint + VG_PATH_CAPABILITY_ALL); + vgAppendPathData(vgpath, 10, roundedrect_types, pts); +#endif + + return vgpath; +} + extern QImage qt_imageForBrush(int style, bool invert); static QImage colorizeBitmap(const QImage &image, const QColor &color) @@ -2332,6 +2415,21 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color) #endif } +void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode) +{ + Q_D(QVGPaintEngine); + if (d->simpleTransform) { + QVGPainterState *s = state(); + VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); + d->draw(vgpath, s->pen, s->brush); +#if defined(QVG_NO_MODIFY_PATH) + vgDestroyPath(vgpath); +#endif + } else { + QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); + } +} + void QVGPaintEngine::drawRects(const QRect *rects, int rectCount) { #if !defined(QVG_NO_MODIFY_PATH) diff --git a/src/openvg/qpaintengine_vg_p.h b/src/openvg/qpaintengine_vg_p.h index 5c0f525..a3487dc 100644 --- a/src/openvg/qpaintengine_vg_p.h +++ b/src/openvg/qpaintengine_vg_p.h @@ -108,6 +108,8 @@ public: void fillRect(const QRectF &rect, const QBrush &brush); void fillRect(const QRectF &rect, const QColor &color); + void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode); + void drawRects(const QRect *rects, int rectCount); void drawRects(const QRectF *rects, int rectCount); |