Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include <private/qquickvaluetypes_p.h>
++
++ #include <qtquickglobal.h>
++ #include <private/qqmlvaluetype_p.h>
++ #include <private/qqmlstringconverters_p.h>
++ #include <private/qcolorspace_p.h>
++ #include <private/qfont_p.h>
++
++ QT_BEGIN_NAMESPACE
++
++ QQuickColorValueType::QQuickColorValueType(const QString &string)
++ : QColor(QColor::fromString(string))
++ {
++ }
++
++ QVariant QQuickColorValueType::create(const QJSValue &params)
++ {
++ return params.isString() ? QColor::fromString(params.toString()) : QVariant();
++ }
++
++ QString QQuickColorValueType::toString() const
++ {
++ return QColor::name(QColor::alpha() != 255 ? QColor::HexArgb : QColor::HexRgb);
++ }
++
++ int QQuickColorValueType::rgba() const
++ {
++ return QColor::rgba();
++ }
++
++ QColor QQuickColorValueType::lighter(qreal factor) const
++ {
++ if (std::isnan(factor)) {
++ qWarning("NaN given as argument to color.lighter()");
++ return QColor();
++ }
++
++ return QColor::lighter(int(qRound(factor*100.)));
++ }
++
++ QColor QQuickColorValueType::darker(qreal factor) const
++ {
++ if (std::isnan(factor)) {
++ qWarning("NaN given as argument to color.darker()");
++ return QColor();
++ }
++
++ return QColor::darker(int(qRound(factor*100.)));
++ }
++
++ QColor QQuickColorValueType::alpha(qreal value) const
++ {
++ QColor color = *this;
++ color.setAlphaF(value);
++ return color;
++ }
++
++ QColor QQuickColorValueType::tint(const QColor &tintColor) const
++ {
++ int tintAlpha = tintColor.alpha();
++ if (tintAlpha == 0xFF)
++ return tintColor;
++ else if (tintAlpha == 0x00)
++ return *this;
++
++ // tint the base color and return the final color
++ const QColor baseColor = QColor::toRgb();
++ const qreal a = tintColor.alphaF();
++ const qreal inv_a = 1.0 - a;
++
++ const qreal r = tintColor.redF() * a + baseColor.redF() * inv_a;
++ const qreal g = tintColor.greenF() * a + baseColor.greenF() * inv_a;
++ const qreal b = tintColor.blueF() * a + baseColor.blueF() * inv_a;
++
++ return QColor::fromRgbF(r, g, b, a + inv_a * baseColor.alphaF());
++ }
++
++ qreal QQuickColorValueType::r() const
++ {
++ return QColor::redF();
++ }
++
++ qreal QQuickColorValueType::g() const
++ {
++ return QColor::greenF();
++ }
++
++ qreal QQuickColorValueType::b() const
++ {
++ return QColor::blueF();
++ }
++
++ qreal QQuickColorValueType::a() const
++ {
++ return QColor::alphaF();
++ }
++
++ qreal QQuickColorValueType::hsvHue() const
++ {
++ return QColor::hsvHueF();
++ }
++
++ qreal QQuickColorValueType::hsvSaturation() const
++ {
++ return QColor::hsvSaturationF();
++ }
++
++ qreal QQuickColorValueType::hsvValue() const
++ {
++ return QColor::valueF();
++ }
++
++ qreal QQuickColorValueType::hslHue() const
++ {
++ return QColor::hslHueF();
++ }
++
++ qreal QQuickColorValueType::hslSaturation() const
++ {
++ return QColor::hslSaturationF();
++ }
++
++ qreal QQuickColorValueType::hslLightness() const
++ {
++ return QColor::lightnessF();
++ }
++
++ bool QQuickColorValueType::isValid() const
++ {
++ return QColor::isValid();
++ }
++
++ void QQuickColorValueType::setR(qreal r)
++ {
++ QColor::setRedF(r);
++ }
++
++ void QQuickColorValueType::setG(qreal g)
++ {
++ QColor::setGreenF(g);
++ }
++
++ void QQuickColorValueType::setB(qreal b)
++ {
++ QColor::setBlueF(b);
++ }
++
++ void QQuickColorValueType::setA(qreal a)
++ {
++ QColor::setAlphaF(a);
++ }
++
++ void QQuickColorValueType::setHsvHue(qreal hsvHue)
++ {
++ float hue, saturation, value, alpha;
++ QColor::getHsvF(&hue, &saturation, &value, &alpha);
++ QColor::setHsvF(hsvHue, saturation, value, alpha);
++ }
++
++ void QQuickColorValueType::setHsvSaturation(qreal hsvSaturation)
++ {
++ float hue, saturation, value, alpha;
++ QColor::getHsvF(&hue, &saturation, &value, &alpha);
++ QColor::setHsvF(hue, hsvSaturation, value, alpha);
++ }
++
++ void QQuickColorValueType::setHsvValue(qreal hsvValue)
++ {
++ float hue, saturation, value, alpha;
++ QColor::getHsvF(&hue, &saturation, &value, &alpha);
++ QColor::setHsvF(hue, saturation, hsvValue, alpha);
++ }
++
++ void QQuickColorValueType::setHslHue(qreal hslHue)
++ {
++ float hue, saturation, lightness, alpha;
++ QColor::getHslF(&hue, &saturation, &lightness, &alpha);
++ QColor::setHslF(hslHue, saturation, lightness, alpha);
++ }
++
++ void QQuickColorValueType::setHslSaturation(qreal hslSaturation)
++ {
++ float hue, saturation, lightness, alpha;
++ QColor::getHslF(&hue, &saturation, &lightness, &alpha);
++ QColor::setHslF(hue, hslSaturation, lightness, alpha);
++ }
++
++ void QQuickColorValueType::setHslLightness(qreal hslLightness)
++ {
++ float hue, saturation, lightness, alpha;
++ QColor::getHslF(&hue, &saturation, &lightness, &alpha);
++ QColor::setHslF(hue, saturation, hslLightness, alpha);
++ }
++
++ QVariant QQuickVector2DValueType::create(const QJSValue &params)
++ {
++ if (params.isString())
++ return QQmlStringConverters::valueTypeFromNumberString<QVector2D, 2, u','>(params.toString());
++ if (params.isArray())
++ return QVector2D(params.property(0).toNumber(), params.property(1).toNumber());
++ return QVariant();
++ }
++
++ QString QQuickVector2DValueType::toString() const
++ {
++ return QString::fromLatin1("QVector2D(%1, %2)").arg(QVector2D::x()).arg(QVector2D::y());
++ }
++
++ qreal QQuickVector2DValueType::x() const
++ {
++ return QVector2D::x();
++ }
++
++ qreal QQuickVector2DValueType::y() const
++ {
++ return QVector2D::y();
++ }
++
++ void QQuickVector2DValueType::setX(qreal x)
++ {
++ QVector2D::setX(x);
++ }
++
++ void QQuickVector2DValueType::setY(qreal y)
++ {
++ QVector2D::setY(y);
++ }
++
++ qreal QQuickVector2DValueType::dotProduct(const QVector2D &vec) const
++ {
++ return QVector2D::dotProduct(*this, vec);
++ }
++
++ QVector2D QQuickVector2DValueType::times(const QVector2D &vec) const
++ {
++ return *this * vec;
++ }
++
++ QVector2D QQuickVector2DValueType::times(qreal scalar) const
++ {
++ return *this * scalar;
++ }
++
++ QVector2D QQuickVector2DValueType::plus(const QVector2D &vec) const
++ {
++ return *this + vec;
++ }
++
++ QVector2D QQuickVector2DValueType::minus(const QVector2D &vec) const
++ {
++ return *this - vec;
++ }
++
++ QVector2D QQuickVector2DValueType::normalized() const
++ {
++ return QVector2D::normalized();
++ }
++
++ qreal QQuickVector2DValueType::length() const
++ {
++ return QVector2D::length();
++ }
++
++ QVector3D QQuickVector2DValueType::toVector3d() const
++ {
++ return QVector2D::toVector3D();
++ }
++
++ QVector4D QQuickVector2DValueType::toVector4d() const
++ {
++ return QVector2D::toVector4D();
++ }
++
++ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec, qreal epsilon) const
++ {
++ qreal absEps = qAbs(epsilon);
++ if (qAbs(QVector2D::x() - vec.x()) > absEps)
++ return false;
++ if (qAbs(QVector2D::y() - vec.y()) > absEps)
++ return false;
++ return true;
++ }
++
++ bool QQuickVector2DValueType::fuzzyEquals(const QVector2D &vec) const
++ {
++ return qFuzzyCompare(*this, vec);
++ }
++
++ QVariant QQuickVector3DValueType::create(const QJSValue &params)
++ {
++ if (params.isString()) {
++ return QQmlStringConverters::valueTypeFromNumberString<QVector3D, 3, u',', u','>(
++ params.toString());
++ }
++
++ if (params.isArray()) {
++ return QVector3D(params.property(0).toNumber(), params.property(1).toNumber(),
++ params.property(2).toNumber());
++ }
++ return QVariant();
++ }
++
++ QString QQuickVector3DValueType::toString() const
++ {
++ return QString::fromLatin1("QVector3D(%1, %2, %3)")
++ .arg(QVector3D::x()).arg(QVector3D::y()).arg(QVector3D::z());
++ }
++
++ qreal QQuickVector3DValueType::x() const
++ {
++ return QVector3D::x();
++ }
++
++ qreal QQuickVector3DValueType::y() const
++ {
++ return QVector3D::y();
++ }
++
++ qreal QQuickVector3DValueType::z() const
++ {
++ return QVector3D::z();
++ }
++
++ void QQuickVector3DValueType::setX(qreal x)
++ {
++ QVector3D::setX(x);
++ }
++
++ void QQuickVector3DValueType::setY(qreal y)
++ {
++ QVector3D::setY(y);
++ }
++
++ void QQuickVector3DValueType::setZ(qreal z)
++ {
++ QVector3D::setZ(z);
++ }
++
++ QVector3D QQuickVector3DValueType::crossProduct(const QVector3D &vec) const
++ {
++ return QVector3D::crossProduct(*this, vec);
++ }
++
++ qreal QQuickVector3DValueType::dotProduct(const QVector3D &vec) const
++ {
++ return QVector3D::dotProduct(*this, vec);
++ }
++
++ QVector3D QQuickVector3DValueType::times(const QMatrix4x4 &m) const
++ {
++ return (QVector4D(*this, 1) * m).toVector3DAffine();
++ }
++
++ QVector3D QQuickVector3DValueType::times(const QVector3D &vec) const
++ {
++ return *this * vec;
++ }
++
++ QVector3D QQuickVector3DValueType::times(qreal scalar) const
++ {
++ return *this * scalar;
++ }
++
++ QVector3D QQuickVector3DValueType::plus(const QVector3D &vec) const
++ {
++ return *this + vec;
++ }
++
++ QVector3D QQuickVector3DValueType::minus(const QVector3D &vec) const
++ {
++ return *this - vec;
++ }
++
++ QVector3D QQuickVector3DValueType::normalized() const
++ {
++ return QVector3D::normalized();
++ }
++
++ qreal QQuickVector3DValueType::length() const
++ {
++ return QVector3D::length();
++ }
++
++ QVector2D QQuickVector3DValueType::toVector2d() const
++ {
++ return QVector3D::toVector2D();
++ }
++
++ QVector4D QQuickVector3DValueType::toVector4d() const
++ {
++ return QVector3D::toVector4D();
++ }
++
++ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec, qreal epsilon) const
++ {
++ qreal absEps = qAbs(epsilon);
++ if (qAbs(QVector3D::x() - vec.x()) > absEps)
++ return false;
++ if (qAbs(QVector3D::y() - vec.y()) > absEps)
++ return false;
++ if (qAbs(QVector3D::z() - vec.z()) > absEps)
++ return false;
++ return true;
++ }
++
++ bool QQuickVector3DValueType::fuzzyEquals(const QVector3D &vec) const
++ {
++ return qFuzzyCompare(*this, vec);
++ }
++
++ QVariant QQuickVector4DValueType::create(const QJSValue &params)
++ {
++ if (params.isString()) {
++ return QQmlStringConverters::valueTypeFromNumberString<QVector4D, 4, u',', u',', u','>(
++ params.toString());
++ }
++
++ if (params.isArray()) {
++ return QVector4D(params.property(0).toNumber(), params.property(1).toNumber(),
++ params.property(2).toNumber(), params.property(3).toNumber());
++ }
++
++ return QVariant();
++ }
++
++ QString QQuickVector4DValueType::toString() const
++ {
++ return QString::fromLatin1("QVector4D(%1, %2, %3, %4)")
++ .arg(QVector4D::x()).arg(QVector4D::y()).arg(QVector4D::z()).arg(QVector4D::w());
++ }
++
++ qreal QQuickVector4DValueType::x() const
++ {
++ return QVector4D::x();
++ }
++
++ qreal QQuickVector4DValueType::y() const
++ {
++ return QVector4D::y();
++ }
++
++ qreal QQuickVector4DValueType::z() const
++ {
++ return QVector4D::z();
++ }
++
++ qreal QQuickVector4DValueType::w() const
++ {
++ return QVector4D::w();
++ }
++
++ void QQuickVector4DValueType::setX(qreal x)
++ {
++ QVector4D::setX(x);
++ }
++
++ void QQuickVector4DValueType::setY(qreal y)
++ {
++ QVector4D::setY(y);
++ }
++
++ void QQuickVector4DValueType::setZ(qreal z)
++ {
++ QVector4D::setZ(z);
++ }
++
++ void QQuickVector4DValueType::setW(qreal w)
++ {
++ QVector4D::setW(w);
++ }
++
++ qreal QQuickVector4DValueType::dotProduct(const QVector4D &vec) const
++ {
++ return QVector4D::dotProduct(*this, vec);
++ }
++
++ QVector4D QQuickVector4DValueType::times(const QVector4D &vec) const
++ {
++ return *this * vec;
++ }
++
++ QVector4D QQuickVector4DValueType::times(const QMatrix4x4 &m) const
++ {
++ return *this * m;
++ }
++
++ QVector4D QQuickVector4DValueType::times(qreal scalar) const
++ {
++ return *this * scalar;
++ }
++
++ QVector4D QQuickVector4DValueType::plus(const QVector4D &vec) const
++ {
++ return *this + vec;
++ }
++
++ QVector4D QQuickVector4DValueType::minus(const QVector4D &vec) const
++ {
++ return *this - vec;
++ }
++
++ QVector4D QQuickVector4DValueType::normalized() const
++ {
++ return QVector4D::normalized();
++ }
++
++ qreal QQuickVector4DValueType::length() const
++ {
++ return QVector4D::length();
++ }
++
++ QVector2D QQuickVector4DValueType::toVector2d() const
++ {
++ return QVector4D::toVector2D();
++ }
++
++ QVector3D QQuickVector4DValueType::toVector3d() const
++ {
++ return QVector4D::toVector3D();
++ }
++
++ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec, qreal epsilon) const
++ {
++ qreal absEps = qAbs(epsilon);
++ if (qAbs(QVector4D::x() - vec.x()) > absEps)
++ return false;
++ if (qAbs(QVector4D::y() - vec.y()) > absEps)
++ return false;
++ if (qAbs(QVector4D::z() - vec.z()) > absEps)
++ return false;
++ if (qAbs(QVector4D::w() - vec.w()) > absEps)
++ return false;
++ return true;
++ }
++
++ bool QQuickVector4DValueType::fuzzyEquals(const QVector4D &vec) const
++ {
++ return qFuzzyCompare(*this, vec);
++ }
++
++ QVariant QQuickQuaternionValueType::create(const QJSValue &params)
++ {
++ if (params.isString()) {
++ return QQmlStringConverters::valueTypeFromNumberString<QQuaternion, 4, u',', u',', u','>(
++ params.toString());
++ }
++
++ if (params.isArray()) {
++ return QQuaternion(params.property(0).toNumber(), params.property(1).toNumber(),
++ params.property(2).toNumber(), params.property(3).toNumber());
++ }
++
++ return QVariant();
++ }
++
++ QString QQuickQuaternionValueType::toString() const
++ {
++ return QString::fromLatin1("QQuaternion(%1, %2, %3, %4)")
++ .arg(QQuaternion::scalar())
++ .arg(QQuaternion::x())
++ .arg(QQuaternion::y())
++ .arg(QQuaternion::z());
++ }
++
++ qreal QQuickQuaternionValueType::scalar() const
++ {
++ return QQuaternion::scalar();
++ }
++
++ qreal QQuickQuaternionValueType::x() const
++ {
++ return QQuaternion::x();
++ }
++
++ qreal QQuickQuaternionValueType::y() const
++ {
++ return QQuaternion::y();
++ }
++
++ qreal QQuickQuaternionValueType::z() const
++ {
++ return QQuaternion::z();
++ }
++
++ void QQuickQuaternionValueType::setScalar(qreal scalar)
++ {
++ QQuaternion::setScalar(scalar);
++ }
++
++ void QQuickQuaternionValueType::setX(qreal x)
++ {
++ QQuaternion::setX(x);
++ }
++
++ void QQuickQuaternionValueType::setY(qreal y)
++ {
++ QQuaternion::setY(y);
++ }
++
++ void QQuickQuaternionValueType::setZ(qreal z)
++ {
++ QQuaternion::setZ(z);
++ }
++
++ qreal QQuickQuaternionValueType::dotProduct(const QQuaternion &q) const
++ {
++ return QQuaternion::dotProduct(*this, q);
++ }
++
++ QQuaternion QQuickQuaternionValueType::times(const QQuaternion &q) const
++ {
++ return *this * q;
++ }
++
++ QVector3D QQuickQuaternionValueType::times(const QVector3D &vec) const
++ {
++ return *this * vec;
++ }
++
++ QQuaternion QQuickQuaternionValueType::times(qreal factor) const
++ {
++ return *this * factor;
++ }
++
++ QQuaternion QQuickQuaternionValueType::plus(const QQuaternion &q) const
++ {
++ return *this + q;
++ }
++
++ QQuaternion QQuickQuaternionValueType::minus(const QQuaternion &q) const
++ {
++ return *this - q;
++ }
++
++ QQuaternion QQuickQuaternionValueType::normalized() const
++ {
++ return QQuaternion::normalized();
++ }
++
++ QQuaternion QQuickQuaternionValueType::inverted() const
++ {
++ return QQuaternion::inverted();
++ }
++
++ QQuaternion QQuickQuaternionValueType::conjugated() const
++ {
++ return QQuaternion::conjugated();
++ }
++
++ qreal QQuickQuaternionValueType::length() const
++ {
++ return QQuaternion::length();
++ }
++
++ QVector3D QQuickQuaternionValueType::toEulerAngles() const
++ {
++ return QQuaternion::toEulerAngles();
++ }
++
++ QVector4D QQuickQuaternionValueType::toVector4d() const
++ {
++ return QQuaternion::toVector4D();
++ }
++
++ bool QQuickQuaternionValueType::fuzzyEquals(const QQuaternion &q, qreal epsilon) const
++ {
++ qreal absEps = qAbs(epsilon);
++ if (qAbs(QQuaternion::scalar() - q.scalar()) > absEps)
++ return false;
++ if (qAbs(QQuaternion::x() - q.x()) > absEps)
++ return false;
++ if (qAbs(QQuaternion::y() - q.y()) > absEps)
++ return false;
++ if (qAbs(QQuaternion::z() - q.z()) > absEps)
++ return false;
++ return true;
++ }
++
++ bool QQuickQuaternionValueType::fuzzyEquals(const QQuaternion &q) const
++ {
++ return qFuzzyCompare(*this, q);
++ }
++
++ QVariant QQuickMatrix4x4ValueType::create(const QJSValue &params)
++ {
++ if (params.isNull() || params.isUndefined())
++ return QMatrix4x4();
++
++ if (params.isString()) {
++ return QQmlStringConverters::valueTypeFromNumberString<QMatrix4x4, 16, u',', u',', u',',
++ u',', u',', u',', u',', u',', u',',
++ u',', u',', u',', u',', u',', u','>(
++ params.toString());
++ }
++
++ if (params.isArray() && params.property(QStringLiteral("length")).toInt() == 16) {
++ return QMatrix4x4(params.property(0).toNumber(),
++ params.property(1).toNumber(),
++ params.property(2).toNumber(),
++ params.property(3).toNumber(),
++ params.property(4).toNumber(),
++ params.property(5).toNumber(),
++ params.property(6).toNumber(),
++ params.property(7).toNumber(),
++ params.property(8).toNumber(),
++ params.property(9).toNumber(),
++ params.property(10).toNumber(),
++ params.property(11).toNumber(),
++ params.property(12).toNumber(),
++ params.property(13).toNumber(),
++ params.property(14).toNumber(),
++ params.property(15).toNumber());
++ }
++
++ return QVariant();
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::times(const QMatrix4x4 &m) const
++ {
++ return *this * m;
++ }
++
++ QVector4D QQuickMatrix4x4ValueType::times(const QVector4D &vec) const
++ {
++ return *this * vec;
++ }
++
++ QVector3D QQuickMatrix4x4ValueType::times(const QVector3D &vec) const
++ {
++ return QMatrix4x4::map(vec);
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::times(qreal factor) const
++ {
++ return *this * factor;
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::plus(const QMatrix4x4 &m) const
++ {
++ return *this + m;
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::minus(const QMatrix4x4 &m) const
++ {
++ return *this - m;
++ }
++
++ QVector4D QQuickMatrix4x4ValueType::row(int n) const
++ {
++ return QMatrix4x4::row(n);
++ }
++
++ QVector4D QQuickMatrix4x4ValueType::column(int m) const
++ {
++ return QMatrix4x4::column(m);
++ }
++
++ qreal QQuickMatrix4x4ValueType::determinant() const
++ {
++ return QMatrix4x4::determinant();
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::inverted() const
++ {
++ return QMatrix4x4::inverted();
++ }
++
++ QMatrix4x4 QQuickMatrix4x4ValueType::transposed() const
++ {
++ return QMatrix4x4::transposed();
++ }
++
++ QPointF QQuickMatrix4x4ValueType::map(const QPointF p) const
++ {
++ return QMatrix4x4::map(p);
++ }
++
++ QRectF QQuickMatrix4x4ValueType::mapRect(const QRectF r) const
++ {
++ return QMatrix4x4::mapRect(r);
++ }
++
++ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m, qreal epsilon) const
++ {
++ qreal absEps = qAbs(epsilon);
++ for (int i = 0; i < 4; ++i) {
++ for (int j = 0; j < 4; ++j) {
++ if (qAbs((*this)(i,j) - m(i,j)) > absEps) {
++ return false;
++ }
++ }
++ }
++ return true;
++ }
++
++ bool QQuickMatrix4x4ValueType::fuzzyEquals(const QMatrix4x4 &m) const
++ {
++ return qFuzzyCompare(*this, m);
++ }
++
++ /*!
++ \qmltype PlanarTransform
++ \inqmlmodule QtQuick
++ \since 6.8
++
++ \brief Provides utility functions for matrix4x4 when used for 2D transforms.
++
++ The \c PlanarTransform is a global object with utility functions.
++
++ It is not instantiable; to use it, call the members of the global \c PlanarTransform object
++ directly. For example:
++
++ \qml
++ Item {
++ transform: Matrix4x4 { matrix: PlanarTransform.fromAffineMatrix(1, 0, 0.36, 1, -36, 0) }
++ }
++ \endqml
++ */
++
++ QQuickPlanarTransform::QQuickPlanarTransform(QObject *parent)
++ : QObject(parent)
++ {
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::identity()
++
++ Returns a matrix4x4 for the identity transform.
++
++ This is equivalent to \l Qt::matrix4x4().
++ */
++
++ QMatrix4x4 QQuickPlanarTransform::identity()
++ {
++ return QMatrix4x4();
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::fromAffineMatrix(real scaleX, real shearY,
++ real shearX, real scaleY,
++ real translateX, real translateY)
++
++ Returns a matrix4x4 for an affine (non-projecting) 2D transform with the specified values.
++
++ This method and its argument order correspond to SVG's \c matrix() function and the
++ six-argument QTransform constructor. The result is this 4x4 matrix:
++
++ \table
++ \row \li \a scaleX \li \a shearX \li 0 \li \a translateX
++ \row \li \a shearY \li \a scaleY \li 0 \li \a translateY
++ \row \li 0 \li 0 \li 1 \li 0
++ \row \li 0 \li 0 \li 0 \li 1
++ \endtable
++ */
++
++ QMatrix4x4 QQuickPlanarTransform::fromAffineMatrix(float scaleX, float shearY,
++ float shearX, float scaleY,
++ float translateX, float translateY)
++ {
++ return QMatrix4x4(scaleX, shearX, 0, translateX,
++ shearY, scaleY, 0, translateY,
++ 0, 0, 1, 0,
++ 0, 0, 0, 1);
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::fromTranslate(real translateX, real translateY)
++
++ Returns a matrix4x4 for a 2D transform that translates by \a translateX horizontally and
++ \a translateY vertically.
++ */
++ QMatrix4x4 QQuickPlanarTransform::fromTranslate(float translateX, float translateY)
++ {
++ QMatrix4x4 xf;
++ xf.translate(translateX, translateY);
++ return xf;
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::fromScale(real scaleX, real scaleY, real originX, real originY)
++
++ Returns a matrix4x4 for a 2D transform that scales by \a scaleX horizontally and \a scaleY
++ vertically, centered at the point (\a originX, \a originY).
++
++ \a originX and \a originY are optional and default to (0, 0).
++ */
++ QMatrix4x4 QQuickPlanarTransform::fromScale(float scaleX, float scaleY, float originX, float originY)
++ {
++ QMatrix4x4 xf;
++ xf.translate(originX, originY);
++ xf.scale(scaleX, scaleY);
++ xf.translate(-originX, -originY);
++ return xf;
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::fromRotate(real angle, real originX, real originY)
++
++ Returns a matrix4x4 for a 2D transform that rotates by \a angle degrees around the point (\a
++ originX, \a originY).
++
++ \a originX and \a originY are optional and default to (0, 0).
++ */
++ QMatrix4x4 QQuickPlanarTransform::fromRotate(float angle, float originX, float originY)
++ {
++ QMatrix4x4 xf;
++ xf.translate(originX, originY);
++ xf.rotate(angle, 0, 0, 1);
++ xf.translate(-originX, -originY);
++ return xf;
++ }
++
++ /*!
++ \qmlmethod matrix4x4 PlanarTransform::fromShear(float shearX, float shearY, float originX, float originY)
++
++ Returns a matrix4x4 for a 2D transform that shears by \a shearX horizontally and \a shearY
++ vertically, centered at the point (\a originX, \a originY).
++
++ \a originX and \a originY are optional and default to (0, 0).
++ */
++ QMatrix4x4 QQuickPlanarTransform::fromShear(float shearX, float shearY, float originX, float originY)
++ {
++ QMatrix4x4 xf;
++ xf.translate(originX, originY);
++ xf *= QMatrix4x4(1, shearX, 0, 0, shearY, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
++ xf.translate(-originX, -originY);
++ return xf;
++ }
++
++ template<typename T>
++ void setFontProperty(QFont &font, void (QFont::*setter)(T value), QString name,
++ const QJSValue &params, bool *ok)
++ {
++ const QJSValue value = params.property(name);
++
++ if constexpr (std::is_same_v<T, bool>) {
++ if (value.isBool()) {
++ (font.*setter)(value.toBool());
++ *ok = true;
++ }
++ } else if constexpr (std::is_same_v<
++ typename std::remove_cv<typename std::remove_reference<T>::type>::type,
++ QString>) {
++ if (value.isString()) {
++ (font.*setter)(value.toString());
++ *ok = true;
++ }
++ } else if constexpr (std::is_integral_v<T> || std::is_enum_v<T>) {
++ if (value.isNumber()) {
++ (font.*setter)(T(value.toInt()));
++ *ok = true;
++ }
++ } else if constexpr (std::is_floating_point_v<T>) {
++ if (value.isNumber()) {
++ (font.*setter)(value.toNumber());
++ *ok = true;
++ }
++ }
++ }
++
++ QVariant QQuickFontValueType::create(const QJSValue &params)
++ {
++ if (!params.isObject())
++ return QVariant();
++
++ bool ok = false;
++ QFont ret;
++
++ setFontProperty(ret, &QFont::setBold, QStringLiteral("bold"), params, &ok);
++ setFontProperty(ret, &QFont::setCapitalization, QStringLiteral("capitalization"), params, &ok);
++ setFontProperty(ret, &QFont::setFamily, QStringLiteral("family"), params, &ok);
++ setFontProperty(ret, &QFont::setItalic, QStringLiteral("italic"), params, &ok);
++ setFontProperty(ret, &QFont::setPixelSize, QStringLiteral("pixelSize"), params, &ok);
++ setFontProperty(ret, &QFont::setPointSize, QStringLiteral("pointSize"), params, &ok);
++ setFontProperty(ret, &QFont::setStrikeOut, QStringLiteral("strikeout"), params, &ok);
++ setFontProperty(ret, &QFont::setStyleName, QStringLiteral("styleName"), params, &ok);
++ setFontProperty(ret, &QFont::setUnderline, QStringLiteral("underline"), params, &ok);
++ setFontProperty(ret, &QFont::setWeight, QStringLiteral("weight"), params, &ok);
++ setFontProperty(ret, &QFont::setWordSpacing, QStringLiteral("wordSpacing"), params, &ok);
++ setFontProperty(ret, &QFont::setHintingPreference, QStringLiteral("hintingPreference"), params, &ok);
++ setFontProperty(ret, &QFont::setKerning, QStringLiteral("kerning"), params, &ok);
++
++ {
++ const QJSValue vlspac = params.property(QStringLiteral("letterSpacing"));
++ if (vlspac.isNumber()) {
++ ret.setLetterSpacing(QFont::AbsoluteSpacing, vlspac.toNumber());
++ ok = true;
++ }
++ }
++
++ {
++ const QJSValue vshaping = params.property(QStringLiteral("preferShaping"));
++ if (vshaping.isBool()) {
++ const bool enable = vshaping.toBool();
++ const QFont::StyleStrategy strategy = ret.styleStrategy();
++ if (enable)
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferNoShaping));
++ else
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferNoShaping));
++ ok = true;
++ }
++ }
++
++ {
++ const QJSValue typoMetrics = params.property(QStringLiteral("preferTypoLineMetrics"));
++ if (typoMetrics.isBool()) {
++ const bool enable = typoMetrics.toBool();
++ const QFont::StyleStrategy strategy = ret.styleStrategy();
++ if (enable)
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::PreferTypoLineMetrics));
++ else
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::PreferTypoLineMetrics));
++ ok = true;
++ }
++ }
++
++ {
++ const QJSValue ctxFontMerging = params.property(QStringLiteral("contextFontMerging"));
++ if (ctxFontMerging.isBool()) {
++ const bool enable = ctxFontMerging.toBool();
++ const QFont::StyleStrategy strategy = ret.styleStrategy();
++ if (enable)
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy | QFont::ContextFontMerging));
++ else
++ ret.setStyleStrategy(QFont::StyleStrategy(strategy & ~QFont::ContextFontMerging));
++ ok = true;
++ }
++ }
++
++ {
++ const QJSValue variableAxes = params.property(QStringLiteral("variableAxes"));
++ if (variableAxes.isObject()) {
++ QVariantMap variantMap = variableAxes.toVariant().toMap();
++ for (auto [variableAxisName, variableAxisValue] : variantMap.asKeyValueRange()) {
++ const auto maybeTag = QFont::Tag::fromString(variableAxisName);
++ if (!maybeTag) {
++ qWarning() << "Invalid variable axis" << variableAxisName << "ignored";
++ continue;
++ }
++
++ bool valueOk;
++ float value = variableAxisValue.toFloat(&valueOk);
++ if (!valueOk) {
++ qWarning() << "Variable axis" << variableAxisName << "value" << variableAxisValue << "is not a floating point value.";
++ continue;
++ }
++
++ ret.setVariableAxis(*maybeTag, value);
++ ok = true;
++ }
++ }
++ }
++
++ {
++ const QJSValue features = params.property(QStringLiteral("features"));
++ if (features.isObject()) {
++ QVariantMap variantMap = features.toVariant().toMap();
++ for (auto [featureName, featureValue] : variantMap.asKeyValueRange()) {
++ const auto maybeTag = QFont::Tag::fromString(featureName);
++ if (!maybeTag) {
++ qWarning() << "Invalid font feature" << featureName << "ignored";
++ continue;
++ }
++
++ bool valueOk;
++ quint32 value = featureValue.toUInt(&valueOk);
++ if (!valueOk) {
++ qWarning() << "Font feature" << featureName << "value" << featureValue << "is not an integer.";
++ continue;
++ }
++
++ ret.setFeature(*maybeTag, value);
++ ok = true;
++ }
++ }
++ }
++
++ return ok ? ret : QVariant();
++ }
++
++ QString QQuickFontValueType::toString() const
++ {
++ return QLatin1String("QFont(%1)").arg(QFont::toString());
++ }
++
++ QString QQuickFontValueType::family() const
++ {
++ return QFont::family();
++ }
++
++ void QQuickFontValueType::setFamily(const QString &family)
++ {
++ QFont::setFamily(family);
++ }
++
++ QString QQuickFontValueType::styleName() const
++ {
++ return QFont::styleName();
++ }
++
++ void QQuickFontValueType::setStyleName(const QString &style)
++ {
++ QFont::setStyleName(style);
++ }
++
++ bool QQuickFontValueType::bold() const
++ {
++ return QFont::bold();
++ }
++
++ void QQuickFontValueType::setBold(bool b)
++ {
++ QFont::setBold(b);
++ }
++
++ int QQuickFontValueType::weight() const
++ {
++ return QFont::weight();
++ }
++
++ void QQuickFontValueType::setWeight(int w)
++ {
++ QFont::setWeight(QFont::Weight(w));
++ }
++
++ bool QQuickFontValueType::italic() const
++ {
++ return QFont::italic();
++ }
++
++ void QQuickFontValueType::setItalic(bool b)
++ {
++ QFont::setItalic(b);
++ }
++
++ bool QQuickFontValueType::underline() const
++ {
++ return QFont::underline();
++ }
++
++ void QQuickFontValueType::setUnderline(bool b)
++ {
++ QFont::setUnderline(b);
++ }
++
++ bool QQuickFontValueType::overline() const
++ {
++ return QFont::overline();
++ }
++
++ void QQuickFontValueType::setOverline(bool b)
++ {
++ QFont::setOverline(b);
++ }
++
++ bool QQuickFontValueType::strikeout() const
++ {
++ return QFont::strikeOut();
++ }
++
++ void QQuickFontValueType::setStrikeout(bool b)
++ {
++ QFont::setStrikeOut(b);
++ }
++
++ qreal QQuickFontValueType::pointSize() const
++ {
++ if (QFont::pointSizeF() == -1) {
++ return QFont::pixelSize() * qreal(72.) / qreal(qt_defaultDpi());
++ }
++ return QFont::pointSizeF();
++ }
++
++ void QQuickFontValueType::setPointSize(qreal size)
++ {
++ if ((QFont::resolveMask() & QFont::SizeResolved) && QFont::pixelSize() != -1) {
++ qWarning() << "Both point size and pixel size set. Using pixel size.";
++ return;
++ }
++
++ if (size >= 0.0) {
++ QFont::setPointSizeF(size);
++ }
++ }
++
++ int QQuickFontValueType::pixelSize() const
++ {
++ if (QFont::pixelSize() == -1) {
++ return (QFont::pointSizeF() * qt_defaultDpi()) / qreal(72.);
++ }
++ return QFont::pixelSize();
++ }
++
++ void QQuickFontValueType::setPixelSize(int size)
++ {
++ if (size >0) {
++ if ((QFont::resolveMask() & QFont::SizeResolved) && QFont::pointSizeF() != -1)
++ qWarning() << "Both point size and pixel size set. Using pixel size.";
++ QFont::setPixelSize(size);
++ }
++ }
++
++ QQuickFontEnums::Capitalization QQuickFontValueType::capitalization() const
++ {
++ return (QQuickFontEnums::Capitalization)QFont::capitalization();
++ }
++
++ void QQuickFontValueType::setCapitalization(QQuickFontEnums::Capitalization c)
++ {
++ QFont::setCapitalization((QFont::Capitalization)c);
++ }
++
++ qreal QQuickFontValueType::letterSpacing() const
++ {
++ return QFont::letterSpacing();
++ }
++
++ void QQuickFontValueType::setLetterSpacing(qreal size)
++ {
++ QFont::setLetterSpacing(QFont::AbsoluteSpacing, size);
++ }
++
++ qreal QQuickFontValueType::wordSpacing() const
++ {
++ return QFont::wordSpacing();
++ }
++
++ void QQuickFontValueType::setWordSpacing(qreal size)
++ {
++ QFont::setWordSpacing(size);
++ }
++
++ QQuickFontEnums::HintingPreference QQuickFontValueType::hintingPreference() const
++ {
++ return QQuickFontEnums::HintingPreference(QFont::hintingPreference());
++ }
++
++ void QQuickFontValueType::setHintingPreference(QQuickFontEnums::HintingPreference hintingPreference)
++ {
++ QFont::setHintingPreference(QFont::HintingPreference(hintingPreference));
++ }
++
++ bool QQuickFontValueType::kerning() const
++ {
++ return QFont::kerning();
++ }
++
++ void QQuickFontValueType::setKerning(bool b)
++ {
++ QFont::setKerning(b);
++ }
++
++ bool QQuickFontValueType::preferShaping() const
++ {
++ return (QFont::styleStrategy() & QFont::PreferNoShaping) == 0;
++ }
++
++ void QQuickFontValueType::setPreferShaping(bool enable)
++ {
++ if (enable) {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(QFont::styleStrategy() & ~QFont::PreferNoShaping));
++ } else {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(QFont::styleStrategy() | QFont::PreferNoShaping));
++ }
++ }
++
++ void QQuickFontValueType::setVariableAxes(const QVariantMap &variableAxes)
++ {
++ QFont::clearVariableAxes();
++ for (auto [variableAxisName, variableAxisValue] : variableAxes.asKeyValueRange()) {
++ const auto maybeTag = QFont::Tag::fromString(variableAxisName);
++ if (!maybeTag) {
++ qWarning() << "Invalid variable axis" << variableAxisName << "ignored";
++ continue;
++ }
++
++ bool ok;
++ float value = variableAxisValue.toFloat(&ok);
++ if (!ok) {
++ qWarning() << "Variable axis" << variableAxisName << "value" << variableAxisValue
++ << "is not a floating point value.";
++ continue;
++ }
++
++ QFont::setVariableAxis(*maybeTag, value);
++ }
++ }
++
++ QVariantMap QQuickFontValueType::variableAxes() const
++ {
++ QVariantMap ret;
++ for (const auto &tag : QFont::variableAxisTags())
++ ret.insert(QString::fromUtf8(tag.toString()), QFont::variableAxisValue(tag));
++
++ return ret;
++ }
++
++ void QQuickFontValueType::setFeatures(const QVariantMap &features)
++ {
++ QFont::clearFeatures();
++ for (auto [featureName, featureValue] : features.asKeyValueRange()) {
++ const auto maybeTag = QFont::Tag::fromString(featureName);
++ if (!maybeTag) {
++ qWarning() << "Invalid font feature" << featureName << "ignored";
++ continue;
++ }
++
++ bool ok;
++ quint32 value = featureValue.toUInt(&ok);
++ if (!ok) {
++ qWarning() << "Font feature" << featureName << "value" << featureValue << "is not an integer.";
++ continue;
++ }
++
++ QFont::setFeature(*maybeTag, value);
++ }
++ }
++
++ QVariantMap QQuickFontValueType::features() const
++ {
++ QVariantMap ret;
++ for (const auto &tag : QFont::featureTags())
++ ret.insert(QString::fromUtf8(tag.toString()), QFont::featureValue(tag));
++
++ return ret;
++ }
++
++ bool QQuickFontValueType::contextFontMerging() const
++ {
++ return (QFont::styleStrategy() & QFont::ContextFontMerging) != 0;
++ }
++
++ void QQuickFontValueType::setContextFontMerging(bool enable)
++ {
++ if (enable) {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(
++ QFont::styleStrategy() | QFont::ContextFontMerging));
++ } else {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(
++ QFont::styleStrategy() & ~QFont::ContextFontMerging));
++ }
++ }
++
++ bool QQuickFontValueType::preferTypoLineMetrics() const
++ {
++ return (QFont::styleStrategy() & QFont::PreferTypoLineMetrics) != 0;
++ }
++
++ void QQuickFontValueType::setPreferTypoLineMetrics(bool enable)
++ {
++ if (enable) {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(
++ QFont::styleStrategy() | QFont::PreferTypoLineMetrics));
++ } else {
++ QFont::setStyleStrategy(
++ static_cast<QFont::StyleStrategy>(
++ QFont::styleStrategy() & ~QFont::PreferTypoLineMetrics));
++ }
++ }
++
++ QVariant QQuickColorSpaceValueType::create(const QJSValue &params)
++ {
++ if (!params.isObject())
++ return QVariant();
++
++
++ const QJSValue vName = params.property(QStringLiteral("namedColorSpace"));
++ if (vName.isNumber())
++ return QColorSpace((QColorSpace::NamedColorSpace)vName.toInt());
++
++ const QJSValue vPri = params.property(QStringLiteral("primaries"));
++ const QJSValue vTra = params.property(QStringLiteral("transferFunction"));
++ if (!vPri.isNumber() || !vTra.isNumber())
++ return QVariant();
++
++ QColorSpace::Primaries pri = static_cast<QColorSpace::Primaries>(vPri.toInt());
++ QColorSpace::TransferFunction tra = static_cast<QColorSpace::TransferFunction>(vTra.toInt());
++ float gamma = 0.0f;
++ if (tra == QColorSpace::TransferFunction::Gamma) {
++ const QJSValue vGam = params.property(QStringLiteral("gamma"));
++ if (!vGam.isNumber())
++ return QVariant();
++ gamma = vGam.toNumber();
++ }
++
++ return QColorSpace(pri, tra, gamma);
++ }
++
++ QQuickColorSpaceEnums::NamedColorSpace QQuickColorSpaceValueType::namedColorSpace() const noexcept
++ {
++ if (const auto *p = QColorSpacePrivate::get(*this))
++ return (QQuickColorSpaceEnums::NamedColorSpace)p->namedColorSpace;
++ return QQuickColorSpaceEnums::Unknown;
++ }
++ void QQuickColorSpaceValueType::setNamedColorSpace(
++ QQuickColorSpaceEnums::NamedColorSpace namedColorSpace)
++ {
++ *static_cast<QColorSpace *>(this) = { (QColorSpace::NamedColorSpace)namedColorSpace };
++ }
++
++ QQuickColorSpaceEnums::Primaries QQuickColorSpaceValueType::primaries() const noexcept
++ {
++ return (QQuickColorSpaceEnums::Primaries)QColorSpace::primaries();
++ }
++
++ void QQuickColorSpaceValueType::setPrimaries(QQuickColorSpaceEnums::Primaries primariesId)
++ {
++ QColorSpace::setPrimaries((QColorSpace::Primaries)primariesId);
++ }
++
++ QQuickColorSpaceEnums::TransferFunction QQuickColorSpaceValueType::transferFunction() const noexcept
++ {
++ return (QQuickColorSpaceEnums::TransferFunction)QColorSpace::transferFunction();
++ }
++
++ void QQuickColorSpaceValueType::setTransferFunction(
++ QQuickColorSpaceEnums::TransferFunction transferFunction)
++ {
++ QColorSpace::setTransferFunction(
++ (QColorSpace::TransferFunction)transferFunction, QColorSpace::gamma());
++ }
++
++ float QQuickColorSpaceValueType::gamma() const noexcept
++ {
++ return QColorSpace::gamma();
++ }
++
++ void QQuickColorSpaceValueType::setGamma(float gamma)
++ {
++ QColorSpace::setTransferFunction(QColorSpace::transferFunction(), gamma);
++ }
++
++ QT_END_NAMESPACE
++
++ #include "moc_qquickvaluetypes_p.cpp"