aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-04-03 11:58:46 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-04-25 13:03:28 +0000
commite2520ff76be49c5aa917741cc6a380fe1549e47d (patch)
tree6ec310e84eba500ac39a49c8df2ed0d22acd2dff /src/quick/items
parentb334a92493c9e4956b0fc631610857d1b1cf5f6d (diff)
Move PathItem to qt.labs
Change-Id: I1cd686cff60bd40fe2cbbc34f917fac7835b6b7d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Andy Nichols <andy.nichols@qt.io> Reviewed-by: Robin Burchell <robin.burchell@crimson.no>
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp3
-rw-r--r--src/quick/items/items.pri15
-rw-r--r--src/quick/items/qquickitemsmodule.cpp6
-rw-r--r--src/quick/items/qquickpathitem.cpp2258
-rw-r--r--src/quick/items/qquickpathitem_p.h335
-rw-r--r--src/quick/items/qquickpathitem_p_p.h282
-rw-r--r--src/quick/items/qquickpathitemgenericrenderer.cpp775
-rw-r--r--src/quick/items/qquickpathitemgenericrenderer_p.h303
-rw-r--r--src/quick/items/qquickpathitemnvprrenderer.cpp923
-rw-r--r--src/quick/items/qquickpathitemnvprrenderer_p.h237
-rw-r--r--src/quick/items/qquickpathitemsoftwarerenderer.cpp277
-rw-r--r--src/quick/items/qquickpathitemsoftwarerenderer_p.h136
12 files changed, 4 insertions, 5546 deletions
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index 1a6f530bfa..715fc4b2c7 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -40,6 +40,7 @@
#include "qquickcontext2d_p.h"
#include "qquickcontext2dcommandbuffer_p.h"
#include "qquickcanvasitem_p.h"
+#include <private/qtquickglobal_p.h>
#include <private/qquickcontext2dtexture_p.h>
#include <private/qquickitem_p.h>
#if QT_CONFIG(quick_shadereffect)
@@ -136,7 +137,7 @@ Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
THROW_GENERIC_ERROR("Not a Context2D object");
#define qClamp(val, min, max) qMin(qMax(val, min), max)
#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
-QColor qt_color_from_string(const QV4::Value &name)
+Q_QUICK_PRIVATE_EXPORT QColor qt_color_from_string(const QV4::Value &name)
{
QByteArray str = name.toQString().toUtf8();
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri
index 511c6f18d8..0f8061b5ef 100644
--- a/src/quick/items/items.pri
+++ b/src/quick/items/items.pri
@@ -148,20 +148,9 @@ qtConfig(quick-listview) {
qtConfig(quick-pathview) {
HEADERS += \
$$PWD/qquickpathview_p.h \
- $$PWD/qquickpathview_p_p.h \
- $$PWD/qquickpathitem_p.h \
- $$PWD/qquickpathitem_p_p.h \
- $$PWD/qquickpathitemgenericrenderer_p.h \
- $$PWD/qquickpathitemsoftwarerenderer_p.h
+ $$PWD/qquickpathview_p_p.h
SOURCES += \
- $$PWD/qquickpathview.cpp \
- $$PWD/qquickpathitem.cpp \
- $$PWD/qquickpathitemgenericrenderer.cpp \
- $$PWD/qquickpathitemsoftwarerenderer.cpp
- qtConfig(opengl) {
- HEADERS += $$PWD/qquickpathitemnvprrenderer_p.h
- SOURCES += $$PWD/qquickpathitemnvprrenderer.cpp
- }
+ $$PWD/qquickpathview.cpp
}
qtConfig(quick-positioners) {
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 9e692da442..e6321e9365 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -70,7 +70,6 @@
#if QT_CONFIG(quick_path)
#include <private/qquickpath_p.h>
#include <private/qquickpathinterpolator_p.h>
-#include "qquickpathitem_p.h"
#endif
#if QT_CONFIG(quick_positioners)
#include "qquickpositioners_p.h"
@@ -381,11 +380,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
#if QT_CONFIG(quick_path)
qmlRegisterType<QQuickPathArc, 2>(uri, 2, 9, "PathArc");
qmlRegisterType<QQuickPathMove>(uri, 2, 9, "PathMove");
- qmlRegisterType<QQuickPathItem>(uri, 2, 9, "PathItem");
- qmlRegisterType<QQuickVisualPath>(uri, 2, 9, "VisualPath");
- qmlRegisterType<QQuickPathGradientStop>(uri, 2, 9, "PathGradientStop");
- qmlRegisterUncreatableType<QQuickPathGradient>(uri, 2, 9, "PathGradient", QQuickPathGradient::tr("PathGradient is an abstract base class"));
- qmlRegisterType<QQuickPathLinearGradient>(uri, 2, 9, "PathLinearGradient");
#endif
qmlRegisterType<QQuickText, 9>(uri, 2, 9, "Text");
diff --git a/src/quick/items/qquickpathitem.cpp b/src/quick/items/qquickpathitem.cpp
deleted file mode 100644
index fae16064e5..0000000000
--- a/src/quick/items/qquickpathitem.cpp
+++ /dev/null
@@ -1,2258 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpathitem_p.h"
-#include "qquickpathitem_p_p.h"
-#include "qquickpathitemgenericrenderer_p.h"
-#include "qquickpathitemnvprrenderer_p.h"
-#include "qquickpathitemsoftwarerenderer_p.h"
-#include <private/qsgtexture_p.h>
-#include <private/qquicksvgparser_p.h>
-#include <QtGui/private/qdrawhelper_p.h>
-#include <QOpenGLFunctions>
-
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-#include <private/qv4qobjectwrapper_p.h>
-#include <private/qv4mm_p.h>
-#include <private/qqmlengine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-QQuickPathItemStrokeFillParams::QQuickPathItemStrokeFillParams()
- : strokeColor(Qt::white),
- strokeWidth(1),
- fillColor(Qt::white),
- fillRule(QQuickVisualPath::OddEvenFill),
- joinStyle(QQuickVisualPath::BevelJoin),
- miterLimit(2),
- capStyle(QQuickVisualPath::SquareCap),
- strokeStyle(QQuickVisualPath::SolidLine),
- dashOffset(0),
- fillGradient(nullptr)
-{
- dashPattern << 4 << 2; // 4 * strokeWidth dash followed by 2 * strokeWidth space
-}
-
-QPainterPath QQuickPathItemPath::toPainterPath() const
-{
- QPainterPath p;
- int coordIdx = 0;
- for (int i = 0; i < cmd.count(); ++i) {
- switch (cmd[i]) {
- case QQuickPathItemPath::MoveTo:
- p.moveTo(coords[coordIdx], coords[coordIdx + 1]);
- coordIdx += 2;
- break;
- case QQuickPathItemPath::LineTo:
- p.lineTo(coords[coordIdx], coords[coordIdx + 1]);
- coordIdx += 2;
- break;
- case QQuickPathItemPath::QuadTo:
- p.quadTo(coords[coordIdx], coords[coordIdx + 1],
- coords[coordIdx + 2], coords[coordIdx + 3]);
- coordIdx += 4;
- break;
- case QQuickPathItemPath::CubicTo:
- p.cubicTo(coords[coordIdx], coords[coordIdx + 1],
- coords[coordIdx + 2], coords[coordIdx + 3],
- coords[coordIdx + 4], coords[coordIdx + 5]);
- coordIdx += 6;
- break;
- case QQuickPathItemPath::ArcTo:
- // does not map to the QPainterPath API; reuse the helper code from QQuickSvgParser
- QQuickSvgParser::pathArc(p,
- coords[coordIdx], coords[coordIdx + 1], // radius
- coords[coordIdx + 2], // xAxisRotation
- !qFuzzyIsNull(coords[coordIdx + 6]), // useLargeArc
- !qFuzzyIsNull(coords[coordIdx + 5]), // sweep flag
- coords[coordIdx + 3], coords[coordIdx + 4], // end
- p.currentPosition().x(), p.currentPosition().y());
- coordIdx += 7;
- break;
- default:
- qWarning("Unknown JS path command: %d", cmd[i]);
- break;
- }
- }
- return p;
-}
-
-/*!
- \qmltype VisualPath
- \instantiates QQuickVisualPath
- \inqmlmodule QtQuick
- \ingroup qtquick-paths
- \ingroup qtquick-views
- \inherits Object
- \brief Describes a Path and associated properties for stroking and filling
- \since 5.10
-
- A PathItem contains one or more VisualPath elements. At least one
- VisualPath is necessary in order to have a PathItem output anything
- visible. A VisualPath in turn contains a Path and properties describing the
- stroking and filling parameters, such as the stroke width and color, the
- fill color or gradient, join and cap styles, and so on. Finally, the Path
- object contains a list of path elements like PathMove, PathLine, PathCubic,
- PathQuad, PathArc.
-
- Any property changes in these data sets will be bubble up and change the
- output of the PathItem. This means that it is simple and easy to change, or
- even animate, the starting and ending position, control points, or any
- stroke or fill parameters using the usual QML bindings and animation types
- like NumberAnimation.
-
- In the following example the line join style changes automatically based on
- the value of joinStyleIndex:
-
- \code
- VisualPath {
- strokeColor: "black"
- strokeWidth: 16
- fillColor: "transparent"
- capStyle: VisualPath.RoundCap
-
- property int joinStyleIndex: 0
- property variant styles: [ VisualPath.BevelJoin, VisualPath.MiterJoin, VisualPath.RoundJoin ]
-
- joinStyle: styles[joinStyleIndex]
-
- Path {
- startX: 30
- startY: 30
- PathLine { x: 100; y: 100 }
- PathLine { x: 30; y: 100 }
- }
- }
- \endcode
-
- Once associated with a PathItem, here is the output with a joinStyleIndex
- of 2 (VisualPath.RoundJoin):
-
- \image visualpath-code-example.png
- */
-
-QQuickVisualPathPrivate::QQuickVisualPathPrivate()
- : path(nullptr),
- dirty(DirtyAll)
-{
-}
-
-QQuickVisualPath::QQuickVisualPath(QObject *parent)
- : QObject(*(new QQuickVisualPathPrivate), parent)
-{
-}
-
-QQuickVisualPath::~QQuickVisualPath()
-{
-}
-
-/*!
- \qmlproperty Path QtQuick::VisualPath::path
-
- This property holds the Path object.
-
- \default
- */
-
-QQuickPath *QQuickVisualPath::path() const
-{
- Q_D(const QQuickVisualPath);
- return d->path;
-}
-
-void QQuickVisualPath::setPath(QQuickPath *path)
-{
- Q_D(QQuickVisualPath);
- if (d->path == path)
- return;
-
- if (d->path)
- qmlobject_disconnect(d->path, QQuickPath, SIGNAL(changed()),
- this, QQuickVisualPath, SLOT(_q_pathChanged()));
- d->path = path;
- qmlobject_connect(d->path, QQuickPath, SIGNAL(changed()),
- this, QQuickVisualPath, SLOT(_q_pathChanged()));
-
- d->dirty |= QQuickVisualPathPrivate::DirtyPath;
- emit pathChanged();
- emit changed();
-}
-
-void QQuickVisualPathPrivate::_q_pathChanged()
-{
- Q_Q(QQuickVisualPath);
- dirty |= DirtyPath;
- emit q->changed();
-}
-
-/*!
- \qmlproperty color QtQuick::VisualPath::strokeColor
-
- This property holds the stroking color.
-
- When set to \c transparent, no stroking occurs.
-
- The default value is \c white.
- */
-
-QColor QQuickVisualPath::strokeColor() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.strokeColor;
-}
-
-void QQuickVisualPath::setStrokeColor(const QColor &color)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.strokeColor != color) {
- d->sfp.strokeColor = color;
- d->dirty |= QQuickVisualPathPrivate::DirtyStrokeColor;
- emit strokeColorChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty color QtQuick::VisualPath::strokeWidth
-
- This property holds the stroke width.
-
- When set to a negative value, no stroking occurs.
-
- The default value is 1.
- */
-
-qreal QQuickVisualPath::strokeWidth() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.strokeWidth;
-}
-
-void QQuickVisualPath::setStrokeWidth(qreal w)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.strokeWidth != w) {
- d->sfp.strokeWidth = w;
- d->dirty |= QQuickVisualPathPrivate::DirtyStrokeWidth;
- emit strokeWidthChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty color QtQuick::VisualPath::fillColor
-
- This property holds the fill color.
-
- When set to \c transparent, no filling occurs.
-
- The default value is \c white.
- */
-
-QColor QQuickVisualPath::fillColor() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.fillColor;
-}
-
-void QQuickVisualPath::setFillColor(const QColor &color)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.fillColor != color) {
- d->sfp.fillColor = color;
- d->dirty |= QQuickVisualPathPrivate::DirtyFillColor;
- emit fillColorChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick::VisualPath::fillRule
-
- This property holds the fill rule. The default value is
- VisualPath.OddEvenFill. For an example on fill rules, see
- QPainterPath::setFillRule().
-
- \list
- \li VisualPath.OddEvenFill
- \li VisualPath.WindingFill
- \endlist
- */
-
-QQuickVisualPath::FillRule QQuickVisualPath::fillRule() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.fillRule;
-}
-
-void QQuickVisualPath::setFillRule(FillRule fillRule)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.fillRule != fillRule) {
- d->sfp.fillRule = fillRule;
- d->dirty |= QQuickVisualPathPrivate::DirtyFillRule;
- emit fillRuleChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick::VisualPath::joinStyle
-
- This property defines how joins between two connected lines are drawn. The
- default value is VisualPath.BevelJoin.
-
- \list
- \li VisualPath.MiterJoin - The outer edges of the lines are extended to meet at an angle, and this area is filled.
- \li VisualPath.BevelJoin - The triangular notch between the two lines is filled.
- \li VisualPath.RoundJoin - A circular arc between the two lines is filled.
- \endlist
- */
-
-QQuickVisualPath::JoinStyle QQuickVisualPath::joinStyle() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.joinStyle;
-}
-
-void QQuickVisualPath::setJoinStyle(JoinStyle style)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.joinStyle != style) {
- d->sfp.joinStyle = style;
- d->dirty |= QQuickVisualPathPrivate::DirtyStyle;
- emit joinStyleChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty int QtQuick::VisualPath::miterLimit
-
- When VisualPath.joinStyle is set to VisualPath.MiterJoin, this property
- specifies how far the miter join can extend from the join point.
-
- The default value is 2.
- */
-
-int QQuickVisualPath::miterLimit() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.miterLimit;
-}
-
-void QQuickVisualPath::setMiterLimit(int limit)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.miterLimit != limit) {
- d->sfp.miterLimit = limit;
- d->dirty |= QQuickVisualPathPrivate::DirtyStyle;
- emit miterLimitChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick::VisualPath::capStyle
-
- This property defines how the end points of lines are drawn. The
- default value is VisualPath.SquareCap.
-
- \list
- \li VisualPath.FlatCap - A square line end that does not cover the end point of the line.
- \li VisualPath.SquareCap - A square line end that covers the end point and extends beyond it by half the line width.
- \li VisualPath.RoundCap - A rounded line end.
- \endlist
- */
-
-QQuickVisualPath::CapStyle QQuickVisualPath::capStyle() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.capStyle;
-}
-
-void QQuickVisualPath::setCapStyle(CapStyle style)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.capStyle != style) {
- d->sfp.capStyle = style;
- d->dirty |= QQuickVisualPathPrivate::DirtyStyle;
- emit capStyleChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick::VisualPath::strokeStyle
-
- This property defines the style of stroking. The default value is
- VisualPath.SolidLine.
-
- \list
- \li VisualPath.SolidLine - A plain line.
- \li VisualPath.DashLine - Dashes separated by a few pixels.
- \endlist
- */
-
-QQuickVisualPath::StrokeStyle QQuickVisualPath::strokeStyle() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.strokeStyle;
-}
-
-void QQuickVisualPath::setStrokeStyle(StrokeStyle style)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.strokeStyle != style) {
- d->sfp.strokeStyle = style;
- d->dirty |= QQuickVisualPathPrivate::DirtyDash;
- emit strokeStyleChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty real QtQuick::VisualPath::dashOffset
-
- This property defines the starting point on the dash pattern, measured in
- units used to specify the dash pattern.
-
- The default value is 0.
-
- \sa QPen::setDashOffset()
- */
-
-qreal QQuickVisualPath::dashOffset() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.dashOffset;
-}
-
-void QQuickVisualPath::setDashOffset(qreal offset)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.dashOffset != offset) {
- d->sfp.dashOffset = offset;
- d->dirty |= QQuickVisualPathPrivate::DirtyDash;
- emit dashOffsetChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty list<real> QtQuick::VisualPath::dashPattern
-
- This property defines the dash pattern when VisualPath.strokeStyle is set
- to VisualPath.DashLine. The pattern must be specified as an even number of
- positive entries where the entries 1, 3, 5... are the dashes and 2, 4, 6...
- are the spaces. The pattern is specified in units of the pen's width.
-
- The default value is (4, 2), meaning a dash of 4 * VisualPath.strokeWidth
- pixels followed by a space of 2 * VisualPath.strokeWidth pixels.
-
- \sa QPen::setDashPattern()
- */
-
-QVector<qreal> QQuickVisualPath::dashPattern() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.dashPattern;
-}
-
-void QQuickVisualPath::setDashPattern(const QVector<qreal> &array)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.dashPattern != array) {
- d->sfp.dashPattern = array;
- d->dirty |= QQuickVisualPathPrivate::DirtyDash;
- emit dashPatternChanged();
- emit changed();
- }
-}
-
-/*!
- \qmlproperty PathGradient QtQuick::VisualPath::fillGradient
-
- This property defines the fill gradient. By default no gradient is enabled
- and the value is \c null. In this case the fill uses a solid color based on
- the value of VisuaLPath.fillColor.
-
- When set, VisualPath.fillColor is ignored and filling is done using one of
- the PathGradient subtypes.
- */
-
-QQuickPathGradient *QQuickVisualPath::fillGradient() const
-{
- Q_D(const QQuickVisualPath);
- return d->sfp.fillGradient;
-}
-
-void QQuickVisualPath::setFillGradient(QQuickPathGradient *gradient)
-{
- Q_D(QQuickVisualPath);
- if (d->sfp.fillGradient != gradient) {
- if (d->sfp.fillGradient)
- qmlobject_disconnect(d->sfp.fillGradient, QQuickPathGradient, SIGNAL(updated()),
- this, QQuickVisualPath, SLOT(_q_fillGradientChanged()));
- d->sfp.fillGradient = gradient;
- if (d->sfp.fillGradient)
- qmlobject_connect(d->sfp.fillGradient, QQuickPathGradient, SIGNAL(updated()),
- this, QQuickVisualPath, SLOT(_q_fillGradientChanged()));
- d->dirty |= QQuickVisualPathPrivate::DirtyFillGradient;
- emit changed();
- }
-}
-
-void QQuickVisualPathPrivate::_q_fillGradientChanged()
-{
- Q_Q(QQuickVisualPath);
- dirty |= DirtyFillGradient;
- emit q->changed();
-}
-
-void QQuickVisualPath::resetFillGradient()
-{
- setFillGradient(nullptr);
-}
-
-/*!
- \qmltype PathItem
- \instantiates QQuickPathItem
- \inqmlmodule QtQuick
- \ingroup qtquick-paths
- \ingroup qtquick-views
- \inherits Item
- \brief Renders a path
- \since 5.10
-
- Renders a path either by generating geometry via QPainterPath and manual
- triangulation or by using a GPU vendor extension like \c{GL_NV_path_rendering}.
-
- This approach is different from rendering shapes via QQuickPaintedItem or
- the 2D Canvas because the path never gets rasterized in software. Therefore
- PathItem is suitable for creating shapes spreading over larger areas of the
- screen, avoiding the performance penalty for texture uploads or framebuffer
- blits. In addition, the declarative API allows manipulating, binding to,
- and even animating the path element properties like starting and ending
- position, the control points, etc.
-
- The types for specifying path elements are shared between \l PathView and
- PathItem. However, not all PathItem implementations support all path
- element types, while some may not make sense for PathView. PathItem's
- currently supported subset is: PathMove, PathLine, PathQuad, PathCubic,
- PathArc, PathSvg.
-
- See \l Path for a detailed overview of the supported path elements.
-
- \code
- PathItem {
- width: 200
- height: 150
- anchors.centerIn: parent
- VisualPath {
- strokeWidth: 4
- strokeColor: "red"
- fillGradient: PathLinearGradient {
- x1: 20; y1: 20
- x2: 180; y2: 130
- PathGradientStop { position: 0; color: "blue" }
- PathGradientStop { position: 0.2; color: "green" }
- PathGradientStop { position: 0.4; color: "red" }
- PathGradientStop { position: 0.6; color: "yellow" }
- PathGradientStop { position: 1; color: "cyan" }
- }
- strokeStyle: VisualPath.DashLine
- dashPattern: [ 1, 4 ]
- Path {
- startX: 20; startY: 20
- PathLine { x: 180; y: 130 }
- PathLine { x: 20; y: 130 }
- PathLine { x: 20; y: 20 }
- }
- }
- }
- \endcode
-
- \image pathitem-code-example.png
-
- \note It is important to be aware of performance implications, in
- particular when the application is running on the generic PathItem
- implementation due to not having support for accelerated path rendering.
- The geometry generation happens entirely on the CPU in this case, and this
- is potentially expensive. Changing the set of path elements, changing the
- properties of these elements, or changing certain properties of the
- PathItem itself all lead to retriangulation on every change. Therefore,
- applying animation to such properties can heavily affect performance on
- less powerful systems. If animating properties other than stroke and fill
- colors is a must, it is recommended to target systems providing
- \c{GL_NV_path_rendering} where the cost of path property changes is much
- smaller.
-
- The following list summarizes the available PathItem rendering approaches:
-
- \list
-
- \li When running with the default, OpenGL backend of Qt Quick, both the
- generic, triangulation-based and the NVIDIA-specific
- \c{GL_NV_path_rendering} methods are available. The choice is made at
- runtime, depending on the graphics driver's capabilities. When this is not
- desired, applications can force using the generic method by setting the
- PathItem.enableVendorExtensions property to \c false.
-
- \li The \c software backend is fully supported. The path is rendered via
- QPainter::strokePath() and QPainter::fillPath() in this case.
-
- \li The Direct 3D 12 backend is not currently supported.
-
- \li The OpenVG backend is not currently supported.
-
- \endlist
-
- \sa Path, PathMove, PathLine, PathQuad, PathCubic, PathArc, PathSvg
-*/
-
-QQuickPathItemPrivate::QQuickPathItemPrivate()
- : componentComplete(true),
- vpChanged(false),
- rendererType(QQuickPathItem::UnknownRenderer),
- async(false),
- status(QQuickPathItem::Null),
- renderer(nullptr),
- enableVendorExts(true)
-{
-}
-
-QQuickPathItemPrivate::~QQuickPathItemPrivate()
-{
- delete renderer;
-}
-
-void QQuickPathItemPrivate::_q_visualPathChanged()
-{
- Q_Q(QQuickPathItem);
- vpChanged = true;
- q->polish();
-}
-
-void QQuickPathItemPrivate::setStatus(QQuickPathItem::Status newStatus)
-{
- Q_Q(QQuickPathItem);
- if (status != newStatus) {
- status = newStatus;
- emit q->statusChanged();
- }
-}
-
-QQuickPathItem::QQuickPathItem(QQuickItem *parent)
- : QQuickItem(*(new QQuickPathItemPrivate), parent)
-{
- setFlag(ItemHasContents);
-}
-
-QQuickPathItem::~QQuickPathItem()
-{
-}
-
-/*!
- \qmlproperty enumeration QtQuick::PathItem::rendererType
-
- This property determines which path rendering backend is active.
-
- \list
-
- \li PathItem.UnknownRenderer - The renderer is unknown.
-
- \li PathItem.GeometryRenderer - The generic, driver independent solution
- for OpenGL. Uses the same CPU-based triangulation approach as QPainter's
- OpenGL 2 paint engine. This is the default on non-NVIDIA hardware when the
- default, OpenGL Qt Quick scenegraph backend is in use.
-
- \li PathItem.NvprRenderer - Path items are rendered by performing OpenGL
- calls using the \c{GL_NV_path_rendering} extension. This is the default on
- NVIDIA hardware when the default, OpenGL Qt Quick scenegraph backend is in
- use.
-
- \li PathItem.SoftwareRenderer - Pure QPainter drawing using the raster
- paint engine. This is the default, and only, option when the Qt Quick
- scenegraph is running with the \c software backend.
-
- \endlist
-*/
-
-QQuickPathItem::RendererType QQuickPathItem::rendererType() const
-{
- Q_D(const QQuickPathItem);
- return d->rendererType;
-}
-
-/*!
- \qmlproperty bool QtQuick::PathItem::asynchronous
-
- When PathItem.rendererType is PathItem.GeometryRenderer, the input path is
- triangulated on the CPU during the polishing phase of the PathItem. This is
- potentially expensive. To offload this work to separate worker threads, set
- this property to \c true.
-
- When enabled, making a PathItem visible will not wait for the content to
- become available. Instead, the gui/main thread is not blocked and the
- results of the path rendering are shown only when all the asynchronous work
- has been finished.
-
- The default value is \c false.
- */
-
-bool QQuickPathItem::asynchronous() const
-{
- Q_D(const QQuickPathItem);
- return d->async;
-}
-
-void QQuickPathItem::setAsynchronous(bool async)
-{
- Q_D(QQuickPathItem);
- if (d->async != async) {
- d->async = async;
- emit asynchronousChanged();
- if (d->componentComplete)
- d->_q_visualPathChanged();
- }
-}
-
-/*!
- \qmlproperty bool QtQuick::PathItem::enableVendorExtensions
-
- This property controls the usage of non-standard OpenGL extensions like
- GL_NV_path_rendering. To disable PathItem.NvprRenderer and force a uniform
- behavior regardless of the graphics card and drivers, set this property to
- \c false.
-
- The default value is \c true.
- */
-
-bool QQuickPathItem::enableVendorExtensions() const
-{
- Q_D(const QQuickPathItem);
- return d->enableVendorExts;
-}
-
-void QQuickPathItem::setEnableVendorExtensions(bool enable)
-{
- Q_D(QQuickPathItem);
- if (d->enableVendorExts != enable) {
- d->enableVendorExts = enable;
- emit enableVendorExtensionsChanged();
- }
-}
-
-/*!
- \qmlproperty enumeration QtQuick::PathItem::status
-
- This property determines the status of the PathItem and is relevant when
- PathItem.asynchronous is set to \c true.
-
- \list
-
- \li PathItem.Null - Not yet initialized.
-
- \li PathItem.Ready - The PathItem has finished processing.
-
- \li PathItem.Processing - The path is being processed.
-
- \endlist
- */
-
-QQuickPathItem::Status QQuickPathItem::status() const
-{
- Q_D(const QQuickPathItem);
- return d->status;
-}
-
-static QQuickVisualPath *vpe_at(QQmlListProperty<QQuickVisualPath> *property, int index)
-{
- QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(static_cast<QQuickPathItem *>(property->object));
- return d->qmlData.vp.at(index);
-}
-
-static void vpe_append(QQmlListProperty<QQuickVisualPath> *property, QQuickVisualPath *obj)
-{
- QQuickPathItem *item = static_cast<QQuickPathItem *>(property->object);
- QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(item);
- d->qmlData.vp.append(obj);
-
- if (d->componentComplete) {
- QObject::connect(obj, SIGNAL(changed()), item, SLOT(_q_visualPathChanged()));
- d->_q_visualPathChanged();
- }
-}
-
-static int vpe_count(QQmlListProperty<QQuickVisualPath> *property)
-{
- QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(static_cast<QQuickPathItem *>(property->object));
- return d->qmlData.vp.count();
-}
-
-static void vpe_clear(QQmlListProperty<QQuickVisualPath> *property)
-{
- QQuickPathItem *item = static_cast<QQuickPathItem *>(property->object);
- QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(item);
-
- for (QQuickVisualPath *p : d->qmlData.vp)
- QObject::disconnect(p, SIGNAL(changed()), item, SLOT(_q_visualPathChanged()));
-
- d->qmlData.vp.clear();
-
- if (d->componentComplete)
- d->_q_visualPathChanged();
-}
-
-/*!
- \qmlproperty list<VisualPath> QtQuick::PathItem::elements
-
- This property holds the VisualPath objects that define the contents of the
- PathItem.
-
- \default
- */
-
-QQmlListProperty<QQuickVisualPath> QQuickPathItem::elements()
-{
- return QQmlListProperty<QQuickVisualPath>(this,
- nullptr,
- vpe_append,
- vpe_count,
- vpe_at,
- vpe_clear);
-}
-
-void QQuickPathItem::classBegin()
-{
- Q_D(QQuickPathItem);
- d->componentComplete = false;
-}
-
-void QQuickPathItem::componentComplete()
-{
- Q_D(QQuickPathItem);
- d->componentComplete = true;
-
- for (QQuickVisualPath *p : d->qmlData.vp)
- connect(p, SIGNAL(changed()), this, SLOT(_q_visualPathChanged()));
-
- d->_q_visualPathChanged();
-}
-
-void QQuickPathItem::updatePolish()
-{
- Q_D(QQuickPathItem);
-
- if (!d->vpChanged)
- return;
-
- d->vpChanged = false;
-
- if (!d->renderer) {
- d->createRenderer();
- if (!d->renderer)
- return;
- emit rendererChanged();
- }
-
- // endSync() is where expensive calculations may happen (or get kicked off
- // on worker threads), depending on the backend. Therefore do this only
- // when the item is visible.
- if (isVisible())
- d->sync();
-
- update();
-}
-
-void QQuickPathItem::itemChange(ItemChange change, const ItemChangeData &data)
-{
- Q_D(QQuickPathItem);
-
- // sync may have been deferred; do it now if the item became visible
- if (change == ItemVisibleHasChanged && data.boolValue)
- d->_q_visualPathChanged();
-
- QQuickItem::itemChange(change, data);
-}
-
-QSGNode *QQuickPathItem::updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
-{
- // Called on the render thread, with the gui thread blocked. We can now
- // safely access gui thread data.
-
- Q_D(QQuickPathItem);
- if (d->renderer) {
- if (!node)
- node = d->createNode();
- d->renderer->updateNode();
- }
- return node;
-}
-
-// the renderer object lives on the gui thread
-void QQuickPathItemPrivate::createRenderer()
-{
- Q_Q(QQuickPathItem);
- QSGRendererInterface *ri = q->window()->rendererInterface();
- if (!ri)
- return;
-
- switch (ri->graphicsApi()) {
-#ifndef QT_NO_OPENGL
- case QSGRendererInterface::OpenGL:
- if (enableVendorExts && QQuickPathItemNvprRenderNode::isSupported()) {
- rendererType = QQuickPathItem::NvprRenderer;
- renderer = new QQuickPathItemNvprRenderer;
- } else {
- rendererType = QQuickPathItem::GeometryRenderer;
- renderer = new QQuickPathItemGenericRenderer(q);
- }
- break;
-#endif
- case QSGRendererInterface::Software:
- rendererType = QQuickPathItem::SoftwareRenderer;
- renderer = new QQuickPathItemSoftwareRenderer;
- break;
- default:
- qWarning("No path backend for this graphics API yet");
- break;
- }
-}
-
-// the node lives on the render thread
-QSGNode *QQuickPathItemPrivate::createNode()
-{
- Q_Q(QQuickPathItem);
- QSGNode *node = nullptr;
- if (!q->window())
- return node;
- QSGRendererInterface *ri = q->window()->rendererInterface();
- if (!ri)
- return node;
-
- switch (ri->graphicsApi()) {
-#ifndef QT_NO_OPENGL
- case QSGRendererInterface::OpenGL:
- if (enableVendorExts && QQuickPathItemNvprRenderNode::isSupported()) {
- node = new QQuickPathItemNvprRenderNode;
- static_cast<QQuickPathItemNvprRenderer *>(renderer)->setNode(
- static_cast<QQuickPathItemNvprRenderNode *>(node));
- } else {
- node = new QQuickPathItemGenericNode;
- static_cast<QQuickPathItemGenericRenderer *>(renderer)->setRootNode(
- static_cast<QQuickPathItemGenericNode *>(node));
- }
- break;
-#endif
- case QSGRendererInterface::Software:
- node = new QQuickPathItemSoftwareRenderNode(q);
- static_cast<QQuickPathItemSoftwareRenderer *>(renderer)->setNode(
- static_cast<QQuickPathItemSoftwareRenderNode *>(node));
- break;
- default:
- qWarning("No path backend for this graphics API yet");
- break;
- }
-
- return node;
-}
-
-static void q_asyncPathItemReady(void *data)
-{
- QQuickPathItemPrivate *self = static_cast<QQuickPathItemPrivate *>(data);
- self->setStatus(QQuickPathItem::Ready);
-}
-
-void QQuickPathItemPrivate::sync()
-{
- const bool useAsync = async && renderer->flags().testFlag(QQuickAbstractPathRenderer::SupportsAsync);
- if (useAsync) {
- setStatus(QQuickPathItem::Processing);
- renderer->setAsyncCallback(q_asyncPathItemReady, this);
- }
-
- if (!jsData.isValid()) {
- // Standard route: The path and stroke/fill parameters are provided via
- // VisualPath and Path.
- const int count = qmlData.vp.count();
- renderer->beginSync(count);
-
- for (int i = 0; i < count; ++i) {
- QQuickVisualPath *p = qmlData.vp[i];
- int &dirty(QQuickVisualPathPrivate::get(p)->dirty);
-
- if (dirty & QQuickVisualPathPrivate::DirtyPath)
- renderer->setPath(i, p->path());
- if (dirty & QQuickVisualPathPrivate::DirtyStrokeColor)
- renderer->setStrokeColor(i, p->strokeColor());
- if (dirty & QQuickVisualPathPrivate::DirtyStrokeWidth)
- renderer->setStrokeWidth(i, p->strokeWidth());
- if (dirty & QQuickVisualPathPrivate::DirtyFillColor)
- renderer->setFillColor(i, p->fillColor());
- if (dirty & QQuickVisualPathPrivate::DirtyFillRule)
- renderer->setFillRule(i, p->fillRule());
- if (dirty & QQuickVisualPathPrivate::DirtyStyle) {
- renderer->setJoinStyle(i, p->joinStyle(), p->miterLimit());
- renderer->setCapStyle(i, p->capStyle());
- }
- if (dirty & QQuickVisualPathPrivate::DirtyDash)
- renderer->setStrokeStyle(i, p->strokeStyle(), p->dashOffset(), p->dashPattern());
- if (dirty & QQuickVisualPathPrivate::DirtyFillGradient)
- renderer->setFillGradient(i, p->fillGradient());
-
- dirty = 0;
- }
-
- renderer->endSync(useAsync);
- } else {
- // Path and stroke/fill params provided from JavaScript. This avoids
- // QObjects at the expense of not supporting changes afterwards.
- const int count = jsData.paths.count();
- renderer->beginSync(count);
-
- for (int i = 0; i < count; ++i) {
- renderer->setJSPath(i, jsData.paths[i]);
- const QQuickPathItemStrokeFillParams sfp(jsData.sfp[i]);
- renderer->setStrokeColor(i, sfp.strokeColor);
- renderer->setStrokeWidth(i, sfp.strokeWidth);
- renderer->setFillColor(i, sfp.fillColor);
- renderer->setFillRule(i, sfp.fillRule);
- renderer->setJoinStyle(i, sfp.joinStyle, sfp.miterLimit);
- renderer->setCapStyle(i, sfp.capStyle);
- renderer->setStrokeStyle(i, sfp.strokeStyle, sfp.dashOffset, sfp.dashPattern);
- renderer->setFillGradient(i, sfp.fillGradient);
- }
-
- renderer->endSync(useAsync);
- }
-
- if (!useAsync)
- setStatus(QQuickPathItem::Ready);
-}
-
-// ***** gradient support *****
-
-/*!
- \qmltype PathGradientStop
- \instantiates QQuickPathGradientStop
- \inqmlmodule QtQuick
- \ingroup qtquick-paths
- \ingroup qtquick-views
- \inherits Object
- \brief Defines a color at a position in a gradient
- \since 5.10
- */
-
-QQuickPathGradientStop::QQuickPathGradientStop(QObject *parent)
- : QObject(parent),
- m_position(0),
- m_color(Qt::black)
-{
-}
-
-/*!
- \qmlproperty real QtQuick::PathGradientStop::position
-
- The position and color properties describe the color used at a given
- position in a gradient, as represented by a gradient stop.
-
- The default value is 0.
- */
-
-qreal QQuickPathGradientStop::position() const
-{
- return m_position;
-}
-
-void QQuickPathGradientStop::setPosition(qreal position)
-{
- if (m_position != position) {
- m_position = position;
- if (QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(parent()))
- emit grad->updated();
- }
-}
-
-/*!
- \qmlproperty real QtQuick::PathGradientStop::color
-
- The position and color properties describe the color used at a given
- position in a gradient, as represented by a gradient stop.
-
- The default value is \c black.
- */
-
-QColor QQuickPathGradientStop::color() const
-{
- return m_color;
-}
-
-void QQuickPathGradientStop::setColor(const QColor &color)
-{
- if (m_color != color) {
- m_color = color;
- if (QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(parent()))
- emit grad->updated();
- }
-}
-
-/*!
- \qmltype PathGradient
- \instantiates QQuickPathGradient
- \inqmlmodule QtQuick
- \ingroup qtquick-paths
- \ingroup qtquick-views
- \inherits Object
- \brief Base type of PathItem fill gradients
- \since 5.10
-
- This is an abstract base class for gradients like PathLinearGradient and
- cannot be created directly.
- */
-
-QQuickPathGradient::QQuickPathGradient(QObject *parent)
- : QObject(parent),
- m_spread(PadSpread)
-{
-}
-
-int QQuickPathGradient::countStops(QQmlListProperty<QObject> *list)
-{
- QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(list->object);
- Q_ASSERT(grad);
- return grad->m_stops.count();
-}
-
-QObject *QQuickPathGradient::atStop(QQmlListProperty<QObject> *list, int index)
-{
- QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(list->object);
- Q_ASSERT(grad);
- return grad->m_stops.at(index);
-}
-
-void QQuickPathGradient::appendStop(QQmlListProperty<QObject> *list, QObject *stop)
-{
- QQuickPathGradientStop *sstop = qobject_cast<QQuickPathGradientStop *>(stop);
- if (!sstop) {
- qWarning("Gradient stop list only supports QQuickPathGradientStop elements");
- return;
- }
- QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(list->object);
- Q_ASSERT(grad);
- sstop->setParent(grad);
- grad->m_stops.append(sstop);
-}
-
-/*!
- \qmlproperty list<Object> QtQuick::PathGradient::stops
- \default
-
- The list of PathGradientStop objects defining the colors at given positions
- in the gradient.
- */
-
-QQmlListProperty<QObject> QQuickPathGradient::stops()
-{
- return QQmlListProperty<QObject>(this, nullptr,
- &QQuickPathGradient::appendStop,
- &QQuickPathGradient::countStops,
- &QQuickPathGradient::atStop,
- nullptr);
-}
-
-QGradientStops QQuickPathGradient::sortedGradientStops() const
-{
- QGradientStops result;
- for (int i = 0; i < m_stops.count(); ++i) {
- QQuickPathGradientStop *s = static_cast<QQuickPathGradientStop *>(m_stops[i]);
- int j = 0;
- while (j < result.count() && result[j].first < s->position())
- ++j;
- result.insert(j, QGradientStop(s->position(), s->color()));
- }
- return result;
-}
-
-/*!
- \qmlproperty enumeration QtQuick::PathGradient::spred
-
- Specifies how the area outside the gradient area should be filled. The
- default value is PathGradient.PadSpread.
-
- \list
- \li PathGradient.PadSpread - The area is filled with the closest stop color.
- \li PathGradient.RepeatSpread - The gradient is repeated outside the gradient area.
- \li PathGradient.ReflectSpread - The gradient is reflected outside the gradient area.
- \endlist
- */
-
-QQuickPathGradient::SpreadMode QQuickPathGradient::spread() const
-{
- return m_spread;
-}
-
-void QQuickPathGradient::setSpread(SpreadMode mode)
-{
- if (m_spread != mode) {
- m_spread = mode;
- emit spreadChanged();
- emit updated();
- }
-}
-
-/*!
- \qmltype PathLinearGradient
- \instantiates QQuickPathLinearGradient
- \inqmlmodule QtQuick
- \ingroup qtquick-paths
- \ingroup qtquick-views
- \inherits PathGradient
- \brief Linear gradient
- \since 5.10
-
- Linear gradients interpolate colors between start and end points. Outside
- these points the gradient is either padded, reflected or repeated depending
- on the spread type.
-
- \sa QLinearGradient
- */
-
-QQuickPathLinearGradient::QQuickPathLinearGradient(QObject *parent)
- : QQuickPathGradient(parent)
-{
-}
-
-/*!
- \qmlproperty real QtQuick::PathLinearGradient::x1
- \qmlproperty real QtQuick::PathLinearGradient::y1
- \qmlproperty real QtQuick::PathLinearGradient::x2
- \qmlproperty real QtQuick::PathLinearGradient::y2
-
- These properties define the start and end points between which color
- interpolation occurs. By default both the stard and end points are set to
- (0, 0).
- */
-
-qreal QQuickPathLinearGradient::x1() const
-{
- return m_start.x();
-}
-
-void QQuickPathLinearGradient::setX1(qreal v)
-{
- if (m_start.x() != v) {
- m_start.setX(v);
- emit x1Changed();
- emit updated();
- }
-}
-
-qreal QQuickPathLinearGradient::y1() const
-{
- return m_start.y();
-}
-
-void QQuickPathLinearGradient::setY1(qreal v)
-{
- if (m_start.y() != v) {
- m_start.setY(v);
- emit y1Changed();
- emit updated();
- }
-}
-
-qreal QQuickPathLinearGradient::x2() const
-{
- return m_end.x();
-}
-
-void QQuickPathLinearGradient::setX2(qreal v)
-{
- if (m_end.x() != v) {
- m_end.setX(v);
- emit x2Changed();
- emit updated();
- }
-}
-
-qreal QQuickPathLinearGradient::y2() const
-{
- return m_end.y();
-}
-
-void QQuickPathLinearGradient::setY2(qreal v)
-{
- if (m_end.y() != v) {
- m_end.setY(v);
- emit y2Changed();
- emit updated();
- }
-}
-
-#ifndef QT_NO_OPENGL
-
-// contexts sharing with each other get the same cache instance
-class QQuickPathItemGradientCacheWrapper
-{
-public:
- QQuickPathItemGradientCache *get(QOpenGLContext *context)
- {
- return m_resource.value<QQuickPathItemGradientCache>(context);
- }
-
-private:
- QOpenGLMultiGroupSharedResource m_resource;
-};
-
-QQuickPathItemGradientCache *QQuickPathItemGradientCache::currentCache()
-{
- static QQuickPathItemGradientCacheWrapper qt_path_gradient_caches;
- return qt_path_gradient_caches.get(QOpenGLContext::currentContext());
-}
-
-// let QOpenGLContext manage the lifetime of the cached textures
-QQuickPathItemGradientCache::~QQuickPathItemGradientCache()
-{
- m_cache.clear();
-}
-
-void QQuickPathItemGradientCache::invalidateResource()
-{
- m_cache.clear();
-}
-
-void QQuickPathItemGradientCache::freeResource(QOpenGLContext *)
-{
- qDeleteAll(m_cache);
- m_cache.clear();
-}
-
-static void generateGradientColorTable(const QQuickPathItemGradientCache::GradientDesc &gradient,
- uint *colorTable, int size, float opacity)
-{
- int pos = 0;
- const QGradientStops &s = gradient.stops;
- const bool colorInterpolation = true;
-
- uint alpha = qRound(opacity * 256);
- uint current_color = ARGB_COMBINE_ALPHA(s[0].second.rgba(), alpha);
- qreal incr = 1.0 / qreal(size);
- qreal fpos = 1.5 * incr;
- colorTable[pos++] = ARGB2RGBA(qPremultiply(current_color));
-
- while (fpos <= s.first().first) {
- colorTable[pos] = colorTable[pos - 1];
- pos++;
- fpos += incr;
- }
-
- if (colorInterpolation)
- current_color = qPremultiply(current_color);
-
- const int sLast = s.size() - 1;
- for (int i = 0; i < sLast; ++i) {
- qreal delta = 1/(s[i+1].first - s[i].first);
- uint next_color = ARGB_COMBINE_ALPHA(s[i + 1].second.rgba(), alpha);
- if (colorInterpolation)
- next_color = qPremultiply(next_color);
-
- while (fpos < s[i+1].first && pos < size) {
- int dist = int(256 * ((fpos - s[i].first) * delta));
- int idist = 256 - dist;
- if (colorInterpolation)
- colorTable[pos] = ARGB2RGBA(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
- else
- colorTable[pos] = ARGB2RGBA(qPremultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist)));
- ++pos;
- fpos += incr;
- }
- current_color = next_color;
- }
-
- Q_ASSERT(s.size() > 0);
-
- uint last_color = ARGB2RGBA(qPremultiply(ARGB_COMBINE_ALPHA(s[sLast].second.rgba(), alpha)));
- for ( ; pos < size; ++pos)
- colorTable[pos] = last_color;
-
- colorTable[size-1] = last_color;
-}
-
-QSGTexture *QQuickPathItemGradientCache::get(const GradientDesc &grad)
-{
- QSGPlainTexture *tx = m_cache[grad];
- if (!tx) {
- QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
- GLuint id;
- f->glGenTextures(1, &id);
- f->glBindTexture(GL_TEXTURE_2D, id);
- static const uint W = 1024; // texture size is 1024x1
- uint buf[W];
- generateGradientColorTable(grad, buf, W, 1.0f);
- f->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, W, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, buf);
- tx = new QSGPlainTexture;
- tx->setTextureId(id);
- switch (grad.spread) {
- case QQuickPathGradient::PadSpread:
- tx->setHorizontalWrapMode(QSGTexture::ClampToEdge);
- tx->setVerticalWrapMode(QSGTexture::ClampToEdge);
- break;
- case QQuickPathGradient::RepeatSpread:
- tx->setHorizontalWrapMode(QSGTexture::Repeat);
- tx->setVerticalWrapMode(QSGTexture::Repeat);
- break;
- case QQuickPathGradient::ReflectSpread:
- tx->setHorizontalWrapMode(QSGTexture::MirroredRepeat);
- tx->setVerticalWrapMode(QSGTexture::MirroredRepeat);
- break;
- default:
- qWarning("Unknown gradient spread mode %d", grad.spread);
- break;
- }
- m_cache[grad] = tx;
- }
- return tx;
-}
-
-#endif // QT_NO_OPENGL
-
-// ***** JS-based alternative for creating static paths, (mostly) without QObjects *****
-
-class QQuickPathItemJSEngineData : public QV8Engine::Deletable
-{
-public:
- QQuickPathItemJSEngineData(QV4::ExecutionEngine *engine);
-
- QV4::PersistentValue pathProto;
- QV4::PersistentValue strokeFillParamsProto;
-};
-
-V4_DEFINE_EXTENSION(QQuickPathItemJSEngineData, engineData)
-
-namespace QV4 {
-namespace Heap {
-
-struct QQuickPathItemJSPathPrototype : Object {
- void init() { Object::init(); }
-};
-
-struct QQuickPathItemJSPath : Object {
- void init() { Object::init(); }
- QQuickPathItemPathObject *obj;
-};
-
-struct QQuickPathItemJSStrokeFillParamsPrototype : Object {
- void init() { Object::init(); }
-};
-
-struct QQuickPathItemJSStrokeFillParams : Object {
- void init() { Object::init(); }
- QQuickPathItemStrokeFillParamsObject *obj;
-};
-
-} // namespace Heap
-} // namespace QV4
-
-struct QQuickPathItemJSPathPrototype : public QV4::Object
-{
- V4_OBJECT2(QQuickPathItemJSPathPrototype, QV4::Object)
-public:
- static QV4::Heap::QQuickPathItemJSPathPrototype *create(QV4::ExecutionEngine *engine)
- {
- QV4::Scope scope(engine);
- auto obj = engine->memoryManager->allocObject<QQuickPathItemJSPathPrototype>();
- QV4::Scoped<QQuickPathItemJSPathPrototype> o(scope, obj);
-
- o->defineDefaultProperty(QStringLiteral("clear"), method_clear, 0);
- o->defineDefaultProperty(QStringLiteral("moveTo"), method_moveTo, 0);
- o->defineDefaultProperty(QStringLiteral("lineTo"), method_lineTo, 0);
- o->defineDefaultProperty(QStringLiteral("quadTo"), method_quadTo, 0);
- o->defineDefaultProperty(QStringLiteral("cubicTo"), method_cubicTo, 0);
- o->defineDefaultProperty(QStringLiteral("arcTo"), method_arcTo, 0);
-
- return o->d();
- }
-
- static void method_clear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_quadTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_cubicTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-};
-
-DEFINE_OBJECT_VTABLE(QQuickPathItemJSPathPrototype);
-
-struct QQuickPathItemJSStrokeFillParamsPrototype : public QV4::Object
-{
- V4_OBJECT2(QQuickPathItemJSStrokeFillParamsPrototype, QV4::Object)
-public:
- static QV4::Heap::QQuickPathItemJSStrokeFillParamsPrototype *create(QV4::ExecutionEngine *engine)
- {
- QV4::Scope scope(engine);
- auto obj = engine->memoryManager->allocObject<QQuickPathItemJSStrokeFillParamsPrototype>();
- QV4::Scoped<QQuickPathItemJSStrokeFillParamsPrototype> o(scope, obj);
-
- o->defineDefaultProperty(QStringLiteral("clear"), method_clear, 0);
-
- return o->d();
- }
-
- static void method_clear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-};
-
-DEFINE_OBJECT_VTABLE(QQuickPathItemJSStrokeFillParamsPrototype);
-
-struct QQuickPathItemJSPath : public QV4::Object
-{
- V4_OBJECT2(QQuickPathItemJSPath, QV4::Object)
-};
-
-DEFINE_OBJECT_VTABLE(QQuickPathItemJSPath);
-
-struct QQuickPathItemJSStrokeFillParams : public QV4::Object
-{
- V4_OBJECT2(QQuickPathItemJSStrokeFillParams, QV4::Object)
-
- static void method_get_strokeColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_strokeColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_strokeWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_strokeWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_fillColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_fillColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_joinStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_joinStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_capStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_capStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_dashOffset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_dashOffset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_dashPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_dashPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_get_fillGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
- static void method_set_fillGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
-};
-
-DEFINE_OBJECT_VTABLE(QQuickPathItemJSStrokeFillParams);
-
-void QQuickPathItemJSPathPrototype::method_clear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- r->d()->obj->clear();
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSPathPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- if (callData->argc >= 2) {
- QQuickPathItemPathObject *p = r->d()->obj;
- p->path.cmd.append(QQuickPathItemPath::MoveTo);
- p->path.coords.append(callData->args[0].toNumber());
- p->path.coords.append(callData->args[1].toNumber());
- }
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSPathPrototype::method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- if (callData->argc >= 2) {
- QQuickPathItemPathObject *p = r->d()->obj;
- p->path.cmd.append(QQuickPathItemPath::LineTo);
- p->path.coords.append(callData->args[0].toNumber());
- p->path.coords.append(callData->args[1].toNumber());
- }
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSPathPrototype::method_quadTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- if (callData->argc >= 4) {
- QQuickPathItemPathObject *p = r->d()->obj;
- p->path.cmd.append(QQuickPathItemPath::QuadTo);
- const QV4::Value *v = callData->args;
- p->path.coords.append(v[0].toNumber()); // cx
- p->path.coords.append(v[1].toNumber()); // cy
- p->path.coords.append(v[2].toNumber()); // x
- p->path.coords.append(v[3].toNumber()); // y
- }
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSPathPrototype::method_cubicTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- if (callData->argc >= 6) {
- QQuickPathItemPathObject *p = r->d()->obj;
- p->path.cmd.append(QQuickPathItemPath::CubicTo);
- const QV4::Value *v = callData->args;
- p->path.coords.append(v[0].toNumber()); // c1x
- p->path.coords.append(v[1].toNumber()); // c1y
- p->path.coords.append(v[2].toNumber()); // c2x
- p->path.coords.append(v[3].toNumber()); // c2y
- p->path.coords.append(v[4].toNumber()); // x
- p->path.coords.append(v[5].toNumber()); // y
- }
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSPathPrototype::method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSPath> r(scope, callData->thisObject.as<QQuickPathItemJSPath>());
-
- if (callData->argc >= 7) {
- QQuickPathItemPathObject *p = r->d()->obj;
- p->path.cmd.append(QQuickPathItemPath::ArcTo);
- const QV4::Value *v = callData->args;
- p->path.coords.append(v[0].toNumber()); // radiusX
- p->path.coords.append(v[1].toNumber()); // radiusY
- p->path.coords.append(v[2].toNumber()); // xAxisRotation
- p->path.coords.append(v[3].toNumber()); // x
- p->path.coords.append(v[4].toNumber()); // y
- p->path.coords.append(v[5].toNumber()); // sweepFlag
- p->path.coords.append(v[6].toNumber()); // largeArc
- }
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-void QQuickPathItemJSStrokeFillParamsPrototype::method_clear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- r->d()->obj->clear();
-
- scope.result = callData->thisObject.asReturnedValue();
-}
-
-extern QColor qt_color_from_string(const QV4::Value &name); // qquickcontext2d.cpp
-
-static inline QString qt_color_string(const QColor &color)
-{
- if (color.alpha() == 255)
- return color.name();
- QString alphaString = QString::number(color.alphaF(), 'f');
- while (alphaString.endsWith(QLatin1Char('0')))
- alphaString.chop(1);
- if (alphaString.endsWith(QLatin1Char('.')))
- alphaString += QLatin1Char('0');
- return QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_strokeColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = QV4::Encode(scope.engine->newString(qt_color_string(r->d()->obj->sfp.strokeColor)));
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_strokeColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isString())
- r->d()->obj->sfp.strokeColor = qt_color_from_string(value);
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_strokeWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.strokeWidth);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_strokeWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- r->d()->obj->sfp.strokeWidth = value->toNumber();
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_fillColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = QV4::Encode(scope.engine->newString(qt_color_string(r->d()->obj->sfp.fillColor)));
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_fillColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isString())
- r->d()->obj->sfp.fillColor = qt_color_from_string(value);
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.fillRule);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isInt32())
- r->d()->obj->sfp.fillRule = QQuickVisualPath::FillRule(value->integerValue());
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_joinStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.joinStyle);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_joinStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isInt32())
- r->d()->obj->sfp.joinStyle = QQuickVisualPath::JoinStyle(value->integerValue());
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.miterLimit);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- r->d()->obj->sfp.miterLimit = value->toNumber();
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_capStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.capStyle);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_capStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isInt32())
- r->d()->obj->sfp.capStyle = QQuickVisualPath::CapStyle(value->integerValue());
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.strokeStyle);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isInt32())
- r->d()->obj->sfp.strokeStyle = QQuickVisualPath::StrokeStyle(value->integerValue());
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_dashOffset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = scope.engine->fromVariant(r->d()->obj->sfp.dashOffset);
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_dashOffset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- r->d()->obj->sfp.dashOffset = value->toNumber();
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_dashPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedArrayObject a(scope, scope.engine->newArrayObject());
- QQuickPathItemStrokeFillParamsObject *p = r->d()->obj;
- a->arrayReserve(p->sfp.dashPattern.count());
- QV4::ScopedValue v(scope);
- for (int i = 0; i < p->sfp.dashPattern.count(); ++i)
- a->arrayPut(i, (v = scope.engine->fromVariant(p->sfp.dashPattern[i])));
- a->setArrayLengthUnchecked(p->sfp.dashPattern.count());
-
- scope.result = a.asReturnedValue();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_dashPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- if (value->isObject()) {
- QV4::Scoped<QV4::ArrayObject> ao(scope, value);
- if (!!ao) {
- QQuickPathItemStrokeFillParamsObject *p = r->d()->obj;
- p->sfp.dashPattern.resize(ao->getLength());
- QV4::ScopedValue val(scope);
- for (int i = 0; i < p->sfp.dashPattern.count(); ++i) {
- val = ao->getIndexed(i);
- p->sfp.dashPattern[i] = val->toNumber();
- }
- }
- }
-
- scope.result = QV4::Encode::undefined();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_get_fillGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- scope.result = r->d()->obj->v4fillGradient.value();
-}
-
-void QQuickPathItemJSStrokeFillParams::method_set_fillGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
-{
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> r(scope, callData->thisObject.as<QQuickPathItemJSStrokeFillParams>());
-
- QV4::ScopedValue value(scope, callData->argument(0));
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
- if (!!qobjectWrapper) {
- if (QQuickPathGradient *grad = qobject_cast<QQuickPathGradient *>(qobjectWrapper->object())) {
- r->d()->obj->v4fillGradient.set(scope.engine, value);
- r->d()->obj->sfp.fillGradient = grad;
- }
- } else {
- r->d()->obj->v4fillGradient.set(scope.engine, nullptr);
- r->d()->obj->sfp.fillGradient = nullptr;
- }
-
- scope.result = QV4::Encode::undefined();
-}
-
-QQuickPathItemJSEngineData::QQuickPathItemJSEngineData(QV4::ExecutionEngine *v4)
-{
- QV4::Scope scope(v4);
-
- QV4::ScopedObject proto(scope, QQuickPathItemJSPathPrototype::create(v4));
- pathProto = proto;
-
- proto = QV4::ScopedObject(scope, QQuickPathItemJSStrokeFillParamsPrototype::create(v4));
-
- proto->defineAccessorProperty(QStringLiteral("strokeColor"),
- QQuickPathItemJSStrokeFillParams::method_get_strokeColor,
- QQuickPathItemJSStrokeFillParams::method_set_strokeColor);
- proto->defineAccessorProperty(QStringLiteral("strokeWidth"),
- QQuickPathItemJSStrokeFillParams::method_get_strokeWidth,
- QQuickPathItemJSStrokeFillParams::method_set_strokeWidth);
- proto->defineAccessorProperty(QStringLiteral("fillColor"),
- QQuickPathItemJSStrokeFillParams::method_get_fillColor,
- QQuickPathItemJSStrokeFillParams::method_set_fillColor);
- proto->defineAccessorProperty(QStringLiteral("fillRule"),
- QQuickPathItemJSStrokeFillParams::method_get_fillRule,
- QQuickPathItemJSStrokeFillParams::method_set_fillRule);
- proto->defineAccessorProperty(QStringLiteral("joinStyle"),
- QQuickPathItemJSStrokeFillParams::method_get_joinStyle,
- QQuickPathItemJSStrokeFillParams::method_set_joinStyle);
- proto->defineAccessorProperty(QStringLiteral("miterLimit"),
- QQuickPathItemJSStrokeFillParams::method_get_miterLimit,
- QQuickPathItemJSStrokeFillParams::method_set_miterLimit);
- proto->defineAccessorProperty(QStringLiteral("capStyle"),
- QQuickPathItemJSStrokeFillParams::method_get_capStyle,
- QQuickPathItemJSStrokeFillParams::method_set_capStyle);
- proto->defineAccessorProperty(QStringLiteral("strokeStyle"),
- QQuickPathItemJSStrokeFillParams::method_get_strokeStyle,
- QQuickPathItemJSStrokeFillParams::method_set_strokeStyle);
- proto->defineAccessorProperty(QStringLiteral("dashOffset"),
- QQuickPathItemJSStrokeFillParams::method_get_dashOffset,
- QQuickPathItemJSStrokeFillParams::method_set_dashOffset);
- proto->defineAccessorProperty(QStringLiteral("dashPattern"),
- QQuickPathItemJSStrokeFillParams::method_get_dashPattern,
- QQuickPathItemJSStrokeFillParams::method_set_dashPattern);
- proto->defineAccessorProperty(QStringLiteral("fillGradient"),
- QQuickPathItemJSStrokeFillParams::method_get_fillGradient,
- QQuickPathItemJSStrokeFillParams::method_set_fillGradient);
-
- strokeFillParamsProto = proto;
-}
-
-void QQuickPathItemPathObject::setV4Engine(QV4::ExecutionEngine *engine)
-{
- QQuickPathItemJSEngineData *ed = engineData(engine);
- QV4::Scope scope(engine);
- QV4::Scoped<QQuickPathItemJSPath> wrapper(scope, engine->memoryManager->allocObject<QQuickPathItemJSPath>());
- QV4::ScopedObject p(scope, ed->pathProto.value());
- wrapper->setPrototype(p);
- wrapper->d()->obj = this;
- m_v4value = wrapper;
-}
-
-/*!
- \qmltype JSPath
- \inqmlmodule QtQuick
- \ingroup qtquick-path
- \brief Describes a path via a JavaScript API
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::moveTo(x, y)
-
- Moves the path's position to the absolute position specified by (\a x, \a y).
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::lineTo(x, y)
-
- Defines a straight line to the absolute position specified by (\a x, \a y).
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::quadTo(cx, cy, x, y)
-
- Defines a quadratic Bezier curve with a control point (\a cx, \a cy) and an
- end point of (\a x, \a y).
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::cubicTo(c1x, c1y, c2x, c2y, x, y)
-
- Defines a cubic Bezier curve with two control points (\a c1x, \a c1y) and
- (\a c2x, \a c2y), and an end point of (\a x, \a y).
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::arcTo(radiusX, radiusY, xAxisRotation, x, y, sweepFlag, largeArc)
-
- Defines an elliptical arc, following the elliptical arc command in SVG. See
- \l{https://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands}{the
- SVG path specification} for details on the parameters.
- */
-
-/*!
- \qmlmethod void QtQuick::JSPath::clear()
-
- Clears the path object removing all path elements. This is more lightweight
- than creating a new JSPath object.
- */
-
-void QQuickPathItemPathObject::clear()
-{
- path = QQuickPathItemPath();
-}
-
-/*!
- \qmltype StrokeFillParams
- \inqmlmodule QtQuick
- \ingroup qtquick-path
- \brief Describes stroke and fill parameters via a JavaScript API
-
- The properties of StrokeFillParams objects correspond 1:1 to VisualPath
- properties. The possible values for enumerations are the same as well, for
- example:
-
- \code
- sfp.strokeStyle = VisualPath.DashLine;
- sfp.capStyle = VisualPath.RoundCap;
- \endcode
- */
-
-/*!
- \qmlproperty color QtQuick::StrokeFillParams::strokeColor
- */
-
-/*!
- \qmlproperty real QtQuick::StrokeFillParams::strokeWidth
- */
-
-/*!
- \qmlproperty color QtQuick::StrokeFillParams::fillColor
- */
-
-/*!
- \qmlproperty enumeration QtQuick::StrokeFillParams::fillRule
- */
-
-/*!
- \qmlproperty enumeration QtQuick::StrokeFillParams::joinStyle
- */
-
-/*!
- \qmlproperty int QtQuick::StrokeFillParams::miterLimit
- */
-
-/*!
- \qmlproperty enumeration QtQuick::StrokeFillParams::capStyle
- */
-
-/*!
- \qmlproperty enumeration QtQuick::StrokeFillParams::strokeStyle
- */
-
-/*!
- \qmlproperty real QtQuick::StrokeFillParams::dashOffset
- */
-
-/*!
- \qmlproperty list<real> QtQuick::StrokeFillParams::dashPattern
-
- The dash pattern can be specified using JavaScript arrays.
-
- \code
- sfp.dashPattern = [ 4, 2 ];
- \endcode
- */
-
-/*!
- \qmlproperty object QtQuick::StrokeFillParams::fillGradient
-
- Sets the fill gradient. The default value is null. Gradients cannot be
- created from JavaScript. Instead, reference a PathLinearGradient or other
- item by id.
-
- \code
- PathLinearGradient { id: grad; ... }
- ...
- sfp.fillGradient = grad;
- \endcode
- */
-
-/*!
- \qmlmethod void QtQuick::StrokeFillParams::clear()
-
- Resets all values to their defaults. This is more lightweight than creating
- a new StrokeFillParams object.
- */
-
-void QQuickPathItemStrokeFillParamsObject::clear()
-{
- sfp = QQuickPathItemStrokeFillParams();
- if (!v4fillGradient.isNullOrUndefined())
- v4fillGradient.set(v4fillGradient.engine(), nullptr);
-}
-
-void QQuickPathItemStrokeFillParamsObject::setV4Engine(QV4::ExecutionEngine *engine)
-{
- QQuickPathItemJSEngineData *ed = engineData(engine);
- QV4::Scope scope(engine);
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> wrapper(scope, engine->memoryManager->allocObject<QQuickPathItemJSStrokeFillParams>());
- QV4::ScopedObject p(scope, ed->strokeFillParamsProto.value());
- wrapper->setPrototype(p);
- wrapper->d()->obj = this;
- m_v4value = wrapper;
-}
-
-/*!
- \qmlmethod JSPath QtQuick::PathItem::newPath()
-
- Creates and returns a new object that describes a path and offers a
- JavaScript API. Paired with a stroke-fill parameter object it is
- equivalent to a VisualPath.
-
- The following two snippets are equivalent when it comes to the end result:
-
- \code
- var p = pathItem.newPath();
- var sfp = pathItem.newStrokeFillParams();
- sfp.fillColor = "white";
- sfp.strokeColor = "black";
- sfp.strokeWidth = 0.172;
- p.moveTo(-122.304, 84.285);
- p.cubicTo(-122.304, 84.285, -122.203, 86.179, -123.027, 86.16);
- pathItem.appendVisualPath(p, sfp);
- \endcode
-
- \code
- PathItem {
- VisualPath {
- fillColor: "white"
- strokeColor: "black"
- strokeWidth: 0.172
- Path {
- startX: -122.304; startY: 84.285
- PathCubic { control1X: -122.304; control1Y: 84.285; control2X: -122.203; control2Y: 86.179; x: -123.027; y: 86.16 }
- }
- }
- }
- \endcode
-
- The latter offers a full declarative API, with the possibility to binding
- to and animating properties, while the former uses less resources due to
- greatly reducing the number of QObject instances created.
-*/
-
-void QQuickPathItem::newPath(QQmlV4Function *args)
-{
- QQuickPathItemPathObject *obj = new QQuickPathItemPathObject(this);
- obj->setV4Engine(QQmlEnginePrivate::get(qmlEngine(this))->v4engine());
- args->setReturnValue(obj->v4value());
-}
-
-/*!
- \qmlmethod StrokeFillParams QtQuick::PathItem::newStrokeFillParams()
-
- Creates and returns a new object that describes stroke and fill parameters
- and offers a JavaScript API. Paired with a path object it is equivalent to
- a VisualPath.
- */
-
-void QQuickPathItem::newStrokeFillParams(QQmlV4Function *args)
-{
- QQuickPathItemStrokeFillParamsObject *obj = new QQuickPathItemStrokeFillParamsObject(this);
- obj->setV4Engine(QQmlEnginePrivate::get(qmlEngine(this))->v4engine());
- args->setReturnValue(obj->v4value());
-}
-
-/*!
- \qmlmethod void QtQuick::PathItem::clearVisualPaths()
-
- Clears the list of visual paths.
-
- \note This applies only to path and stroke-fill parameter objects registered
- via appendVisualPaths().
- */
-
-void QQuickPathItem::clearVisualPaths(QQmlV4Function *args)
-{
- Q_UNUSED(args);
- Q_D(QQuickPathItem);
- d->jsData.paths.clear();
- d->jsData.sfp.clear();
-}
-
-/*!
- \qmlmethod void QtQuick::PathItem::commitVisualPaths()
-
- Updates the PathItem.
-
- In order to avoid rendering a half-prepared PathItem, calling
- PathItem.appendVisualPath() does not trigger any processing. Instead,
- applications must call this function when all path and stroke-fill
- parameter objects are registered.
- */
-
-void QQuickPathItem::commitVisualPaths(QQmlV4Function *args)
-{
- Q_UNUSED(args);
- Q_D(QQuickPathItem);
- d->_q_visualPathChanged();
-}
-
-/*!
- \qmlmethod void QtQuick::PathItem::appendVisualPath(object path, object strokeFillParams)
-
- Adds the visual path compoes of \a path and \a strokeFillParams into the
- PathItem.
-
- \note The declarative and imprative (JavaScript) APIs of PathItem use
- independent data structures. Calling this function has no effect on the
- PathItem.elements property and vice versa. Once this function is called,
- the PathItem will only consider the data registered via this function and
- will ignore the declarative elements property.
- */
-
-void QQuickPathItem::appendVisualPath(QQmlV4Function *args)
-{
- if (args->length() < 2)
- return;
-
- Q_D(QQuickPathItem);
- QV4::Scope scope(args->v4engine());
- QV4::Scoped<QQuickPathItemJSPath> jsp(scope, (*args)[0]);
- QV4::Scoped<QQuickPathItemJSStrokeFillParams> jssfp(scope, (*args)[1]);
-
- const QQuickPathItemPath &path(jsp->d()->obj->path);
- const QQuickPathItemStrokeFillParams &sfp(jssfp->d()->obj->sfp);
-
- d->jsData.paths.append(path);
- d->jsData.sfp.append(sfp);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qquickpathitem_p.cpp"
diff --git a/src/quick/items/qquickpathitem_p.h b/src/quick/items/qquickpathitem_p.h
deleted file mode 100644
index 37b23dee6f..0000000000
--- a/src/quick/items/qquickpathitem_p.h
+++ /dev/null
@@ -1,335 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPATHITEM_P_H
-#define QQUICKPATHITEM_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickitem.h"
-
-#include <private/qtquickglobal_p.h>
-#include <private/qquickpath_p.h>
-#include <private/qv8engine_p.h>
-#include <QGradientStops>
-
-QT_REQUIRE_CONFIG(quick_path);
-
-QT_BEGIN_NAMESPACE
-
-class QQuickVisualPathPrivate;
-class QQuickPathItemPrivate;
-
-class Q_QUICK_PRIVATE_EXPORT QQuickPathGradientStop : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(qreal position READ position WRITE setPosition)
- Q_PROPERTY(QColor color READ color WRITE setColor)
-
-public:
- QQuickPathGradientStop(QObject *parent = nullptr);
-
- qreal position() const;
- void setPosition(qreal position);
-
- QColor color() const;
- void setColor(const QColor &color);
-
-private:
- qreal m_position;
- QColor m_color;
-};
-
-class Q_QUICK_PRIVATE_EXPORT QQuickPathGradient : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QQmlListProperty<QObject> stops READ stops)
- Q_PROPERTY(SpreadMode spread READ spread WRITE setSpread NOTIFY spreadChanged)
- Q_CLASSINFO("DefaultProperty", "stops")
-
-public:
- enum SpreadMode {
- PadSpread,
- RepeatSpread,
- ReflectSpread
- };
- Q_ENUM(SpreadMode)
-
- QQuickPathGradient(QObject *parent = nullptr);
-
- QQmlListProperty<QObject> stops();
-
- QGradientStops sortedGradientStops() const;
-
- SpreadMode spread() const;
- void setSpread(SpreadMode mode);
-
-signals:
- void updated();
- void spreadChanged();
-
-private:
- static int countStops(QQmlListProperty<QObject> *list);
- static QObject *atStop(QQmlListProperty<QObject> *list, int index);
- static void appendStop(QQmlListProperty<QObject> *list, QObject *stop);
-
- QVector<QObject *> m_stops;
- SpreadMode m_spread;
-};
-
-class Q_QUICK_PRIVATE_EXPORT QQuickPathLinearGradient : public QQuickPathGradient
-{
- Q_OBJECT
- Q_PROPERTY(qreal x1 READ x1 WRITE setX1 NOTIFY x1Changed)
- Q_PROPERTY(qreal y1 READ y1 WRITE setY1 NOTIFY y1Changed)
- Q_PROPERTY(qreal x2 READ x2 WRITE setX2 NOTIFY x2Changed)
- Q_PROPERTY(qreal y2 READ y2 WRITE setY2 NOTIFY y2Changed)
- Q_CLASSINFO("DefaultProperty", "stops")
-
-public:
- QQuickPathLinearGradient(QObject *parent = nullptr);
-
- qreal x1() const;
- void setX1(qreal v);
- qreal y1() const;
- void setY1(qreal v);
- qreal x2() const;
- void setX2(qreal v);
- qreal y2() const;
- void setY2(qreal v);
-
-signals:
- void x1Changed();
- void y1Changed();
- void x2Changed();
- void y2Changed();
-
-private:
- QPointF m_start;
- QPointF m_end;
-};
-
-class Q_QUICK_PRIVATE_EXPORT QQuickVisualPath : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(QQuickPath *path READ path WRITE setPath NOTIFY pathChanged)
- Q_CLASSINFO("DefaultProperty", "path")
-
- Q_PROPERTY(QColor strokeColor READ strokeColor WRITE setStrokeColor NOTIFY strokeColorChanged)
- Q_PROPERTY(qreal strokeWidth READ strokeWidth WRITE setStrokeWidth NOTIFY strokeWidthChanged)
- Q_PROPERTY(QColor fillColor READ fillColor WRITE setFillColor NOTIFY fillColorChanged)
- Q_PROPERTY(FillRule fillRule READ fillRule WRITE setFillRule NOTIFY fillRuleChanged)
- Q_PROPERTY(JoinStyle joinStyle READ joinStyle WRITE setJoinStyle NOTIFY joinStyleChanged)
- Q_PROPERTY(int miterLimit READ miterLimit WRITE setMiterLimit NOTIFY miterLimitChanged)
- Q_PROPERTY(CapStyle capStyle READ capStyle WRITE setCapStyle NOTIFY capStyleChanged)
- Q_PROPERTY(StrokeStyle strokeStyle READ strokeStyle WRITE setStrokeStyle NOTIFY strokeStyleChanged)
- Q_PROPERTY(qreal dashOffset READ dashOffset WRITE setDashOffset NOTIFY dashOffsetChanged)
- Q_PROPERTY(QVector<qreal> dashPattern READ dashPattern WRITE setDashPattern NOTIFY dashPatternChanged)
- Q_PROPERTY(QQuickPathGradient *fillGradient READ fillGradient WRITE setFillGradient RESET resetFillGradient)
-
-public:
- enum FillRule {
- OddEvenFill = Qt::OddEvenFill,
- WindingFill = Qt::WindingFill
- };
- Q_ENUM(FillRule)
-
- enum JoinStyle {
- MiterJoin = Qt::MiterJoin,
- BevelJoin = Qt::BevelJoin,
- RoundJoin = Qt::RoundJoin
- };
- Q_ENUM(JoinStyle)
-
- enum CapStyle {
- FlatCap = Qt::FlatCap,
- SquareCap = Qt::SquareCap,
- RoundCap = Qt::RoundCap
- };
- Q_ENUM(CapStyle)
-
- enum StrokeStyle {
- SolidLine = Qt::SolidLine,
- DashLine = Qt::DashLine
- };
- Q_ENUM(StrokeStyle)
-
- QQuickVisualPath(QObject *parent = nullptr);
- ~QQuickVisualPath();
-
- QQuickPath *path() const;
- void setPath(QQuickPath *path);
-
- QColor strokeColor() const;
- void setStrokeColor(const QColor &color);
-
- qreal strokeWidth() const;
- void setStrokeWidth(qreal w);
-
- QColor fillColor() const;
- void setFillColor(const QColor &color);
-
- FillRule fillRule() const;
- void setFillRule(FillRule fillRule);
-
- JoinStyle joinStyle() const;
- void setJoinStyle(JoinStyle style);
-
- int miterLimit() const;
- void setMiterLimit(int limit);
-
- CapStyle capStyle() const;
- void setCapStyle(CapStyle style);
-
- StrokeStyle strokeStyle() const;
- void setStrokeStyle(StrokeStyle style);
-
- qreal dashOffset() const;
- void setDashOffset(qreal offset);
-
- QVector<qreal> dashPattern() const;
- void setDashPattern(const QVector<qreal> &array);
-
- QQuickPathGradient *fillGradient() const;
- void setFillGradient(QQuickPathGradient *gradient);
- void resetFillGradient();
-
-Q_SIGNALS:
- void changed();
- void pathChanged();
- void strokeColorChanged();
- void strokeWidthChanged();
- void fillColorChanged();
- void fillRuleChanged();
- void joinStyleChanged();
- void miterLimitChanged();
- void capStyleChanged();
- void strokeStyleChanged();
- void dashOffsetChanged();
- void dashPatternChanged();
- void fillGradientChanged();
-
-private:
- Q_DISABLE_COPY(QQuickVisualPath)
- Q_DECLARE_PRIVATE(QQuickVisualPath)
- Q_PRIVATE_SLOT(d_func(), void _q_pathChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_fillGradientChanged())
-};
-
-class Q_QUICK_PRIVATE_EXPORT QQuickPathItem : public QQuickItem
-{
- Q_OBJECT
- Q_PROPERTY(RendererType renderer READ rendererType NOTIFY rendererChanged)
- Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
- Q_PROPERTY(bool enableVendorExtensions READ enableVendorExtensions WRITE setEnableVendorExtensions NOTIFY enableVendorExtensionsChanged)
- Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(QQmlListProperty<QQuickVisualPath> elements READ elements)
- Q_CLASSINFO("DefaultProperty", "elements")
-
-public:
- enum RendererType {
- UnknownRenderer,
- GeometryRenderer,
- NvprRenderer,
- SoftwareRenderer
- };
- Q_ENUM(RendererType)
-
- enum Status {
- Null,
- Ready,
- Processing
- };
- Q_ENUM(Status)
-
- QQuickPathItem(QQuickItem *parent = nullptr);
- ~QQuickPathItem();
-
- RendererType rendererType() const;
-
- bool asynchronous() const;
- void setAsynchronous(bool async);
-
- bool enableVendorExtensions() const;
- void setEnableVendorExtensions(bool enable);
-
- Status status() const;
-
- QQmlListProperty<QQuickVisualPath> elements();
-
- Q_INVOKABLE void newPath(QQmlV4Function *args);
- Q_INVOKABLE void newStrokeFillParams(QQmlV4Function *args);
- Q_INVOKABLE void clearVisualPaths(QQmlV4Function *args);
- Q_INVOKABLE void commitVisualPaths(QQmlV4Function *args);
- Q_INVOKABLE void appendVisualPath(QQmlV4Function *args);
-
-protected:
- QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *) override;
- void updatePolish() override;
- void itemChange(ItemChange change, const ItemChangeData &data) override;
- void componentComplete() override;
- void classBegin() override;
-
-Q_SIGNALS:
- void rendererChanged();
- void asynchronousChanged();
- void enableVendorExtensionsChanged();
- void statusChanged();
-
-private:
- Q_DISABLE_COPY(QQuickPathItem)
- Q_DECLARE_PRIVATE(QQuickPathItem)
- Q_PRIVATE_SLOT(d_func(), void _q_visualPathChanged())
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickPathItem)
-
-#endif // QQUICKPATHITEM_P_H
diff --git a/src/quick/items/qquickpathitem_p_p.h b/src/quick/items/qquickpathitem_p_p.h
deleted file mode 100644
index c9a2904a25..0000000000
--- a/src/quick/items/qquickpathitem_p_p.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPATHITEM_P_P_H
-#define QQUICKPATHITEM_P_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpathitem_p.h"
-#include "qquickitem_p.h"
-#include <QPainterPath>
-#include <QColor>
-#include <QBrush>
-#include <private/qopenglcontext_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QSGPlainTexture;
-
-struct QQuickPathItemPath
-{
- enum Command {
- MoveTo,
- LineTo,
- QuadTo,
- CubicTo,
- ArcTo
- };
-
- QVector<Command> cmd;
- QVector<float> coords;
-
- QPainterPath toPainterPath() const;
-};
-
-struct QQuickPathItemStrokeFillParams
-{
- QQuickPathItemStrokeFillParams();
-
- QColor strokeColor;
- qreal strokeWidth;
- QColor fillColor;
- QQuickVisualPath::FillRule fillRule;
- QQuickVisualPath::JoinStyle joinStyle;
- int miterLimit;
- QQuickVisualPath::CapStyle capStyle;
- QQuickVisualPath::StrokeStyle strokeStyle;
- qreal dashOffset;
- QVector<qreal> dashPattern;
- QQuickPathGradient *fillGradient;
-};
-
-class QQuickAbstractPathRenderer
-{
-public:
- enum Flag {
- SupportsAsync = 0x01
- };
- Q_DECLARE_FLAGS(Flags, Flag)
-
- virtual ~QQuickAbstractPathRenderer() { }
-
- // Gui thread
- virtual void beginSync(int totalCount) = 0;
- virtual void endSync(bool async) = 0;
- virtual void setAsyncCallback(void (*)(void *), void *) { }
- virtual Flags flags() const { return 0; }
- // - QML API
- virtual void setPath(int index, const QQuickPath *path) = 0;
- // - JS API
- virtual void setJSPath(int index, const QQuickPathItemPath &path) = 0;
- // - stroke/fill parameters
- virtual void setStrokeColor(int index, const QColor &color) = 0;
- virtual void setStrokeWidth(int index, qreal w) = 0;
- virtual void setFillColor(int index, const QColor &color) = 0;
- virtual void setFillRule(int index, QQuickVisualPath::FillRule fillRule) = 0;
- virtual void setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit) = 0;
- virtual void setCapStyle(int index, QQuickVisualPath::CapStyle capStyle) = 0;
- virtual void setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern) = 0;
- virtual void setFillGradient(int index, QQuickPathGradient *gradient) = 0;
-
- // Render thread, with gui blocked
- virtual void updateNode() = 0;
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickAbstractPathRenderer::Flags)
-
-class QQuickVisualPathPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QQuickVisualPath)
-
-public:
- enum Dirty {
- DirtyPath = 0x01,
- DirtyStrokeColor = 0x02,
- DirtyStrokeWidth = 0x04,
- DirtyFillColor = 0x08,
- DirtyFillRule = 0x10,
- DirtyStyle = 0x20,
- DirtyDash = 0x40,
- DirtyFillGradient = 0x80,
-
- DirtyAll = 0xFF
- };
-
- QQuickVisualPathPrivate();
-
- void _q_pathChanged();
- void _q_fillGradientChanged();
-
- static QQuickVisualPathPrivate *get(QQuickVisualPath *p) { return p->d_func(); }
-
- QQuickPath *path;
- int dirty;
- QQuickPathItemStrokeFillParams sfp;
-};
-
-class QQuickPathItemPrivate : public QQuickItemPrivate
-{
- Q_DECLARE_PUBLIC(QQuickPathItem)
-
-public:
- QQuickPathItemPrivate();
- ~QQuickPathItemPrivate();
-
- void createRenderer();
- QSGNode *createNode();
- void sync();
-
- void _q_visualPathChanged();
- void setStatus(QQuickPathItem::Status newStatus);
-
- static QQuickPathItemPrivate *get(QQuickPathItem *item) { return item->d_func(); }
-
- bool componentComplete;
- bool vpChanged;
- QQuickPathItem::RendererType rendererType;
- bool async;
- QQuickPathItem::Status status;
- QQuickAbstractPathRenderer *renderer;
-
- struct {
- QVector<QQuickVisualPath *> vp;
- } qmlData;
-
- struct {
- bool isValid() const { Q_ASSERT(paths.count() == sfp.count()); return !paths.isEmpty(); }
- QVector<QQuickPathItemPath> paths;
- QVector<QQuickPathItemStrokeFillParams> sfp;
- } jsData;
-
- bool enableVendorExts;
-};
-
-class QQuickPathItemPathObject : public QObject
-{
- Q_OBJECT
-
-public:
- QQuickPathItemPathObject(QObject *parent = nullptr) : QObject(parent) { }
-
- void setV4Engine(QV4::ExecutionEngine *engine);
- QV4::ReturnedValue v4value() const { return m_v4value.value(); }
-
- QQuickPathItemPath path;
-
- void clear();
-
-private:
- QV4::PersistentValue m_v4value;
-};
-
-class QQuickPathItemStrokeFillParamsObject : public QObject
-{
- Q_OBJECT
-
-public:
- QQuickPathItemStrokeFillParamsObject(QObject *parent = nullptr) : QObject(parent) { }
-
- void setV4Engine(QV4::ExecutionEngine *engine);
- QV4::ReturnedValue v4value() const { return m_v4value.value(); }
-
- QQuickPathItemStrokeFillParams sfp;
- QV4::PersistentValue v4fillGradient;
-
- void clear();
-
-private:
- QV4::PersistentValue m_v4value;
-};
-
-#ifndef QT_NO_OPENGL
-
-class QQuickPathItemGradientCache : public QOpenGLSharedResource
-{
-public:
- struct GradientDesc {
- QGradientStops stops;
- QPointF start;
- QPointF end;
- QQuickPathGradient::SpreadMode spread;
- bool operator==(const GradientDesc &other) const
- {
- return start == other.start && end == other.end && spread == other.spread
- && stops == other.stops;
- }
- };
-
- QQuickPathItemGradientCache(QOpenGLContext *context) : QOpenGLSharedResource(context->shareGroup()) { }
- ~QQuickPathItemGradientCache();
-
- void invalidateResource() override;
- void freeResource(QOpenGLContext *) override;
-
- QSGTexture *get(const GradientDesc &grad);
-
- static QQuickPathItemGradientCache *currentCache();
-
-private:
- QHash<GradientDesc, QSGPlainTexture *> m_cache;
-};
-
-inline uint qHash(const QQuickPathItemGradientCache::GradientDesc &v, uint seed = 0)
-{
- uint h = seed;
- h += v.start.x() + v.end.y() + v.spread;
- for (int i = 0; i < 3 && i < v.stops.count(); ++i)
- h += v.stops[i].second.rgba();
- return h;
-}
-
-#endif // QT_NO_OPENGL
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/quick/items/qquickpathitemgenericrenderer.cpp b/src/quick/items/qquickpathitemgenericrenderer.cpp
deleted file mode 100644
index 4e8fe55df2..0000000000
--- a/src/quick/items/qquickpathitemgenericrenderer.cpp
+++ /dev/null
@@ -1,775 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpathitemgenericrenderer_p.h"
-#include <QtGui/private/qtriangulator_p.h>
-#include <QtGui/private/qtriangulatingstroker_p.h>
-#include <QThreadPool>
-
-#ifndef QT_NO_OPENGL
-#include <QSGVertexColorMaterial>
-#include <QOpenGLContext>
-#include <QOffscreenSurface>
-#include <QtGui/private/qopenglextensions_p.h>
-#endif
-
-QT_BEGIN_NAMESPACE
-
-static const qreal TRI_SCALE = 1;
-
-struct ColoredVertex // must match QSGGeometry::ColoredPoint2D
-{
- float x, y;
- QQuickPathItemGenericRenderer::Color4ub color;
- void set(float nx, float ny, QQuickPathItemGenericRenderer::Color4ub ncolor)
- {
- x = nx; y = ny; color = ncolor;
- }
-};
-
-static inline QQuickPathItemGenericRenderer::Color4ub colorToColor4ub(const QColor &c)
-{
- QQuickPathItemGenericRenderer::Color4ub color = {
- uchar(qRound(c.redF() * c.alphaF() * 255)),
- uchar(qRound(c.greenF() * c.alphaF() * 255)),
- uchar(qRound(c.blueF() * c.alphaF() * 255)),
- uchar(qRound(c.alphaF() * 255))
- };
- return color;
-}
-
-QQuickPathItemGenericStrokeFillNode::QQuickPathItemGenericStrokeFillNode(QQuickWindow *window)
- : m_geometry(new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), 0, 0)),
- m_window(window),
- m_material(nullptr)
-{
- setGeometry(m_geometry);
- activateMaterial(MatSolidColor);
-#ifdef QSG_RUNTIME_DESCRIPTION
- qsgnode_set_description(this, QLatin1String("stroke-fill"));
-#endif
-}
-
-QQuickPathItemGenericStrokeFillNode::~QQuickPathItemGenericStrokeFillNode()
-{
- delete m_geometry;
-}
-
-void QQuickPathItemGenericStrokeFillNode::activateMaterial(Material m)
-{
- switch (m) {
- case MatSolidColor:
- // Use vertexcolor material. Items with different colors remain batchable
- // this way, at the expense of having to provide per-vertex color values.
- if (!m_solidColorMaterial)
- m_solidColorMaterial.reset(QQuickPathItemGenericMaterialFactory::createVertexColor(m_window));
- m_material = m_solidColorMaterial.data();
- break;
- case MatLinearGradient:
- if (!m_linearGradientMaterial)
- m_linearGradientMaterial.reset(QQuickPathItemGenericMaterialFactory::createLinearGradient(m_window, this));
- m_material = m_linearGradientMaterial.data();
- break;
- default:
- qWarning("Unknown material %d", m);
- return;
- }
-
- if (material() != m_material)
- setMaterial(m_material);
-}
-
-static bool q_supportsElementIndexUint(QSGRendererInterface::GraphicsApi api)
-{
- static bool elementIndexUint = true;
-#ifndef QT_NO_OPENGL
- if (api == QSGRendererInterface::OpenGL) {
- static bool elementIndexUintChecked = false;
- if (!elementIndexUintChecked) {
- elementIndexUintChecked = true;
- QOpenGLContext *context = QOpenGLContext::currentContext();
- QScopedPointer<QOpenGLContext> dummyContext;
- QScopedPointer<QOffscreenSurface> dummySurface;
- bool ok = true;
- if (!context) {
- dummyContext.reset(new QOpenGLContext);
- dummyContext->create();
- context = dummyContext.data();
- dummySurface.reset(new QOffscreenSurface);
- dummySurface->setFormat(context->format());
- dummySurface->create();
- ok = context->makeCurrent(dummySurface.data());
- }
- if (ok) {
- elementIndexUint = static_cast<QOpenGLExtensions *>(context->functions())->hasOpenGLExtension(
- QOpenGLExtensions::ElementIndexUint);
- }
- }
- }
-#else
- Q_UNUSED(api);
-#endif
- return elementIndexUint;
-}
-
-QQuickPathItemGenericRenderer::~QQuickPathItemGenericRenderer()
-{
- for (VisualPathData &d : m_vp) {
- if (d.pendingFill)
- d.pendingFill->orphaned = true;
- if (d.pendingStroke)
- d.pendingStroke->orphaned = true;
- }
-}
-
-// sync, and so triangulation too, happens on the gui thread
-// - except when async is set, in which case triangulation is moved to worker threads
-
-void QQuickPathItemGenericRenderer::beginSync(int totalCount)
-{
- if (m_vp.count() != totalCount) {
- m_vp.resize(totalCount);
- m_accDirty |= DirtyList;
- }
- for (VisualPathData &d : m_vp)
- d.syncDirty = 0;
-}
-
-void QQuickPathItemGenericRenderer::setPath(int index, const QQuickPath *path)
-{
- VisualPathData &d(m_vp[index]);
- d.path = path ? path->path() : QPainterPath();
- d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setJSPath(int index, const QQuickPathItemPath &path)
-{
- VisualPathData &d(m_vp[index]);
- d.path = path.toPainterPath();
- d.syncDirty |= DirtyFillGeom | DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setStrokeColor(int index, const QColor &color)
-{
- VisualPathData &d(m_vp[index]);
- d.strokeColor = colorToColor4ub(color);
- d.syncDirty |= DirtyColor;
-}
-
-void QQuickPathItemGenericRenderer::setStrokeWidth(int index, qreal w)
-{
- VisualPathData &d(m_vp[index]);
- d.strokeWidth = w;
- if (w >= 0.0f)
- d.pen.setWidthF(w);
- d.syncDirty |= DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setFillColor(int index, const QColor &color)
-{
- VisualPathData &d(m_vp[index]);
- d.fillColor = colorToColor4ub(color);
- d.syncDirty |= DirtyColor;
-}
-
-void QQuickPathItemGenericRenderer::setFillRule(int index, QQuickVisualPath::FillRule fillRule)
-{
- VisualPathData &d(m_vp[index]);
- d.fillRule = Qt::FillRule(fillRule);
- d.syncDirty |= DirtyFillGeom;
-}
-
-void QQuickPathItemGenericRenderer::setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit)
-{
- VisualPathData &d(m_vp[index]);
- d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle));
- d.pen.setMiterLimit(miterLimit);
- d.syncDirty |= DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setCapStyle(int index, QQuickVisualPath::CapStyle capStyle)
-{
- VisualPathData &d(m_vp[index]);
- d.pen.setCapStyle(Qt::PenCapStyle(capStyle));
- d.syncDirty |= DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern)
-{
- VisualPathData &d(m_vp[index]);
- d.pen.setStyle(Qt::PenStyle(strokeStyle));
- if (strokeStyle == QQuickVisualPath::DashLine) {
- d.pen.setDashPattern(dashPattern);
- d.pen.setDashOffset(dashOffset);
- }
- d.syncDirty |= DirtyStrokeGeom;
-}
-
-void QQuickPathItemGenericRenderer::setFillGradient(int index, QQuickPathGradient *gradient)
-{
- VisualPathData &d(m_vp[index]);
- d.fillGradientActive = gradient != nullptr;
- if (gradient) {
- d.fillGradient.stops = gradient->sortedGradientStops();
- d.fillGradient.spread = gradient->spread();
- if (QQuickPathLinearGradient *g = qobject_cast<QQuickPathLinearGradient *>(gradient)) {
- d.fillGradient.start = QPointF(g->x1(), g->y1());
- d.fillGradient.end = QPointF(g->x2(), g->y2());
- } else {
- Q_UNREACHABLE();
- }
- }
- d.syncDirty |= DirtyFillGradient;
-}
-
-void QQuickPathItemFillRunnable::run()
-{
- QQuickPathItemGenericRenderer::triangulateFill(path, fillColor, &fillVertices, &fillIndices, &indexType, supportsElementIndexUint);
- emit done(this);
-}
-
-void QQuickPathItemStrokeRunnable::run()
-{
- QQuickPathItemGenericRenderer::triangulateStroke(path, pen, strokeColor, &strokeVertices, clipSize);
- emit done(this);
-}
-
-void QQuickPathItemGenericRenderer::setAsyncCallback(void (*callback)(void *), void *data)
-{
- m_asyncCallback = callback;
- m_asyncCallbackData = data;
-}
-
-static QThreadPool *pathWorkThreadPool = nullptr;
-
-static void deletePathWorkThreadPool()
-{
- delete pathWorkThreadPool;
- pathWorkThreadPool = nullptr;
-}
-
-void QQuickPathItemGenericRenderer::endSync(bool async)
-{
- bool didKickOffAsync = false;
-
- for (int i = 0; i < m_vp.count(); ++i) {
- VisualPathData &d(m_vp[i]);
- if (!d.syncDirty)
- continue;
-
- m_accDirty |= d.syncDirty;
-
- // Use a shadow dirty flag in order to avoid losing state in case there are
- // multiple syncs with different dirty flags before we get to updateNode()
- // on the render thread (with the gui thread blocked). For our purposes
- // here syncDirty is still required since geometry regeneration must only
- // happen when there was an actual change in this particular sync round.
- d.effectiveDirty |= d.syncDirty;
-
- if (d.path.isEmpty()) {
- d.fillVertices.clear();
- d.fillIndices.clear();
- d.strokeVertices.clear();
- continue;
- }
-
- if (async && !pathWorkThreadPool) {
- qAddPostRoutine(deletePathWorkThreadPool);
- pathWorkThreadPool = new QThreadPool;
- const int idealCount = QThread::idealThreadCount();
- pathWorkThreadPool->setMaxThreadCount(idealCount > 0 ? idealCount * 2 : 4);
- }
-
- if ((d.syncDirty & DirtyFillGeom) && d.fillColor.a) {
- d.path.setFillRule(d.fillRule);
- if (m_api == QSGRendererInterface::Unknown)
- m_api = m_item->window()->rendererInterface()->graphicsApi();
- if (async) {
- QQuickPathItemFillRunnable *r = new QQuickPathItemFillRunnable;
- r->setAutoDelete(false);
- if (d.pendingFill)
- d.pendingFill->orphaned = true;
- d.pendingFill = r;
- r->path = d.path;
- r->fillColor = d.fillColor;
- r->supportsElementIndexUint = q_supportsElementIndexUint(m_api);
- // Unlikely in practice but in theory m_vp could be
- // resized. Therefore, capture 'i' instead of 'd'.
- QObject::connect(r, &QQuickPathItemFillRunnable::done, qApp, [this, i](QQuickPathItemFillRunnable *r) {
- // Bail out when orphaned (meaning either another run was
- // started after this one, or the renderer got destroyed).
- if (!r->orphaned && i < m_vp.count()) {
- VisualPathData &d(m_vp[i]);
- d.fillVertices = r->fillVertices;
- d.fillIndices = r->fillIndices;
- d.indexType = r->indexType;
- d.pendingFill = nullptr;
- d.effectiveDirty |= DirtyFillGeom;
- maybeUpdateAsyncItem();
- }
- r->deleteLater();
- });
- didKickOffAsync = true;
- pathWorkThreadPool->start(r);
- } else {
- triangulateFill(d.path, d.fillColor, &d.fillVertices, &d.fillIndices, &d.indexType, q_supportsElementIndexUint(m_api));
- }
- }
-
- if ((d.syncDirty & DirtyStrokeGeom) && d.strokeWidth >= 0.0f && d.strokeColor.a) {
- if (async) {
- QQuickPathItemStrokeRunnable *r = new QQuickPathItemStrokeRunnable;
- r->setAutoDelete(false);
- if (d.pendingStroke)
- d.pendingStroke->orphaned = true;
- d.pendingStroke = r;
- r->path = d.path;
- r->pen = d.pen;
- r->strokeColor = d.strokeColor;
- r->clipSize = QSize(m_item->width(), m_item->height());
- QObject::connect(r, &QQuickPathItemStrokeRunnable::done, qApp, [this, i](QQuickPathItemStrokeRunnable *r) {
- if (!r->orphaned && i < m_vp.count()) {
- VisualPathData &d(m_vp[i]);
- d.strokeVertices = r->strokeVertices;
- d.pendingStroke = nullptr;
- d.effectiveDirty |= DirtyStrokeGeom;
- maybeUpdateAsyncItem();
- }
- r->deleteLater();
- });
- didKickOffAsync = true;
- pathWorkThreadPool->start(r);
- } else {
- triangulateStroke(d.path, d.pen, d.strokeColor, &d.strokeVertices,
- QSize(m_item->width(), m_item->height()));
- }
- }
- }
-
- if (!didKickOffAsync && async && m_asyncCallback)
- m_asyncCallback(m_asyncCallbackData);
-}
-
-void QQuickPathItemGenericRenderer::maybeUpdateAsyncItem()
-{
- for (const VisualPathData &d : qAsConst(m_vp)) {
- if (d.pendingFill || d.pendingStroke)
- return;
- }
- m_accDirty |= DirtyFillGeom | DirtyStrokeGeom;
- m_item->update();
- if (m_asyncCallback)
- m_asyncCallback(m_asyncCallbackData);
-}
-
-// the stroke/fill triangulation functions may be invoked either on the gui
-// thread or some worker thread and must thus be self-contained.
-void QQuickPathItemGenericRenderer::triangulateFill(const QPainterPath &path,
- const Color4ub &fillColor,
- VertexContainerType *fillVertices,
- IndexContainerType *fillIndices,
- QSGGeometry::Type *indexType,
- bool supportsElementIndexUint)
-{
- const QVectorPath &vp = qtVectorPathForPath(path);
-
- QTriangleSet ts = qTriangulate(vp, QTransform::fromScale(TRI_SCALE, TRI_SCALE), 1, supportsElementIndexUint);
- const int vertexCount = ts.vertices.count() / 2; // just a qreal vector with x,y hence the / 2
- fillVertices->resize(vertexCount);
- ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(fillVertices->data());
- const qreal *vsrc = ts.vertices.constData();
- for (int i = 0; i < vertexCount; ++i)
- vdst[i].set(vsrc[i * 2] / TRI_SCALE, vsrc[i * 2 + 1] / TRI_SCALE, fillColor);
-
- size_t indexByteSize;
- if (ts.indices.type() == QVertexIndexVector::UnsignedShort) {
- *indexType = QSGGeometry::UnsignedShortType;
- // fillIndices is still QVector<quint32>. Just resize to N/2 and pack
- // the N quint16s into it.
- fillIndices->resize(ts.indices.size() / 2);
- indexByteSize = ts.indices.size() * sizeof(quint16);
- } else {
- *indexType = QSGGeometry::UnsignedIntType;
- fillIndices->resize(ts.indices.size());
- indexByteSize = ts.indices.size() * sizeof(quint32);
- }
- memcpy(fillIndices->data(), ts.indices.data(), indexByteSize);
-}
-
-void QQuickPathItemGenericRenderer::triangulateStroke(const QPainterPath &path,
- const QPen &pen,
- const Color4ub &strokeColor,
- VertexContainerType *strokeVertices,
- const QSize &clipSize)
-{
- const QVectorPath &vp = qtVectorPathForPath(path);
- const QRectF clip(QPointF(0, 0), clipSize);
- const qreal inverseScale = 1.0 / TRI_SCALE;
-
- QTriangulatingStroker stroker;
- stroker.setInvScale(inverseScale);
-
- if (pen.style() == Qt::SolidLine) {
- stroker.process(vp, pen, clip, 0);
- } else {
- QDashedStrokeProcessor dashStroker;
- dashStroker.setInvScale(inverseScale);
- dashStroker.process(vp, pen, clip, 0);
- QVectorPath dashStroke(dashStroker.points(), dashStroker.elementCount(),
- dashStroker.elementTypes(), 0);
- stroker.process(dashStroke, pen, clip, 0);
- }
-
- if (!stroker.vertexCount()) {
- strokeVertices->clear();
- return;
- }
-
- const int vertexCount = stroker.vertexCount() / 2; // just a float vector with x,y hence the / 2
- strokeVertices->resize(vertexCount);
- ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(strokeVertices->data());
- const float *vsrc = stroker.vertices();
- for (int i = 0; i < vertexCount; ++i)
- vdst[i].set(vsrc[i * 2], vsrc[i * 2 + 1], strokeColor);
-}
-
-void QQuickPathItemGenericRenderer::setRootNode(QQuickPathItemGenericNode *node)
-{
- if (m_rootNode != node) {
- m_rootNode = node;
- m_accDirty |= DirtyList;
- }
-}
-
-// on the render thread with gui blocked
-void QQuickPathItemGenericRenderer::updateNode()
-{
- if (!m_rootNode || !m_accDirty)
- return;
-
-// [ m_rootNode ]
-// / / /
-// #0 [ fill ] [ stroke ] [ next ]
-// / / |
-// #1 [ fill ] [ stroke ] [ next ]
-// / / |
-// #2 [ fill ] [ stroke ] [ next ]
-// ...
-// ...
-
- QQuickPathItemGenericNode **nodePtr = &m_rootNode;
- QQuickPathItemGenericNode *prevNode = nullptr;
-
- for (VisualPathData &d : m_vp) {
- if (!*nodePtr) {
- *nodePtr = new QQuickPathItemGenericNode;
- prevNode->m_next = *nodePtr;
- prevNode->appendChildNode(*nodePtr);
- }
-
- QQuickPathItemGenericNode *node = *nodePtr;
-
- if (m_accDirty & DirtyList)
- d.effectiveDirty |= DirtyFillGeom | DirtyStrokeGeom | DirtyColor | DirtyFillGradient;
-
- if (!d.effectiveDirty) {
- prevNode = node;
- nodePtr = &node->m_next;
- continue;
- }
-
- if (d.fillColor.a == 0) {
- delete node->m_fillNode;
- node->m_fillNode = nullptr;
- } else if (!node->m_fillNode) {
- node->m_fillNode = new QQuickPathItemGenericStrokeFillNode(m_item->window());
- if (node->m_strokeNode)
- node->removeChildNode(node->m_strokeNode);
- node->appendChildNode(node->m_fillNode);
- if (node->m_strokeNode)
- node->appendChildNode(node->m_strokeNode);
- d.effectiveDirty |= DirtyFillGeom;
- }
-
- if (d.strokeWidth < 0.0f || d.strokeColor.a == 0) {
- delete node->m_strokeNode;
- node->m_strokeNode = nullptr;
- } else if (!node->m_strokeNode) {
- node->m_strokeNode = new QQuickPathItemGenericStrokeFillNode(m_item->window());
- node->appendChildNode(node->m_strokeNode);
- d.effectiveDirty |= DirtyStrokeGeom;
- }
-
- updateFillNode(&d, node);
- updateStrokeNode(&d, node);
-
- d.effectiveDirty = 0;
-
- prevNode = node;
- nodePtr = &node->m_next;
- }
-
- if (*nodePtr && prevNode) {
- prevNode->removeChildNode(*nodePtr);
- delete *nodePtr;
- *nodePtr = nullptr;
- }
-
- m_accDirty = 0;
-}
-
-void QQuickPathItemGenericRenderer::updateShadowDataInNode(VisualPathData *d, QQuickPathItemGenericStrokeFillNode *n)
-{
- if (d->fillGradientActive) {
- if (d->effectiveDirty & DirtyFillGradient)
- n->m_fillGradient = d->fillGradient;
- }
-}
-
-void QQuickPathItemGenericRenderer::updateFillNode(VisualPathData *d, QQuickPathItemGenericNode *node)
-{
- if (!node->m_fillNode)
- return;
- if (!(d->effectiveDirty & (DirtyFillGeom | DirtyColor | DirtyFillGradient)))
- return;
-
- // Make a copy of the data that will be accessed by the material on
- // the render thread. This must be done even when we bail out below.
- QQuickPathItemGenericStrokeFillNode *n = node->m_fillNode;
- updateShadowDataInNode(d, n);
-
- QSGGeometry *g = n->m_geometry;
- if (d->fillVertices.isEmpty()) {
- if (g->vertexCount() || g->indexCount()) {
- g->allocate(0, 0);
- n->markDirty(QSGNode::DirtyGeometry);
- }
- return;
- }
-
- if (d->fillGradientActive) {
- n->activateMaterial(QQuickPathItemGenericStrokeFillNode::MatLinearGradient);
- if (d->effectiveDirty & DirtyFillGradient) {
- // Gradients are implemented via a texture-based material.
- n->markDirty(QSGNode::DirtyMaterial);
- // stop here if only the gradient changed; no need to touch the geometry
- if (!(d->effectiveDirty & DirtyFillGeom))
- return;
- }
- } else {
- n->activateMaterial(QQuickPathItemGenericStrokeFillNode::MatSolidColor);
- // fast path for updating only color values when no change in vertex positions
- if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyFillGeom)) {
- ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData());
- for (int i = 0; i < g->vertexCount(); ++i)
- vdst[i].set(vdst[i].x, vdst[i].y, d->fillColor);
- n->markDirty(QSGNode::DirtyGeometry);
- return;
- }
- }
-
- const int indexCount = d->indexType == QSGGeometry::UnsignedShortType
- ? d->fillIndices.count() * 2 : d->fillIndices.count();
- if (g->indexType() != d->indexType) {
- g = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(),
- d->fillVertices.count(), indexCount, d->indexType);
- n->setGeometry(g);
- delete n->m_geometry;
- n->m_geometry = g;
- } else {
- g->allocate(d->fillVertices.count(), indexCount);
- }
- g->setDrawingMode(QSGGeometry::DrawTriangles);
- memcpy(g->vertexData(), d->fillVertices.constData(), g->vertexCount() * g->sizeOfVertex());
- memcpy(g->indexData(), d->fillIndices.constData(), g->indexCount() * g->sizeOfIndex());
-
- n->markDirty(QSGNode::DirtyGeometry);
-}
-
-void QQuickPathItemGenericRenderer::updateStrokeNode(VisualPathData *d, QQuickPathItemGenericNode *node)
-{
- if (!node->m_strokeNode)
- return;
- if (!(d->effectiveDirty & (DirtyStrokeGeom | DirtyColor)))
- return;
-
- QQuickPathItemGenericStrokeFillNode *n = node->m_strokeNode;
- QSGGeometry *g = n->m_geometry;
- if (d->strokeVertices.isEmpty()) {
- if (g->vertexCount() || g->indexCount()) {
- g->allocate(0, 0);
- n->markDirty(QSGNode::DirtyGeometry);
- }
- return;
- }
-
- n->markDirty(QSGNode::DirtyGeometry);
-
- // Async loading runs update once, bails out above, then updates again once
- // ready. Set the material dirty then. This is in-line with fill where the
- // first activateMaterial() achieves the same.
- if (!g->vertexCount())
- n->markDirty(QSGNode::DirtyMaterial);
-
- if ((d->effectiveDirty & DirtyColor) && !(d->effectiveDirty & DirtyStrokeGeom)) {
- ColoredVertex *vdst = reinterpret_cast<ColoredVertex *>(g->vertexData());
- for (int i = 0; i < g->vertexCount(); ++i)
- vdst[i].set(vdst[i].x, vdst[i].y, d->strokeColor);
- return;
- }
-
- g->allocate(d->strokeVertices.count(), 0);
- g->setDrawingMode(QSGGeometry::DrawTriangleStrip);
- memcpy(g->vertexData(), d->strokeVertices.constData(), g->vertexCount() * g->sizeOfVertex());
-}
-
-QSGMaterial *QQuickPathItemGenericMaterialFactory::createVertexColor(QQuickWindow *window)
-{
- QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
-
-#ifndef QT_NO_OPENGL
- if (api == QSGRendererInterface::OpenGL) // ### so much for "generic"...
- return new QSGVertexColorMaterial;
-#endif
-
- qWarning("Vertex-color material: Unsupported graphics API %d", api);
- return nullptr;
-}
-
-QSGMaterial *QQuickPathItemGenericMaterialFactory::createLinearGradient(QQuickWindow *window,
- QQuickPathItemGenericStrokeFillNode *node)
-{
- QSGRendererInterface::GraphicsApi api = window->rendererInterface()->graphicsApi();
-
-#ifndef QT_NO_OPENGL
- if (api == QSGRendererInterface::OpenGL) // ### so much for "generic"...
- return new QQuickPathItemLinearGradientMaterial(node);
-#endif
-
- qWarning("Linear gradient material: Unsupported graphics API %d", api);
- return nullptr;
-}
-
-#ifndef QT_NO_OPENGL
-
-QSGMaterialType QQuickPathItemLinearGradientShader::type;
-
-QQuickPathItemLinearGradientShader::QQuickPathItemLinearGradientShader()
-{
- setShaderSourceFile(QOpenGLShader::Vertex,
- QStringLiteral(":/qt-project.org/items/shaders/lineargradient.vert"));
- setShaderSourceFile(QOpenGLShader::Fragment,
- QStringLiteral(":/qt-project.org/items/shaders/lineargradient.frag"));
-}
-
-void QQuickPathItemLinearGradientShader::initialize()
-{
- m_opacityLoc = program()->uniformLocation("opacity");
- m_matrixLoc = program()->uniformLocation("matrix");
- m_gradStartLoc = program()->uniformLocation("gradStart");
- m_gradEndLoc = program()->uniformLocation("gradEnd");
-}
-
-void QQuickPathItemLinearGradientShader::updateState(const RenderState &state, QSGMaterial *mat, QSGMaterial *)
-{
- QQuickPathItemLinearGradientMaterial *m = static_cast<QQuickPathItemLinearGradientMaterial *>(mat);
-
- if (state.isOpacityDirty())
- program()->setUniformValue(m_opacityLoc, state.opacity());
-
- if (state.isMatrixDirty())
- program()->setUniformValue(m_matrixLoc, state.combinedMatrix());
-
- QQuickPathItemGenericStrokeFillNode *node = m->node();
- program()->setUniformValue(m_gradStartLoc, QVector2D(node->m_fillGradient.start));
- program()->setUniformValue(m_gradEndLoc, QVector2D(node->m_fillGradient.end));
-
- QSGTexture *tx = QQuickPathItemGradientCache::currentCache()->get(node->m_fillGradient);
- tx->bind();
-}
-
-char const *const *QQuickPathItemLinearGradientShader::attributeNames() const
-{
- static const char *const attr[] = { "vertexCoord", "vertexColor", nullptr };
- return attr;
-}
-
-int QQuickPathItemLinearGradientMaterial::compare(const QSGMaterial *other) const
-{
- Q_ASSERT(other && type() == other->type());
- const QQuickPathItemLinearGradientMaterial *m = static_cast<const QQuickPathItemLinearGradientMaterial *>(other);
-
- QQuickPathItemGenericStrokeFillNode *a = node();
- QQuickPathItemGenericStrokeFillNode *b = m->node();
- Q_ASSERT(a && b);
- if (a == b)
- return 0;
-
- const QQuickPathItemGradientCache::GradientDesc *ga = &a->m_fillGradient;
- const QQuickPathItemGradientCache::GradientDesc *gb = &b->m_fillGradient;
-
- if (int d = ga->spread - gb->spread)
- return d;
-
- if (int d = ga->start.x() - gb->start.x())
- return d;
- if (int d = ga->start.y() - gb->start.y())
- return d;
- if (int d = ga->end.x() - gb->end.x())
- return d;
- if (int d = ga->end.y() - gb->end.y())
- return d;
-
- if (int d = ga->stops.count() - gb->stops.count())
- return d;
-
- for (int i = 0; i < ga->stops.count(); ++i) {
- if (int d = ga->stops[i].first - gb->stops[i].first)
- return d;
- if (int d = ga->stops[i].second.rgba() - gb->stops[i].second.rgba())
- return d;
- }
-
- return 0;
-}
-
-#endif // QT_NO_OPENGL
-
-QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpathitemgenericrenderer_p.h b/src/quick/items/qquickpathitemgenericrenderer_p.h
deleted file mode 100644
index 70a9e88d2f..0000000000
--- a/src/quick/items/qquickpathitemgenericrenderer_p.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPATHITEMGENERICRENDERER_P_H
-#define QQUICKPATHITEMGENERICRENDERER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpathitem_p_p.h"
-#include <qsgnode.h>
-#include <qsggeometry.h>
-#include <qsgmaterial.h>
-#include <qsgrendererinterface.h>
-#include <QtCore/qrunnable.h>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPathItemGenericNode;
-class QQuickPathItemGenericStrokeFillNode;
-class QQuickPathItemFillRunnable;
-class QQuickPathItemStrokeRunnable;
-
-class QQuickPathItemGenericRenderer : public QQuickAbstractPathRenderer
-{
-public:
- enum Dirty {
- DirtyFillGeom = 0x01,
- DirtyStrokeGeom = 0x02,
- DirtyColor = 0x04,
- DirtyFillGradient = 0x08,
- DirtyList = 0x10 // only for accDirty
- };
-
- QQuickPathItemGenericRenderer(QQuickItem *item)
- : m_item(item),
- m_api(QSGRendererInterface::Unknown),
- m_rootNode(nullptr),
- m_accDirty(0),
- m_asyncCallback(nullptr)
- { }
- ~QQuickPathItemGenericRenderer();
-
- void beginSync(int totalCount) override;
- void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickPathItemPath &path) override;
- void setStrokeColor(int index, const QColor &color) override;
- void setStrokeWidth(int index, qreal w) override;
- void setFillColor(int index, const QColor &color) override;
- void setFillRule(int index, QQuickVisualPath::FillRule fillRule) override;
- void setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit) override;
- void setCapStyle(int index, QQuickVisualPath::CapStyle capStyle) override;
- void setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern) override;
- void setFillGradient(int index, QQuickPathGradient *gradient) override;
- void endSync(bool async) override;
- void setAsyncCallback(void (*)(void *), void *) override;
- Flags flags() const override { return SupportsAsync; }
-
- void updateNode() override;
-
- void setRootNode(QQuickPathItemGenericNode *node);
-
- struct Color4ub { unsigned char r, g, b, a; };
- typedef QVector<QSGGeometry::ColoredPoint2D> VertexContainerType;
- typedef QVector<quint32> IndexContainerType;
-
- static void triangulateFill(const QPainterPath &path,
- const Color4ub &fillColor,
- VertexContainerType *fillVertices,
- IndexContainerType *fillIndices,
- QSGGeometry::Type *indexType,
- bool supportsElementIndexUint);
- static void triangulateStroke(const QPainterPath &path,
- const QPen &pen,
- const Color4ub &strokeColor,
- VertexContainerType *strokeVertices,
- const QSize &clipSize);
-
-private:
- void maybeUpdateAsyncItem();
-
- struct VisualPathData {
- float strokeWidth;
- QPen pen;
- Color4ub strokeColor;
- Color4ub fillColor;
- Qt::FillRule fillRule;
- QPainterPath path;
- bool fillGradientActive;
- QQuickPathItemGradientCache::GradientDesc fillGradient;
- VertexContainerType fillVertices;
- IndexContainerType fillIndices;
- QSGGeometry::Type indexType;
- VertexContainerType strokeVertices;
- int syncDirty;
- int effectiveDirty = 0;
- QQuickPathItemFillRunnable *pendingFill = nullptr;
- QQuickPathItemStrokeRunnable *pendingStroke = nullptr;
- };
-
- void updateShadowDataInNode(VisualPathData *d, QQuickPathItemGenericStrokeFillNode *n);
- void updateFillNode(VisualPathData *d, QQuickPathItemGenericNode *node);
- void updateStrokeNode(VisualPathData *d, QQuickPathItemGenericNode *node);
-
- QQuickItem *m_item;
- QSGRendererInterface::GraphicsApi m_api;
- QQuickPathItemGenericNode *m_rootNode;
- QVector<VisualPathData> m_vp;
- int m_accDirty;
- void (*m_asyncCallback)(void *);
- void *m_asyncCallbackData;
-};
-
-class QQuickPathItemFillRunnable : public QObject, public QRunnable
-{
- Q_OBJECT
-
-public:
- void run() override;
-
- bool orphaned = false;
-
- // input
- QPainterPath path;
- QQuickPathItemGenericRenderer::Color4ub fillColor;
- bool supportsElementIndexUint;
-
- // output
- QQuickPathItemGenericRenderer::VertexContainerType fillVertices;
- QQuickPathItemGenericRenderer::IndexContainerType fillIndices;
- QSGGeometry::Type indexType;
-
-Q_SIGNALS:
- void done(QQuickPathItemFillRunnable *self);
-};
-
-class QQuickPathItemStrokeRunnable : public QObject, public QRunnable
-{
- Q_OBJECT
-
-public:
- void run() override;
-
- bool orphaned = false;
-
- // input
- QPainterPath path;
- QPen pen;
- QQuickPathItemGenericRenderer::Color4ub strokeColor;
- QSize clipSize;
-
- // output
- QQuickPathItemGenericRenderer::VertexContainerType strokeVertices;
-
-Q_SIGNALS:
- void done(QQuickPathItemStrokeRunnable *self);
-};
-
-class QQuickPathItemGenericStrokeFillNode : public QSGGeometryNode
-{
-public:
- QQuickPathItemGenericStrokeFillNode(QQuickWindow *window);
- ~QQuickPathItemGenericStrokeFillNode();
-
- enum Material {
- MatSolidColor,
- MatLinearGradient
- };
-
- void activateMaterial(Material m);
-
- QQuickWindow *window() const { return m_window; }
-
- // shadow data for custom materials
- QQuickPathItemGradientCache::GradientDesc m_fillGradient;
-
-private:
- QSGGeometry *m_geometry;
- QQuickWindow *m_window;
- QSGMaterial *m_material;
- QScopedPointer<QSGMaterial> m_solidColorMaterial;
- QScopedPointer<QSGMaterial> m_linearGradientMaterial;
-
- friend class QQuickPathItemGenericRenderer;
-};
-
-class QQuickPathItemGenericNode : public QSGNode
-{
-public:
- QQuickPathItemGenericStrokeFillNode *m_fillNode = nullptr;
- QQuickPathItemGenericStrokeFillNode *m_strokeNode = nullptr;
- QQuickPathItemGenericNode *m_next = nullptr;
-};
-
-class QQuickPathItemGenericMaterialFactory
-{
-public:
- static QSGMaterial *createVertexColor(QQuickWindow *window);
- static QSGMaterial *createLinearGradient(QQuickWindow *window, QQuickPathItemGenericStrokeFillNode *node);
-};
-
-#ifndef QT_NO_OPENGL
-
-class QQuickPathItemLinearGradientShader : public QSGMaterialShader
-{
-public:
- QQuickPathItemLinearGradientShader();
-
- void initialize() override;
- void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
- char const *const *attributeNames() const override;
-
- static QSGMaterialType type;
-
-private:
- int m_opacityLoc;
- int m_matrixLoc;
- int m_gradStartLoc;
- int m_gradEndLoc;
-};
-
-class QQuickPathItemLinearGradientMaterial : public QSGMaterial
-{
-public:
- QQuickPathItemLinearGradientMaterial(QQuickPathItemGenericStrokeFillNode *node)
- : m_node(node)
- {
- // Passing RequiresFullMatrix is essential in order to prevent the
- // batch renderer from baking in simple, translate-only transforms into
- // the vertex data. The shader will rely on the fact that
- // vertexCoord.xy is the PathItem-space coordinate and so no modifications
- // are welcome.
- setFlag(Blending | RequiresFullMatrix);
- }
-
- QSGMaterialType *type() const override
- {
- return &QQuickPathItemLinearGradientShader::type;
- }
-
- int compare(const QSGMaterial *other) const override;
-
- QSGMaterialShader *createShader() const override
- {
- return new QQuickPathItemLinearGradientShader;
- }
-
- QQuickPathItemGenericStrokeFillNode *node() const { return m_node; }
-
-private:
- QQuickPathItemGenericStrokeFillNode *m_node;
-};
-
-#endif // QT_NO_OPENGL
-
-QT_END_NAMESPACE
-
-#endif // QQUICKPATHITEMGENERICRENDERER_P_H
diff --git a/src/quick/items/qquickpathitemnvprrenderer.cpp b/src/quick/items/qquickpathitemnvprrenderer.cpp
deleted file mode 100644
index f8504f9985..0000000000
--- a/src/quick/items/qquickpathitemnvprrenderer.cpp
+++ /dev/null
@@ -1,923 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpathitemnvprrenderer_p.h"
-#include <QOpenGLExtraFunctions>
-#include <QOpenGLFramebufferObject>
-#include <QOpenGLShaderProgram>
-#include <QOpenGLBuffer>
-#include <private/qquickpath_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-void QQuickPathItemNvprRenderer::beginSync(int totalCount)
-{
- if (m_vp.count() != totalCount) {
- m_vp.resize(totalCount);
- m_accDirty |= DirtyList;
- }
-}
-
-void QQuickPathItemNvprRenderer::setPath(int index, const QQuickPath *path)
-{
- VisualPathGuiData &d(m_vp[index]);
- convertPath(path, &d);
- d.dirty |= DirtyPath;
- 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]);
- d.strokeColor = color;
- d.dirty |= DirtyStyle;
- m_accDirty |= DirtyStyle;
-}
-
-void QQuickPathItemNvprRenderer::setStrokeWidth(int index, qreal w)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.strokeWidth = w;
- d.dirty |= DirtyStyle;
- m_accDirty |= DirtyStyle;
-}
-
-void QQuickPathItemNvprRenderer::setFillColor(int index, const QColor &color)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.fillColor = color;
- d.dirty |= DirtyStyle;
- m_accDirty |= DirtyStyle;
-}
-
-void QQuickPathItemNvprRenderer::setFillRule(int index, QQuickVisualPath::FillRule fillRule)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.fillRule = fillRule;
- d.dirty |= DirtyFillRule;
- m_accDirty |= DirtyFillRule;
-}
-
-void QQuickPathItemNvprRenderer::setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.joinStyle = joinStyle;
- d.miterLimit = miterLimit;
- d.dirty |= DirtyStyle;
- m_accDirty |= DirtyStyle;
-}
-
-void QQuickPathItemNvprRenderer::setCapStyle(int index, QQuickVisualPath::CapStyle capStyle)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.capStyle = capStyle;
- d.dirty |= DirtyStyle;
- m_accDirty |= DirtyStyle;
-}
-
-void QQuickPathItemNvprRenderer::setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.dashActive = strokeStyle == QQuickVisualPath::DashLine;
- d.dashOffset = dashOffset;
- d.dashPattern = dashPattern;
- d.dirty |= DirtyDash;
- m_accDirty |= DirtyDash;
-}
-
-void QQuickPathItemNvprRenderer::setFillGradient(int index, QQuickPathGradient *gradient)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.fillGradientActive = gradient != nullptr;
- if (gradient) {
- d.fillGradient.stops = gradient->sortedGradientStops();
- d.fillGradient.spread = gradient->spread();
- if (QQuickPathLinearGradient *g = qobject_cast<QQuickPathLinearGradient *>(gradient)) {
- d.fillGradient.start = QPointF(g->x1(), g->y1());
- d.fillGradient.end = QPointF(g->x2(), g->y2());
- } else {
- Q_UNREACHABLE();
- }
- }
- d.dirty |= DirtyFillGradient;
- m_accDirty |= DirtyFillGradient;
-}
-
-void QQuickPathItemNvprRenderer::endSync(bool)
-{
-}
-
-void QQuickPathItemNvprRenderer::setNode(QQuickPathItemNvprRenderNode *node)
-{
- if (m_node != node) {
- m_node = node;
- m_accDirty |= DirtyList;
- }
-}
-
-QDebug operator<<(QDebug debug, const QQuickPathItemNvprRenderer::NvprPath &path)
-{
- QDebugStateSaver saver(debug);
- debug.space().noquote();
- if (!path.str.isEmpty()) {
- debug << "Path with SVG string" << path.str;
- return debug;
- }
- debug << "Path with" << path.cmd.count() << "commands";
- int ci = 0;
- for (GLubyte cmd : path.cmd) {
- static struct { GLubyte cmd; const char *s; int coordCount; } nameTab[] = {
- { GL_MOVE_TO_NV, "moveTo", 2 },
- { GL_LINE_TO_NV, "lineTo", 2 },
- { GL_QUADRATIC_CURVE_TO_NV, "quadTo", 4 },
- { GL_CUBIC_CURVE_TO_NV, "cubicTo", 6 },
- { GL_LARGE_CW_ARC_TO_NV, "arcTo-large-CW", 5 },
- { GL_LARGE_CCW_ARC_TO_NV, "arcTo-large-CCW", 5 },
- { GL_SMALL_CW_ARC_TO_NV, "arcTo-small-CW", 5 },
- { GL_SMALL_CCW_ARC_TO_NV, "arcTo-small-CCW", 5 },
- { GL_CLOSE_PATH_NV, "closePath", 0 } };
- for (size_t i = 0; i < sizeof(nameTab) / sizeof(nameTab[0]); ++i) {
- if (nameTab[i].cmd == cmd) {
- QByteArray cs;
- for (int j = 0; j < nameTab[i].coordCount; ++j) {
- cs.append(QByteArray::number(path.coord[ci++]));
- cs.append(' ');
- }
- debug << "\n " << nameTab[i].s << " " << cs;
- break;
- }
- }
- }
- return debug;
-}
-
-static inline void appendCoords(QVector<GLfloat> *v, QQuickCurve *c, QPointF *pos)
-{
- QPointF p(c->hasRelativeX() ? pos->x() + c->relativeX() : c->x(),
- c->hasRelativeY() ? pos->y() + c->relativeY() : c->y());
- v->append(p.x());
- v->append(p.y());
- *pos = p;
-}
-
-static inline void appendControlCoords(QVector<GLfloat> *v, QQuickPathQuad *c, const QPointF &pos)
-{
- QPointF p(c->hasRelativeControlX() ? pos.x() + c->relativeControlX() : c->controlX(),
- c->hasRelativeControlY() ? pos.y() + c->relativeControlY() : c->controlY());
- v->append(p.x());
- v->append(p.y());
-}
-
-static inline void appendControl1Coords(QVector<GLfloat> *v, QQuickPathCubic *c, const QPointF &pos)
-{
- QPointF p(c->hasRelativeControl1X() ? pos.x() + c->relativeControl1X() : c->control1X(),
- c->hasRelativeControl1Y() ? pos.y() + c->relativeControl1Y() : c->control1Y());
- v->append(p.x());
- v->append(p.y());
-}
-
-static inline void appendControl2Coords(QVector<GLfloat> *v, QQuickPathCubic *c, const QPointF &pos)
-{
- QPointF p(c->hasRelativeControl2X() ? pos.x() + c->relativeControl2X() : c->control2X(),
- c->hasRelativeControl2Y() ? pos.y() + c->relativeControl2Y() : c->control2Y());
- v->append(p.x());
- v->append(p.y());
-}
-
-void QQuickPathItemNvprRenderer::convertPath(const QQuickPath *path, VisualPathGuiData *d)
-{
- d->path = NvprPath();
- if (!path)
- return;
-
- const QList<QQuickPathElement *> &pp(QQuickPathPrivate::get(path)->_pathElements);
- if (pp.isEmpty())
- return;
-
- QPointF startPos(path->startX(), path->startY());
- QPointF pos(startPos);
- if (!qFuzzyIsNull(pos.x()) || !qFuzzyIsNull(pos.y())) {
- d->path.cmd.append(GL_MOVE_TO_NV);
- d->path.coord.append(pos.x());
- d->path.coord.append(pos.y());
- }
-
- for (QQuickPathElement *e : pp) {
- if (QQuickPathMove *o = qobject_cast<QQuickPathMove *>(e)) {
- d->path.cmd.append(GL_MOVE_TO_NV);
- appendCoords(&d->path.coord, o, &pos);
- startPos = pos;
- } else if (QQuickPathLine *o = qobject_cast<QQuickPathLine *>(e)) {
- d->path.cmd.append(GL_LINE_TO_NV);
- appendCoords(&d->path.coord, o, &pos);
- } else if (QQuickPathQuad *o = qobject_cast<QQuickPathQuad *>(e)) {
- d->path.cmd.append(GL_QUADRATIC_CURVE_TO_NV);
- appendControlCoords(&d->path.coord, o, pos);
- appendCoords(&d->path.coord, o, &pos);
- } else if (QQuickPathCubic *o = qobject_cast<QQuickPathCubic *>(e)) {
- d->path.cmd.append(GL_CUBIC_CURVE_TO_NV);
- appendControl1Coords(&d->path.coord, o, pos);
- appendControl2Coords(&d->path.coord, o, pos);
- appendCoords(&d->path.coord, o, &pos);
- } else if (QQuickPathArc *o = qobject_cast<QQuickPathArc *>(e)) {
- const bool sweepFlag = o->direction() == QQuickPathArc::Clockwise; // maps to CCW, not a typo
- GLenum cmd;
- if (o->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(o->radiusX());
- d->path.coord.append(o->radiusY());
- d->path.coord.append(o->xAxisRotation());
- appendCoords(&d->path.coord, o, &pos);
- } else if (QQuickPathSvg *o = qobject_cast<QQuickPathSvg *>(e)) {
- // PathSvg cannot be combined with other elements. But take at
- // least startX and startY into account.
- if (d->path.str.isEmpty())
- d->path.str = QString(QStringLiteral("M %1 %2 ")).arg(pos.x()).arg(pos.y()).toUtf8();
- d->path.str.append(o->path().toUtf8());
- } else {
- qWarning() << "PathItem/NVPR: unsupported Path element" << e;
- }
- }
-
- // For compatibility with QTriangulatingStroker. SVG and others would not
- // implicitly close the path when end_pos == start_pos (start_pos being the
- // last moveTo pos); that would still need an explicit 'z' or similar. We
- // don't have an explicit close command, so just fake a close when the
- // positions match.
- if (pos == startPos)
- 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;
- return QVector4D(c.redF() * o, c.greenF() * o, c.blueF() * o, o);
-}
-
-void QQuickPathItemNvprRenderer::updateNode()
-{
- // Called on the render thread with gui blocked -> update the node with its
- // own copy of all relevant data.
-
- if (!m_accDirty)
- return;
-
- const int count = m_vp.count();
- const bool listChanged = m_accDirty & DirtyList;
- if (listChanged)
- m_node->m_vp.resize(count);
-
- for (int i = 0; i < count; ++i) {
- VisualPathGuiData &src(m_vp[i]);
- QQuickPathItemNvprRenderNode::VisualPathRenderData &dst(m_node->m_vp[i]);
-
- int dirty = src.dirty;
- src.dirty = 0;
- if (listChanged)
- dirty |= DirtyPath | DirtyStyle | DirtyFillRule | DirtyDash | DirtyFillGradient;
-
- // updateNode() can be called several times with different dirty
- // states before render() gets invoked. So accumulate.
- dst.dirty |= dirty;
-
- if (dirty & DirtyPath)
- dst.source = src.path;
-
- if (dirty & DirtyStyle) {
- dst.strokeWidth = src.strokeWidth;
- dst.strokeColor = qsg_premultiply(src.strokeColor, 1.0f);
- dst.fillColor = qsg_premultiply(src.fillColor, 1.0f);
- switch (src.joinStyle) {
- case QQuickVisualPath::MiterJoin:
- dst.joinStyle = GL_MITER_TRUNCATE_NV;
- break;
- case QQuickVisualPath::BevelJoin:
- dst.joinStyle = GL_BEVEL_NV;
- break;
- case QQuickVisualPath::RoundJoin:
- dst.joinStyle = GL_ROUND_NV;
- break;
- default:
- Q_UNREACHABLE();
- }
- dst.miterLimit = src.miterLimit;
- switch (src.capStyle) {
- case QQuickVisualPath::FlatCap:
- dst.capStyle = GL_FLAT;
- break;
- case QQuickVisualPath::SquareCap:
- dst.capStyle = GL_SQUARE_NV;
- break;
- case QQuickVisualPath::RoundCap:
- dst.capStyle = GL_ROUND_NV;
- break;
- default:
- Q_UNREACHABLE();
- }
- }
-
- if (dirty & DirtyFillRule) {
- switch (src.fillRule) {
- case QQuickVisualPath::OddEvenFill:
- dst.fillRule = GL_INVERT;
- break;
- case QQuickVisualPath::WindingFill:
- dst.fillRule = GL_COUNT_UP_NV;
- break;
- default:
- Q_UNREACHABLE();
- }
- }
-
- if (dirty & DirtyDash) {
- dst.dashOffset = src.dashOffset;
- if (src.dashActive) {
- dst.dashPattern.resize(src.dashPattern.count());
- // Multiply by strokeWidth because the PathItem API follows QPen
- // meaning the input dash pattern here is in width units.
- for (int i = 0; i < src.dashPattern.count(); ++i)
- dst.dashPattern[i] = GLfloat(src.dashPattern[i]) * src.strokeWidth;
- } else {
- dst.dashPattern.clear();
- }
- }
-
- if (dirty & DirtyFillGradient) {
- dst.fillGradientActive = src.fillGradientActive;
- if (src.fillGradientActive)
- dst.fillGradient = src.fillGradient;
- }
- }
-
- m_node->markDirty(QSGNode::DirtyMaterial);
- m_accDirty = 0;
-}
-
-bool QQuickPathItemNvprRenderNode::nvprInited = false;
-QQuickNvprFunctions QQuickPathItemNvprRenderNode::nvpr;
-QQuickNvprMaterialManager QQuickPathItemNvprRenderNode::mtlmgr;
-
-QQuickPathItemNvprRenderNode::~QQuickPathItemNvprRenderNode()
-{
- releaseResources();
-}
-
-void QQuickPathItemNvprRenderNode::releaseResources()
-{
- for (VisualPathRenderData &d : m_vp) {
- if (d.path) {
- nvpr.deletePaths(d.path, 1);
- d.path = 0;
- }
- if (d.fallbackFbo) {
- delete d.fallbackFbo;
- d.fallbackFbo = nullptr;
- }
- }
-
- m_fallbackBlitter.destroy();
-}
-
-void QQuickNvprMaterialManager::create(QQuickNvprFunctions *nvpr)
-{
- m_nvpr = nvpr;
-}
-
-void QQuickNvprMaterialManager::releaseResources()
-{
- QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
- for (MaterialDesc &mtl : m_materials) {
- if (mtl.ppl) {
- f->glDeleteProgramPipelines(1, &mtl.ppl);
- mtl = MaterialDesc();
- }
- }
-}
-
-QQuickNvprMaterialManager::MaterialDesc *QQuickNvprMaterialManager::activateMaterial(Material m)
-{
- QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
- MaterialDesc &mtl(m_materials[m]);
-
- if (!mtl.ppl) {
- if (m == MatSolid) {
- static const char *fragSrc =
- "#version 310 es\n"
- "precision highp float;\n"
- "out vec4 fragColor;\n"
- "uniform vec4 color;\n"
- "uniform float opacity;\n"
- "void main() {\n"
- " fragColor = color * opacity;\n"
- "}\n";
- if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
- qWarning("NVPR: Failed to create shader pipeline for solid fill");
- return nullptr;
- }
- Q_ASSERT(mtl.ppl && mtl.prg);
- mtl.uniLoc[0] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "color");
- Q_ASSERT(mtl.uniLoc[0] >= 0);
- mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
- Q_ASSERT(mtl.uniLoc[1] >= 0);
- } else if (m == MatLinearGradient) {
- static const char *fragSrc =
- "#version 310 es\n"
- "precision highp float;\n"
- "layout(location = 0) in vec2 uv;"
- "uniform float opacity;\n"
- "uniform sampler2D gradTab;\n"
- "uniform vec2 gradStart;\n"
- "uniform vec2 gradEnd;\n"
- "out vec4 fragColor;\n"
- "void main() {\n"
- " vec2 gradVec = gradEnd - gradStart;\n"
- " float gradTabIndex = dot(gradVec, uv - gradStart) / (gradVec.x * gradVec.x + gradVec.y * gradVec.y);\n"
- " fragColor = texture(gradTab, vec2(gradTabIndex, 0.5)) * opacity;\n"
- "}\n";
- if (!m_nvpr->createFragmentOnlyPipeline(fragSrc, &mtl.ppl, &mtl.prg)) {
- qWarning("NVPR: Failed to create shader pipeline for linear gradient");
- return nullptr;
- }
- Q_ASSERT(mtl.ppl && mtl.prg);
- mtl.uniLoc[1] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "opacity");
- Q_ASSERT(mtl.uniLoc[1] >= 0);
- mtl.uniLoc[2] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "gradStart");
- Q_ASSERT(mtl.uniLoc[2] >= 0);
- mtl.uniLoc[3] = f->glGetProgramResourceLocation(mtl.prg, GL_UNIFORM, "gradEnd");
- Q_ASSERT(mtl.uniLoc[3] >= 0);
- } else {
- Q_UNREACHABLE();
- }
- }
-
- f->glBindProgramPipeline(mtl.ppl);
-
- return &mtl;
-}
-
-void QQuickPathItemNvprRenderNode::updatePath(VisualPathRenderData *d)
-{
- if (d->dirty & QQuickPathItemNvprRenderer::DirtyPath) {
- if (!d->path) {
- d->path = nvpr.genPaths(1);
- Q_ASSERT(d->path != 0);
- }
- if (d->source.str.isEmpty()) {
- nvpr.pathCommands(d->path, d->source.cmd.count(), d->source.cmd.constData(),
- d->source.coord.count(), GL_FLOAT, d->source.coord.constData());
- } else {
- nvpr.pathString(d->path, GL_PATH_FORMAT_SVG_NV, d->source.str.count(), d->source.str.constData());
- }
- }
-
- if (d->dirty & QQuickPathItemNvprRenderer::DirtyStyle) {
- nvpr.pathParameterf(d->path, GL_PATH_STROKE_WIDTH_NV, d->strokeWidth);
- nvpr.pathParameteri(d->path, GL_PATH_JOIN_STYLE_NV, d->joinStyle);
- nvpr.pathParameteri(d->path, GL_PATH_MITER_LIMIT_NV, d->miterLimit);
- nvpr.pathParameteri(d->path, GL_PATH_END_CAPS_NV, d->capStyle);
- nvpr.pathParameteri(d->path, GL_PATH_DASH_CAPS_NV, d->capStyle);
- }
-
- if (d->dirty & QQuickPathItemNvprRenderer::DirtyDash) {
- nvpr.pathParameterf(d->path, GL_PATH_DASH_OFFSET_NV, d->dashOffset);
- // count == 0 -> no dash
- nvpr.pathDashArray(d->path, d->dashPattern.count(), d->dashPattern.constData());
- }
-
- if (d->dirty)
- d->fallbackValid = false;
-}
-
-void QQuickPathItemNvprRenderNode::renderStroke(VisualPathRenderData *d, int strokeStencilValue, int writeMask)
-{
- QQuickNvprMaterialManager::MaterialDesc *mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatSolid);
- f->glProgramUniform4f(mtl->prg, mtl->uniLoc[0],
- d->strokeColor.x(), d->strokeColor.y(), d->strokeColor.z(), d->strokeColor.w());
- f->glProgramUniform1f(mtl->prg, mtl->uniLoc[1], inheritedOpacity());
-
- nvpr.stencilThenCoverStrokePath(d->path, strokeStencilValue, writeMask, GL_CONVEX_HULL_NV);
-}
-
-void QQuickPathItemNvprRenderNode::renderFill(VisualPathRenderData *d)
-{
- QQuickNvprMaterialManager::MaterialDesc *mtl = nullptr;
- if (d->fillGradientActive) {
- mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatLinearGradient);
- QSGTexture *tx = QQuickPathItemGradientCache::currentCache()->get(d->fillGradient);
- tx->bind();
- // uv = vec2(coeff[0] * x + coeff[1] * y + coeff[2], coeff[3] * x + coeff[4] * y + coeff[5])
- // where x and y are in path coordinate space, which is just what
- // we need since the gradient's start and stop are in that space too.
- GLfloat coeff[6] = { 1, 0, 0,
- 0, 1, 0 };
- nvpr.programPathFragmentInputGen(mtl->prg, 0, GL_OBJECT_LINEAR_NV, 2, coeff);
- f->glProgramUniform2f(mtl->prg, mtl->uniLoc[2], d->fillGradient.start.x(), d->fillGradient.start.y());
- f->glProgramUniform2f(mtl->prg, mtl->uniLoc[3], d->fillGradient.end.x(), d->fillGradient.end.y());
- } else {
- mtl = mtlmgr.activateMaterial(QQuickNvprMaterialManager::MatSolid);
- f->glProgramUniform4f(mtl->prg, mtl->uniLoc[0],
- d->fillColor.x(), d->fillColor.y(), d->fillColor.z(), d->fillColor.w());
- }
- f->glProgramUniform1f(mtl->prg, mtl->uniLoc[1], inheritedOpacity());
-
- const int writeMask = 0xFF;
- nvpr.stencilThenCoverFillPath(d->path, d->fillRule, writeMask, GL_BOUNDING_BOX_NV);
-}
-
-void QQuickPathItemNvprRenderNode::renderOffscreenFill(VisualPathRenderData *d)
-{
- if (d->fallbackValid && d->fallbackFbo)
- return;
-
- GLfloat bb[4];
- nvpr.getPathParameterfv(d->path, GL_PATH_STROKE_BOUNDING_BOX_NV, bb);
- QSize sz = QSizeF(bb[2] - bb[0] + 1, bb[3] - bb[1] + 1).toSize();
- d->fallbackSize = QSize(qMax(32, sz.width()), qMax(32, sz.height()));
- d->fallbackTopLeft = QPointF(bb[0], bb[1]);
-
- if (d->fallbackFbo && d->fallbackFbo->size() != d->fallbackSize) {
- delete d->fallbackFbo;
- d->fallbackFbo = nullptr;
- }
- if (!d->fallbackFbo)
- d->fallbackFbo = new QOpenGLFramebufferObject(d->fallbackSize, QOpenGLFramebufferObject::CombinedDepthStencil);
- if (!d->fallbackFbo->bind())
- return;
-
- GLint prevViewport[4];
- f->glGetIntegerv(GL_VIEWPORT, prevViewport);
-
- f->glViewport(0, 0, d->fallbackSize.width(), d->fallbackSize.height());
- f->glDisable(GL_DEPTH_TEST);
- f->glClearColor(0, 0, 0, 0);
- f->glClearStencil(0);
- f->glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- f->glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
- f->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
- QMatrix4x4 mv;
- mv.translate(-d->fallbackTopLeft.x(), -d->fallbackTopLeft.y());
- nvpr.matrixLoadf(GL_PATH_MODELVIEW_NV, mv.constData());
- QMatrix4x4 proj;
- proj.ortho(0, d->fallbackSize.width(), d->fallbackSize.height(), 0, 1, -1);
- nvpr.matrixLoadf(GL_PATH_PROJECTION_NV, proj.constData());
-
- renderFill(d);
-
- d->fallbackFbo->release();
- f->glEnable(GL_DEPTH_TEST);
- f->glViewport(prevViewport[0], prevViewport[1], prevViewport[2], prevViewport[3]);
-
- d->fallbackValid = true;
-}
-
-void QQuickPathItemNvprRenderNode::setupStencilForCover(bool stencilClip, int sv)
-{
- if (!stencilClip) {
- // Assume stencil buffer is cleared to 0 for each frame.
- // Within the frame dppass=GL_ZERO for glStencilOp ensures stencil is reset and so no need to clear.
- f->glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
- f->glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
- } else {
- f->glStencilFunc(GL_LESS, sv, 0xFF); // pass if (sv & 0xFF) < (stencil_value & 0xFF)
- f->glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // dppass: replace with the original value (clip's stencil ref value)
- }
-}
-
-void QQuickPathItemNvprRenderNode::render(const RenderState *state)
-{
- f = QOpenGLContext::currentContext()->extraFunctions();
-
- if (!nvprInited) {
- if (!nvpr.create()) {
- qWarning("NVPR init failed");
- return;
- }
- mtlmgr.create(&nvpr);
- nvprInited = true;
- }
-
- f->glUseProgram(0);
- f->glStencilMask(~0);
- f->glEnable(GL_STENCIL_TEST);
-
- const bool stencilClip = state->stencilEnabled();
- // when true, the stencil buffer already has a clip path with a ref value of sv
- const int sv = state->stencilValue();
- const bool hasScissor = state->scissorEnabled();
-
- if (hasScissor) {
- // scissor rect is already set, just enable scissoring
- f->glEnable(GL_SCISSOR_TEST);
- }
-
- // Depth test against the opaque batches rendered before.
- f->glEnable(GL_DEPTH_TEST);
- f->glDepthFunc(GL_LESS);
- nvpr.pathCoverDepthFunc(GL_LESS);
- nvpr.pathStencilDepthOffset(-0.05f, -1);
-
- bool reloadMatrices = true;
-
- for (VisualPathRenderData &d : m_vp) {
- updatePath(&d);
-
- const bool hasFill = d.hasFill();
- const bool hasStroke = d.hasStroke();
-
- if (hasFill && stencilClip) {
- // Fall back to a texture when complex clipping is in use and we have
- // to fill. Reconciling glStencilFillPath's and the scenegraph's clip
- // stencil semantics has not succeeded so far...
- if (hasScissor)
- f->glDisable(GL_SCISSOR_TEST);
- renderOffscreenFill(&d);
- reloadMatrices = true;
- if (hasScissor)
- f->glEnable(GL_SCISSOR_TEST);
- }
-
- if (reloadMatrices) {
- reloadMatrices = false;
- nvpr.matrixLoadf(GL_PATH_MODELVIEW_NV, matrix()->constData());
- nvpr.matrixLoadf(GL_PATH_PROJECTION_NV, state->projectionMatrix()->constData());
- }
-
- // Fill!
- if (hasFill) {
- if (!stencilClip) {
- setupStencilForCover(false, 0);
- renderFill(&d);
- } else {
- if (!m_fallbackBlitter.isCreated())
- m_fallbackBlitter.create();
- f->glStencilFunc(GL_EQUAL, sv, 0xFF);
- f->glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- QMatrix4x4 mv = *matrix();
- mv.translate(d.fallbackTopLeft.x(), d.fallbackTopLeft.y());
- m_fallbackBlitter.texturedQuad(d.fallbackFbo->texture(), d.fallbackFbo->size(),
- *state->projectionMatrix(), mv,
- inheritedOpacity());
- }
- }
-
- // Stroke!
- if (hasStroke) {
- const int strokeStencilValue = 0x80;
- const int writeMask = 0x80;
-
- setupStencilForCover(stencilClip, sv);
- if (stencilClip) {
- // for the stencil step (eff. read mask == 0xFF & ~writeMask)
- nvpr.pathStencilFunc(GL_EQUAL, sv, 0xFF);
- // With stencilCLip == true the read mask for the stencil test before the stencil step is 0x7F.
- // This assumes the clip stencil value is <= 127.
- if (sv >= strokeStencilValue)
- qWarning("PathItem/NVPR: stencil clip ref value %d too large; expect rendering errors", sv);
- }
-
- renderStroke(&d, strokeStencilValue, writeMask);
- }
-
- if (stencilClip)
- nvpr.pathStencilFunc(GL_ALWAYS, 0, ~0);
-
- d.dirty = 0;
- }
-
- f->glBindProgramPipeline(0);
-}
-
-QSGRenderNode::StateFlags QQuickPathItemNvprRenderNode::changedStates() const
-{
- return BlendState | StencilState | DepthState | ScissorState;
-}
-
-QSGRenderNode::RenderingFlags QQuickPathItemNvprRenderNode::flags() const
-{
- return DepthAwareRendering; // avoid hitting the less optimal no-opaque-batch path in the renderer
-}
-
-bool QQuickPathItemNvprRenderNode::isSupported()
-{
- static const bool nvprDisabled = qEnvironmentVariableIntValue("QT_NO_NVPR") != 0;
- return !nvprDisabled && QQuickNvprFunctions::isSupported();
-}
-
-bool QQuickNvprBlitter::create()
-{
- if (isCreated())
- destroy();
-
- m_program = new QOpenGLShaderProgram;
- if (QOpenGLContext::currentContext()->format().profile() == QSurfaceFormat::CoreProfile) {
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/items/shaders/shadereffect_core.vert"));
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/items/shaders/shadereffect_core.frag"));
- } else {
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, QStringLiteral(":/qt-project.org/items/shaders/shadereffect.vert"));
- m_program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, QStringLiteral(":/qt-project.org/items/shaders/shadereffect.frag"));
- }
- m_program->bindAttributeLocation("qt_Vertex", 0);
- m_program->bindAttributeLocation("qt_MultiTexCoord0", 1);
- if (!m_program->link())
- return false;
-
- m_matrixLoc = m_program->uniformLocation("qt_Matrix");
- m_opacityLoc = m_program->uniformLocation("qt_Opacity");
-
- m_buffer = new QOpenGLBuffer;
- if (!m_buffer->create())
- return false;
- m_buffer->bind();
- m_buffer->allocate(4 * sizeof(GLfloat) * 6);
- m_buffer->release();
-
- return true;
-}
-
-void QQuickNvprBlitter::destroy()
-{
- if (m_program) {
- delete m_program;
- m_program = nullptr;
- }
- if (m_buffer) {
- delete m_buffer;
- m_buffer = nullptr;
- }
-}
-
-void QQuickNvprBlitter::texturedQuad(GLuint textureId, const QSize &size,
- const QMatrix4x4 &proj, const QMatrix4x4 &modelview,
- float opacity)
-{
- QOpenGLExtraFunctions *f = QOpenGLContext::currentContext()->extraFunctions();
-
- m_program->bind();
-
- QMatrix4x4 m = proj * modelview;
- m_program->setUniformValue(m_matrixLoc, m);
- m_program->setUniformValue(m_opacityLoc, opacity);
-
- m_buffer->bind();
-
- if (size != m_prevSize) {
- m_prevSize = size;
-
- QPointF p0(size.width() - 1, size.height() - 1);
- QPointF p1(0, 0);
- QPointF p2(0, size.height() - 1);
- QPointF p3(size.width() - 1, 0);
-
- GLfloat vertices[6 * 4] = {
- GLfloat(p0.x()), GLfloat(p0.y()), 1, 0,
- GLfloat(p1.x()), GLfloat(p1.y()), 0, 1,
- GLfloat(p2.x()), GLfloat(p2.y()), 0, 0,
-
- GLfloat(p0.x()), GLfloat(p0.y()), 1, 0,
- GLfloat(p3.x()), GLfloat(p3.y()), 1, 1,
- GLfloat(p1.x()), GLfloat(p1.y()), 0, 1,
- };
-
- m_buffer->write(0, vertices, sizeof(vertices));
- }
-
- m_program->enableAttributeArray(0);
- m_program->enableAttributeArray(1);
- f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
- f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const void *) (2 * sizeof(GLfloat)));
-
- f->glBindTexture(GL_TEXTURE_2D, textureId);
-
- f->glDrawArrays(GL_TRIANGLES, 0, 6);
-
- f->glBindTexture(GL_TEXTURE_2D, 0);
- m_buffer->release();
- m_program->release();
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpathitemnvprrenderer_p.h b/src/quick/items/qquickpathitemnvprrenderer_p.h
deleted file mode 100644
index deab9cf7f9..0000000000
--- a/src/quick/items/qquickpathitemnvprrenderer_p.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPATHITEMNVPRRENDERER_P_H
-#define QQUICKPATHITEMNVPRRENDERER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpathitem_p_p.h"
-#include <qsgrendernode.h>
-#include <private/qquicknvprfunctions_p.h>
-#include <QColor>
-#include <QVector4D>
-#include <QDebug>
-
-#ifndef QT_NO_OPENGL
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPathItemNvprRenderNode;
-class QOpenGLFramebufferObject;
-class QOpenGLBuffer;
-class QOpenGLExtraFunctions;
-
-class QQuickPathItemNvprRenderer : public QQuickAbstractPathRenderer
-{
-public:
- enum Dirty {
- DirtyPath = 0x01,
- DirtyStyle = 0x02,
- DirtyFillRule = 0x04,
- DirtyDash = 0x08,
- DirtyFillGradient = 0x10,
- DirtyList = 0x20
- };
-
- void beginSync(int totalCount) override;
- void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickPathItemPath &path) override;
- void setStrokeColor(int index, const QColor &color) override;
- void setStrokeWidth(int index, qreal w) override;
- void setFillColor(int index, const QColor &color) override;
- void setFillRule(int index, QQuickVisualPath::FillRule fillRule) override;
- void setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit) override;
- void setCapStyle(int index, QQuickVisualPath::CapStyle capStyle) override;
- void setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern) override;
- void setFillGradient(int index, QQuickPathGradient *gradient) override;
- void endSync(bool async) override;
-
- void updateNode() override;
-
- void setNode(QQuickPathItemNvprRenderNode *node);
-
- struct NvprPath {
- QVector<GLubyte> cmd;
- QVector<GLfloat> coord;
- QByteArray str;
- };
-
-private:
- struct VisualPathGuiData {
- int dirty = 0;
- NvprPath path;
- qreal strokeWidth;
- QColor strokeColor;
- QColor fillColor;
- QQuickVisualPath::JoinStyle joinStyle;
- int miterLimit;
- QQuickVisualPath::CapStyle capStyle;
- QQuickVisualPath::FillRule fillRule;
- bool dashActive;
- qreal dashOffset;
- QVector<qreal> dashPattern;
- bool fillGradientActive;
- QQuickPathItemGradientCache::GradientDesc fillGradient;
- };
-
- void convertPath(const QQuickPath *path, VisualPathGuiData *d);
- void convertJSPath(const QQuickPathItemPath &path, VisualPathGuiData *d);
-
- QQuickPathItemNvprRenderNode *m_node = nullptr;
- int m_accDirty = 0;
-
- QVector<VisualPathGuiData> m_vp;
-};
-
-QDebug operator<<(QDebug debug, const QQuickPathItemNvprRenderer::NvprPath &path);
-
-class QQuickNvprMaterialManager
-{
-public:
- enum Material {
- MatSolid,
- MatLinearGradient,
-
- NMaterials
- };
-
- struct MaterialDesc {
- GLuint ppl = 0;
- GLuint prg = 0;
- int uniLoc[4];
- };
-
- void create(QQuickNvprFunctions *nvpr);
- MaterialDesc *activateMaterial(Material m);
- void releaseResources();
-
-private:
- QQuickNvprFunctions *m_nvpr;
- MaterialDesc m_materials[NMaterials];
-};
-
-class QQuickNvprBlitter
-{
-public:
- bool create();
- void destroy();
- bool isCreated() const { return m_program != nullptr; }
- void texturedQuad(GLuint textureId, const QSize &size,
- const QMatrix4x4 &proj, const QMatrix4x4 &modelview,
- float opacity);
-
-private:
- QOpenGLShaderProgram *m_program = nullptr;
- QOpenGLBuffer *m_buffer = nullptr;
- int m_matrixLoc;
- int m_opacityLoc;
- QSize m_prevSize;
-};
-
-class QQuickPathItemNvprRenderNode : public QSGRenderNode
-{
-public:
- ~QQuickPathItemNvprRenderNode();
-
- void render(const RenderState *state) override;
- void releaseResources() override;
- StateFlags changedStates() const override;
- RenderingFlags flags() const override;
-
- static bool isSupported();
-
-private:
- struct VisualPathRenderData {
- GLuint path = 0;
- int dirty = 0;
- QQuickPathItemNvprRenderer::NvprPath source;
- GLfloat strokeWidth;
- QVector4D strokeColor;
- QVector4D fillColor;
- GLenum joinStyle;
- GLint miterLimit;
- GLenum capStyle;
- GLenum fillRule;
- GLfloat dashOffset;
- QVector<GLfloat> dashPattern;
- bool fillGradientActive;
- QQuickPathItemGradientCache::GradientDesc fillGradient;
- QOpenGLFramebufferObject *fallbackFbo = nullptr;
- bool fallbackValid = false;
- QSize fallbackSize;
- QPointF fallbackTopLeft;
-
- bool hasFill() const { return !qFuzzyIsNull(fillColor.w()) || fillGradientActive; }
- bool hasStroke() const { return strokeWidth >= 0.0f && !qFuzzyIsNull(strokeColor.w()); }
- };
-
- void updatePath(VisualPathRenderData *d);
- void renderStroke(VisualPathRenderData *d, int strokeStencilValue, int writeMask);
- void renderFill(VisualPathRenderData *d);
- void renderOffscreenFill(VisualPathRenderData *d);
- void setupStencilForCover(bool stencilClip, int sv);
-
- static bool nvprInited;
- static QQuickNvprFunctions nvpr;
- static QQuickNvprMaterialManager mtlmgr;
-
- QQuickNvprBlitter m_fallbackBlitter;
- QOpenGLExtraFunctions *f = nullptr;
-
- QVector<VisualPathRenderData> m_vp;
-
- friend class QQuickPathItemNvprRenderer;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_OPENGL
-
-#endif // QQUICKPATHITEMNVPRRENDERER_P_H
diff --git a/src/quick/items/qquickpathitemsoftwarerenderer.cpp b/src/quick/items/qquickpathitemsoftwarerenderer.cpp
deleted file mode 100644
index b7aa93bf65..0000000000
--- a/src/quick/items/qquickpathitemsoftwarerenderer.cpp
+++ /dev/null
@@ -1,277 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickpathitemsoftwarerenderer_p.h"
-#include <private/qquickpath_p_p.h>
-
-QT_BEGIN_NAMESPACE
-
-void QQuickPathItemSoftwareRenderer::beginSync(int totalCount)
-{
- if (m_vp.count() != totalCount) {
- m_vp.resize(totalCount);
- m_accDirty |= DirtyList;
- }
-}
-
-void QQuickPathItemSoftwareRenderer::setPath(int index, const QQuickPath *path)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.path = path ? path->path() : QPainterPath();
- d.dirty |= DirtyPath;
- m_accDirty |= DirtyPath;
-}
-
-void QQuickPathItemSoftwareRenderer::setJSPath(int index, const QQuickPathItemPath &path)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.path = path.toPainterPath();
- d.dirty |= DirtyPath;
- m_accDirty |= DirtyPath;
-}
-
-void QQuickPathItemSoftwareRenderer::setStrokeColor(int index, const QColor &color)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.pen.setColor(color);
- d.dirty |= DirtyPen;
- m_accDirty |= DirtyPen;
-}
-
-void QQuickPathItemSoftwareRenderer::setStrokeWidth(int index, qreal w)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.strokeWidth = w;
- if (w >= 0.0f)
- d.pen.setWidthF(w);
- d.dirty |= DirtyPen;
- m_accDirty |= DirtyPen;
-}
-
-void QQuickPathItemSoftwareRenderer::setFillColor(int index, const QColor &color)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.fillColor = color;
- d.brush.setColor(color);
- d.dirty |= DirtyBrush;
- m_accDirty |= DirtyBrush;
-}
-
-void QQuickPathItemSoftwareRenderer::setFillRule(int index, QQuickVisualPath::FillRule fillRule)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.fillRule = Qt::FillRule(fillRule);
- d.dirty |= DirtyFillRule;
- m_accDirty |= DirtyFillRule;
-}
-
-void QQuickPathItemSoftwareRenderer::setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.pen.setJoinStyle(Qt::PenJoinStyle(joinStyle));
- d.pen.setMiterLimit(miterLimit);
- d.dirty |= DirtyPen;
- m_accDirty |= DirtyPen;
-}
-
-void QQuickPathItemSoftwareRenderer::setCapStyle(int index, QQuickVisualPath::CapStyle capStyle)
-{
- VisualPathGuiData &d(m_vp[index]);
- d.pen.setCapStyle(Qt::PenCapStyle(capStyle));
- d.dirty |= DirtyPen;
- m_accDirty |= DirtyPen;
-}
-
-void QQuickPathItemSoftwareRenderer::setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern)
-{
- VisualPathGuiData &d(m_vp[index]);
- switch (strokeStyle) {
- case QQuickVisualPath::SolidLine:
- d.pen.setStyle(Qt::SolidLine);
- break;
- case QQuickVisualPath::DashLine:
- d.pen.setStyle(Qt::CustomDashLine);
- d.pen.setDashPattern(dashPattern);
- d.pen.setDashOffset(dashOffset);
- break;
- default:
- break;
- }
- d.dirty |= DirtyPen;
- m_accDirty |= DirtyPen;
-}
-
-void QQuickPathItemSoftwareRenderer::setFillGradient(int index, QQuickPathGradient *gradient)
-{
- VisualPathGuiData &d(m_vp[index]);
- if (QQuickPathLinearGradient *linearGradient = qobject_cast<QQuickPathLinearGradient *>(gradient)) {
- QLinearGradient painterGradient(linearGradient->x1(), linearGradient->y1(),
- linearGradient->x2(), linearGradient->y2());
- painterGradient.setStops(linearGradient->sortedGradientStops());
- switch (gradient->spread()) {
- case QQuickPathGradient::PadSpread:
- painterGradient.setSpread(QGradient::PadSpread);
- break;
- case QQuickPathGradient::RepeatSpread:
- painterGradient.setSpread(QGradient::RepeatSpread);
- break;
- case QQuickPathGradient::ReflectSpread:
- painterGradient.setSpread(QGradient::ReflectSpread);
- break;
- default:
- break;
- }
- d.brush = QBrush(painterGradient);
- } else {
- d.brush = QBrush(d.fillColor);
- }
- d.dirty |= DirtyBrush;
- m_accDirty |= DirtyBrush;
-}
-
-void QQuickPathItemSoftwareRenderer::endSync(bool)
-{
-}
-
-void QQuickPathItemSoftwareRenderer::setNode(QQuickPathItemSoftwareRenderNode *node)
-{
- if (m_node != node) {
- m_node = node;
- m_accDirty |= DirtyList;
- }
-}
-
-void QQuickPathItemSoftwareRenderer::updateNode()
-{
- if (!m_accDirty)
- return;
-
- const int count = m_vp.count();
- const bool listChanged = m_accDirty & DirtyList;
- if (listChanged)
- m_node->m_vp.resize(count);
-
- m_node->m_boundingRect = QRectF();
-
- for (int i = 0; i < count; ++i) {
- VisualPathGuiData &src(m_vp[i]);
- QQuickPathItemSoftwareRenderNode::VisualPathRenderData &dst(m_node->m_vp[i]);
-
- if (listChanged || (src.dirty & DirtyPath)) {
- dst.path = src.path;
- dst.path.setFillRule(src.fillRule);
- }
-
- if (listChanged || (src.dirty & DirtyFillRule))
- dst.path.setFillRule(src.fillRule);
-
- if (listChanged || (src.dirty & DirtyPen)) {
- dst.pen = src.pen;
- dst.strokeWidth = src.strokeWidth;
- }
-
- if (listChanged || (src.dirty & DirtyBrush))
- dst.brush = src.brush;
-
- src.dirty = 0;
-
- QRectF br = dst.path.boundingRect();
- const float sw = qMax(1.0f, dst.strokeWidth);
- br.adjust(-sw, -sw, sw, sw);
- m_node->m_boundingRect |= br;
- }
-
- m_node->markDirty(QSGNode::DirtyMaterial);
- m_accDirty = 0;
-}
-
-QQuickPathItemSoftwareRenderNode::QQuickPathItemSoftwareRenderNode(QQuickPathItem *item)
- : m_item(item)
-{
-}
-
-QQuickPathItemSoftwareRenderNode::~QQuickPathItemSoftwareRenderNode()
-{
- releaseResources();
-}
-
-void QQuickPathItemSoftwareRenderNode::releaseResources()
-{
-}
-
-void QQuickPathItemSoftwareRenderNode::render(const RenderState *state)
-{
- if (m_vp.isEmpty())
- return;
-
- QSGRendererInterface *rif = m_item->window()->rendererInterface();
- QPainter *p = static_cast<QPainter *>(rif->getResource(m_item->window(), QSGRendererInterface::PainterResource));
- Q_ASSERT(p);
-
- const QRegion *clipRegion = state->clipRegion();
- if (clipRegion && !clipRegion->isEmpty())
- p->setClipRegion(*clipRegion, Qt::ReplaceClip); // must be done before setTransform
-
- p->setTransform(matrix()->toTransform());
- p->setOpacity(inheritedOpacity());
-
- for (const VisualPathRenderData &d : qAsConst(m_vp)) {
- p->setPen(d.strokeWidth >= 0.0f && d.pen.color() != Qt::transparent ? d.pen : Qt::NoPen);
- p->setBrush(d.brush.color() != Qt::transparent ? d.brush : Qt::NoBrush);
- p->drawPath(d.path);
- }
-}
-
-QSGRenderNode::StateFlags QQuickPathItemSoftwareRenderNode::changedStates() const
-{
- return 0;
-}
-
-QSGRenderNode::RenderingFlags QQuickPathItemSoftwareRenderNode::flags() const
-{
- return BoundedRectRendering; // avoid fullscreen updates by saying we won't draw outside rect()
-}
-
-QRectF QQuickPathItemSoftwareRenderNode::rect() const
-{
- return m_boundingRect;
-}
-
-QT_END_NAMESPACE
diff --git a/src/quick/items/qquickpathitemsoftwarerenderer_p.h b/src/quick/items/qquickpathitemsoftwarerenderer_p.h
deleted file mode 100644
index e76590bdfe..0000000000
--- a/src/quick/items/qquickpathitemsoftwarerenderer_p.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQuick module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKPATHITEMSOFTWARERENDERER_P_H
-#define QQUICKPATHITEMSOFTWARERENDERER_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of a number of Qt sources files. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qquickpathitem_p_p.h"
-#include <qsgrendernode.h>
-#include <QPen>
-#include <QBrush>
-
-QT_BEGIN_NAMESPACE
-
-class QQuickPathItemSoftwareRenderNode;
-
-class QQuickPathItemSoftwareRenderer : public QQuickAbstractPathRenderer
-{
-public:
- enum Dirty {
- DirtyPath = 0x01,
- DirtyPen = 0x02,
- DirtyFillRule = 0x04,
- DirtyBrush = 0x08,
- DirtyList = 0x10
- };
-
- void beginSync(int totalCount) override;
- void setPath(int index, const QQuickPath *path) override;
- void setJSPath(int index, const QQuickPathItemPath &path) override;
- void setStrokeColor(int index, const QColor &color) override;
- void setStrokeWidth(int index, qreal w) override;
- void setFillColor(int index, const QColor &color) override;
- void setFillRule(int index, QQuickVisualPath::FillRule fillRule) override;
- void setJoinStyle(int index, QQuickVisualPath::JoinStyle joinStyle, int miterLimit) override;
- void setCapStyle(int index, QQuickVisualPath::CapStyle capStyle) override;
- void setStrokeStyle(int index, QQuickVisualPath::StrokeStyle strokeStyle,
- qreal dashOffset, const QVector<qreal> &dashPattern) override;
- void setFillGradient(int index, QQuickPathGradient *gradient) override;
- void endSync(bool async) override;
-
- void updateNode() override;
-
- void setNode(QQuickPathItemSoftwareRenderNode *node);
-
-private:
- QQuickPathItemSoftwareRenderNode *m_node = nullptr;
- int m_accDirty = 0;
- struct VisualPathGuiData {
- int dirty = 0;
- QPainterPath path;
- QPen pen;
- float strokeWidth;
- QColor fillColor;
- QBrush brush;
- Qt::FillRule fillRule;
- };
- QVector<VisualPathGuiData> m_vp;
-};
-
-class QQuickPathItemSoftwareRenderNode : public QSGRenderNode
-{
-public:
- QQuickPathItemSoftwareRenderNode(QQuickPathItem *item);
- ~QQuickPathItemSoftwareRenderNode();
-
- void render(const RenderState *state) override;
- void releaseResources() override;
- StateFlags changedStates() const override;
- RenderingFlags flags() const override;
- QRectF rect() const override;
-
-private:
- QQuickPathItem *m_item;
-
- struct VisualPathRenderData {
- QPainterPath path;
- QPen pen;
- float strokeWidth;
- QBrush brush;
- };
- QVector<VisualPathRenderData> m_vp;
- QRectF m_boundingRect;
-
- friend class QQuickPathItemSoftwareRenderer;
-};
-
-QT_END_NAMESPACE
-
-#endif // QQUICKPATHITEMSOFTWARERENDERER_P_H