diff options
Diffstat (limited to 'src/plugins/scenegraph/openvg/qopenvgmatrix.cpp')
-rw-r--r-- | src/plugins/scenegraph/openvg/qopenvgmatrix.cpp | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp new file mode 100644 index 0000000000..83ce96578e --- /dev/null +++ b/src/plugins/scenegraph/openvg/qopenvgmatrix.cpp @@ -0,0 +1,378 @@ +/**************************************************************************** +** +** 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 "qopenvgmatrix.h" + +QT_BEGIN_NAMESPACE + +// QOpenVGMatrix: Because Qt will never have enough matrix classes +// Internally the data is stored as column-major format +// So this is a 3x3 version of QMatrix4x4 for optimal +// OpenVG usage. + +QOpenVGMatrix::QOpenVGMatrix() +{ + setToIdentity(); +} + +QOpenVGMatrix::QOpenVGMatrix(const float *values) +{ + for (int col = 0; col < 3; ++col) + for (int row = 0; row < 3; ++row) + m[col][row] = values[col * 3 + row]; +} + +const float &QOpenVGMatrix::operator()(int row, int column) const +{ + Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); + return m[column][row]; +} + +float &QOpenVGMatrix::operator()(int row, int column) +{ + Q_ASSERT(row >= 0 && row < 4 && column >= 0 && column < 4); + return m[column][row]; +} + +bool QOpenVGMatrix::isIdentity() const +{ + if (m[0][0] != 1.0f || m[0][1] != 0.0f || m[0][2] != 0.0f) + return false; + if ( m[1][0] != 0.0f || m[1][1] != 1.0f) + return false; + if (m[1][2] != 0.0f || m[2][0] != 0.0f) + return false; + if (m[2][1] != 0.0f || m[2][2] != 1.0f) + return false; + + return true; +} + +void QOpenVGMatrix::setToIdentity() +{ + m[0][0] = 1.0f; + m[0][1] = 0.0f; + m[0][2] = 0.0f; + m[1][0] = 0.0f; + m[1][1] = 1.0f; + m[1][2] = 0.0f; + m[2][0] = 0.0f; + m[2][1] = 0.0f; + m[2][2] = 1.0f; +} + +bool QOpenVGMatrix::isAffine() const +{ + if (m[0][2] == 0.0f && m[1][2] == 0.0f && m[2][2] == 1.0f) + return true; + + return false; +} + +QPointF QOpenVGMatrix::map(const QPointF &point) const +{ + return *this * point; +} + +void QOpenVGMatrix::fill(float value) +{ + m[0][0] = value; + m[0][1] = value; + m[0][2] = value; + m[1][0] = value; + m[1][1] = value; + m[1][2] = value; + m[2][0] = value; + m[2][1] = value; + m[2][2] = value; +} + +QOpenVGMatrix QOpenVGMatrix::transposed() const +{ + QOpenVGMatrix result; + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + result.m[col][row] = m[row][col]; + } + return result; +} + +QOpenVGMatrix &QOpenVGMatrix::operator+=(const QOpenVGMatrix &other) +{ + m[0][0] += other.m[0][0]; + m[0][1] += other.m[0][1]; + m[0][2] += other.m[0][2]; + m[1][0] += other.m[1][0]; + m[1][1] += other.m[1][1]; + m[1][2] += other.m[1][2]; + m[2][0] += other.m[2][0]; + m[2][1] += other.m[2][1]; + m[2][2] += other.m[2][2]; + return *this; +} + +QOpenVGMatrix &QOpenVGMatrix::operator-=(const QOpenVGMatrix &other) +{ + m[0][0] -= other.m[0][0]; + m[0][1] -= other.m[0][1]; + m[0][2] -= other.m[0][2]; + m[1][0] -= other.m[1][0]; + m[1][1] -= other.m[1][1]; + m[1][2] -= other.m[1][2]; + m[2][0] -= other.m[2][0]; + m[2][1] -= other.m[2][1]; + m[2][2] -= other.m[2][2]; + return *this; +} + +QOpenVGMatrix &QOpenVGMatrix::operator*=(const QOpenVGMatrix &other) +{ + float m0, m1; + m0 = m[0][0] * other.m[0][0] + + m[1][0] * other.m[0][1] + + m[2][0] * other.m[0][2]; + m1 = m[0][0] * other.m[1][0] + + m[1][0] * other.m[1][1] + + m[2][0] * other.m[1][2]; + m[2][0] = m[0][0] * other.m[2][0] + + m[1][0] * other.m[2][1] + + m[2][0] * other.m[2][2]; + m[0][0] = m0; + m[1][0] = m1; + + m0 = m[0][1] * other.m[0][0] + + m[1][1] * other.m[0][1] + + m[2][1] * other.m[0][2]; + m1 = m[0][1] * other.m[1][0] + + m[1][1] * other.m[1][1] + + m[2][1] * other.m[1][2]; + m[2][1] = m[0][1] * other.m[2][0] + + m[1][1] * other.m[2][1] + + m[2][1] * other.m[2][2]; + m[0][1] = m0; + m[1][1] = m1; + + m0 = m[0][2] * other.m[0][0] + + m[1][2] * other.m[0][1] + + m[2][2] * other.m[0][2]; + m1 = m[0][2] * other.m[1][0] + + m[1][2] * other.m[1][1] + + m[2][2] * other.m[1][2]; + m[2][2] = m[0][2] * other.m[2][0] + + m[1][2] * other.m[2][1] + + m[2][2] * other.m[2][2]; + m[0][2] = m0; + m[1][2] = m1; + return *this; +} + +QOpenVGMatrix &QOpenVGMatrix::operator*=(float factor) +{ + m[0][0] *= factor; + m[0][1] *= factor; + m[0][2] *= factor; + m[1][0] *= factor; + m[1][1] *= factor; + m[1][2] *= factor; + m[2][0] *= factor; + m[2][1] *= factor; + m[2][2] *= factor; + return *this; +} + +QOpenVGMatrix &QOpenVGMatrix::operator/=(float divisor) +{ + m[0][0] /= divisor; + m[0][1] /= divisor; + m[0][2] /= divisor; + m[1][0] /= divisor; + m[1][1] /= divisor; + m[1][2] /= divisor; + m[2][0] /= divisor; + m[2][1] /= divisor; + m[2][2] /= divisor; + return *this; +} + +bool QOpenVGMatrix::operator==(const QOpenVGMatrix &other) const +{ + return m[0][0] == other.m[0][0] && + m[0][1] == other.m[0][1] && + m[0][2] == other.m[0][2] && + m[1][0] == other.m[1][0] && + m[1][1] == other.m[1][1] && + m[1][2] == other.m[1][2] && + m[2][0] == other.m[2][0] && + m[2][1] == other.m[2][1] && + m[2][2] == other.m[2][2]; +} + +bool QOpenVGMatrix::operator!=(const QOpenVGMatrix &other) const +{ + return m[0][0] != other.m[0][0] || + m[0][1] != other.m[0][1] || + m[0][2] != other.m[0][2] || + m[1][0] != other.m[1][0] || + m[1][1] != other.m[1][1] || + m[1][2] != other.m[1][2] || + m[2][0] != other.m[2][0] || + m[2][1] != other.m[2][1] || + m[2][2] != other.m[2][2]; +} + +void QOpenVGMatrix::copyDataTo(float *values) const +{ + // Row-Major? + for (int row = 0; row < 3; ++row) { + for (int col = 0; col < 3; ++col) + values[row * 3 + col] = float(m[col][row]); + } +} + +QOpenVGMatrix operator*(const QOpenVGMatrix &m1, const QOpenVGMatrix &m2) +{ + QOpenVGMatrix matrix; + matrix.m[0][0] = m1.m[0][0] * m2.m[0][0] + + m1.m[1][0] * m2.m[0][1] + + m1.m[2][0] * m2.m[0][2]; + matrix.m[0][1] = m1.m[0][1] * m2.m[0][0] + + m1.m[1][1] * m2.m[0][1] + + m1.m[2][1] * m2.m[0][2]; + matrix.m[0][2] = m1.m[0][2] * m2.m[0][0] + + m1.m[1][2] * m2.m[0][1] + + m1.m[2][2] * m2.m[0][2]; + + matrix.m[1][0] = m1.m[0][0] * m2.m[1][0] + + m1.m[1][0] * m2.m[1][1] + + m1.m[2][0] * m2.m[1][2]; + matrix.m[1][1] = m1.m[0][1] * m2.m[1][0] + + m1.m[1][1] * m2.m[1][1] + + m1.m[2][1] * m2.m[1][2]; + matrix.m[1][2] = m1.m[0][2] * m2.m[1][0] + + m1.m[1][2] * m2.m[1][1] + + m1.m[2][2] * m2.m[1][2]; + + matrix.m[2][0] = m1.m[0][0] * m2.m[2][0] + + m1.m[1][0] * m2.m[2][1] + + m1.m[2][0] * m2.m[2][2]; + matrix.m[2][1] = m1.m[0][1] * m2.m[2][0] + + m1.m[1][1] * m2.m[2][1] + + m1.m[2][1] * m2.m[2][2]; + matrix.m[2][2] = m1.m[0][2] * m2.m[2][0] + + m1.m[1][2] * m2.m[2][1] + + m1.m[2][2] * m2.m[2][2]; + return matrix; +} + +QPointF operator*(const QPointF& point, const QOpenVGMatrix& matrix) +{ + float xin = point.x(); + float yin = point.y(); + float x = xin * matrix.m[0][0] + + yin * matrix.m[0][1] + + matrix.m[0][2]; + float y = xin * matrix.m[1][0] + + yin * matrix.m[1][1] + + matrix.m[1][2]; + float w = xin * matrix.m[2][0] + + yin * matrix.m[2][1] + + matrix.m[2][2]; + if (w == 1.0f) { + return QPointF(float(x), float(y)); + } else { + return QPointF(float(x / w), float(y / w)); + } +} + +QPointF operator*(const QOpenVGMatrix& matrix, const QPointF& point) +{ + float xin = point.x(); + float yin = point.y(); + float x = xin * matrix.m[0][0] + + yin * matrix.m[1][0] + + matrix.m[2][0]; + float y = xin * matrix.m[0][1] + + yin * matrix.m[1][1] + + matrix.m[2][1]; + float w = xin * matrix.m[0][2] + + yin * matrix.m[1][2] + + matrix.m[2][2]; + if (w == 1.0f) { + return QPointF(float(x), float(y)); + } else { + return QPointF(float(x / w), float(y / w)); + } +} + +QDebug operator<<(QDebug dbg, const QOpenVGMatrix &m) +{ + QDebugStateSaver saver(dbg); + // Output in row-major order because it is more human-readable. + dbg.nospace() << "QOpenVGMatrix:(" << endl + << qSetFieldWidth(10) + << m(0, 0) << m(0, 1) << m(0, 2) << endl + << m(1, 0) << m(1, 1) << m(1, 2) << endl + << m(2, 0) << m(2, 1) << m(2, 2) << endl + << qSetFieldWidth(0) << ')'; + return dbg; +} + +QDataStream &operator<<(QDataStream &stream, const QOpenVGMatrix &matrix) +{ + for (int row = 0; row < 3; ++row) + for (int col = 0; col < 3; ++col) + stream << matrix(row, col); + return stream; +} + + +QDataStream &operator>>(QDataStream &stream, QOpenVGMatrix &matrix) +{ + float x; + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + stream >> x; + matrix(row, col) = x; + } + } + return stream; +} + + +QT_END_NAMESPACE |