aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickpathitemnvprrenderer.cpp
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-01-24 18:27:27 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-01-27 09:12:28 +0000
commita48244d5aa1d14c286b7cd39afebcfff9c9dcb60 (patch)
tree7acd17b061bf6f5afccc4f737e11704ebf035acd /src/quick/items/qquickpathitemnvprrenderer.cpp
parent00d3f3e9da071efce92d320884b331ea559fb292 (diff)
JS API for defining static paths and draw params
In order to avoid the over head of one QObject for each VisualPath, Path and PathXxxx element, provide an optional JavaScript API. PathItem { VisualPath { strokeWidth: 4; fillColor: "blue"; dashPattern: [ 1, 2, 3, 4]; capStyle: RoundCap path: Path { PathMove { x: 100; y: 200 } PathLine { x: 300; y: 300 } } } can now also be written as, at least when the path and the stroke/fill params are static and do not need changing/animating later on: PathItem { Component.onCompleted: { var path = newPath(); var sfp = newStrokeFillParams(); path.moveTo(100, 200); path.lineTo(300, 300); sfp.strokeWidth = 4; sfp.fillColor = "blue"; sfp.dashPattern = [ 1, 2, 3, 4 ]; sfp.capStyle = VisualPath.RoundCap; appendVisualPath(path, sfp); commitVisualPaths(); } } In order to emphasize the difference from an imperative API (like context2d), keep the path and the path stroke/fill parameters separate. To preserve our sanity, extras like gradients are not mapped to JavaScript, instead, one still references an QML-defined object from properties like fillGradient. The objects from newPath() and newStrokeFillParams() are reusable by calling clear(). This avoids the need for multiple temp objects when there are multiple paths. Add a simple test and a hidden stress test with the tiger to the manual test. Change-Id: I3b1e275bacf8c8fc52f585fbed5d6f9354d5ae8e Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/quick/items/qquickpathitemnvprrenderer.cpp')
-rw-r--r--src/quick/items/qquickpathitemnvprrenderer.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/quick/items/qquickpathitemnvprrenderer.cpp b/src/quick/items/qquickpathitemnvprrenderer.cpp
index 13fab2dc76..f8504f9985 100644
--- a/src/quick/items/qquickpathitemnvprrenderer.cpp
+++ b/src/quick/items/qquickpathitemnvprrenderer.cpp
@@ -62,6 +62,14 @@ void QQuickPathItemNvprRenderer::setPath(int index, const QQuickPath *path)
m_accDirty |= DirtyPath;
}
+void QQuickPathItemNvprRenderer::setJSPath(int index, const QQuickPathItemPath &path)
+{
+ VisualPathGuiData &d(m_vp[index]);
+ convertJSPath(path, &d);
+ d.dirty |= DirtyPath;
+ m_accDirty |= DirtyPath;
+}
+
void QQuickPathItemNvprRenderer::setStrokeColor(int index, const QColor &color)
{
VisualPathGuiData &d(m_vp[index]);
@@ -288,6 +296,82 @@ void QQuickPathItemNvprRenderer::convertPath(const QQuickPath *path, VisualPathG
d->path.cmd.append(GL_CLOSE_PATH_NV);
}
+void QQuickPathItemNvprRenderer::convertJSPath(const QQuickPathItemPath &path, VisualPathGuiData *d)
+{
+ d->path = NvprPath();
+ if (path.cmd.isEmpty())
+ return;
+
+ QPointF startPos(0, 0);
+ QPointF pos(startPos);
+ int coordIdx = 0;
+
+ for (QQuickPathItemPath::Command cmd : path.cmd) {
+ switch (cmd) {
+ case QQuickPathItemPath::MoveTo:
+ d->path.cmd.append(GL_MOVE_TO_NV);
+ pos = QPointF(path.coords[coordIdx], path.coords[coordIdx + 1]);
+ startPos = pos;
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ coordIdx += 2;
+ break;
+ case QQuickPathItemPath::LineTo:
+ d->path.cmd.append(GL_LINE_TO_NV);
+ pos = QPointF(path.coords[coordIdx], path.coords[coordIdx + 1]);
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ coordIdx += 2;
+ break;
+ case QQuickPathItemPath::QuadTo:
+ d->path.cmd.append(GL_QUADRATIC_CURVE_TO_NV);
+ d->path.coord.append(path.coords[coordIdx]);
+ d->path.coord.append(path.coords[coordIdx + 1]);
+ pos = QPointF(path.coords[coordIdx + 2], path.coords[coordIdx + 3]);
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ coordIdx += 4;
+ break;
+ case QQuickPathItemPath::CubicTo:
+ d->path.cmd.append(GL_CUBIC_CURVE_TO_NV);
+ d->path.coord.append(path.coords[coordIdx]);
+ d->path.coord.append(path.coords[coordIdx + 1]);
+ d->path.coord.append(path.coords[coordIdx + 2]);
+ d->path.coord.append(path.coords[coordIdx + 3]);
+ pos = QPointF(path.coords[coordIdx + 4], path.coords[coordIdx + 5]);
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ coordIdx += 6;
+ break;
+ case QQuickPathItemPath::ArcTo:
+ {
+ const bool sweepFlag = !qFuzzyIsNull(path.coords[coordIdx + 5]);
+ const bool useLargeArc = !qFuzzyIsNull(path.coords[coordIdx + 6]);
+ GLenum cmd;
+ if (useLargeArc)
+ cmd = sweepFlag ? GL_LARGE_CCW_ARC_TO_NV : GL_LARGE_CW_ARC_TO_NV;
+ else
+ cmd = sweepFlag ? GL_SMALL_CCW_ARC_TO_NV : GL_SMALL_CW_ARC_TO_NV;
+ d->path.cmd.append(cmd);
+ d->path.coord.append(path.coords[coordIdx]); // rx
+ d->path.coord.append(path.coords[coordIdx + 1]); // ry
+ d->path.coord.append(path.coords[coordIdx + 2]); // xrot
+ pos = QPointF(path.coords[coordIdx + 3], path.coords[coordIdx + 4]);
+ d->path.coord.append(pos.x());
+ d->path.coord.append(pos.y());
+ coordIdx += 7;
+ }
+ break;
+ default:
+ qWarning("Unknown JS path command: %d", cmd);
+ break;
+ }
+ }
+
+ if (pos == startPos)
+ d->path.cmd.append(GL_CLOSE_PATH_NV);
+}
+
static inline QVector4D qsg_premultiply(const QColor &c, float globalOpacity)
{
const float o = c.alphaF() * globalOpacity;