From e2520ff76be49c5aa917741cc6a380fe1549e47d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 3 Apr 2017 11:58:46 +0200 Subject: Move PathItem to qt.labs Change-Id: I1cd686cff60bd40fe2cbbc34f917fac7835b6b7d Reviewed-by: Qt CI Bot Reviewed-by: Andy Nichols Reviewed-by: Robin Burchell --- src/quick/items/context2d/qquickcontext2d.cpp | 3 +- src/quick/items/items.pri | 15 +- src/quick/items/qquickitemsmodule.cpp | 6 - src/quick/items/qquickpathitem.cpp | 2258 -------------------- src/quick/items/qquickpathitem_p.h | 335 --- src/quick/items/qquickpathitem_p_p.h | 282 --- src/quick/items/qquickpathitemgenericrenderer.cpp | 775 ------- src/quick/items/qquickpathitemgenericrenderer_p.h | 303 --- src/quick/items/qquickpathitemnvprrenderer.cpp | 923 -------- src/quick/items/qquickpathitemnvprrenderer_p.h | 237 -- src/quick/items/qquickpathitemsoftwarerenderer.cpp | 277 --- src/quick/items/qquickpathitemsoftwarerenderer_p.h | 136 -- src/quick/util/qquicknvprfunctions.cpp | 284 --- src/quick/util/qquicknvprfunctions_p.h | 406 ---- src/quick/util/qquicknvprfunctions_p_p.h | 70 - src/quick/util/qquicksvgparser_p.h | 7 +- src/quick/util/util.pri | 7 - 17 files changed, 8 insertions(+), 6316 deletions(-) delete mode 100644 src/quick/items/qquickpathitem.cpp delete mode 100644 src/quick/items/qquickpathitem_p.h delete mode 100644 src/quick/items/qquickpathitem_p_p.h delete mode 100644 src/quick/items/qquickpathitemgenericrenderer.cpp delete mode 100644 src/quick/items/qquickpathitemgenericrenderer_p.h delete mode 100644 src/quick/items/qquickpathitemnvprrenderer.cpp delete mode 100644 src/quick/items/qquickpathitemnvprrenderer_p.h delete mode 100644 src/quick/items/qquickpathitemsoftwarerenderer.cpp delete mode 100644 src/quick/items/qquickpathitemsoftwarerenderer_p.h delete mode 100644 src/quick/util/qquicknvprfunctions.cpp delete mode 100644 src/quick/util/qquicknvprfunctions_p.h delete mode 100644 src/quick/util/qquicknvprfunctions_p_p.h (limited to 'src/quick') 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 #include #include #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 #include -#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(uri, 2, 9, "PathArc"); qmlRegisterType(uri, 2, 9, "PathMove"); - qmlRegisterType(uri, 2, 9, "PathItem"); - qmlRegisterType(uri, 2, 9, "VisualPath"); - qmlRegisterType(uri, 2, 9, "PathGradientStop"); - qmlRegisterUncreatableType(uri, 2, 9, "PathGradient", QQuickPathGradient::tr("PathGradient is an abstract base class")); - qmlRegisterType(uri, 2, 9, "PathLinearGradient"); #endif qmlRegisterType(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 -#include -#include -#include - -#include -#include -#include -#include -#include - -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 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 QQuickVisualPath::dashPattern() const -{ - Q_D(const QQuickVisualPath); - return d->sfp.dashPattern; -} - -void QQuickVisualPath::setDashPattern(const QVector &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 *property, int index) -{ - QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(static_cast(property->object)); - return d->qmlData.vp.at(index); -} - -static void vpe_append(QQmlListProperty *property, QQuickVisualPath *obj) -{ - QQuickPathItem *item = static_cast(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 *property) -{ - QQuickPathItemPrivate *d = QQuickPathItemPrivate::get(static_cast(property->object)); - return d->qmlData.vp.count(); -} - -static void vpe_clear(QQmlListProperty *property) -{ - QQuickPathItem *item = static_cast(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 QtQuick::PathItem::elements - - This property holds the VisualPath objects that define the contents of the - PathItem. - - \default - */ - -QQmlListProperty QQuickPathItem::elements() -{ - return QQmlListProperty(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(renderer)->setNode( - static_cast(node)); - } else { - node = new QQuickPathItemGenericNode; - static_cast(renderer)->setRootNode( - static_cast(node)); - } - break; -#endif - case QSGRendererInterface::Software: - node = new QQuickPathItemSoftwareRenderNode(q); - static_cast(renderer)->setNode( - static_cast(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(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(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(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 *list) -{ - QQuickPathGradient *grad = qobject_cast(list->object); - Q_ASSERT(grad); - return grad->m_stops.count(); -} - -QObject *QQuickPathGradient::atStop(QQmlListProperty *list, int index) -{ - QQuickPathGradient *grad = qobject_cast(list->object); - Q_ASSERT(grad); - return grad->m_stops.at(index); -} - -void QQuickPathGradient::appendStop(QQmlListProperty *list, QObject *stop) -{ - QQuickPathGradientStop *sstop = qobject_cast(stop); - if (!sstop) { - qWarning("Gradient stop list only supports QQuickPathGradientStop elements"); - return; - } - QQuickPathGradient *grad = qobject_cast(list->object); - Q_ASSERT(grad); - sstop->setParent(grad); - grad->m_stops.append(sstop); -} - -/*! - \qmlproperty list QtQuick::PathGradient::stops - \default - - The list of PathGradientStop objects defining the colors at given positions - in the gradient. - */ - -QQmlListProperty QQuickPathGradient::stops() -{ - return QQmlListProperty(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(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(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(); - QV4::Scoped 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(); - QV4::Scoped 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 r(scope, callData->thisObject.as()); - - r->d()->obj->clear(); - - scope.result = callData->thisObject.asReturnedValue(); -} - -void QQuickPathItemJSPathPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) -{ - QV4::Scoped r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - 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 r(scope, callData->thisObject.as()); - - QV4::ScopedValue value(scope, callData->argument(0)); - if (value->isObject()) { - QV4::Scoped 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 r(scope, callData->thisObject.as()); - - scope.result = r->d()->obj->v4fillGradient.value(); -} - -void QQuickPathItemJSStrokeFillParams::method_set_fillGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) -{ - QV4::Scoped r(scope, callData->thisObject.as()); - - QV4::ScopedValue value(scope, callData->argument(0)); - QV4::Scoped qobjectWrapper(scope, value); - if (!!qobjectWrapper) { - if (QQuickPathGradient *grad = qobject_cast(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 wrapper(scope, engine->memoryManager->allocObject()); - 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 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 wrapper(scope, engine->memoryManager->allocObject()); - 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 jsp(scope, (*args)[0]); - QV4::Scoped 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 -#include -#include -#include - -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 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 stops(); - - QGradientStops sortedGradientStops() const; - - SpreadMode spread() const; - void setSpread(SpreadMode mode); - -signals: - void updated(); - void spreadChanged(); - -private: - static int countStops(QQmlListProperty *list); - static QObject *atStop(QQmlListProperty *list, int index); - static void appendStop(QQmlListProperty *list, QObject *stop); - - QVector 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 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 dashPattern() const; - void setDashPattern(const QVector &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 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 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 -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QSGPlainTexture; - -struct QQuickPathItemPath -{ - enum Command { - MoveTo, - LineTo, - QuadTo, - CubicTo, - ArcTo - }; - - QVector cmd; - QVector 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 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 &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 vp; - } qmlData; - - struct { - bool isValid() const { Q_ASSERT(paths.count() == sfp.count()); return !paths.isEmpty(); } - QVector paths; - QVector 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 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 -#include -#include - -#ifndef QT_NO_OPENGL -#include -#include -#include -#include -#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 dummyContext; - QScopedPointer 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(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 &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(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(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. 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(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(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(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(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(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 -#include -#include -#include -#include - -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 &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 VertexContainerType; - typedef QVector 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 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 m_solidColorMaterial; - QScopedPointer 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 -#include -#include -#include -#include - -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 &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(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 *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 *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 *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 *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 &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(e)) { - d->path.cmd.append(GL_MOVE_TO_NV); - appendCoords(&d->path.coord, o, &pos); - startPos = pos; - } else if (QQuickPathLine *o = qobject_cast(e)) { - d->path.cmd.append(GL_LINE_TO_NV); - appendCoords(&d->path.coord, o, &pos); - } else if (QQuickPathQuad *o = qobject_cast(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(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(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(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 -#include -#include -#include -#include - -#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 &dashPattern) override; - void setFillGradient(int index, QQuickPathGradient *gradient) override; - void endSync(bool async) override; - - void updateNode() override; - - void setNode(QQuickPathItemNvprRenderNode *node); - - struct NvprPath { - QVector cmd; - QVector 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 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 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 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 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 - -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 &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(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(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 -#include -#include - -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 &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 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 m_vp; - QRectF m_boundingRect; - - friend class QQuickPathItemSoftwareRenderer; -}; - -QT_END_NAMESPACE - -#endif // QQUICKPATHITEMSOFTWARERENDERER_P_H diff --git a/src/quick/util/qquicknvprfunctions.cpp b/src/quick/util/qquicknvprfunctions.cpp deleted file mode 100644 index 40eb2bb932..0000000000 --- a/src/quick/util/qquicknvprfunctions.cpp +++ /dev/null @@ -1,284 +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 "qquicknvprfunctions_p.h" - -#ifndef QT_NO_OPENGL - -#include -#include -#include -#include "qquicknvprfunctions_p_p.h" - -QT_BEGIN_NAMESPACE - -/*! - \class QQuickNvprFunctions - - \brief Function resolvers and other helpers for GL_NV_path_rendering - for both desktop (GL 4.3+) and mobile/embedded (GLES 3.1+) in a manner - that does not distract builds that do not have NVPR support either at - compile or run time. - - \internal - */ - -QQuickNvprFunctions::QQuickNvprFunctions() - : d(new QQuickNvprFunctionsPrivate(this)) -{ -} - -QQuickNvprFunctions::~QQuickNvprFunctions() -{ - delete d; -} - -/*! - \return a recommended QSurfaceFormat suitable for GL_NV_path_rendering on top - of OpenGL 4.3 or OpenGL ES 3.1. - */ -QSurfaceFormat QQuickNvprFunctions::format() -{ - QSurfaceFormat fmt; - fmt.setDepthBufferSize(24); - fmt.setStencilBufferSize(8); - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) { - fmt.setVersion(4, 3); - fmt.setProfile(QSurfaceFormat::CompatibilityProfile); - } else if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { - fmt.setVersion(3, 1); - } - return fmt; -} - -/*! - \return true if GL_NV_path_rendering is supported with the current OpenGL - context. - - When there is no current context, a temporary dummy one will be created and - made current. - */ -bool QQuickNvprFunctions::isSupported() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - QScopedPointer tempContext; - QScopedPointer tempSurface; - if (!ctx) { - tempContext.reset(new QOpenGLContext); - if (!tempContext->create()) - return false; - ctx = tempContext.data(); - tempSurface.reset(new QOffscreenSurface); - tempSurface->setFormat(ctx->format()); - tempSurface->create(); - if (!ctx->makeCurrent(tempSurface.data())) - return false; - } - - if (!ctx->hasExtension(QByteArrayLiteral("GL_NV_path_rendering"))) - return false; - - // Do not check for DSA as the string may not be exposed on ES - // drivers, yet the functions we need are resolvable. -#if 0 - if (!ctx->hasExtension(QByteArrayLiteral("GL_EXT_direct_state_access"))) { - qWarning("QtQuickPath/NVPR: GL_EXT_direct_state_access not supported"); - return false; - } -#endif - - return true; -} - -/*! - Initializes using the current OpenGL context. - - \return true when GL_NV_path_rendering is supported and initialization was - successful. - */ -bool QQuickNvprFunctions::create() -{ - return isSupported() && d->resolve(); -} - -/*! - Creates a program pipeline consisting of a separable fragment shader program. - - This is essential for using NVPR with OpenGL ES 3.1+ since normal, - GLES2-style programs would not work without a vertex shader. - - \note \a fragmentShaderSource should be a \c{version 310 es} shader since - this works both on desktop and embedded NVIDIA drivers, thus avoiding the - need to fight GLSL and GLSL ES differences. - - The pipeline object is stored into \a pipeline, the fragment shader program - into \a program. - - Use QOpenGLExtraFunctions to set uniforms, bind the pipeline, etc. - - \return \c false on failure in which case the error log is printed on the - debug output. \c true on success. - */ -bool QQuickNvprFunctions::createFragmentOnlyPipeline(const char *fragmentShaderSource, GLuint *pipeline, GLuint *program) -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (!ctx) - return false; - - QOpenGLExtraFunctions *f = ctx->extraFunctions(); - *program = f->glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragmentShaderSource); - GLint status = 0; - f->glGetProgramiv(*program, GL_LINK_STATUS, &status); - if (!status) { - GLint len = 0; - f->glGetProgramiv(*program, GL_INFO_LOG_LENGTH, &len); - if (len) { - QByteArray s; - s.resize(len); - f->glGetProgramInfoLog(*program, s.count(), nullptr, s.data()); - qWarning("Failed to create separable shader program:\n%s", s.constData()); - } - return false; - } - - f->glGenProgramPipelines(1, pipeline); - f->glUseProgramStages(*pipeline, GL_FRAGMENT_SHADER_BIT, *program); - f->glActiveShaderProgram(*pipeline, *program); - - f->glValidateProgramPipeline(*pipeline); - status = 0; - f->glGetProgramPipelineiv(*pipeline, GL_VALIDATE_STATUS, &status); - if (!status) { - GLint len = 0; - f->glGetProgramPipelineiv(*pipeline, GL_INFO_LOG_LENGTH, &len); - if (len) { - QByteArray s; - s.resize(len); - f->glGetProgramPipelineInfoLog(*pipeline, s.count(), nullptr, s.data()); - qWarning("Program pipeline validation failed:\n%s", s.constData()); - } - return false; - } - - return true; -} - -#define PROC(type, name) reinterpret_cast(ctx->getProcAddress(#name)) - -bool QQuickNvprFunctionsPrivate::resolve() -{ - QOpenGLContext *ctx = QOpenGLContext::currentContext(); - - q->genPaths = PROC(PFNGLGENPATHSNVPROC, glGenPathsNV); - q->deletePaths = PROC(PFNGLDELETEPATHSNVPROC, glDeletePathsNV); - q->isPath = PROC(PFNGLISPATHNVPROC, glIsPathNV); - q->pathCommands = PROC(PFNGLPATHCOMMANDSNVPROC, glPathCommandsNV); - q->pathCoords = PROC(PFNGLPATHCOORDSNVPROC, glPathCoordsNV); - q->pathSubCommands = PROC(PFNGLPATHSUBCOMMANDSNVPROC, glPathSubCommandsNV); - q->pathSubCoords = PROC(PFNGLPATHSUBCOORDSNVPROC, glPathSubCoordsNV); - q->pathString = PROC(PFNGLPATHSTRINGNVPROC, glPathStringNV); - q->pathGlyphs = PROC(PFNGLPATHGLYPHSNVPROC, glPathGlyphsNV); - q->pathGlyphRange = PROC(PFNGLPATHGLYPHRANGENVPROC, glPathGlyphRangeNV); - q->weightPaths = PROC(PFNGLWEIGHTPATHSNVPROC, glWeightPathsNV); - q->copyPath = PROC(PFNGLCOPYPATHNVPROC, glCopyPathNV); - q->interpolatePaths = PROC(PFNGLINTERPOLATEPATHSNVPROC, glInterpolatePathsNV); - q->transformPath = PROC(PFNGLTRANSFORMPATHNVPROC, glTransformPathNV); - q->pathParameteriv = PROC(PFNGLPATHPARAMETERIVNVPROC, glPathParameterivNV); - q->pathParameteri = PROC(PFNGLPATHPARAMETERINVPROC, glPathParameteriNV); - q->pathParameterfv = PROC(PFNGLPATHPARAMETERFVNVPROC, glPathParameterfvNV); - q->pathParameterf = PROC(PFNGLPATHPARAMETERFNVPROC, glPathParameterfNV); - q->pathDashArray = PROC(PFNGLPATHDASHARRAYNVPROC, glPathDashArrayNV); - q->pathStencilFunc = PROC(PFNGLPATHSTENCILFUNCNVPROC, glPathStencilFuncNV); - q->pathStencilDepthOffset = PROC(PFNGLPATHSTENCILDEPTHOFFSETNVPROC, glPathStencilDepthOffsetNV); - q->stencilFillPath = PROC(PFNGLSTENCILFILLPATHNVPROC, glStencilFillPathNV); - q->stencilStrokePath = PROC(PFNGLSTENCILSTROKEPATHNVPROC, glStencilStrokePathNV); - q->stencilFillPathInstanced = PROC(PFNGLSTENCILFILLPATHINSTANCEDNVPROC, glStencilFillPathInstancedNV); - q->stencilStrokePathInstanced = PROC(PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC, glStencilStrokePathInstancedNV); - q->pathCoverDepthFunc = PROC(PFNGLPATHCOVERDEPTHFUNCNVPROC, glPathCoverDepthFuncNV); - q->pathColorGen = PROC(PFNGLPATHCOLORGENNVPROC, glPathColorGenNV); - q->pathTexGen = PROC(PFNGLPATHTEXGENNVPROC, glPathTexGenNV); - q->pathFogGen = PROC(PFNGLPATHFOGGENNVPROC, glPathFogGenNV); - q->coverFillPath = PROC(PFNGLCOVERFILLPATHNVPROC, glCoverFillPathNV); - q->coverStrokePath = PROC(PFNGLCOVERSTROKEPATHNVPROC, glCoverStrokePathNV); - q->coverFillPathInstanced = PROC(PFNGLCOVERFILLPATHINSTANCEDNVPROC, glCoverFillPathInstancedNV); - q->coverStrokePathInstanced = PROC(PFNGLCOVERSTROKEPATHINSTANCEDNVPROC, glCoverStrokePathInstancedNV); - q->getPathParameteriv = PROC(PFNGLGETPATHPARAMETERIVNVPROC, glGetPathParameterivNV); - q->getPathParameterfv = PROC(PFNGLGETPATHPARAMETERFVNVPROC, glGetPathParameterfvNV); - q->getPathCommands = PROC(PFNGLGETPATHCOMMANDSNVPROC, glGetPathCommandsNV); - q->getPathCoords = PROC(PFNGLGETPATHCOORDSNVPROC, glGetPathCoordsNV); - q->getPathDashArray = PROC(PFNGLGETPATHDASHARRAYNVPROC, glGetPathDashArrayNV); - q->getPathMetrics = PROC(PFNGLGETPATHMETRICSNVPROC, glGetPathMetricsNV); - q->getPathMetricRange = PROC(PFNGLGETPATHMETRICRANGENVPROC, glGetPathMetricRangeNV); - q->getPathSpacing = PROC(PFNGLGETPATHSPACINGNVPROC, glGetPathSpacingNV); - q->getPathColorgeniv = PROC(PFNGLGETPATHCOLORGENIVNVPROC, glGetPathColorGenivNV); - q->getPathColorgenfv = PROC(PFNGLGETPATHCOLORGENFVNVPROC, glGetPathColorGenfvNV); - q->getPathTexGeniv = PROC(PFNGLGETPATHTEXGENIVNVPROC, glGetPathTexGenivNV); - q->getPathTexGenfv = PROC(PFNGLGETPATHTEXGENFVNVPROC, glGetPathTexGenfvNV); - q->isPointInFillPath = PROC(PFNGLISPOINTINFILLPATHNVPROC, glIsPointInFillPathNV); - q->isPointInStrokePath = PROC(PFNGLISPOINTINSTROKEPATHNVPROC, glIsPointInStrokePathNV); - q->getPathLength = PROC(PFNGLGETPATHLENGTHNVPROC, glGetPathLengthNV); - q->getPointAlongPath = PROC(PFNGLPOINTALONGPATHNVPROC, glPointAlongPathNV); - q->matrixLoad3x2f = PROC(PFNGLMATRIXLOAD3X2FNVPROC, glMatrixLoad3x2fNV); - q->matrixLoad3x3f = PROC(PFNGLMATRIXLOAD3X3FNVPROC, glMatrixLoad3x3fNV); - q->matrixLoadTranspose3x3f = PROC(PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC, glMatrixLoadTranspose3x3fNV); - q->matrixMult3x2f = PROC(PFNGLMATRIXMULT3X2FNVPROC, glMatrixMult3x2fNV); - q->matrixMult3x3f = PROC(PFNGLMATRIXMULT3X3FNVPROC, glMatrixMult3x3fNV); - q->matrixMultTranspose3x3f = PROC(PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC, glMatrixMultTranspose3x3fNV); - q->stencilThenCoverFillPath = PROC(PFNGLSTENCILTHENCOVERFILLPATHNVPROC, glStencilThenCoverFillPathNV); - q->stencilThenCoverStrokePath = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC, glStencilThenCoverStrokePathNV); - q->stencilThenCoverFillPathInstanced = PROC(PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC, glStencilThenCoverFillPathInstancedNV); - q->stencilThenCoverStrokePathInstanced = PROC(PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC, glStencilThenCoverStrokePathInstancedNV); - q->pathGlyphIndexRange = PROC(PFNGLPATHGLYPHINDEXRANGENVPROC, glPathGlyphIndexRangeNV); - q->pathGlyphIndexArray = PROC(PFNGLPATHGLYPHINDEXARRAYNVPROC, glPathGlyphIndexArrayNV); - q->pathMemoryGlyphIndexArray = PROC(PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC, glPathMemoryGlyphIndexArrayNV); - q->programPathFragmentInputGen = PROC(PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC, glProgramPathFragmentInputGenNV); - q->getProgramResourcefv = PROC(PFNGLGETPROGRAMRESOURCEFVNVPROC, glGetProgramResourcefvNV); - - q->matrixLoadf = PROC(PFNGLMATRIXLOADFEXTPROC, glMatrixLoadfEXT); - q->matrixLoadIdentity = PROC(PFNGLMATRIXLOADIDENTITYEXTPROC, glMatrixLoadIdentityEXT); - - return q->genPaths != nullptr // base path rendering ext - && q->programPathFragmentInputGen != nullptr // updated path rendering ext - && q->matrixLoadf != nullptr // direct state access ext - && q->matrixLoadIdentity != nullptr; -} - -QT_END_NAMESPACE - -#endif // QT_NO_OPENGL diff --git a/src/quick/util/qquicknvprfunctions_p.h b/src/quick/util/qquicknvprfunctions_p.h deleted file mode 100644 index 7900388305..0000000000 --- a/src/quick/util/qquicknvprfunctions_p.h +++ /dev/null @@ -1,406 +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 QQUICKNVPRFUNCTIONS_P_H -#define QQUICKNVPRFUNCTIONS_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 -#include - -#ifndef QT_NO_OPENGL - -QT_BEGIN_NAMESPACE - -#ifndef GL_NV_path_rendering -#define GL_PATH_FORMAT_SVG_NV 0x9070 -#define GL_PATH_FORMAT_PS_NV 0x9071 -#define GL_STANDARD_FONT_NAME_NV 0x9072 -#define GL_SYSTEM_FONT_NAME_NV 0x9073 -#define GL_FILE_NAME_NV 0x9074 -#define GL_PATH_STROKE_WIDTH_NV 0x9075 -#define GL_PATH_END_CAPS_NV 0x9076 -#define GL_PATH_INITIAL_END_CAP_NV 0x9077 -#define GL_PATH_TERMINAL_END_CAP_NV 0x9078 -#define GL_PATH_JOIN_STYLE_NV 0x9079 -#define GL_PATH_MITER_LIMIT_NV 0x907A -#define GL_PATH_DASH_CAPS_NV 0x907B -#define GL_PATH_INITIAL_DASH_CAP_NV 0x907C -#define GL_PATH_TERMINAL_DASH_CAP_NV 0x907D -#define GL_PATH_DASH_OFFSET_NV 0x907E -#define GL_PATH_CLIENT_LENGTH_NV 0x907F -#define GL_PATH_FILL_MODE_NV 0x9080 -#define GL_PATH_FILL_MASK_NV 0x9081 -#define GL_PATH_FILL_COVER_MODE_NV 0x9082 -#define GL_PATH_STROKE_COVER_MODE_NV 0x9083 -#define GL_PATH_STROKE_MASK_NV 0x9084 -#define GL_COUNT_UP_NV 0x9088 -#define GL_COUNT_DOWN_NV 0x9089 -#define GL_PATH_OBJECT_BOUNDING_BOX_NV 0x908A -#define GL_CONVEX_HULL_NV 0x908B -#define GL_BOUNDING_BOX_NV 0x908D -#define GL_TRANSLATE_X_NV 0x908E -#define GL_TRANSLATE_Y_NV 0x908F -#define GL_TRANSLATE_2D_NV 0x9090 -#define GL_TRANSLATE_3D_NV 0x9091 -#define GL_AFFINE_2D_NV 0x9092 -#define GL_AFFINE_3D_NV 0x9094 -#define GL_TRANSPOSE_AFFINE_2D_NV 0x9096 -#define GL_TRANSPOSE_AFFINE_3D_NV 0x9098 -#define GL_UTF8_NV 0x909A -#define GL_UTF16_NV 0x909B -#define GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV 0x909C -#define GL_PATH_COMMAND_COUNT_NV 0x909D -#define GL_PATH_COORD_COUNT_NV 0x909E -#define GL_PATH_DASH_ARRAY_COUNT_NV 0x909F -#define GL_PATH_COMPUTED_LENGTH_NV 0x90A0 -#define GL_PATH_FILL_BOUNDING_BOX_NV 0x90A1 -#define GL_PATH_STROKE_BOUNDING_BOX_NV 0x90A2 -#define GL_SQUARE_NV 0x90A3 -#define GL_ROUND_NV 0x90A4 -#define GL_TRIANGULAR_NV 0x90A5 -#define GL_BEVEL_NV 0x90A6 -#define GL_MITER_REVERT_NV 0x90A7 -#define GL_MITER_TRUNCATE_NV 0x90A8 -#define GL_SKIP_MISSING_GLYPH_NV 0x90A9 -#define GL_USE_MISSING_GLYPH_NV 0x90AA -#define GL_PATH_ERROR_POSITION_NV 0x90AB -#define GL_PATH_FOG_GEN_MODE_NV 0x90AC -#define GL_ACCUM_ADJACENT_PAIRS_NV 0x90AD -#define GL_ADJACENT_PAIRS_NV 0x90AE -#define GL_FIRST_TO_REST_NV 0x90AF -#define GL_PATH_GEN_MODE_NV 0x90B0 -#define GL_PATH_GEN_COEFF_NV 0x90B1 -#define GL_PATH_GEN_COLOR_FORMAT_NV 0x90B2 -#define GL_PATH_GEN_COMPONENTS_NV 0x90B3 -#define GL_PATH_STENCIL_FUNC_NV 0x90B7 -#define GL_PATH_STENCIL_REF_NV 0x90B8 -#define GL_PATH_STENCIL_VALUE_MASK_NV 0x90B9 -#define GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV 0x90BD -#define GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV 0x90BE -#define GL_PATH_COVER_DEPTH_FUNC_NV 0x90BF -#define GL_PATH_DASH_OFFSET_RESET_NV 0x90B4 -#define GL_MOVE_TO_RESETS_NV 0x90B5 -#define GL_MOVE_TO_CONTINUES_NV 0x90B6 -#define GL_CLOSE_PATH_NV 0x00 -#define GL_MOVE_TO_NV 0x02 -#define GL_RELATIVE_MOVE_TO_NV 0x03 -#define GL_LINE_TO_NV 0x04 -#define GL_RELATIVE_LINE_TO_NV 0x05 -#define GL_HORIZONTAL_LINE_TO_NV 0x06 -#define GL_RELATIVE_HORIZONTAL_LINE_TO_NV 0x07 -#define GL_VERTICAL_LINE_TO_NV 0x08 -#define GL_RELATIVE_VERTICAL_LINE_TO_NV 0x09 -#define GL_QUADRATIC_CURVE_TO_NV 0x0A -#define GL_RELATIVE_QUADRATIC_CURVE_TO_NV 0x0B -#define GL_CUBIC_CURVE_TO_NV 0x0C -#define GL_RELATIVE_CUBIC_CURVE_TO_NV 0x0D -#define GL_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0E -#define GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV 0x0F -#define GL_SMOOTH_CUBIC_CURVE_TO_NV 0x10 -#define GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV 0x11 -#define GL_SMALL_CCW_ARC_TO_NV 0x12 -#define GL_RELATIVE_SMALL_CCW_ARC_TO_NV 0x13 -#define GL_SMALL_CW_ARC_TO_NV 0x14 -#define GL_RELATIVE_SMALL_CW_ARC_TO_NV 0x15 -#define GL_LARGE_CCW_ARC_TO_NV 0x16 -#define GL_RELATIVE_LARGE_CCW_ARC_TO_NV 0x17 -#define GL_LARGE_CW_ARC_TO_NV 0x18 -#define GL_RELATIVE_LARGE_CW_ARC_TO_NV 0x19 -#define GL_RESTART_PATH_NV 0xF0 -#define GL_DUP_FIRST_CUBIC_CURVE_TO_NV 0xF2 -#define GL_DUP_LAST_CUBIC_CURVE_TO_NV 0xF4 -#define GL_RECT_NV 0xF6 -#define GL_CIRCULAR_CCW_ARC_TO_NV 0xF8 -#define GL_CIRCULAR_CW_ARC_TO_NV 0xFA -#define GL_CIRCULAR_TANGENT_ARC_TO_NV 0xFC -#define GL_ARC_TO_NV 0xFE -#define GL_RELATIVE_ARC_TO_NV 0xFF -#define GL_BOLD_BIT_NV 0x01 -#define GL_ITALIC_BIT_NV 0x02 -#define GL_GLYPH_WIDTH_BIT_NV 0x01 -#define GL_GLYPH_HEIGHT_BIT_NV 0x02 -#define GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV 0x04 -#define GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV 0x08 -#define GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV 0x10 -#define GL_GLYPH_VERTICAL_BEARING_X_BIT_NV 0x20 -#define GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV 0x40 -#define GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV 0x80 -#define GL_GLYPH_HAS_KERNING_BIT_NV 0x100 -#define GL_FONT_X_MIN_BOUNDS_BIT_NV 0x00010000 -#define GL_FONT_Y_MIN_BOUNDS_BIT_NV 0x00020000 -#define GL_FONT_X_MAX_BOUNDS_BIT_NV 0x00040000 -#define GL_FONT_Y_MAX_BOUNDS_BIT_NV 0x00080000 -#define GL_FONT_UNITS_PER_EM_BIT_NV 0x00100000 -#define GL_FONT_ASCENDER_BIT_NV 0x00200000 -#define GL_FONT_DESCENDER_BIT_NV 0x00400000 -#define GL_FONT_HEIGHT_BIT_NV 0x00800000 -#define GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV 0x01000000 -#define GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV 0x02000000 -#define GL_FONT_UNDERLINE_POSITION_BIT_NV 0x04000000 -#define GL_FONT_UNDERLINE_THICKNESS_BIT_NV 0x08000000 -#define GL_FONT_HAS_KERNING_BIT_NV 0x10000000 -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_ROUNDED_RECT_NV 0xE8 -#define GL_RELATIVE_ROUNDED_RECT_NV 0xE9 -#define GL_ROUNDED_RECT2_NV 0xEA -#define GL_RELATIVE_ROUNDED_RECT2_NV 0xEB -#define GL_ROUNDED_RECT4_NV 0xEC -#define GL_RELATIVE_ROUNDED_RECT4_NV 0xED -#define GL_ROUNDED_RECT8_NV 0xEE -#define GL_RELATIVE_ROUNDED_RECT8_NV 0xEF -#define GL_RELATIVE_RECT_NV 0xF7 -#define GL_FONT_GLYPHS_AVAILABLE_NV 0x9368 -#define GL_FONT_TARGET_UNAVAILABLE_NV 0x9369 -#define GL_FONT_UNAVAILABLE_NV 0x936A -#define GL_FONT_UNINTELLIGIBLE_NV 0x936B -#define GL_CONIC_CURVE_TO_NV 0x1A -#define GL_RELATIVE_CONIC_CURVE_TO_NV 0x1B -#define GL_FONT_NUM_GLYPH_INDICES_BIT_NV 0x20000000 -#define GL_STANDARD_FONT_FORMAT_NV 0x936C -#define GL_2_BYTES_NV 0x1407 -#define GL_3_BYTES_NV 0x1408 -#define GL_4_BYTES_NV 0x1409 -#define GL_EYE_LINEAR_NV 0x2400 -#define GL_OBJECT_LINEAR_NV 0x2401 -#define GL_CONSTANT_NV 0x8576 -#define GL_PATH_PROJECTION_NV 0x1701 -#define GL_PATH_MODELVIEW_NV 0x1700 -#define GL_PATH_MODELVIEW_STACK_DEPTH_NV 0x0BA3 -#define GL_PATH_MODELVIEW_MATRIX_NV 0x0BA6 -#define GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV 0x0D36 -#define GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV 0x84E3 -#define GL_PATH_PROJECTION_STACK_DEPTH_NV 0x0BA4 -#define GL_PATH_PROJECTION_MATRIX_NV 0x0BA7 -#define GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV 0x0D38 -#define GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV 0x84E4 -#define GL_FRAGMENT_INPUT_NV 0x936D - -typedef GLuint (QOPENGLF_APIENTRYP PFNGLGENPATHSNVPROC) (GLsizei range); -typedef void (QOPENGLF_APIENTRYP PFNGLDELETEPATHSNVPROC) (GLuint path, GLsizei range); -typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPATHNVPROC) (GLuint path); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOMMANDSNVPROC) (GLuint path, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOORDSNVPROC) (GLuint path, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHSUBCOMMANDSNVPROC) (GLuint path, GLsizei commandStart, GLsizei commandsToDelete, GLsizei numCommands, const GLubyte *commands, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHSUBCOORDSNVPROC) (GLuint path, GLsizei coordStart, GLsizei numCoords, GLenum coordType, const void *coords); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTRINGNVPROC) (GLuint path, GLenum format, GLsizei length, const void *pathString); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHGLYPHSNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLsizei numGlyphs, GLenum type, const void *charcodes, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHGLYPHRANGENVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyph, GLsizei numGlyphs, GLenum handleMissingGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (QOPENGLF_APIENTRYP PFNGLWEIGHTPATHSNVPROC) (GLuint resultPath, GLsizei numPaths, const GLuint *paths, const GLfloat *weights); -typedef void (QOPENGLF_APIENTRYP PFNGLCOPYPATHNVPROC) (GLuint resultPath, GLuint srcPath); -typedef void (QOPENGLF_APIENTRYP PFNGLINTERPOLATEPATHSNVPROC) (GLuint resultPath, GLuint pathA, GLuint pathB, GLfloat weight); -typedef void (QOPENGLF_APIENTRYP PFNGLTRANSFORMPATHNVPROC) (GLuint resultPath, GLuint srcPath, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, const GLint *value); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERINVPROC) (GLuint path, GLenum pname, GLint value); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, const GLfloat *value); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHPARAMETERFNVPROC) (GLuint path, GLenum pname, GLfloat value); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHDASHARRAYNVPROC) (GLuint path, GLsizei dashCount, const GLfloat *dashArray); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTENCILFUNCNVPROC) (GLenum func, GLint ref, GLuint mask); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHSTENCILDEPTHOFFSETNVPROC) (GLfloat factor, GLfloat units); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOVERDEPTHFUNCNVPROC) (GLenum func); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHCOLORGENNVPROC) (GLenum color, GLenum genMode, GLenum colorFormat, const GLfloat *coeffs); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHTEXGENNVPROC) (GLenum texCoordSet, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (QOPENGLF_APIENTRYP PFNGLPATHFOGGENNVPROC) (GLenum genMode); -typedef void (QOPENGLF_APIENTRYP PFNGLCOVERFILLPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (QOPENGLF_APIENTRYP PFNGLCOVERSTROKEPATHNVPROC) (GLuint path, GLenum coverMode); -typedef void (QOPENGLF_APIENTRYP PFNGLCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHPARAMETERIVNVPROC) (GLuint path, GLenum pname, GLint *value); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHPARAMETERFVNVPROC) (GLuint path, GLenum pname, GLfloat *value); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOMMANDSNVPROC) (GLuint path, GLubyte *commands); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOORDSNVPROC) (GLuint path, GLfloat *coords); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHDASHARRAYNVPROC) (GLuint path, GLfloat *dashArray); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHMETRICSNVPROC) (GLbitfield metricQueryMask, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLsizei stride, GLfloat *metrics); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHMETRICRANGENVPROC) (GLbitfield metricQueryMask, GLuint firstPathName, GLsizei numPaths, GLsizei stride, GLfloat *metrics); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHSPACINGNVPROC) (GLenum pathListMode, GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, GLenum transformType, GLfloat *returnedSpacing); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOLORGENIVNVPROC) (GLenum color, GLenum pname, GLint *value); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHCOLORGENFVNVPROC) (GLenum color, GLenum pname, GLfloat *value); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHTEXGENIVNVPROC) (GLenum texCoordSet, GLenum pname, GLint *value); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPATHTEXGENFVNVPROC) (GLenum texCoordSet, GLenum pname, GLfloat *value); -typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPOINTINFILLPATHNVPROC) (GLuint path, GLuint mask, GLfloat x, GLfloat y); -typedef GLboolean (QOPENGLF_APIENTRYP PFNGLISPOINTINSTROKEPATHNVPROC) (GLuint path, GLfloat x, GLfloat y); -typedef GLfloat (QOPENGLF_APIENTRYP PFNGLGETPATHLENGTHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments); -typedef GLboolean (QOPENGLF_APIENTRYP PFNGLPOINTALONGPATHNVPROC) (GLuint path, GLsizei startSegment, GLsizei numSegments, GLfloat distance, GLfloat *x, GLfloat *y, GLfloat *tangentX, GLfloat *tangentY); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOAD3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOAD3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULT3X2FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULT3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC) (GLenum matrixMode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHNVPROC) (GLuint path, GLenum fillMode, GLuint mask, GLenum coverMode); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC) (GLuint path, GLint reference, GLuint mask, GLenum coverMode); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLenum fillMode, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef void (QOPENGLF_APIENTRYP PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC) (GLsizei numPaths, GLenum pathNameType, const void *paths, GLuint pathBase, GLint reference, GLuint mask, GLenum coverMode, GLenum transformType, const GLfloat *transformValues); -typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHGLYPHINDEXRANGENVPROC) (GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint pathParameterTemplate, GLfloat emScale, GLuint baseAndCount[2]); -typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, const void *fontName, GLbitfield fontStyle, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef GLenum (QOPENGLF_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale); -typedef void (QOPENGLF_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs); -typedef void (QOPENGLF_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params); -#endif - -#ifndef GL_FLAT -#define GL_FLAT 0x1D00 -#endif - -#ifndef GL_INVERT -#define GL_INVERT 0x150A -#endif - -#ifndef GL_EXT_direct_state_access -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (QOPENGLF_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); -#endif - -// When building on a system with GLES 2.0 or 3.0, we may still compile the NVPR -// code path even though it's never used. Keep it compiling by defining the -// necessary ES 3.1 separable program constants. -#ifndef GL_FRAGMENT_SHADER_BIT -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#endif -#ifndef GL_UNIFORM -#define GL_UNIFORM 0x92E1 -#endif - -class QQuickNvprFunctionsPrivate; - -class QQuickNvprFunctions -{ -public: - QQuickNvprFunctions(); - ~QQuickNvprFunctions(); - - static QSurfaceFormat format(); - static bool isSupported(); - - bool create(); - - bool createFragmentOnlyPipeline(const char *fragmentShaderSource, GLuint *pipeline, GLuint *program); - - PFNGLGENPATHSNVPROC genPaths = nullptr; - PFNGLDELETEPATHSNVPROC deletePaths = nullptr; - PFNGLISPATHNVPROC isPath = nullptr; - PFNGLPATHCOMMANDSNVPROC pathCommands = nullptr; - PFNGLPATHCOORDSNVPROC pathCoords = nullptr; - PFNGLPATHSUBCOMMANDSNVPROC pathSubCommands = nullptr; - PFNGLPATHSUBCOORDSNVPROC pathSubCoords = nullptr; - PFNGLPATHSTRINGNVPROC pathString = nullptr; - PFNGLPATHGLYPHSNVPROC pathGlyphs = nullptr; - PFNGLPATHGLYPHRANGENVPROC pathGlyphRange = nullptr; - PFNGLWEIGHTPATHSNVPROC weightPaths = nullptr; - PFNGLCOPYPATHNVPROC copyPath = nullptr; - PFNGLINTERPOLATEPATHSNVPROC interpolatePaths = nullptr; - PFNGLTRANSFORMPATHNVPROC transformPath = nullptr; - PFNGLPATHPARAMETERIVNVPROC pathParameteriv = nullptr; - PFNGLPATHPARAMETERINVPROC pathParameteri = nullptr; - PFNGLPATHPARAMETERFVNVPROC pathParameterfv = nullptr; - PFNGLPATHPARAMETERFNVPROC pathParameterf = nullptr; - PFNGLPATHDASHARRAYNVPROC pathDashArray = nullptr; - PFNGLPATHSTENCILFUNCNVPROC pathStencilFunc = nullptr; - PFNGLPATHSTENCILDEPTHOFFSETNVPROC pathStencilDepthOffset = nullptr; - PFNGLSTENCILFILLPATHNVPROC stencilFillPath = nullptr; - PFNGLSTENCILSTROKEPATHNVPROC stencilStrokePath = nullptr; - PFNGLSTENCILFILLPATHINSTANCEDNVPROC stencilFillPathInstanced = nullptr; - PFNGLSTENCILSTROKEPATHINSTANCEDNVPROC stencilStrokePathInstanced = nullptr; - PFNGLPATHCOVERDEPTHFUNCNVPROC pathCoverDepthFunc = nullptr; - PFNGLPATHCOLORGENNVPROC pathColorGen = nullptr; - PFNGLPATHTEXGENNVPROC pathTexGen = nullptr; - PFNGLPATHFOGGENNVPROC pathFogGen = nullptr; - PFNGLCOVERFILLPATHNVPROC coverFillPath = nullptr; - PFNGLCOVERSTROKEPATHNVPROC coverStrokePath = nullptr; - PFNGLCOVERFILLPATHINSTANCEDNVPROC coverFillPathInstanced = nullptr; - PFNGLCOVERSTROKEPATHINSTANCEDNVPROC coverStrokePathInstanced = nullptr; - PFNGLGETPATHPARAMETERIVNVPROC getPathParameteriv = nullptr; - PFNGLGETPATHPARAMETERFVNVPROC getPathParameterfv = nullptr; - PFNGLGETPATHCOMMANDSNVPROC getPathCommands = nullptr; - PFNGLGETPATHCOORDSNVPROC getPathCoords = nullptr; - PFNGLGETPATHDASHARRAYNVPROC getPathDashArray = nullptr; - PFNGLGETPATHMETRICSNVPROC getPathMetrics = nullptr; - PFNGLGETPATHMETRICRANGENVPROC getPathMetricRange = nullptr; - PFNGLGETPATHSPACINGNVPROC getPathSpacing = nullptr; - PFNGLGETPATHCOLORGENIVNVPROC getPathColorgeniv = nullptr; - PFNGLGETPATHCOLORGENFVNVPROC getPathColorgenfv = nullptr; - PFNGLGETPATHTEXGENIVNVPROC getPathTexGeniv = nullptr; - PFNGLGETPATHTEXGENFVNVPROC getPathTexGenfv = nullptr; - PFNGLISPOINTINFILLPATHNVPROC isPointInFillPath = nullptr; - PFNGLISPOINTINSTROKEPATHNVPROC isPointInStrokePath = nullptr; - PFNGLGETPATHLENGTHNVPROC getPathLength = nullptr; - PFNGLPOINTALONGPATHNVPROC getPointAlongPath = nullptr; - PFNGLMATRIXLOAD3X2FNVPROC matrixLoad3x2f = nullptr; - PFNGLMATRIXLOAD3X3FNVPROC matrixLoad3x3f = nullptr; - PFNGLMATRIXLOADTRANSPOSE3X3FNVPROC matrixLoadTranspose3x3f = nullptr; - PFNGLMATRIXMULT3X2FNVPROC matrixMult3x2f = nullptr; - PFNGLMATRIXMULT3X3FNVPROC matrixMult3x3f = nullptr; - PFNGLMATRIXMULTTRANSPOSE3X3FNVPROC matrixMultTranspose3x3f = nullptr; - PFNGLSTENCILTHENCOVERFILLPATHNVPROC stencilThenCoverFillPath = nullptr; - PFNGLSTENCILTHENCOVERSTROKEPATHNVPROC stencilThenCoverStrokePath = nullptr; - PFNGLSTENCILTHENCOVERFILLPATHINSTANCEDNVPROC stencilThenCoverFillPathInstanced = nullptr; - PFNGLSTENCILTHENCOVERSTROKEPATHINSTANCEDNVPROC stencilThenCoverStrokePathInstanced = nullptr; - PFNGLPATHGLYPHINDEXRANGENVPROC pathGlyphIndexRange = nullptr; - PFNGLPATHGLYPHINDEXARRAYNVPROC pathGlyphIndexArray = nullptr; - PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC pathMemoryGlyphIndexArray = nullptr; - PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC programPathFragmentInputGen = nullptr; - PFNGLGETPROGRAMRESOURCEFVNVPROC getProgramResourcefv = nullptr; - - PFNGLMATRIXLOADFEXTPROC matrixLoadf = nullptr; - PFNGLMATRIXLOADIDENTITYEXTPROC matrixLoadIdentity = nullptr; - -private: - QQuickNvprFunctionsPrivate *d; -}; - -QT_END_NAMESPACE - -#endif // QT_NO_OPENGL - -#endif // QQUICKNVPRFUNCTIONS_P_H diff --git a/src/quick/util/qquicknvprfunctions_p_p.h b/src/quick/util/qquicknvprfunctions_p_p.h deleted file mode 100644 index 6df20566af..0000000000 --- a/src/quick/util/qquicknvprfunctions_p_p.h +++ /dev/null @@ -1,70 +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 QQUICKNVPRFUNCTIONS_P_P_H -#define QQUICKNVPRFUNCTIONS_P_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 "qquicknvprfunctions_p.h" - -QT_BEGIN_NAMESPACE - -class QQuickNvprFunctionsPrivate -{ -public: - QQuickNvprFunctionsPrivate(QQuickNvprFunctions *q_ptr) : q(q_ptr) { } - - bool resolve(); - - QQuickNvprFunctions *q; -}; - -QT_END_NAMESPACE - -#endif // QQUICKNVPRFUNCTIONS_P_P_H diff --git a/src/quick/util/qquicksvgparser_p.h b/src/quick/util/qquicksvgparser_p.h index 44b0d1b6dd..1777b99bf4 100644 --- a/src/quick/util/qquicksvgparser_p.h +++ b/src/quick/util/qquicksvgparser_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include #include #include @@ -59,9 +60,9 @@ QT_BEGIN_NAMESPACE namespace QQuickSvgParser { bool parsePathDataFast(const QString &dataStr, QPainterPath &path); - void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation, - int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx, - qreal cury); + Q_QUICK_PRIVATE_EXPORT void pathArc(QPainterPath &path, qreal rx, qreal ry, qreal x_axis_rotation, + int large_arc_flag, int sweep_flag, qreal x, qreal y, qreal curx, + qreal cury); } QT_END_NAMESPACE diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri index 56eb8ea3b7..b53b132cce 100644 --- a/src/quick/util/util.pri +++ b/src/quick/util/util.pri @@ -79,11 +79,4 @@ qtConfig(quick-path) { $$PWD/qquickpath_p.h \ $$PWD/qquickpath_p_p.h \ $$PWD/qquickpathinterpolator_p.h - qtConfig(opengl) { - SOURCES += \ - $$PWD/qquicknvprfunctions.cpp - HEADERS += \ - $$PWD/qquicknvprfunctions_p.h \ - $$PWD/qquicknvprfunctions_p_p.h - } } -- cgit v1.2.3