summaryrefslogtreecommitdiffstats
path: root/src/gui/painting
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/painting')
-rw-r--r--src/gui/painting/painting.pri2
-rw-r--r--src/gui/painting/qbackingstore.cpp2
-rw-r--r--src/gui/painting/qbrush.cpp20
-rw-r--r--src/gui/painting/qbrush.h10
-rw-r--r--src/gui/painting/qcolor.cpp52
-rw-r--r--src/gui/painting/qcolor.h19
-rw-r--r--src/gui/painting/qcolormatrix_p.h2
-rw-r--r--src/gui/painting/qdatabuffer_p.h4
-rw-r--r--src/gui/painting/qdrawhelper.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_ssse3.cpp2
-rw-r--r--src/gui/painting/qmatrix.cpp1191
-rw-r--r--src/gui/painting/qmatrix.h194
-rw-r--r--src/gui/painting/qpaintdevice.qdoc3
-rw-r--r--src/gui/painting/qpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintengine.h3
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h8
-rw-r--r--src/gui/painting/qpainter.cpp381
-rw-r--r--src/gui/painting/qpainter.h25
-rw-r--r--src/gui/painting/qpainter_p.h2
-rw-r--r--src/gui/painting/qpainterpath.cpp101
-rw-r--r--src/gui/painting/qpainterpath.h14
-rw-r--r--src/gui/painting/qpainterpath_p.h1
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp439
-rw-r--r--src/gui/painting/qplatformbackingstore.h16
-rw-r--r--src/gui/painting/qpolygon.cpp12
-rw-r--r--src/gui/painting/qpolygon.h2
-rw-r--r--src/gui/painting/qregion.cpp2
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp4
-rw-r--r--src/gui/painting/qtransform.cpp635
-rw-r--r--src/gui/painting/qtransform.h112
30 files changed, 598 insertions, 2664 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 94a88f55dc..21a40540c4 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -26,7 +26,6 @@ HEADERS += \
painting/qfixed_p.h \
painting/qgrayraster_p.h \
painting/qicc_p.h \
- painting/qmatrix.h \
painting/qmemrotate_p.h \
painting/qoutlinemapper_p.h \
painting/qpagedpaintdevice.h \
@@ -83,7 +82,6 @@ SOURCES += \
painting/qgrayraster.c \
painting/qicc.cpp \
painting/qimagescale.cpp \
- painting/qmatrix.cpp \
painting/qmemrotate.cpp \
painting/qoutlinemapper.cpp \
painting/qpagedpaintdevice.cpp \
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index 2147d9d61d..5bbc03db80 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -322,7 +322,7 @@ void Q_GUI_EXPORT qt_scrollRectInImage(QImage &img, const QRect &rect, const QPo
// make sure we don't detach
uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
- int lineskip = img.bytesPerLine();
+ qsizetype lineskip = img.bytesPerLine();
int depth = img.depth() >> 3;
const QRect imageRect(0, 0, img.width(), img.height());
diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp
index 28cc20bfc5..c8fc447446 100644
--- a/src/gui/painting/qbrush.cpp
+++ b/src/gui/painting/qbrush.cpp
@@ -892,26 +892,6 @@ bool QBrush::isOpaque() const
return false;
}
-
-#if QT_DEPRECATED_SINCE(5, 15)
-/*!
- \since 4.2
- \obsolete
-
- Use setTransform() instead.
-
- Sets \a matrix as an explicit transformation matrix on the
- current brush. The brush transformation matrix is merged with
- QPainter transformation matrix to produce the final result.
-
- \sa matrix()
-*/
-void QBrush::setMatrix(const QMatrix &matrix)
-{
- setTransform(QTransform(matrix));
-}
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
/*!
\since 4.3
diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h
index 3a01248c57..621387615b 100644
--- a/src/gui/painting/qbrush.h
+++ b/src/gui/painting/qbrush.h
@@ -46,7 +46,6 @@
#include <QtCore/qvector.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/qcolor.h>
-#include <QtGui/qmatrix.h>
#include <QtGui/qtransform.h>
#include <QtGui/qimage.h>
#include <QtGui/qpixmap.h>
@@ -89,11 +88,6 @@ public:
inline Qt::BrushStyle style() const;
void setStyle(Qt::BrushStyle);
-#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use transform()") inline const QMatrix &matrix() const;
- QT_DEPRECATED_X("Use setTransform()") void setMatrix(const QMatrix &mat);
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
inline QTransform transform() const;
void setTransform(const QTransform &);
@@ -159,10 +153,6 @@ struct QBrushData
inline Qt::BrushStyle QBrush::style() const { return d->style; }
inline const QColor &QBrush::color() const { return d->color; }
-#if QT_DEPRECATED_SINCE(5, 15)
-QT_DEPRECATED_X("Use transform()")
-inline const QMatrix &QBrush::matrix() const { return d->transform.toAffine(); }
-#endif // QT_DEPRECATED_SINCE(5, 15)
inline QTransform QBrush::transform() const { return d->transform; }
inline bool QBrush::isDetached() const { return d->ref.loadRelaxed() == 1; }
diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp
index f15f6aeebd..eac2a50c8c 100644
--- a/src/gui/painting/qcolor.cpp
+++ b/src/gui/painting/qcolor.cpp
@@ -855,18 +855,6 @@ QColor::QColor(Spec spec) noexcept
*/
/*!
- Returns the name of the color in the format "#RRGGBB"; i.e. a "#"
- character followed by three two-digit hexadecimal numbers.
-
- \sa setNamedColor()
-*/
-
-QString QColor::name() const
-{
- return name(HexRgb);
-}
-
-/*!
\since 5.2
Returns the name of the color in the specified \a format.
@@ -1086,6 +1074,7 @@ void QColor::setHsvF(qreal h, qreal s, qreal v, qreal a)
|| (v < qreal(0.0) || v > qreal(1.0))
|| (a < qreal(0.0) || a > qreal(1.0))) {
qWarning("QColor::setHsvF: HSV parameters out of range");
+ invalidate();
return;
}
@@ -1198,7 +1187,8 @@ void QColor::setHslF(qreal h, qreal s, qreal l, qreal a)
|| (s < qreal(0.0) || s > qreal(1.0))
|| (l < qreal(0.0) || l > qreal(1.0))
|| (a < qreal(0.0) || a > qreal(1.0))) {
- qWarning("QColor::setHsvF: HSV parameters out of range");
+ qWarning("QColor::setHslF: HSL parameters out of range");
+ invalidate();
return;
}
@@ -1224,7 +1214,7 @@ void QColor::setHslF(qreal h, qreal s, qreal l, qreal a)
void QColor::setHsl(int h, int s, int l, int a)
{
if (h < -1 || (uint)s > 255 || (uint)l > 255 || (uint)a > 255) {
- qWarning("QColor::setHsv: HSV parameters out of range");
+ qWarning("QColor::setHsl: HSL parameters out of range");
invalidate();
return;
}
@@ -2626,16 +2616,6 @@ QColor QColor::fromHslF(qreal h, qreal s, qreal l, qreal a)
}
/*!
- \obsolete
-
- Use the \c const overload instead.
-*/
-void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a)
-{
- const_cast<const QColor *>(this)->getCmyk(c, m, y, k, a);
-}
-
-/*!
Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
cyan, magenta, yellow, black, and alpha-channel (transparency) components
of the color's CMYK value.
@@ -2665,16 +2645,6 @@ void QColor::getCmyk(int *c, int *m, int *y, int *k, int *a) const
}
/*!
- \obsolete
-
- Use the \c const overload instead.
-*/
-void QColor::getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a)
-{
- const_cast<const QColor *>(this)->getCmykF(c, m, y, k, a);
-}
-
-/*!
Sets the contents pointed to by \a c, \a m, \a y, \a k, and \a a, to the
cyan, magenta, yellow, black, and alpha-channel (transparency) components
of the color's CMYK value.
@@ -2719,6 +2689,7 @@ void QColor::setCmyk(int c, int m, int y, int k, int a)
|| k < 0 || k > 255
|| a < 0 || a > 255) {
qWarning("QColor::setCmyk: CMYK parameters out of range");
+ invalidate();
return;
}
@@ -2748,6 +2719,7 @@ void QColor::setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a)
|| k < qreal(0.0) || k > qreal(1.0)
|| a < qreal(0.0) || a > qreal(1.0)) {
qWarning("QColor::setCmykF: CMYK parameters out of range");
+ invalidate();
return;
}
@@ -2920,18 +2892,6 @@ QColor QColor::dark(int factor) const noexcept
}
#endif
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
-/*!
- Assigns a copy of \a color to this color, and returns a reference to it.
-*/
-QColor &QColor::operator=(const QColor &color) noexcept
-{
- cspec = color.cspec;
- ct.argb = color.ct.argb;
- return *this;
-}
-#endif
-
/*! \overload
Assigns a copy of \a color and returns a reference to this color.
*/
diff --git a/src/gui/painting/qcolor.h b/src/gui/painting/qcolor.h
index 0189f4e5f1..ad624e6b60 100644
--- a/src/gui/painting/qcolor.h
+++ b/src/gui/painting/qcolor.h
@@ -46,6 +46,8 @@
#include <QtCore/qstringlist.h>
#include <QtGui/qrgba64.h>
+#include <limits.h>
+
QT_BEGIN_NAMESPACE
@@ -87,24 +89,11 @@ public:
inline QColor(QLatin1String name);
QColor(Spec spec) noexcept;
-#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
- // ### Qt 6: remove all of these, the trivial ones are fine.
- Q_DECL_CONSTEXPR QColor(const QColor &color) noexcept
- : cspec(color.cspec), ct(color.ct)
- {}
- Q_DECL_CONSTEXPR QColor(QColor &&other) noexcept : cspec(other.cspec), ct(other.ct) {}
- QColor &operator=(QColor &&other) noexcept
- { cspec = other.cspec; ct = other.ct; return *this; }
- QColor &operator=(const QColor &) noexcept;
-#endif // Qt < 6
-
QColor &operator=(Qt::GlobalColor color) noexcept;
bool isValid() const noexcept;
- // ### Qt 6: merge overloads
- QString name() const;
- QString name(NameFormat format) const;
+ QString name(NameFormat format = HexRgb) const;
#if QT_STRINGVIEW_LEVEL < 2
void setNamedColor(const QString& name);
@@ -180,11 +169,9 @@ public:
qreal yellowF() const noexcept;
qreal blackF() const noexcept;
- void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr); // ### Qt 6: remove
void getCmyk(int *c, int *m, int *y, int *k, int *a = nullptr) const;
void setCmyk(int c, int m, int y, int k, int a = 255);
- void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr); // ### Qt 6: remove
void getCmykF(qreal *c, qreal *m, qreal *y, qreal *k, qreal *a = nullptr) const;
void setCmykF(qreal c, qreal m, qreal y, qreal k, qreal a = 1.0);
diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h
index edb2d32258..749aad3b2c 100644
--- a/src/gui/painting/qcolormatrix_p.h
+++ b/src/gui/painting/qcolormatrix_p.h
@@ -112,7 +112,7 @@ inline bool operator!=(const QColorVector &v1, const QColorVector &v2)
// A matrix mapping 3 value colors.
-// Not using QMatrix because only floats are needed and performance is critical.
+// Not using QTransform because only floats are needed and performance is critical.
class QColorMatrix
{
public:
diff --git a/src/gui/painting/qdatabuffer_p.h b/src/gui/painting/qdatabuffer_p.h
index 181d19da0b..676750b716 100644
--- a/src/gui/painting/qdatabuffer_p.h
+++ b/src/gui/painting/qdatabuffer_p.h
@@ -116,7 +116,7 @@ public:
capacity = 1;
while (capacity < size)
capacity *= 2;
- buffer = (Type*) realloc(buffer, capacity * sizeof(Type));
+ buffer = (Type*) realloc(static_cast<void*>(buffer), capacity * sizeof(Type));
Q_CHECK_PTR(buffer);
}
}
@@ -124,7 +124,7 @@ public:
inline void shrink(int size) {
capacity = size;
if (size) {
- buffer = (Type*) realloc(buffer, capacity * sizeof(Type));
+ buffer = (Type*) realloc(static_cast<void*>(buffer), capacity * sizeof(Type));
Q_CHECK_PTR(buffer);
} else {
free(buffer);
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 2d4045fe29..e4e8305620 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -2906,7 +2906,7 @@ static void QT_FASTCALL fetchTransformedBilinearARGB32PM_fast_rotate_helper(uint
int32x4_t v_fdy = vdupq_n_s32(fdy * 4);
const uchar *textureData = image.imageData;
- const int bytesPerLine = image.bytesPerLine;
+ const qsizetype bytesPerLine = image.bytesPerLine;
int32x4_t v_fx = vmovq_n_s32(fx);
int32x4_t v_fy = vmovq_n_s32(fy);
diff --git a/src/gui/painting/qdrawhelper_ssse3.cpp b/src/gui/painting/qdrawhelper_ssse3.cpp
index 14d7047bb6..a175b591dd 100644
--- a/src/gui/painting/qdrawhelper_ssse3.cpp
+++ b/src/gui/painting/qdrawhelper_ssse3.cpp
@@ -197,7 +197,7 @@ void qt_memfill24_ssse3(quint24 *dest, quint24 color, qsizetype count)
quint24 *end = dest + count;
constexpr uchar x = 2, y = 1, z = 0;
- Q_DECL_ALIGN(__m128i) static const uchar
+ alignas(__m128i) static const uchar
shuffleMask[16 + 1] = { x, y, z, x, y, z, x, y, z, x, y, z, x, y, z, x, y };
__m128i mval1 = _mm_shuffle_epi8(m, _mm_load_si128(reinterpret_cast<const __m128i *>(shuffleMask)));
diff --git a/src/gui/painting/qmatrix.cpp b/src/gui/painting/qmatrix.cpp
deleted file mode 100644
index 7ebd2dbd09..0000000000
--- a/src/gui/painting/qmatrix.cpp
+++ /dev/null
@@ -1,1191 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui 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 "qmatrix.h"
-
-#include "qdatastream.h"
-#include "qdebug.h"
-#include "qhashfunctions.h"
-#include "qregion.h"
-#include "qpainterpath.h"
-#include "qpainterpath_p.h"
-#include "qtransform.h"
-#include "qvariant.h"
-#include <qmath.h>
-
-#include <limits.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QMatrix
- \brief The QMatrix class specifies 2D transformations of a
- coordinate system.
- \obsolete
-
- \ingroup painting
- \inmodule QtGui
-
- A matrix specifies how to translate, scale, shear or rotate the
- coordinate system, and is typically used when rendering graphics.
- QMatrix, in contrast to QTransform, does not allow perspective
- transformations. QTransform is the recommended transformation
- class in Qt.
-
- A QMatrix object can be built using the setMatrix(), scale(),
- rotate(), translate() and shear() functions. Alternatively, it
- can be built by applying \l {QMatrix#Basic Matrix
- Operations}{basic matrix operations}. The matrix can also be
- defined when constructed, and it can be reset to the identity
- matrix (the default) using the reset() function.
-
- The QMatrix class supports mapping of graphic primitives: A given
- point, line, polygon, region, or painter path can be mapped to the
- coordinate system defined by \e this matrix using the map()
- function. In case of a rectangle, its coordinates can be
- transformed using the mapRect() function. A rectangle can also be
- transformed into a \e polygon (mapped to the coordinate system
- defined by \e this matrix), using the mapToPolygon() function.
-
- QMatrix provides the isIdentity() function which returns \c true if
- the matrix is the identity matrix, and the isInvertible() function
- which returns \c true if the matrix is non-singular (i.e. AB = BA =
- I). The inverted() function returns an inverted copy of \e this
- matrix if it is invertible (otherwise it returns the identity
- matrix). In addition, QMatrix provides the determinant() function
- returning the matrix's determinant.
-
- Finally, the QMatrix class supports matrix multiplication, and
- objects of the class can be streamed as well as compared.
-
- \tableofcontents
-
- \section1 Rendering Graphics
-
- When rendering graphics, the matrix defines the transformations
- but the actual transformation is performed by the drawing routines
- in QPainter.
-
- By default, QPainter operates on the associated device's own
- coordinate system. The standard coordinate system of a
- QPaintDevice has its origin located at the top-left position. The
- \e x values increase to the right; \e y values increase
- downward. For a complete description, see the \l {Coordinate
- System}{coordinate system} documentation.
-
- QPainter has functions to translate, scale, shear and rotate the
- coordinate system without using a QMatrix. For example:
-
- \table 100%
- \row
- \li \inlineimage qmatrix-simpletransformation.png
- \li
- \snippet matrix/matrix.cpp 0
- \endtable
-
- Although these functions are very convenient, it can be more
- efficient to build a QMatrix and call QPainter::setMatrix() if you
- want to perform more than a single transform operation. For
- example:
-
- \table 100%
- \row
- \li \inlineimage qmatrix-combinedtransformation.png
- \li
- \snippet matrix/matrix.cpp 1
- \endtable
-
- \section1 Basic Matrix Operations
-
- \image qmatrix-representation.png
-
- A QMatrix object contains a 3 x 3 matrix. The \c dx and \c dy
- elements specify horizontal and vertical translation. The \c m11
- and \c m22 elements specify horizontal and vertical scaling. And
- finally, the \c m21 and \c m12 elements specify horizontal and
- vertical \e shearing.
-
- QMatrix transforms a point in the plane to another point using the
- following formulas:
-
- \snippet code/src_gui_painting_qmatrix.cpp 0
-
- The point \e (x, y) is the original point, and \e (x', y') is the
- transformed point. \e (x', y') can be transformed back to \e (x,
- y) by performing the same operation on the inverted() matrix.
-
- The various matrix elements can be set when constructing the
- matrix, or by using the setMatrix() function later on. They can also
- be manipulated using the translate(), rotate(), scale() and
- shear() convenience functions, The currently set values can be
- retrieved using the m11(), m12(), m21(), m22(), dx() and dy()
- functions.
-
- Translation is the simplest transformation. Setting \c dx and \c
- dy will move the coordinate system \c dx units along the X axis
- and \c dy units along the Y axis. Scaling can be done by setting
- \c m11 and \c m22. For example, setting \c m11 to 2 and \c m22 to
- 1.5 will double the height and increase the width by 50%. The
- identity matrix has \c m11 and \c m22 set to 1 (all others are set
- to 0) mapping a point to itself. Shearing is controlled by \c m12
- and \c m21. Setting these elements to values different from zero
- will twist the coordinate system. Rotation is achieved by
- carefully setting both the shearing factors and the scaling
- factors.
-
- Here's the combined transformations example using basic matrix
- operations:
-
- \table 100%
- \row
- \li \inlineimage qmatrix-combinedtransformation.png
- \li
- \snippet matrix/matrix.cpp 2
- \endtable
-
- \sa QPainter, QTransform, {Coordinate System},
- {painting/affine}{Affine Transformations Example}, {Transformations Example}
-*/
-
-
-// some defines to inline some code
-#define MAPDOUBLE(x, y, nx, ny) \
-{ \
- qreal fx = x; \
- qreal fy = y; \
- nx = _m11*fx + _m21*fy + _dx; \
- ny = _m12*fx + _m22*fy + _dy; \
-}
-
-#define MAPINT(x, y, nx, ny) \
-{ \
- qreal fx = x; \
- qreal fy = y; \
- nx = qRound(_m11*fx + _m21*fy + _dx); \
- ny = qRound(_m12*fx + _m22*fy + _dy); \
-}
-
-/*****************************************************************************
- QMatrix member functions
- *****************************************************************************/
-/*!
- \fn QMatrix::QMatrix(Qt::Initialization)
- \internal
-*/
-
-/*!
- Constructs an identity matrix.
-
- All elements are set to zero except \c m11 and \c m22 (specifying
- the scale), which are set to 1.
-
- \sa reset()
-*/
-
-QMatrix::QMatrix()
- : _m11(1.)
- , _m12(0.)
- , _m21(0.)
- , _m22(1.)
- , _dx(0.)
- , _dy(0.)
-{
-}
-
-/*!
- Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a
- m22, \a dx and \a dy.
-
- \sa setMatrix()
-*/
-
-QMatrix::QMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
- : _m11(m11)
- , _m12(m12)
- , _m21(m21)
- , _m22(m22)
- , _dx(dx)
- , _dy(dy)
-{
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-/*!
- Constructs a matrix that is a copy of the given \a matrix.
- */
-QMatrix::QMatrix(const QMatrix &matrix) noexcept
- : _m11(matrix._m11)
- , _m12(matrix._m12)
- , _m21(matrix._m21)
- , _m22(matrix._m22)
- , _dx(matrix._dx)
- , _dy(matrix._dy)
-{
-}
-#endif
-
-/*!
- Sets the matrix elements to the specified values, \a m11, \a m12,
- \a m21, \a m22, \a dx and \a dy.
-
- Note that this function replaces the previous values. QMatrix
- provide the translate(), rotate(), scale() and shear() convenience
- functions to manipulate the various matrix elements based on the
- currently defined coordinate system.
-
- \sa QMatrix()
-*/
-
-void QMatrix::setMatrix(qreal m11, qreal m12, qreal m21, qreal m22, qreal dx, qreal dy)
-{
- _m11 = m11;
- _m12 = m12;
- _m21 = m21;
- _m22 = m22;
- _dx = dx;
- _dy = dy;
-}
-
-
-/*!
- \fn qreal QMatrix::m11() const
-
- Returns the horizontal scaling factor.
-
- \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-/*!
- \fn qreal QMatrix::m12() const
-
- Returns the vertical shearing factor.
-
- \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-/*!
- \fn qreal QMatrix::m21() const
-
- Returns the horizontal shearing factor.
-
- \sa shear(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-/*!
- \fn qreal QMatrix::m22() const
-
- Returns the vertical scaling factor.
-
- \sa scale(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-/*!
- \fn qreal QMatrix::dx() const
-
- Returns the horizontal translation factor.
-
- \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-/*!
- \fn qreal QMatrix::dy() const
-
- Returns the vertical translation factor.
-
- \sa translate(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-
-
-/*!
- Maps the given coordinates \a x and \a y into the coordinate
- system defined by this matrix. The resulting values are put in *\a
- tx and *\a ty, respectively.
-
- The coordinates are transformed using the following formulas:
-
- \snippet code/src_gui_painting_qmatrix.cpp 1
-
- The point (x, y) is the original point, and (x', y') is the
- transformed point.
-
- \sa {QMatrix#Basic Matrix Operations}{Basic Matrix Operations}
-*/
-
-void QMatrix::map(qreal x, qreal y, qreal *tx, qreal *ty) const
-{
- MAPDOUBLE(x, y, *tx, *ty);
-}
-
-
-
-/*!
- \overload
-
- Maps the given coordinates \a x and \a y into the coordinate
- system defined by this matrix. The resulting values are put in *\a
- tx and *\a ty, respectively. Note that the transformed coordinates
- are rounded to the nearest integer.
-*/
-
-void QMatrix::map(int x, int y, int *tx, int *ty) const
-{
- MAPINT(x, y, *tx, *ty);
-}
-
-QRect QMatrix::mapRect(const QRect &rect) const
-{
- QRect result;
- if (_m12 == 0.0F && _m21 == 0.0F) {
- int x = qRound(_m11*rect.x() + _dx);
- int y = qRound(_m22*rect.y() + _dy);
- int w = qRound(_m11*rect.width());
- int h = qRound(_m22*rect.height());
- if (w < 0) {
- w = -w;
- x -= w;
- }
- if (h < 0) {
- h = -h;
- y -= h;
- }
- result = QRect(x, y, w, h);
- } else {
- // see mapToPolygon for explanations of the algorithm.
- qreal x0, y0;
- qreal x, y;
- MAPDOUBLE(rect.left(), rect.top(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
- MAPDOUBLE(rect.right() + 1, rect.top(), x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- MAPDOUBLE(rect.right() + 1, rect.bottom() + 1, x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- MAPDOUBLE(rect.left(), rect.bottom() + 1, x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- result = QRect(qRound(xmin), qRound(ymin), qRound(xmax)-qRound(xmin), qRound(ymax)-qRound(ymin));
- }
- return result;
-}
-
-/*!
- \fn QRectF QMatrix::mapRect(const QRectF &rectangle) const
-
- Creates and returns a QRectF object that is a copy of the given \a
- rectangle, mapped into the coordinate system defined by this
- matrix.
-
- The rectangle's coordinates are transformed using the following
- formulas:
-
- \snippet code/src_gui_painting_qmatrix.cpp 2
-
- If rotation or shearing has been specified, this function returns
- the \e bounding rectangle. To retrieve the exact region the given
- \a rectangle maps to, use the mapToPolygon() function instead.
-
- \sa mapToPolygon(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-QRectF QMatrix::mapRect(const QRectF &rect) const
-{
- QRectF result;
- if (_m12 == 0.0F && _m21 == 0.0F) {
- qreal x = _m11*rect.x() + _dx;
- qreal y = _m22*rect.y() + _dy;
- qreal w = _m11*rect.width();
- qreal h = _m22*rect.height();
- if (w < 0) {
- w = -w;
- x -= w;
- }
- if (h < 0) {
- h = -h;
- y -= h;
- }
- result = QRectF(x, y, w, h);
- } else {
- qreal x0, y0;
- qreal x, y;
- MAPDOUBLE(rect.x(), rect.y(), x0, y0);
- qreal xmin = x0;
- qreal ymin = y0;
- qreal xmax = x0;
- qreal ymax = y0;
- MAPDOUBLE(rect.x() + rect.width(), rect.y(), x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- MAPDOUBLE(rect.x() + rect.width(), rect.y() + rect.height(), x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- MAPDOUBLE(rect.x(), rect.y() + rect.height(), x, y);
- xmin = qMin(xmin, x);
- ymin = qMin(ymin, y);
- xmax = qMax(xmax, x);
- ymax = qMax(ymax, y);
- result = QRectF(xmin, ymin, xmax-xmin, ymax - ymin);
- }
- return result;
-}
-
-/*!
- \fn QRect QMatrix::mapRect(const QRect &rectangle) const
- \overload
-
- Creates and returns a QRect object that is a copy of the given \a
- rectangle, mapped into the coordinate system defined by this
- matrix. Note that the transformed coordinates are rounded to the
- nearest integer.
-*/
-
-
-/*!
- \fn QPoint operator*(const QPoint &point, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{point}).
-
- \sa QMatrix::map()
-*/
-
-QPoint QMatrix::map(const QPoint &p) const
-{
- qreal fx = p.x();
- qreal fy = p.y();
- return QPoint(qRound(_m11*fx + _m21*fy + _dx),
- qRound(_m12*fx + _m22*fy + _dy));
-}
-
-/*!
- \fn QPointF operator*(const QPointF &point, const QMatrix &matrix)
- \relates QMatrix
-
- Same as \a{matrix}.map(\a{point}).
-
- \sa QMatrix::map()
-*/
-
-/*!
- \overload
-
- Creates and returns a QPointF object that is a copy of the given
- \a point, mapped into the coordinate system defined by this
- matrix.
-*/
-QPointF QMatrix::map(const QPointF &point) const
-{
- qreal fx = point.x();
- qreal fy = point.y();
- return QPointF(_m11*fx + _m21*fy + _dx, _m12*fx + _m22*fy + _dy);
-}
-
-/*!
- \fn QPoint QMatrix::map(const QPoint &point) const
- \overload
-
- Creates and returns a QPoint object that is a copy of the given \a
- point, mapped into the coordinate system defined by this
- matrix. Note that the transformed coordinates are rounded to the
- nearest integer.
-*/
-
-/*!
- \fn QLineF operator*(const QLineF &line, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{line}).
-
- \sa QMatrix::map()
-*/
-
-/*!
- \fn QLine operator*(const QLine &line, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{line}).
-
- \sa QMatrix::map()
-*/
-
-/*!
- \overload
-
- Creates and returns a QLineF object that is a copy of the given \a
- line, mapped into the coordinate system defined by this matrix.
-*/
-QLineF QMatrix::map(const QLineF &line) const
-{
- return QLineF(map(line.p1()), map(line.p2()));
-}
-
-/*!
- \overload
-
- Creates and returns a QLine object that is a copy of the given \a
- line, mapped into the coordinate system defined by this matrix.
- Note that the transformed coordinates are rounded to the nearest
- integer.
-*/
-QLine QMatrix::map(const QLine &line) const
-{
- return QLine(map(line.p1()), map(line.p2()));
-}
-
-/*!
- \fn QPolygonF operator *(const QPolygonF &polygon, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{polygon}).
-
- \sa QMatrix::map()
-*/
-
-/*!
- \fn QPolygon operator*(const QPolygon &polygon, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{polygon}).
-
- \sa QMatrix::map()
-*/
-
-QPolygon QMatrix::map(const QPolygon &a) const
-{
- int size = a.size();
- int i;
- QPolygon p(size);
- const QPoint *da = a.constData();
- QPoint *dp = p.data();
- for(i = 0; i < size; i++) {
- MAPINT(da[i].x(), da[i].y(), dp[i].rx(), dp[i].ry());
- }
- return p;
-}
-
-/*!
- \fn QPolygonF QMatrix::map(const QPolygonF &polygon) const
- \overload
-
- Creates and returns a QPolygonF object that is a copy of the given
- \a polygon, mapped into the coordinate system defined by this
- matrix.
-*/
-QPolygonF QMatrix::map(const QPolygonF &a) const
-{
- int size = a.size();
- int i;
- QPolygonF p(size);
- const QPointF *da = a.constData();
- QPointF *dp = p.data();
- for(i = 0; i < size; i++) {
- MAPDOUBLE(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp);
- }
- return p;
-}
-
-/*!
- \fn QPolygon QMatrix::map(const QPolygon &polygon) const
- \overload
-
- Creates and returns a QPolygon object that is a copy of the given
- \a polygon, mapped into the coordinate system defined by this
- matrix. Note that the transformed coordinates are rounded to the
- nearest integer.
-*/
-
-/*!
- \fn QRegion operator*(const QRegion &region, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{region}).
-
- \sa QMatrix::map()
-*/
-
-extern QPainterPath qt_regionToPath(const QRegion &region);
-
-/*!
- \fn QRegion QMatrix::map(const QRegion &region) const
- \overload
-
- Creates and returns a QRegion object that is a copy of the given
- \a region, mapped into the coordinate system defined by this matrix.
-
- Calling this method can be rather expensive if rotations or
- shearing are used.
-*/
-QRegion QMatrix::map(const QRegion &r) const
-{
- if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) { // translate or identity
- if (_dx == 0.0 && _dy == 0.0) // Identity
- return r;
- QRegion copy(r);
- copy.translate(qRound(_dx), qRound(_dy));
- return copy;
- }
-
- QPainterPath p = map(qt_regionToPath(r));
- return p.toFillPolygon(QTransform()).toPolygon();
-}
-
-/*!
- \fn QPainterPath operator *(const QPainterPath &path, const QMatrix &matrix)
- \relates QMatrix
-
- This is the same as \a{matrix}.map(\a{path}).
-
- \sa QMatrix::map()
-*/
-
-/*!
- \overload
-
- Creates and returns a QPainterPath object that is a copy of the
- given \a path, mapped into the coordinate system defined by this
- matrix.
-*/
-QPainterPath QMatrix::map(const QPainterPath &path) const
-{
- if (path.isEmpty())
- return QPainterPath();
-
- QPainterPath copy = path;
-
- // Translate or identity
- if (_m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0) {
-
- // Translate
- if (_dx != 0.0 || _dy != 0.0) {
- copy.detach();
- for (int i=0; i<path.elementCount(); ++i) {
- QPainterPath::Element &e = copy.d_ptr->elements[i];
- e.x += _dx;
- e.y += _dy;
- }
- }
-
- // Full xform
- } else {
- copy.detach();
- for (int i=0; i<path.elementCount(); ++i) {
- QPainterPath::Element &e = copy.d_ptr->elements[i];
- qreal fx = e.x, fy = e.y;
- e.x = _m11*fx + _m21*fy + _dx;
- e.y = _m12*fx + _m22*fy + _dy;
- }
- }
-
- return copy;
-}
-
-/*!
- \fn QPolygon QMatrix::mapToPolygon(const QRect &rectangle) const
-
- Creates and returns a QPolygon representation of the given \a
- rectangle, mapped into the coordinate system defined by this
- matrix.
-
- The rectangle's coordinates are transformed using the following
- formulas:
-
- \snippet code/src_gui_painting_qmatrix.cpp 3
-
- Polygons and rectangles behave slightly differently when
- transformed (due to integer rounding), so
- \c{matrix.map(QPolygon(rectangle))} is not always the same as
- \c{matrix.mapToPolygon(rectangle)}.
-
- \sa mapRect(), {QMatrix#Basic Matrix Operations}{Basic Matrix
- Operations}
-*/
-QPolygon QMatrix::mapToPolygon(const QRect &rect) const
-{
- QPolygon a(4);
- qreal x[4], y[4];
- if (_m12 == 0.0F && _m21 == 0.0F) {
- x[0] = _m11*rect.x() + _dx;
- y[0] = _m22*rect.y() + _dy;
- qreal w = _m11*rect.width();
- qreal h = _m22*rect.height();
- if (w < 0) {
- w = -w;
- x[0] -= w;
- }
- if (h < 0) {
- h = -h;
- y[0] -= h;
- }
- x[1] = x[0]+w;
- x[2] = x[1];
- x[3] = x[0];
- y[1] = y[0];
- y[2] = y[0]+h;
- y[3] = y[2];
- } else {
- qreal right = rect.x() + rect.width();
- qreal bottom = rect.y() + rect.height();
- MAPDOUBLE(rect.x(), rect.y(), x[0], y[0]);
- MAPDOUBLE(right, rect.y(), x[1], y[1]);
- MAPDOUBLE(right, bottom, x[2], y[2]);
- MAPDOUBLE(rect.x(), bottom, x[3], y[3]);
- }
-#if 0
- int i;
- for(i = 0; i< 4; i++)
- qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], qRound(x[i]), qRound(y[i]));
- qDebug("width=%f, height=%f", qSqrt((x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0])),
- qSqrt((x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3])));
-#endif
- // all coordinates are correctly, tranform to a pointarray
- // (rounding to the next integer)
- a.setPoints(4, qRound(x[0]), qRound(y[0]),
- qRound(x[1]), qRound(y[1]),
- qRound(x[2]), qRound(y[2]),
- qRound(x[3]), qRound(y[3]));
- return a;
-}
-
-/*!
- Resets the matrix to an identity matrix, i.e. all elements are set
- to zero, except \c m11 and \c m22 (specifying the scale) which are
- set to 1.
-
- \sa QMatrix(), isIdentity(), {QMatrix#Basic Matrix
- Operations}{Basic Matrix Operations}
-*/
-
-void QMatrix::reset()
-{
- _m11 = _m22 = 1.0;
- _m12 = _m21 = _dx = _dy = 0.0;
-}
-
-/*!
- \fn bool QMatrix::isIdentity() const
-
- Returns \c true if the matrix is the identity matrix, otherwise
- returns \c false.
-
- \sa reset()
-*/
-
-/*!
- Moves the coordinate system \a dx along the x axis and \a dy along
- the y axis, and returns a reference to the matrix.
-
- \sa setMatrix()
-*/
-
-QMatrix &QMatrix::translate(qreal dx, qreal dy)
-{
- _dx += dx*_m11 + dy*_m21;
- _dy += dy*_m22 + dx*_m12;
- return *this;
-}
-
-/*!
- \fn QMatrix &QMatrix::scale(qreal sx, qreal sy)
-
- Scales the coordinate system by \a sx horizontally and \a sy
- vertically, and returns a reference to the matrix.
-
- \sa setMatrix()
-*/
-
-QMatrix &QMatrix::scale(qreal sx, qreal sy)
-{
- _m11 *= sx;
- _m12 *= sx;
- _m21 *= sy;
- _m22 *= sy;
- return *this;
-}
-
-/*!
- Shears the coordinate system by \a sh horizontally and \a sv
- vertically, and returns a reference to the matrix.
-
- \sa setMatrix()
-*/
-
-QMatrix &QMatrix::shear(qreal sh, qreal sv)
-{
- qreal tm11 = sv*_m21;
- qreal tm12 = sv*_m22;
- qreal tm21 = sh*_m11;
- qreal tm22 = sh*_m12;
- _m11 += tm11;
- _m12 += tm12;
- _m21 += tm21;
- _m22 += tm22;
- return *this;
-}
-
-const qreal deg2rad = qreal(0.017453292519943295769); // pi/180
-
-/*!
- \fn QMatrix &QMatrix::rotate(qreal degrees)
-
- Rotates the coordinate system the given \a degrees
- counterclockwise.
-
- Note that if you apply a QMatrix to a point defined in widget
- coordinates, the direction of the rotation will be clockwise
- because the y-axis points downwards.
-
- Returns a reference to the matrix.
-
- \sa setMatrix()
-*/
-
-QMatrix &QMatrix::rotate(qreal a)
-{
- qreal sina = 0;
- qreal cosa = 0;
- if (a == 90. || a == -270.)
- sina = 1.;
- else if (a == 270. || a == -90.)
- sina = -1.;
- else if (a == 180.)
- cosa = -1.;
- else{
- qreal b = deg2rad*a; // convert to radians
- sina = qSin(b); // fast and convenient
- cosa = qCos(b);
- }
- qreal tm11 = cosa*_m11 + sina*_m21;
- qreal tm12 = cosa*_m12 + sina*_m22;
- qreal tm21 = -sina*_m11 + cosa*_m21;
- qreal tm22 = -sina*_m12 + cosa*_m22;
- _m11 = tm11; _m12 = tm12;
- _m21 = tm21; _m22 = tm22;
- return *this;
-}
-
-/*!
- \fn bool QMatrix::isInvertible() const
-
- Returns \c true if the matrix is invertible, otherwise returns \c false.
-
- \sa inverted()
-*/
-
-/*!
- \since 4.6
- \fn qreal QMatrix::determinant() const
-
- Returns the matrix's determinant.
-*/
-
-/*!
- Returns an inverted copy of this matrix.
-
- If the matrix is singular (not invertible), the returned matrix is
- the identity matrix. If \a invertible is valid (i.e. not 0), its
- value is set to true if the matrix is invertible, otherwise it is
- set to false.
-
- \sa isInvertible()
-*/
-
-QMatrix QMatrix::inverted(bool *invertible) const
-{
- qreal dtr = determinant();
- if (dtr == 0.0) {
- if (invertible)
- *invertible = false; // singular matrix
- return QMatrix(true);
- }
- else { // invertible matrix
- if (invertible)
- *invertible = true;
- qreal dinv = 1.0/dtr;
- return QMatrix((_m22*dinv), (-_m12*dinv),
- (-_m21*dinv), (_m11*dinv),
- ((_m21*_dy - _m22*_dx)*dinv),
- ((_m12*_dx - _m11*_dy)*dinv),
- true);
- }
-}
-
-
-/*!
- \fn bool QMatrix::operator==(const QMatrix &matrix) const
-
- Returns \c true if this matrix is equal to the given \a matrix,
- otherwise returns \c false.
-*/
-
-bool QMatrix::operator==(const QMatrix &m) const
-{
- return _m11 == m._m11 &&
- _m12 == m._m12 &&
- _m21 == m._m21 &&
- _m22 == m._m22 &&
- _dx == m._dx &&
- _dy == m._dy;
-}
-
-
-/*!
- \since 5.6
- \relates QMatrix
-
- Returns the hash value for \a key, using
- \a seed to seed the calculation.
-*/
-uint qHash(const QMatrix &key, uint seed) noexcept
-{
- QtPrivate::QHashCombine hash;
- seed = hash(seed, key.m11());
- seed = hash(seed, key.m12());
- seed = hash(seed, key.m21());
- seed = hash(seed, key.m22());
- seed = hash(seed, key.dx());
- seed = hash(seed, key.dy());
- return seed;
-}
-
-/*!
- \fn bool QMatrix::operator!=(const QMatrix &matrix) const
-
- Returns \c true if this matrix is not equal to the given \a matrix,
- otherwise returns \c false.
-*/
-
-bool QMatrix::operator!=(const QMatrix &m) const
-{
- return _m11 != m._m11 ||
- _m12 != m._m12 ||
- _m21 != m._m21 ||
- _m22 != m._m22 ||
- _dx != m._dx ||
- _dy != m._dy;
-}
-
-/*!
- \fn QMatrix &QMatrix::operator *=(const QMatrix &matrix)
- \overload
-
- Returns the result of multiplying this matrix by the given \a
- matrix.
-*/
-
-QMatrix &QMatrix::operator *=(const QMatrix &m)
-{
- qreal tm11 = _m11*m._m11 + _m12*m._m21;
- qreal tm12 = _m11*m._m12 + _m12*m._m22;
- qreal tm21 = _m21*m._m11 + _m22*m._m21;
- qreal tm22 = _m21*m._m12 + _m22*m._m22;
-
- qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
- qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
-
- _m11 = tm11; _m12 = tm12;
- _m21 = tm21; _m22 = tm22;
- _dx = tdx; _dy = tdy;
- return *this;
-}
-
-/*!
- \fn QMatrix QMatrix::operator *(const QMatrix &matrix) const
-
- Returns the result of multiplying this matrix by the given \a
- matrix.
-
- Note that matrix multiplication is not commutative, i.e. a*b !=
- b*a.
-*/
-
-QMatrix QMatrix::operator *(const QMatrix &m) const
-{
- qreal tm11 = _m11*m._m11 + _m12*m._m21;
- qreal tm12 = _m11*m._m12 + _m12*m._m22;
- qreal tm21 = _m21*m._m11 + _m22*m._m21;
- qreal tm22 = _m21*m._m12 + _m22*m._m22;
-
- qreal tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
- qreal tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
- return QMatrix(tm11, tm12, tm21, tm22, tdx, tdy, true);
-}
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
-/*!
- Assigns the given \a matrix's values to this matrix.
-*/
-QMatrix &QMatrix::operator=(const QMatrix &matrix) noexcept
-{
- _m11 = matrix._m11;
- _m12 = matrix._m12;
- _m21 = matrix._m21;
- _m22 = matrix._m22;
- _dx = matrix._dx;
- _dy = matrix._dy;
- return *this;
-}
-#endif
-
-/*!
- \since 4.2
-
- Returns the matrix as a QVariant.
-*/
-QMatrix::operator QVariant() const
-{
- return QVariant(QMetaType::QMatrix, this);
-}
-
-Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m)
-{
- return m.map(p);
-}
-
-
-/*****************************************************************************
- QMatrix stream functions
- *****************************************************************************/
-#ifndef QT_NO_DATASTREAM
-/*!
- \fn QDataStream &operator<<(QDataStream &stream, const QMatrix &matrix)
- \relates QMatrix
-
- Writes the given \a matrix to the given \a stream and returns a
- reference to the stream.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator<<(QDataStream &s, const QMatrix &m)
-{
- if (s.version() == 1) {
- s << (float)m.m11() << (float)m.m12() << (float)m.m21()
- << (float)m.m22() << (float)m.dx() << (float)m.dy();
- } else {
- s << double(m.m11())
- << double(m.m12())
- << double(m.m21())
- << double(m.m22())
- << double(m.dx())
- << double(m.dy());
- }
- return s;
-}
-
-/*!
- \fn QDataStream &operator>>(QDataStream &stream, QMatrix &matrix)
- \relates QMatrix
-
- Reads the given \a matrix from the given \a stream and returns a
- reference to the stream.
-
- \sa {Serializing Qt Data Types}
-*/
-
-QDataStream &operator>>(QDataStream &s, QMatrix &m)
-{
- if (s.version() == 1) {
- float m11, m12, m21, m22, dx, dy;
- s >> m11; s >> m12; s >> m21; s >> m22;
- s >> dx; s >> dy;
- m.setMatrix(m11, m12, m21, m22, dx, dy);
- }
- else {
- double m11, m12, m21, m22, dx, dy;
- s >> m11;
- s >> m12;
- s >> m21;
- s >> m22;
- s >> dx;
- s >> dy;
- m.setMatrix(m11, m12, m21, m22, dx, dy);
- }
- return s;
-}
-#endif // QT_NO_DATASTREAM
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug dbg, const QMatrix &m)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "QMatrix("
- << "11=" << m.m11()
- << " 12=" << m.m12()
- << " 21=" << m.m21()
- << " 22=" << m.m22()
- << " dx=" << m.dx()
- << " dy=" << m.dy()
- << ')';
- return dbg;
-}
-#endif
-
-/*!
- \fn bool qFuzzyCompare(const QMatrix& m1, const QMatrix& m2)
-
- \relates QMatrix
- \since 4.6
-
- \brief The qFuzzyCompare function is for comparing two matrices
- using a fuzziness factor.
-
- Returns \c true if \a m1 and \a m2 are equal, allowing for a small
- fuzziness factor for floating-point comparisons; false otherwise.
-*/
-
-QT_END_NAMESPACE
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
deleted file mode 100644
index a167260ade..0000000000
--- a/src/gui/painting/qmatrix.h
+++ /dev/null
@@ -1,194 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtGui 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 QMATRIX_H
-#define QMATRIX_H
-
-#include <QtGui/qtguiglobal.h>
-#include <QtGui/qpolygon.h>
-#include <QtGui/qregion.h>
-#include <QtGui/qwindowdefs.h>
-#include <QtCore/qline.h>
-#include <QtCore/qpoint.h>
-#include <QtCore/qrect.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QPainterPath;
-class QVariant;
-
-class Q_GUI_EXPORT QMatrix // 2D transform matrix
-{
-public:
- inline explicit QMatrix(Qt::Initialization) {}
- QMatrix();
- QMatrix(qreal m11, qreal m12, qreal m21, qreal m22,
- qreal dx, qreal dy);
-
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- // ### Qt 6: remove; the compiler-generated ones are fine!
- QMatrix &operator=(QMatrix &&other) noexcept // = default
- { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QMatrix)); return *this; }
- QMatrix &operator=(const QMatrix &) noexcept; // = default
- QMatrix(QMatrix &&other) noexcept // = default
- { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QMatrix)); }
- QMatrix(const QMatrix &other) noexcept; // = default
-#endif
-
- void setMatrix(qreal m11, qreal m12, qreal m21, qreal m22,
- qreal dx, qreal dy);
-
- qreal m11() const { return _m11; }
- qreal m12() const { return _m12; }
- qreal m21() const { return _m21; }
- qreal m22() const { return _m22; }
- qreal dx() const { return _dx; }
- qreal dy() const { return _dy; }
-
- void map(int x, int y, int *tx, int *ty) const;
- void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
- QRect mapRect(const QRect &) const;
- QRectF mapRect(const QRectF &) const;
-
- QPoint map(const QPoint &p) const;
- QPointF map(const QPointF&p) const;
- QLine map(const QLine &l) const;
- QLineF map(const QLineF &l) const;
- QPolygonF map(const QPolygonF &a) const;
- QPolygon map(const QPolygon &a) const;
- QRegion map(const QRegion &r) const;
- QPainterPath map(const QPainterPath &p) const;
- QPolygon mapToPolygon(const QRect &r) const;
-
- void reset();
- inline bool isIdentity() const;
-
- QMatrix &translate(qreal dx, qreal dy);
- QMatrix &scale(qreal sx, qreal sy);
- QMatrix &shear(qreal sh, qreal sv);
- QMatrix &rotate(qreal a);
-
- bool isInvertible() const { return !qFuzzyIsNull(_m11*_m22 - _m12*_m21); }
- qreal determinant() const { return _m11*_m22 - _m12*_m21; }
-
- Q_REQUIRED_RESULT QMatrix inverted(bool *invertible = nullptr) const;
-
- bool operator==(const QMatrix &) const;
- bool operator!=(const QMatrix &) const;
-
- QMatrix &operator*=(const QMatrix &);
- QMatrix operator*(const QMatrix &o) const;
-
- operator QVariant() const;
-
-private:
- inline QMatrix(bool)
- : _m11(1.)
- , _m12(0.)
- , _m21(0.)
- , _m22(1.)
- , _dx(0.)
- , _dy(0.) {}
- inline QMatrix(qreal am11, qreal am12, qreal am21, qreal am22, qreal adx, qreal ady, bool)
- : _m11(am11)
- , _m12(am12)
- , _m21(am21)
- , _m22(am22)
- , _dx(adx)
- , _dy(ady) {}
- friend class QTransform;
- qreal _m11, _m12;
- qreal _m21, _m22;
- qreal _dx, _dy;
-};
-Q_DECLARE_TYPEINFO(QMatrix, Q_MOVABLE_TYPE);
-
-Q_GUI_EXPORT Q_DECL_CONST_FUNCTION uint qHash(const QMatrix &key, uint seed = 0) noexcept;
-
-// mathematical semantics
-inline QPoint operator*(const QPoint &p, const QMatrix &m)
-{ return m.map(p); }
-inline QPointF operator*(const QPointF &p, const QMatrix &m)
-{ return m.map(p); }
-inline QLineF operator*(const QLineF &l, const QMatrix &m)
-{ return m.map(l); }
-inline QLine operator*(const QLine &l, const QMatrix &m)
-{ return m.map(l); }
-inline QPolygon operator *(const QPolygon &a, const QMatrix &m)
-{ return m.map(a); }
-inline QPolygonF operator *(const QPolygonF &a, const QMatrix &m)
-{ return m.map(a); }
-inline QRegion operator *(const QRegion &r, const QMatrix &m)
-{ return m.map(r); }
-Q_GUI_EXPORT QPainterPath operator *(const QPainterPath &p, const QMatrix &m);
-
-inline bool QMatrix::isIdentity() const
-{
- return qFuzzyIsNull(_m11 - 1) && qFuzzyIsNull(_m22 - 1) && qFuzzyIsNull(_m12)
- && qFuzzyIsNull(_m21) && qFuzzyIsNull(_dx) && qFuzzyIsNull(_dy);
-}
-
-inline bool qFuzzyCompare(const QMatrix& m1, const QMatrix& m2)
-{
- return qFuzzyCompare(m1.m11(), m2.m11())
- && qFuzzyCompare(m1.m12(), m2.m12())
- && qFuzzyCompare(m1.m21(), m2.m21())
- && qFuzzyCompare(m1.m22(), m2.m22())
- && qFuzzyCompare(m1.dx(), m2.dx())
- && qFuzzyCompare(m1.dy(), m2.dy());
-}
-
-
-/*****************************************************************************
- QMatrix stream functions
- *****************************************************************************/
-
-#ifndef QT_NO_DATASTREAM
-Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix &);
-Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix &);
-#endif
-
-#ifndef QT_NO_DEBUG_STREAM
-Q_GUI_EXPORT QDebug operator<<(QDebug, const QMatrix &);
-#endif
-
-QT_END_NAMESPACE
-
-#endif // QMATRIX_H
diff --git a/src/gui/painting/qpaintdevice.qdoc b/src/gui/painting/qpaintdevice.qdoc
index 0cba864523..3b93faed84 100644
--- a/src/gui/painting/qpaintdevice.qdoc
+++ b/src/gui/painting/qpaintdevice.qdoc
@@ -39,8 +39,7 @@
right and Y increases downwards. The unit is one pixel.
The drawing capabilities of QPaintDevice are currently implemented
- by the QWidget, QImage, QPixmap, QGLPixelBuffer, QPicture, and
- QPrinter subclasses.
+ by the QWidget, QImage, QPixmap, QPicture, and QPrinter subclasses.
To implement support for a new backend, you must derive from
QPaintDevice and reimplement the virtual paintEngine() function to
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index 315bf0daf2..1785fcd12d 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -508,7 +508,7 @@ void QPaintEngine::drawEllipse(const QRectF &rect)
if (hasFeature(PainterPaths)) {
drawPath(path);
} else {
- QPolygonF polygon = path.toFillPolygon(QTransform());
+ QPolygonF polygon = path.toFillPolygon();
drawPolygon(polygon.data(), polygon.size(), ConvexMode);
}
}
diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h
index e90020dbbf..73727e463d 100644
--- a/src/gui/painting/qpaintengine.h
+++ b/src/gui/painting/qpaintengine.h
@@ -273,9 +273,6 @@ public:
QBrush backgroundBrush() const;
Qt::BGMode backgroundMode() const;
QFont font() const;
-#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use transform()") QMatrix matrix() const;
-#endif // QT_DEPRECATED_SINCE(5, 15)
QTransform transform() const;
Qt::ClipOperation clipOperation() const;
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 089aadc3f7..1244ea6709 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -434,14 +434,14 @@ public:
QImage::Format prepare(QImage *image);
- uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * qsizetype(bytes_per_line); }
+ uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
int width() const { return m_width; }
int height() const { return m_height; }
- int bytesPerLine() const { return bytes_per_line; }
+ qsizetype bytesPerLine() const { return bytes_per_line; }
int bytesPerPixel() const { return bytes_per_pixel; }
template<typename T>
- int stride() { return bytes_per_line / sizeof(T); }
+ int stride() { return static_cast<int>(bytes_per_line / sizeof(T)); }
uchar *buffer() const { return m_buffer; }
@@ -456,7 +456,7 @@ public:
private:
int m_width;
int m_height;
- int bytes_per_line;
+ qsizetype bytes_per_line;
int bytes_per_pixel;
uchar *m_buffer;
};
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 390147463d..49f4d7be2e 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -96,10 +96,15 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
QTextItem::RenderFlags flags, qreal width,
const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
-Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat);
+static void qt_draw_decoration_for_glyphs(QPainter *painter,
+ const QPointF &decorationPosition,
+ const glyph_t *glyphArray,
+ const QFixedPoint *positions,
+ int glyphCount,
+ QFontEngine *fontEngine,
+ bool underline,
+ bool overline,
+ bool strikeOut);
static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
@@ -2555,19 +2560,19 @@ QRegion QPainter::clipRegion() const
case QPainterClipInfo::PathClip: {
QTransform matrix = (info.matrix * d->invMatrix);
if (lastWasNothing) {
- region = QRegion((info.path * matrix).toFillPolygon(QTransform()).toPolygon(),
+ region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
info.path.fillRule());
lastWasNothing = false;
continue;
}
if (info.operation == Qt::IntersectClip) {
- region &= QRegion((info.path * matrix).toFillPolygon(QTransform()).toPolygon(),
+ region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
info.path.fillRule());
} else if (info.operation == Qt::NoClip) {
lastWasNothing = true;
region = QRegion();
} else {
- region = QRegion((info.path * matrix).toFillPolygon(QTransform()).toPolygon(),
+ region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
info.path.fillRule());
}
break;
@@ -2891,175 +2896,6 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
d->updateState(d->state);
}
-#if QT_DEPRECATED_SINCE(5, 13)
-/*!
- \since 4.2
- \obsolete
-
- Sets the transformation matrix to \a matrix and enables transformations.
-
- \note It is advisable to use setWorldTransform() instead of this function to
- preserve the properties of perspective transformations.
-
- If \a combine is true, then \a matrix is combined with the current
- transformation matrix; otherwise \a matrix replaces the current
- transformation matrix.
-
- If \a matrix is the identity matrix and \a combine is false, this
- function calls setWorldMatrixEnabled(false). (The identity matrix is the
- matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
- rest are 0.0.)
-
- The following functions can transform the coordinate system without using
- a QMatrix:
- \list
- \li translate()
- \li scale()
- \li shear()
- \li rotate()
- \endlist
-
- They operate on the painter's worldMatrix() and are implemented like this:
-
- \snippet code/src_gui_painting_qpainter.cpp 4
-
- Note that when using setWorldMatrix() function you should always have
- \a combine be true when you are drawing into a QPicture. Otherwise
- it may not be possible to replay the picture with additional
- transformations; using the translate(), scale(), etc. convenience
- functions is safe.
-
- For more information about the coordinate system, transformations
- and window-viewport conversion, see \l {Coordinate System}.
-
- \sa setWorldTransform(), QTransform
-*/
-
-void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
-{
- setWorldTransform(QTransform(matrix), combine);
-}
-
-/*!
- \since 4.2
- \obsolete
-
- Returns the world transformation matrix.
-
- It is advisable to use worldTransform() because worldMatrix() does not
- preserve the properties of perspective transformations.
-
- \sa {QPainter#Coordinate Transformations}{Coordinate Transformations},
- {Coordinate System}
-*/
-
-const QMatrix &QPainter::worldMatrix() const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::worldMatrix: Painter not active");
- return d->fakeState()->transform.toAffine();
- }
- return d->state->worldMatrix.toAffine();
-}
-
-/*!
- \obsolete
-
- Use setWorldTransform() instead.
-
- \sa setWorldTransform()
-*/
-
-void QPainter::setMatrix(const QMatrix &matrix, bool combine)
-{
- setWorldTransform(QTransform(matrix), combine);
-}
-
-/*!
- \obsolete
-
- Use worldTransform() instead.
-
- \sa worldTransform()
-*/
-
-const QMatrix &QPainter::matrix() const
-{
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_DEPRECATED
- return worldMatrix();
-QT_WARNING_POP
-}
-
-
-/*!
- \since 4.2
- \obsolete
-
- Returns the transformation matrix combining the current
- window/viewport and world transformation.
-
- It is advisable to use combinedTransform() instead of this
- function to preserve the properties of perspective transformations.
-
- \sa setWorldTransform(), setWindow(), setViewport()
-*/
-QMatrix QPainter::combinedMatrix() const
-{
- return combinedTransform().toAffine();
-}
-
-
-/*!
- \obsolete
-
- Returns the matrix that transforms from logical coordinates to
- device coordinates of the platform dependent paint device.
-
- \note It is advisable to use deviceTransform() instead of this
- function to preserve the properties of perspective transformations.
-
- This function is \e only needed when using platform painting
- commands on the platform dependent handle (Qt::HANDLE), and the
- platform does not do transformations nativly.
-
- The QPaintEngine::PaintEngineFeature enum can be queried to
- determine whether the platform performs the transformations or
- not.
-
- \sa worldMatrix(), QPaintEngine::hasFeature(),
-*/
-const QMatrix &QPainter::deviceMatrix() const
-{
- Q_D(const QPainter);
- if (!d->engine) {
- qWarning("QPainter::deviceMatrix: Painter not active");
- return d->fakeState()->transform.toAffine();
- }
- return d->state->matrix.toAffine();
-}
-
-/*!
- \obsolete
-
- Resets any transformations that were made using translate(), scale(),
- shear(), rotate(), setWorldMatrix(), setViewport() and
- setWindow().
-
- It is advisable to use resetTransform() instead of this function
- to preserve the properties of perspective transformations.
-
- \sa {QPainter#Coordinate Transformations}{Coordinate
- Transformations}
-*/
-
-void QPainter::resetMatrix()
-{
- resetTransform();
-}
-#endif
-
/*!
\since 4.2
@@ -3109,34 +2945,6 @@ bool QPainter::worldMatrixEnabled() const
return d->state->WxF;
}
-#if QT_DEPRECATED_SINCE(5, 13)
-/*!
- \obsolete
-
- Use setWorldMatrixEnabled() instead.
-
- \sa setWorldMatrixEnabled()
-*/
-
-void QPainter::setMatrixEnabled(bool enable)
-{
- setWorldMatrixEnabled(enable);
-}
-
-/*!
- \obsolete
-
- Use worldMatrixEnabled() instead
-
- \sa worldMatrixEnabled()
-*/
-
-bool QPainter::matrixEnabled() const
-{
- return worldMatrixEnabled();
-}
-#endif
-
/*!
Scales the coordinate system by (\a{sx}, \a{sy}).
@@ -5607,40 +5415,31 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
}
- d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, fontD->fontEngine,
- glyphRun.overline(), glyphRun.underline(), glyphRun.strikeOut());
+ d->drawGlyphs(engineRequiresPretransformedGlyphPositions
+ ? d->state->transform().map(position)
+ : position,
+ glyphIndexes,
+ fixedPointPositions.data(),
+ count,
+ fontD->fontEngine,
+ glyphRun.overline(),
+ glyphRun.underline(),
+ glyphRun.strikeOut());
}
-void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
+void QPainterPrivate::drawGlyphs(const QPointF &decorationPosition,
+ const quint32 *glyphArray,
+ QFixedPoint *positions,
int glyphCount,
- QFontEngine *fontEngine, bool overline, bool underline,
+ QFontEngine *fontEngine,
+ bool overline,
+ bool underline,
bool strikeOut)
{
Q_Q(QPainter);
updateState(state);
- QFixed leftMost;
- QFixed rightMost;
- QFixed baseLine;
- for (int i=0; i<glyphCount; ++i) {
- glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
- if (i == 0 || leftMost > positions[i].x)
- leftMost = positions[i].x;
-
- // We don't support glyphs that do not share a common baseline. If this turns out to
- // be a relevant use case, then we need to find clusters of glyphs that share a baseline
- // and do a drawTextItemDecorations call per cluster.
- if (i == 0 || baseLine < positions[i].y)
- baseLine = positions[i].y;
-
- // We use the advance rather than the actual bounds to match the algorithm in drawText()
- if (i == 0 || rightMost < positions[i].x + gm.xoff)
- rightMost = positions[i].x + gm.xoff;
- }
-
- QFixed width = rightMost - leftMost;
-
if (extended != nullptr && state->matrix.isAffine()) {
QStaticTextItem staticTextItem;
staticTextItem.color = state->pen.color();
@@ -5674,21 +5473,15 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positio
engine->drawTextItem(QPointF(0, 0), textItem);
}
- QTextItemInt::RenderFlags flags;
- if (underline)
- flags |= QTextItemInt::Underline;
- if (overline)
- flags |= QTextItemInt::Overline;
- if (strikeOut)
- flags |= QTextItemInt::StrikeOut;
-
- drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
- fontEngine,
- nullptr, // textEngine
- (underline
- ? QTextCharFormat::SingleUnderline
- : QTextCharFormat::NoUnderline),
- flags, width.toReal(), QTextCharFormat());
+ qt_draw_decoration_for_glyphs(q,
+ decorationPosition,
+ glyphArray,
+ positions,
+ glyphCount,
+ fontEngine,
+ underline,
+ overline,
+ strikeOut);
}
#endif // QT_NO_RAWFONT
@@ -5868,9 +5661,15 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
}
d->extended->drawStaticTextItem(item);
- qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
- item->numGlyphs, item->fontEngine(), staticText_d->font,
- QTextCharFormat());
+ qt_draw_decoration_for_glyphs(this,
+ topLeftPosition,
+ item->glyphs,
+ item->glyphPositions,
+ item->numGlyphs,
+ item->fontEngine(),
+ staticText_d->font.underline(),
+ staticText_d->font.overline(),
+ staticText_d->font.strikeOut());
}
if (currentColor != oldPen.color())
setPen(oldPen);
@@ -6375,49 +6174,44 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setRenderHint(QPainter::Qt4CompatiblePainting);
}
-Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
- const QFixedPoint *positions, int glyphCount,
- QFontEngine *fontEngine, const QFont &font,
- const QTextCharFormat &charFormat)
+static void qt_draw_decoration_for_glyphs(QPainter *painter,
+ const QPointF &decorationPosition,
+ const glyph_t *glyphArray,
+ const QFixedPoint *positions,
+ int glyphCount,
+ QFontEngine *fontEngine,
+ bool underline,
+ bool overline,
+ bool strikeOut)
{
- if (!(font.underline() || font.strikeOut() || font.overline()))
+ if (!underline && !overline && !strikeOut)
return;
- QFixed leftMost;
- QFixed rightMost;
- QFixed baseLine;
- for (int i=0; i<glyphCount; ++i) {
- glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
- if (i == 0 || leftMost > positions[i].x)
- leftMost = positions[i].x;
-
- // We don't support glyphs that do not share a common baseline. If this turns out to
- // be a relevant use case, then we need to find clusters of glyphs that share a baseline
- // and do a drawTextItemDecoration call per cluster.
- if (i == 0 || baseLine < positions[i].y)
- baseLine = positions[i].y;
-
- // We use the advance rather than the actual bounds to match the algorithm in drawText()
- if (i == 0 || rightMost < positions[i].x + gm.xoff)
- rightMost = positions[i].x + gm.xoff;
- }
-
- QFixed width = rightMost - leftMost;
QTextItem::RenderFlags flags;
-
- if (font.underline())
+ if (underline)
flags |= QTextItem::Underline;
- if (font.overline())
+ if (overline)
flags |= QTextItem::Overline;
- if (font.strikeOut())
+ if (strikeOut)
flags |= QTextItem::StrikeOut;
- drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
+ bool rtl = positions[glyphCount - 1].x < positions[0].x;
+ QFixed baseline = positions[0].y;
+ glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[rtl ? 0 : glyphCount - 1]);
+
+ qreal width = rtl
+ ? (positions[0].x + gm.xoff - positions[glyphCount - 1].x).toReal()
+ : (positions[glyphCount - 1].x + gm.xoff - positions[0].x).toReal();
+
+ drawTextItemDecoration(painter,
+ QPointF(decorationPosition.x(), baseline.toReal()),
fontEngine,
nullptr, // textEngine
- font.underline() ? QTextCharFormat::SingleUnderline
- : QTextCharFormat::NoUnderline, flags,
- width.toReal(), charFormat);
+ underline ? QTextCharFormat::SingleUnderline
+ : QTextCharFormat::NoUnderline,
+ flags,
+ width,
+ QTextCharFormat());
}
void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
@@ -8084,33 +7878,6 @@ QFont QPaintEngineState::font() const
return static_cast<const QPainterState *>(this)->font;
}
-#if QT_DEPRECATED_SINCE(5, 13)
-/*!
- \since 4.2
- \obsolete
-
- Use transform() instead.
-
- Returns the matrix in the current paint engine
- state.
-
- \note It is advisable to use transform() instead of this function to
- preserve the properties of perspective transformations.
-
- This variable should only be used when the state() returns a
- combination which includes the QPaintEngine::DirtyTransform flag.
-
- \sa state(), QPaintEngine::updateState()
-*/
-
-QMatrix QPaintEngineState::matrix() const
-{
- const QPainterState *st = static_cast<const QPainterState *>(this);
-
- return st->matrix.toAffine();
-}
-#endif
-
/*!
\since 4.3
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 77c6504d2e..52de8b6839 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -53,7 +53,6 @@
#include <QtGui/qpolygon.h>
#include <QtGui/qpen.h>
#include <QtGui/qbrush.h>
-#include <QtGui/qmatrix.h>
#include <QtGui/qtransform.h>
#include <QtGui/qfontinfo.h>
#include <QtGui/qfontmetrics.h>
@@ -236,35 +235,11 @@ public:
void restore();
// XForm functions
-#if QT_DEPRECATED_SINCE(5, 13)
- QT_DEPRECATED_X("Use setTransform() instead")
- void setMatrix(const QMatrix &matrix, bool combine = false);
- QT_DEPRECATED_X("Use transform() instead")
- const QMatrix &matrix() const;
- QT_DEPRECATED_X("Use deviceTransform() instead")
- const QMatrix &deviceMatrix() const;
- QT_DEPRECATED_X("Use resetTransform() instead")
- void resetMatrix();
-#endif
-
void setTransform(const QTransform &transform, bool combine = false);
const QTransform &transform() const;
const QTransform &deviceTransform() const;
void resetTransform();
-#if QT_DEPRECATED_SINCE(5, 13)
- QT_DEPRECATED_X("Use setWorldTransform() instead")
- void setWorldMatrix(const QMatrix &matrix, bool combine = false);
- QT_DEPRECATED_X("Use worldTransform() instead")
- const QMatrix &worldMatrix() const;
- QT_DEPRECATED_X("Use combinedTransform() instead")
- QMatrix combinedMatrix() const;
- QT_DEPRECATED_X("Use setWorldMatrixEnabled() instead")
- void setMatrixEnabled(bool enabled);
- QT_DEPRECATED_X("Use worldMatrixEnabled() instead")
- bool matrixEnabled() const;
-#endif
-
void setWorldTransform(const QTransform &matrix, bool combine = false);
const QTransform &worldTransform() const;
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index dafd6e33be..870381d48a 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -235,7 +235,7 @@ public:
void drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine);
#if !defined(QT_NO_RAWFONT)
- void drawGlyphs(const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
+ void drawGlyphs(const QPointF &decorationPosition, const quint32 *glyphArray, QFixedPoint *positionArray, int glyphCount,
QFontEngine *fontEngine, bool overline = false, bool underline = false,
bool strikeOut = false);
#endif
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index ab60afd9cd..11623c78f0 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -44,7 +44,6 @@
#include <qdebug.h>
#include <qiodevice.h>
#include <qlist.h>
-#include <qmatrix.h>
#include <qpen.h>
#include <qpolygon.h>
#include <qtextlayout.h>
@@ -1604,6 +1603,25 @@ QPainterPath QPainterPath::toReversed() const
}
/*!
+ \overload
+
+ Converts the path into a list of polygons without any transformation,
+ and returns the list.
+
+ This function creates one polygon for each subpath regardless of
+ intersecting subpaths (i.e. overlapping bounding rectangles). To
+ make sure that such overlapping subpaths are filled correctly, use
+ the toFillPolygons() function instead.
+
+ \sa toFillPolygons(), toFillPolygon(), {QPainterPath#QPainterPath
+ Conversion}{QPainterPath Conversion}
+*/
+QList<QPolygonF> QPainterPath::toSubpathPolygons() const
+{
+ return toSubpathPolygons(QTransform());
+}
+
+/*!
Converts the path into a list of polygons using the QTransform
\a matrix, and returns the list.
@@ -1660,18 +1678,34 @@ QList<QPolygonF> QPainterPath::toSubpathPolygons(const QTransform &matrix) const
return flatCurves;
}
-#if QT_DEPRECATED_SINCE(5, 15)
/*!
- \overload
- \obsolete
+ \overload
- Use toSubpathPolygons(const QTransform &matrix) instead.
- */
-QList<QPolygonF> QPainterPath::toSubpathPolygons(const QMatrix &matrix) const
+ Converts the path into a list of polygons without any transformation,
+ and returns the list.
+
+ The function differs from the toFillPolygon() function in that it
+ creates several polygons. It is provided because it is usually
+ faster to draw several small polygons than to draw one large
+ polygon, even though the total number of points drawn is the same.
+
+ The toFillPolygons() function differs from the toSubpathPolygons()
+ function in that it create only polygon for subpaths that have
+ overlapping bounding rectangles.
+
+ Like the toFillPolygon() function, this function uses a rewinding
+ technique to make sure that overlapping subpaths can be filled
+ using the correct fill rule. Note that rewinding inserts addition
+ lines in the polygons so the outline of the fill polygon does not
+ match the outline of the path.
+
+ \sa toSubpathPolygons(), toFillPolygon(),
+ {QPainterPath#QPainterPath Conversion}{QPainterPath Conversion}
+*/
+QList<QPolygonF> QPainterPath::toFillPolygons() const
{
- return toSubpathPolygons(QTransform(matrix));
+ return toFillPolygons(QTransform());
}
-#endif // QT_DEPRECATED_SINCE(5, 15)
/*!
Converts the path into a list of polygons using the
@@ -1792,19 +1826,6 @@ QList<QPolygonF> QPainterPath::toFillPolygons(const QTransform &matrix) const
return polys;
}
-#if QT_DEPRECATED_SINCE(5, 15)
-/*!
- \overload
- \obsolete
-
- Use toFillPolygons(const QTransform &matrix) instead.
- */
-QList<QPolygonF> QPainterPath::toFillPolygons(const QMatrix &matrix) const
-{
- return toFillPolygons(QTransform(matrix));
-}
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
//same as qt_polygon_isect_line in qpolygon.cpp
static void qt_painterpath_isect_line(const QPointF &p1,
const QPointF &p2,
@@ -2882,6 +2903,28 @@ void QPainterPathStroker::setDashOffset(qreal offset)
}
/*!
+ \overload
+
+ Converts the path into a polygon without any transformation,
+ and returns the polygon.
+
+ The polygon is created by first converting all subpaths to
+ polygons, then using a rewinding technique to make sure that
+ overlapping subpaths can be filled using the correct fill rule.
+
+ Note that rewinding inserts addition lines in the polygon so
+ the outline of the fill polygon does not match the outline of
+ the path.
+
+ \sa toSubpathPolygons(), toFillPolygons(),
+ {QPainterPath#QPainterPath Conversion}{QPainterPath Conversion}
+*/
+QPolygonF QPainterPath::toFillPolygon() const
+{
+ return toFillPolygon(QTransform());
+}
+
+/*!
Converts the path into a polygon using the QTransform
\a matrix, and returns the polygon.
@@ -2898,7 +2941,6 @@ void QPainterPathStroker::setDashOffset(qreal offset)
*/
QPolygonF QPainterPath::toFillPolygon(const QTransform &matrix) const
{
-
const QList<QPolygonF> flats = toSubpathPolygons(matrix);
QPolygonF polygon;
if (flats.isEmpty())
@@ -2914,19 +2956,6 @@ QPolygonF QPainterPath::toFillPolygon(const QTransform &matrix) const
return polygon;
}
-#if QT_DEPRECATED_SINCE(5, 15)
-/*!
- \overload
- \obsolete
-
- Use toFillPolygon(const QTransform &matrix) instead.
-*/
-QPolygonF QPainterPath::toFillPolygon(const QMatrix &matrix) const
-{
- return toFillPolygon(QTransform(matrix));
-}
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
//derivative of the equation
static inline qreal slopeAt(qreal t, qreal a, qreal b, qreal c, qreal d)
{
diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h
index 26b92dc6fa..078b665222 100644
--- a/src/gui/painting/qpainterpath.h
+++ b/src/gui/painting/qpainterpath.h
@@ -41,7 +41,6 @@
#define QPAINTERPATH_H
#include <QtGui/qtguiglobal.h>
-#include <QtGui/qmatrix.h>
#include <QtCore/qglobal.h>
#include <QtCore/qrect.h>
#include <QtCore/qline.h>
@@ -59,6 +58,7 @@ class QPainterPathStrokerPrivate;
class QPen;
class QPolygonF;
class QRegion;
+class QTransform;
class QVectorPath;
class Q_GUI_EXPORT QPainterPath
@@ -176,16 +176,11 @@ public:
Q_REQUIRED_RESULT QPainterPath toReversed() const;
-#if QT_DEPRECATED_SINCE(5, 15)
- QT_DEPRECATED_X("Use toSubpathPolygons(const QTransform &)")
- QList<QPolygonF> toSubpathPolygons(const QMatrix &matrix = QMatrix()) const;
- QT_DEPRECATED_X("Use toFillPolygons(const QTransform &")
- QList<QPolygonF> toFillPolygons(const QMatrix &matrix = QMatrix()) const;
- QT_DEPRECATED_X("Use toFillPolygon(const QTransform &)")
- QPolygonF toFillPolygon(const QMatrix &matrix = QMatrix()) const;
-#endif // QT_DEPRECATED_SINCE(5, 15)
+ QList<QPolygonF> toSubpathPolygons() const;
QList<QPolygonF> toSubpathPolygons(const QTransform &matrix) const;
+ QList<QPolygonF> toFillPolygons() const;
QList<QPolygonF> toFillPolygons(const QTransform &matrix) const;
+ QPolygonF toFillPolygon() const;
QPolygonF toFillPolygon(const QTransform &matrix) const;
int elementCount() const;
@@ -238,7 +233,6 @@ private:
friend class QPainterPathData;
friend class QPainterPathStroker;
friend class QPainterPathStrokerPrivate;
- friend class QMatrix;
friend class QTransform;
friend class QVectorPath;
friend Q_GUI_EXPORT const QVectorPath &qtVectorPathForPath(const QPainterPath &);
diff --git a/src/gui/painting/qpainterpath_p.h b/src/gui/painting/qpainterpath_p.h
index a420e0b3d9..d52243b0df 100644
--- a/src/gui/painting/qpainterpath_p.h
+++ b/src/gui/painting/qpainterpath_p.h
@@ -74,7 +74,6 @@ public:
friend class QPainterPathData;
friend class QPainterPathStroker;
friend class QPainterPathStrokerPrivate;
- friend class QMatrix;
friend class QTransform;
friend class QVectorPath;
friend struct QPainterPathPrivateDeleter;
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index c092a7153f..e8ac494e04 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -40,43 +40,8 @@
#include "qplatformbackingstore.h"
#include <qwindow.h>
#include <qpixmap.h>
-#include <private/qwindow_p.h>
-
-#include <qopengl.h>
-#include <qopenglcontext.h>
-#include <QtGui/QMatrix4x4>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLFunctions>
-#ifndef QT_NO_OPENGL
-#include <QtGui/qopengltextureblitter.h>
-#include <QtGui/qoffscreensurface.h>
-#endif
-#include <qpa/qplatformgraphicsbuffer.h>
-#include <qpa/qplatformgraphicsbufferhelper.h>
-#ifndef GL_TEXTURE_BASE_LEVEL
-#define GL_TEXTURE_BASE_LEVEL 0x813C
-#endif
-#ifndef GL_TEXTURE_MAX_LEVEL
-#define GL_TEXTURE_MAX_LEVEL 0x813D
-#endif
-#ifndef GL_UNPACK_ROW_LENGTH
-#define GL_UNPACK_ROW_LENGTH 0x0CF2
-#endif
-#ifndef GL_RGB10_A2
-#define GL_RGB10_A2 0x8059
-#endif
-#ifndef GL_UNSIGNED_INT_2_10_10_10_REV
-#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
-#endif
-
-#ifndef GL_FRAMEBUFFER_SRGB
-#define GL_FRAMEBUFFER_SRGB 0x8DB9
-#endif
-#ifndef GL_FRAMEBUFFER_SRGB_CAPABLE
-#define GL_FRAMEBUFFER_SRGB_CAPABLE 0x8DBA
-#endif
+#include <QtCore/private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -88,38 +53,19 @@ public:
QPlatformBackingStorePrivate(QWindow *w)
: window(w)
, backingStore(nullptr)
-#ifndef QT_NO_OPENGL
- , textureId(0)
- , blitter(nullptr)
-#endif
{
}
~QPlatformBackingStorePrivate()
{
#ifndef QT_NO_OPENGL
- if (context) {
- QOffscreenSurface offscreenSurface;
- offscreenSurface.setFormat(context->format());
- offscreenSurface.create();
- context->makeCurrent(&offscreenSurface);
- if (textureId)
- context->functions()->glDeleteTextures(1, &textureId);
- if (blitter)
- blitter->destroy();
- }
- delete blitter;
+ delete openGLSupport;
#endif
}
QWindow *window;
QBackingStore *backingStore;
#ifndef QT_NO_OPENGL
- QScopedPointer<QOpenGLContext> context;
- mutable GLuint textureId;
- mutable QSize textureSize;
- mutable bool needsSwizzle;
- mutable bool premultiplied;
- QOpenGLTextureBlitter *blitter;
+ QPlatformBackingStoreOpenGLSupportBase *openGLSupport = nullptr;
#endif
};
@@ -240,83 +186,20 @@ void QPlatformTextureList::clear()
*/
#ifndef QT_NO_OPENGL
-
-static inline QRect deviceRect(const QRect &rect, QWindow *window)
-{
- QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
- rect.size() * window->devicePixelRatio());
- return deviceRect;
-}
-
-static inline QPoint deviceOffset(const QPoint &pt, QWindow *window)
-{
- return pt * window->devicePixelRatio();
-}
-
-static QRegion deviceRegion(const QRegion &region, QWindow *window, const QPoint &offset)
-{
- if (offset.isNull() && window->devicePixelRatio() <= 1)
- return region;
-
- QVector<QRect> rects;
- rects.reserve(region.rectCount());
- for (const QRect &rect : region)
- rects.append(deviceRect(rect.translated(offset), window));
-
- QRegion deviceRegion;
- deviceRegion.setRects(rects.constData(), rects.count());
- return deviceRegion;
-}
-
-static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
-{
- return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
- topLeftRect.width(), topLeftRect.height());
-}
-
-static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
- QOpenGLTextureBlitter *blitter, const QPoint &offset, bool canUseSrgb)
-{
- const QRect clipRect = textures->clipRect(idx);
- if (clipRect.isEmpty())
- return;
-
- QRect rectInWindow = textures->geometry(idx);
- // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
- rectInWindow.translate(-offset);
-
- const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
- const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
-
- const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window),
- deviceWindowRect);
-
- const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window),
- deviceRect(rectInWindow, window).size(),
- QOpenGLTextureBlitter::OriginBottomLeft);
-
- QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
- const bool srgb = textures->flags(idx).testFlag(QPlatformTextureList::TextureIsSrgb);
- if (srgb && canUseSrgb)
- funcs->glEnable(GL_FRAMEBUFFER_SRGB);
-
- blitter->blit(textures->textureId(idx), target, source);
-
- if (srgb && canUseSrgb)
- funcs->glDisable(GL_FRAMEBUFFER_SRGB);
-}
-
/*!
Flushes the given \a region from the specified \a window onto the
screen, and composes it with the specified \a textures.
- The default implementation retrieves the contents using toTexture()
+ If OpenGLSupport has been enabled using \c setOpenGLSupport,
+ the default implementation retrieves the contents using toTexture()
and composes using OpenGL. May be reimplemented in subclasses if there
is a more efficient native way to do it.
\note \a region is relative to the window which may not be top-level in case
\a window corresponds to a native child widget. \a offset is the position of
the native child relative to the top-level window.
+
+ \sa setOpenGLSupport()
*/
void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
@@ -324,162 +207,13 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
QPlatformTextureList *textures,
bool translucentBackground)
{
- if (!qt_window_private(window)->receivedExpose)
- return;
-
- if (!d_ptr->context) {
- d_ptr->context.reset(new QOpenGLContext);
- d_ptr->context->setFormat(d_ptr->window->requestedFormat());
- d_ptr->context->setScreen(d_ptr->window->screen());
- d_ptr->context->setShareContext(qt_window_private(d_ptr->window)->shareContext());
- if (!d_ptr->context->create()) {
- qCWarning(lcQpaBackingStore, "composeAndFlush: QOpenGLContext creation failed");
- return;
- }
- }
-
- bool current = d_ptr->context->makeCurrent(window);
-
- if (!current && !d_ptr->context->isValid()) {
- delete d_ptr->blitter;
- d_ptr->blitter = nullptr;
- d_ptr->textureId = 0;
- current = d_ptr->context->create() && d_ptr->context->makeCurrent(window);
- }
-
- if (!current) {
- qCWarning(lcQpaBackingStore, "composeAndFlush: makeCurrent() failed");
- return;
- }
-
- qCDebug(lcQpaBackingStore) << "Composing and flushing" << region << "of" << window
- << "at offset" << offset << "with" << textures->count() << "texture(s) in" << textures;
-
- QWindowPrivate::get(window)->lastComposeTime.start();
-
- QOpenGLFunctions *funcs = d_ptr->context->functions();
- funcs->glViewport(0, 0, qRound(window->width() * window->devicePixelRatio()), qRound(window->height() * window->devicePixelRatio()));
- funcs->glClearColor(0, 0, 0, translucentBackground ? 0 : 1);
- funcs->glClear(GL_COLOR_BUFFER_BIT);
-
- if (!d_ptr->blitter) {
- d_ptr->blitter = new QOpenGLTextureBlitter;
- d_ptr->blitter->create();
- }
-
- d_ptr->blitter->bind();
-
- const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window);
- const QPoint deviceWindowOffset = deviceOffset(offset, window);
-
- bool canUseSrgb = false;
- // If there are any sRGB textures in the list, check if the destination
- // framebuffer is sRGB capable.
- for (int i = 0; i < textures->count(); ++i) {
- if (textures->flags(i).testFlag(QPlatformTextureList::TextureIsSrgb)) {
- GLint cap = 0;
- funcs->glGetIntegerv(GL_FRAMEBUFFER_SRGB_CAPABLE, &cap);
- if (cap)
- canUseSrgb = true;
- break;
- }
- }
-
- // Textures for renderToTexture widgets.
- for (int i = 0; i < textures->count(); ++i) {
- if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
- }
-
- // Backingstore texture with the normal widgets.
- GLuint textureId = 0;
- QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft;
- if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) {
- if (graphicsBuffer->size() != d_ptr->textureSize) {
- if (d_ptr->textureId)
- funcs->glDeleteTextures(1, &d_ptr->textureId);
- funcs->glGenTextures(1, &d_ptr->textureId);
- funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- }
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if (QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied)) {
- d_ptr->textureSize = graphicsBuffer->size();
- } else {
- d_ptr->textureSize = QSize(0,0);
- }
-
- graphicsBuffer->unlock();
- } else if (!region.isEmpty()){
- funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- QPlatformGraphicsBufferHelper::lockAndBindToTexture(graphicsBuffer, &d_ptr->needsSwizzle, &d_ptr->premultiplied);
- graphicsBuffer->unlock();
- }
-
- if (graphicsBuffer->origin() == QPlatformGraphicsBuffer::OriginBottomLeft)
- origin = QOpenGLTextureBlitter::OriginBottomLeft;
- textureId = d_ptr->textureId;
- } else {
- TextureFlags flags;
- textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags);
- d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
- d_ptr->premultiplied = (flags & TexturePremultiplied) != 0;
- if (flags & TextureFlip)
- origin = QOpenGLTextureBlitter::OriginBottomLeft;
- }
-
- funcs->glEnable(GL_BLEND);
- if (d_ptr->premultiplied)
- funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
+ if (auto *c = d_ptr->openGLSupport)
+ c->composeAndFlush(window, region, offset, textures, translucentBackground);
else
- funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
-
- if (textureId) {
- if (d_ptr->needsSwizzle)
- d_ptr->blitter->setRedBlueSwizzle(true);
- // The backingstore is for the entire tlw.
- // In case of native children offset tells the position relative to the tlw.
- const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(deviceWindowOffset), d_ptr->textureSize.height());
- const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect,
- d_ptr->textureSize,
- origin);
- d_ptr->blitter->blit(textureId, QMatrix4x4(), source);
- if (d_ptr->needsSwizzle)
- d_ptr->blitter->setRedBlueSwizzle(false);
- }
-
- // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
- bool blendIsPremultiplied = d_ptr->premultiplied;
- for (int i = 0; i < textures->count(); ++i) {
- const QPlatformTextureList::Flags flags = textures->flags(i);
- if (flags.testFlag(QPlatformTextureList::NeedsPremultipliedAlphaBlending)) {
- if (!blendIsPremultiplied) {
- funcs->glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
- blendIsPremultiplied = true;
- }
- } else {
- if (blendIsPremultiplied) {
- funcs->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
- blendIsPremultiplied = false;
- }
- }
- if (flags.testFlag(QPlatformTextureList::StacksOnTop))
- blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset, canUseSrgb);
- }
-
- funcs->glDisable(GL_BLEND);
- d_ptr->blitter->release();
-
- d_ptr->context->swapBuffers(window);
+ qWarning() << Q_FUNC_INFO << "no opengl support set";
}
#endif
+
/*!
Implemented in subclasses to return the content of the backingstore as a QImage.
@@ -504,7 +238,8 @@ QImage QPlatformBackingStore::toImage() const
The ownership of the texture is not transferred. The caller must not store
the return value between calls, but instead call this function before each use.
- The default implementation returns a cached texture if \a dirtyRegion is empty and
+ If OpenGLSupport has been enabled using \c setOpenGLSupport,
+ the default implementation returns a cached texture if \a dirtyRegion is empty and
\a textureSize matches the backingstore size, otherwise it retrieves the content using
toImage() and performs a texture upload. This works only if the value of \a textureSize
is preserved between the calls to this function.
@@ -520,141 +255,17 @@ QImage QPlatformBackingStore::toImage() const
flags will be set to include \c TextureFlip.
\note \a dirtyRegion is relative to the backingstore so no adjustment is needed.
+
+ \sa setOpenGLSupport()
*/
GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
{
- Q_ASSERT(textureSize);
- Q_ASSERT(flags);
-
- QImage image = toImage();
- QSize imageSize = image.size();
-
- QOpenGLContext *ctx = QOpenGLContext::currentContext();
- GLenum internalFormat = GL_RGBA;
- GLuint pixelType = GL_UNSIGNED_BYTE;
-
- bool needsConversion = false;
- *flags = { };
- switch (image.format()) {
- case QImage::Format_ARGB32_Premultiplied:
- *flags |= TexturePremultiplied;
- Q_FALLTHROUGH();
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32:
- *flags |= TextureSwizzle;
- break;
- case QImage::Format_RGBA8888_Premultiplied:
- *flags |= TexturePremultiplied;
- Q_FALLTHROUGH();
- case QImage::Format_RGBX8888:
- case QImage::Format_RGBA8888:
- break;
- case QImage::Format_BGR30:
- case QImage::Format_A2BGR30_Premultiplied:
- if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
- pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- internalFormat = GL_RGB10_A2;
- *flags |= TexturePremultiplied;
- } else {
- needsConversion = true;
- }
- break;
- case QImage::Format_RGB30:
- case QImage::Format_A2RGB30_Premultiplied:
- if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
- pixelType = GL_UNSIGNED_INT_2_10_10_10_REV;
- internalFormat = GL_RGB10_A2;
- *flags |= TextureSwizzle | TexturePremultiplied;
- } else {
- needsConversion = true;
- }
- break;
- default:
- needsConversion = true;
- break;
- }
- if (imageSize.isEmpty()) {
- *textureSize = imageSize;
+ if (auto *c = d_ptr->openGLSupport)
+ return c->toTexture(dirtyRegion, textureSize, flags);
+ else {
+ qWarning() << Q_FUNC_INFO << "no opengl support set";
return 0;
}
-
- // Must rely on the input only, not d_ptr.
- // With the default composeAndFlush() textureSize is &d_ptr->textureSize.
- bool resized = *textureSize != imageSize;
- if (dirtyRegion.isEmpty() && !resized)
- return d_ptr->textureId;
-
- *textureSize = imageSize;
-
- if (needsConversion)
- image = image.convertToFormat(QImage::Format_RGBA8888);
-
- // The image provided by the backingstore may have a stride larger than width * 4, for
- // instance on platforms that manually implement client-side decorations.
- static const int bytesPerPixel = 4;
- const int strideInPixels = image.bytesPerLine() / bytesPerPixel;
- const bool hasUnpackRowLength = !ctx->isOpenGLES() || ctx->format().majorVersion() >= 3;
-
- QOpenGLFunctions *funcs = ctx->functions();
-
- if (hasUnpackRowLength) {
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, strideInPixels);
- } else if (strideInPixels != image.width()) {
- // No UNPACK_ROW_LENGTH on ES 2.0 and yet we would need it. This case is typically
- // hit with QtWayland which is rarely used in combination with a ES2.0-only GL
- // implementation. Therefore, accept the performance hit and do a copy.
- image = image.copy();
- }
-
- if (resized) {
- if (d_ptr->textureId)
- funcs->glDeleteTextures(1, &d_ptr->textureId);
- funcs->glGenTextures(1, &d_ptr->textureId);
- funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- funcs->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- }
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- funcs->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- funcs->glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, imageSize.width(), imageSize.height(), 0, GL_RGBA, pixelType,
- const_cast<uchar*>(image.constBits()));
- } else {
- funcs->glBindTexture(GL_TEXTURE_2D, d_ptr->textureId);
- QRect imageRect = image.rect();
- QRect rect = dirtyRegion.boundingRect() & imageRect;
-
- if (hasUnpackRowLength) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
- image.constScanLine(rect.y()) + rect.x() * bytesPerPixel);
- } else {
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (rect.width() >= imageRect.width() / 2) {
- rect.setX(0);
- rect.setWidth(imageRect.width());
- }
-
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's no gap between scanlines
-
- if (rect.width() == imageRect.width()) {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
- image.constScanLine(rect.y()));
- } else {
- funcs->glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, pixelType,
- image.copy(rect).constBits());
- }
- }
- }
-
- if (hasUnpackRowLength)
- funcs->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- return d_ptr->textureId;
}
#endif // QT_NO_OPENGL
@@ -706,6 +317,18 @@ QBackingStore *QPlatformBackingStore::backingStore() const
return d_ptr->backingStore;
}
+#ifndef QT_NO_OPENGL
+/*!
+ Injects an OpenGL implementation helper. Platform integrations need to
+ call this if they intend to use the default OpenGL implementations of
+ composeAndFlush or toTexture.
+*/
+void QPlatformBackingStore::setOpenGLSupport(QPlatformBackingStoreOpenGLSupportBase *openGLSupport)
+{
+ d_ptr->openGLSupport = openGLSupport;
+}
+#endif // QT_NO_OPENGL
+
/*!
This function is called before painting onto the surface begins,
with the \a region in which the painting will occur.
diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h
index 7aa054f1e2..2a3d7d20b5 100644
--- a/src/gui/painting/qplatformbackingstore.h
+++ b/src/gui/painting/qplatformbackingstore.h
@@ -67,11 +67,10 @@ class QRect;
class QPoint;
class QImage;
class QPlatformBackingStorePrivate;
-class QPlatformWindow;
class QPlatformTextureList;
class QPlatformTextureListPrivate;
-class QOpenGLContext;
class QPlatformGraphicsBuffer;
+class QPlatformBackingStoreOpenGLSupportBase;
#ifndef QT_NO_OPENGL
class Q_GUI_EXPORT QPlatformTextureList : public QObject
@@ -118,6 +117,8 @@ public:
QWindow *window() const;
QBackingStore *backingStore() const;
+ void setOpenGLSupport(QPlatformBackingStoreOpenGLSupportBase *openGLSupport);
+
virtual QPaintDevice *paintDevice() = 0;
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) = 0;
@@ -154,6 +155,17 @@ private:
};
#ifndef QT_NO_OPENGL
+class Q_GUI_EXPORT QPlatformBackingStoreOpenGLSupportBase // pure interface
+{
+public:
+ virtual void composeAndFlush(QWindow *window, const QRegion &region, const QPoint &offset,
+ QPlatformTextureList *textures, bool translucentBackground) = 0;
+ virtual GLuint toTexture(const QRegion &dirtyRegion, QSize *textureSize, QPlatformBackingStore::TextureFlags *flags) const = 0;
+ virtual ~QPlatformBackingStoreOpenGLSupportBase() {}
+};
+#endif // QT_NO_OPENGL
+
+#ifndef QT_NO_OPENGL
Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformBackingStore::TextureFlags)
#endif
diff --git a/src/gui/painting/qpolygon.cpp b/src/gui/painting/qpolygon.cpp
index 4fe819cae0..e9a8793bd0 100644
--- a/src/gui/painting/qpolygon.cpp
+++ b/src/gui/painting/qpolygon.cpp
@@ -899,7 +899,7 @@ QPolygon QPolygon::united(const QPolygon &r) const
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.united(clip).toFillPolygon(QTransform()).toPolygon();
+ return subject.united(clip).toFillPolygon().toPolygon();
}
/*!
@@ -918,7 +918,7 @@ QPolygon QPolygon::intersected(const QPolygon &r) const
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.intersected(clip).toFillPolygon(QTransform()).toPolygon();
+ return subject.intersected(clip).toFillPolygon().toPolygon();
}
/*!
@@ -936,7 +936,7 @@ QPolygon QPolygon::subtracted(const QPolygon &r) const
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.subtracted(clip).toFillPolygon(QTransform()).toPolygon();
+ return subject.subtracted(clip).toFillPolygon().toPolygon();
}
/*!
@@ -975,7 +975,7 @@ QPolygonF QPolygonF::united(const QPolygonF &r) const
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.united(clip).toFillPolygon(QTransform());
+ return subject.united(clip).toFillPolygon();
}
/*!
@@ -994,7 +994,7 @@ QPolygonF QPolygonF::intersected(const QPolygonF &r) const
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.intersected(clip).toFillPolygon(QTransform());
+ return subject.intersected(clip).toFillPolygon();
}
/*!
@@ -1011,7 +1011,7 @@ QPolygonF QPolygonF::subtracted(const QPolygonF &r) const
{
QPainterPath subject; subject.addPolygon(*this);
QPainterPath clip; clip.addPolygon(r);
- return subject.subtracted(clip).toFillPolygon(QTransform());
+ return subject.subtracted(clip).toFillPolygon();
}
/*!
diff --git a/src/gui/painting/qpolygon.h b/src/gui/painting/qpolygon.h
index 93fab55aa1..584965af3b 100644
--- a/src/gui/painting/qpolygon.h
+++ b/src/gui/painting/qpolygon.h
@@ -47,8 +47,6 @@
QT_BEGIN_NAMESPACE
-
-class QMatrix;
class QTransform;
class QRect;
class QVariant;
diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp
index bac042c784..6409ab9528 100644
--- a/src/gui/painting/qregion.cpp
+++ b/src/gui/painting/qregion.cpp
@@ -3917,7 +3917,7 @@ QRegion::QRegion(const QRect &r, RegionType t)
} else if (t == Ellipse) {
QPainterPath path;
path.addEllipse(r.x(), r.y(), r.width(), r.height());
- QPolygon a = path.toSubpathPolygons(QTransform()).at(0).toPolygon();
+ QPolygon a = path.toSubpathPolygons().at(0).toPolygon();
d->qt_rgn = PolygonRegion(a.constData(), a.size(), EvenOddRule);
}
}
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index 91214f27ca..e906397520 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -350,7 +350,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
int mw = qMin(mask.width(), c.w);
int mh = qMin(mask.height(), c.h);
uchar *d = m_image.bits();
- int dbpl = m_image.bytesPerLine();
+ qsizetype dbpl = m_image.bytesPerLine();
for (int y = 0; y < c.h; ++y) {
uchar *dest = d + (c.y + y) *dbpl + c.x/8;
@@ -372,7 +372,7 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c, glyph_t g, QFixed subP
int mw = qMin(mask.width(), c.w);
int mh = qMin(mask.height(), c.h);
uchar *d = m_image.bits();
- int dbpl = m_image.bytesPerLine();
+ qsizetype dbpl = m_image.bytesPerLine();
if (mask.depth() == 1) {
for (int y = 0; y < c.h; ++y) {
diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp
index 9d8bb0c3e2..4adc2b075e 100644
--- a/src/gui/painting/qtransform.cpp
+++ b/src/gui/painting/qtransform.cpp
@@ -41,7 +41,6 @@
#include "qdatastream.h"
#include "qdebug.h"
#include "qhashfunctions.h"
-#include "qmatrix.h"
#include "qregion.h"
#include "qpainterpath.h"
#include "qpainterpath_p.h"
@@ -76,20 +75,20 @@ static void nanWarning(const char *func)
ny = FY_; \
break; \
case TxTranslate: \
- nx = FX_ + affine._dx; \
- ny = FY_ + affine._dy; \
+ nx = FX_ + m_matrix[2][0]; \
+ ny = FY_ + m_matrix[2][1]; \
break; \
case TxScale: \
- nx = affine._m11 * FX_ + affine._dx; \
- ny = affine._m22 * FY_ + affine._dy; \
+ nx = m_matrix[0][0] * FX_ + m_matrix[2][0]; \
+ ny = m_matrix[1][1] * FY_ + m_matrix[2][1]; \
break; \
case TxRotate: \
case TxShear: \
case TxProject: \
- nx = affine._m11 * FX_ + affine._m21 * FY_ + affine._dx; \
- ny = affine._m12 * FX_ + affine._m22 * FY_ + affine._dy; \
+ nx = m_matrix[0][0] * FX_ + m_matrix[1][0] * FY_ + m_matrix[2][0]; \
+ ny = m_matrix[0][1] * FX_ + m_matrix[1][1] * FY_ + m_matrix[2][1]; \
if (t == TxProject) { \
- qreal w = (m_13 * FX_ + m_23 * FY_ + m_33); \
+ qreal w = (m_matrix[0][2] * FX_ + m_matrix[1][2] * FY_ + m_matrix[2][2]); \
if (w < qreal(Q_NEAR_CLIP)) w = qreal(Q_NEAR_CLIP); \
w = 1./w; \
nx *= w; \
@@ -109,14 +108,6 @@ static void nanWarning(const char *func)
or project the coordinate system, and is typically used when
rendering graphics.
- QTransform differs from QMatrix in that it is a true 3x3 matrix,
- allowing perspective transformations. QTransform's toAffine()
- method allows casting QTransform to QMatrix. If a perspective
- transformation has been specified on the matrix, then the
- conversion will cause loss of data.
-
- QTransform is the recommended transformation class in Qt.
-
A QTransform object can be built using the setMatrix(), scale(),
rotate(), translate() and shear() functions. Alternatively, it
can be built by applying \l {QTransform#Basic Matrix
@@ -261,8 +252,7 @@ static void nanWarning(const char *func)
\sa reset()
*/
QTransform::QTransform()
- : affine(true)
- , m_13(0), m_23(0), m_33(1)
+ : m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
, m_type(TxNone)
, m_dirty(TxNone)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -282,8 +272,7 @@ QTransform::QTransform()
QTransform::QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33)
- : affine(h11, h12, h21, h22, h31, h32, true)
- , m_13(h13), m_23(h23), m_33(h33)
+ : m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
, m_type(TxNone)
, m_dirty(TxProject)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -301,8 +290,7 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h13,
*/
QTransform::QTransform(qreal h11, qreal h12, qreal h21,
qreal h22, qreal dx, qreal dy)
- : affine(h11, h12, h21, h22, dx, dy, true)
- , m_13(0), m_23(0), m_33(1)
+ : m_matrix{ {h11, h12, 0}, {h21, h22, 0}, {dx, dy, 1} }
, m_type(TxNone)
, m_dirty(TxShear)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -311,44 +299,23 @@ QTransform::QTransform(qreal h11, qreal h12, qreal h21,
{
}
-#if QT_DEPRECATED_SINCE(5, 15)
-/*!
- \fn QTransform::QTransform(const QMatrix &matrix)
- \obsolete
-
- Constructs a matrix that is a copy of the given \a matrix.
- Note that the \c m13, \c m23, and \c m33 elements are set to 0, 0,
- and 1 respectively.
- */
-QTransform::QTransform(const QMatrix &mtx)
- : affine(mtx._m11, mtx._m12, mtx._m21, mtx._m22, mtx._dx, mtx._dy, true),
- m_13(0), m_23(0), m_33(1)
- , m_type(TxNone)
- , m_dirty(TxShear)
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- , d(nullptr)
-#endif
-{
-}
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
/*!
Returns the adjoint of this matrix.
*/
QTransform QTransform::adjoint() const
{
qreal h11, h12, h13,
- h21, h22, h23,
- h31, h32, h33;
- h11 = affine._m22*m_33 - m_23*affine._dy;
- h21 = m_23*affine._dx - affine._m21*m_33;
- h31 = affine._m21*affine._dy - affine._m22*affine._dx;
- h12 = m_13*affine._dy - affine._m12*m_33;
- h22 = affine._m11*m_33 - m_13*affine._dx;
- h32 = affine._m12*affine._dx - affine._m11*affine._dy;
- h13 = affine._m12*m_23 - m_13*affine._m22;
- h23 = m_13*affine._m21 - affine._m11*m_23;
- h33 = affine._m11*affine._m22 - affine._m12*affine._m21;
+ h21, h22, h23,
+ h31, h32, h33;
+ h11 = m_matrix[1][1] * m_matrix[2][2] - m_matrix[1][2] * m_matrix[2][1];
+ h21 = m_matrix[1][2] * m_matrix[2][0] - m_matrix[1][0] * m_matrix[2][2];
+ h31 = m_matrix[1][0] * m_matrix[2][1] - m_matrix[1][1] * m_matrix[2][0];
+ h12 = m_matrix[0][2] * m_matrix[2][1] - m_matrix[0][1] * m_matrix[2][2];
+ h22 = m_matrix[0][0] * m_matrix[2][2] - m_matrix[0][2] * m_matrix[2][0];
+ h32 = m_matrix[0][1] * m_matrix[2][0] - m_matrix[0][0] * m_matrix[2][1];
+ h13 = m_matrix[0][1] * m_matrix[1][2] - m_matrix[0][2] * m_matrix[1][1];
+ h23 = m_matrix[0][2] * m_matrix[1][0] - m_matrix[0][0] * m_matrix[1][2];
+ h33 = m_matrix[0][0] * m_matrix[1][1] - m_matrix[0][1] * m_matrix[1][0];
return QTransform(h11, h12, h13,
h21, h22, h23,
@@ -360,9 +327,9 @@ QTransform QTransform::adjoint() const
*/
QTransform QTransform::transposed() const
{
- QTransform t(affine._m11, affine._m21, affine._dx,
- affine._m12, affine._m22, affine._dy,
- m_13, m_23, m_33, true);
+ QTransform t(m_matrix[0][0], m_matrix[1][0], m_matrix[2][0],
+ m_matrix[0][1], m_matrix[1][1], m_matrix[2][1],
+ m_matrix[0][2], m_matrix[1][2], m_matrix[2][2], true);
return t;
}
@@ -385,23 +352,23 @@ QTransform QTransform::inverted(bool *invertible) const
case TxNone:
break;
case TxTranslate:
- invert.affine._dx = -affine._dx;
- invert.affine._dy = -affine._dy;
+ invert.m_matrix[2][0] = -m_matrix[2][0];
+ invert.m_matrix[2][1] = -m_matrix[2][1];
break;
case TxScale:
- inv = !qFuzzyIsNull(affine._m11);
- inv &= !qFuzzyIsNull(affine._m22);
+ inv = !qFuzzyIsNull(m_matrix[0][0]);
+ inv &= !qFuzzyIsNull(m_matrix[1][1]);
if (inv) {
- invert.affine._m11 = 1. / affine._m11;
- invert.affine._m22 = 1. / affine._m22;
- invert.affine._dx = -affine._dx * invert.affine._m11;
- invert.affine._dy = -affine._dy * invert.affine._m22;
+ invert.m_matrix[0][0] = 1. / m_matrix[0][0];
+ invert.m_matrix[1][1] = 1. / m_matrix[1][1];
+ invert.m_matrix[2][0] = -m_matrix[2][0] * invert.m_matrix[0][0];
+ invert.m_matrix[2][1] = -m_matrix[2][1] * invert.m_matrix[1][1];
}
break;
- case TxRotate:
- case TxShear:
- invert.affine = affine.inverted(&inv);
- break;
+// case TxRotate:
+// case TxShear:
+// invert.affine = affine.inverted(&inv);
+// break;
default:
// general case
qreal det = determinant();
@@ -442,24 +409,24 @@ QTransform &QTransform::translate(qreal dx, qreal dy)
switch(inline_type()) {
case TxNone:
- affine._dx = dx;
- affine._dy = dy;
+ m_matrix[2][0] = dx;
+ m_matrix[2][1] = dy;
break;
case TxTranslate:
- affine._dx += dx;
- affine._dy += dy;
+ m_matrix[2][0] += dx;
+ m_matrix[2][1] += dy;
break;
case TxScale:
- affine._dx += dx*affine._m11;
- affine._dy += dy*affine._m22;
+ m_matrix[2][0] += dx * m_matrix[0][0];
+ m_matrix[2][1] += dy * m_matrix[1][1];
break;
case TxProject:
- m_33 += dx*m_13 + dy*m_23;
+ m_matrix[2][2] += dx * m_matrix[0][2] + dy * m_matrix[1][2];
Q_FALLTHROUGH();
case TxShear:
case TxRotate:
- affine._dx += dx*affine._m11 + dy*affine._m21;
- affine._dy += dy*affine._m22 + dx*affine._m12;
+ m_matrix[2][0] += dx * m_matrix[0][0] + dy * m_matrix[1][0];
+ m_matrix[2][1] += dy * m_matrix[1][1] + dx * m_matrix[0][1];
break;
}
if (m_dirty < TxTranslate)
@@ -511,21 +478,21 @@ QTransform & QTransform::scale(qreal sx, qreal sy)
switch(inline_type()) {
case TxNone:
case TxTranslate:
- affine._m11 = sx;
- affine._m22 = sy;
+ m_matrix[0][0] = sx;
+ m_matrix[1][1] = sy;
break;
case TxProject:
- m_13 *= sx;
- m_23 *= sy;
+ m_matrix[0][2] *= sx;
+ m_matrix[1][2] *= sy;
Q_FALLTHROUGH();
case TxRotate:
case TxShear:
- affine._m12 *= sx;
- affine._m21 *= sy;
+ m_matrix[0][1] *= sx;
+ m_matrix[1][0] *= sy;
Q_FALLTHROUGH();
case TxScale:
- affine._m11 *= sx;
- affine._m22 *= sy;
+ m_matrix[0][0] *= sx;
+ m_matrix[1][1] *= sy;
break;
}
if (m_dirty < TxScale)
@@ -577,28 +544,30 @@ QTransform & QTransform::shear(qreal sh, qreal sv)
switch(inline_type()) {
case TxNone:
case TxTranslate:
- affine._m12 = sv;
- affine._m21 = sh;
+ m_matrix[0][1] = sv;
+ m_matrix[1][0] = sh;
break;
case TxScale:
- affine._m12 = sv*affine._m22;
- affine._m21 = sh*affine._m11;
+ m_matrix[0][1] = sv*m_matrix[1][1];
+ m_matrix[1][0] = sh*m_matrix[0][0];
break;
case TxProject: {
- qreal tm13 = sv*m_23;
- qreal tm23 = sh*m_13;
- m_13 += tm13;
- m_23 += tm23;
+ qreal tm13 = sv * m_matrix[1][2];
+ qreal tm23 = sh * m_matrix[0][2];
+ m_matrix[0][2] += tm13;
+ m_matrix[1][2] += tm23;
}
Q_FALLTHROUGH();
case TxRotate:
case TxShear: {
- qreal tm11 = sv*affine._m21;
- qreal tm22 = sh*affine._m12;
- qreal tm12 = sv*affine._m22;
- qreal tm21 = sh*affine._m11;
- affine._m11 += tm11; affine._m12 += tm12;
- affine._m21 += tm21; affine._m22 += tm22;
+ qreal tm11 = sv * m_matrix[1][0];
+ qreal tm22 = sh * m_matrix[0][1];
+ qreal tm12 = sv * m_matrix[1][1];
+ qreal tm21 = sh * m_matrix[0][0];
+ m_matrix[0][0] += tm11;
+ m_matrix[0][1] += tm12;
+ m_matrix[1][0] += tm21;
+ m_matrix[1][1] += tm22;
break;
}
}
@@ -653,35 +622,39 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
switch(inline_type()) {
case TxNone:
case TxTranslate:
- affine._m11 = cosa;
- affine._m12 = sina;
- affine._m21 = -sina;
- affine._m22 = cosa;
+ m_matrix[0][0] = cosa;
+ m_matrix[0][1] = sina;
+ m_matrix[1][0] = -sina;
+ m_matrix[1][1] = cosa;
break;
case TxScale: {
- qreal tm11 = cosa*affine._m11;
- qreal tm12 = sina*affine._m22;
- qreal tm21 = -sina*affine._m11;
- qreal tm22 = cosa*affine._m22;
- affine._m11 = tm11; affine._m12 = tm12;
- affine._m21 = tm21; affine._m22 = tm22;
+ qreal tm11 = cosa * m_matrix[0][0];
+ qreal tm12 = sina * m_matrix[1][1];
+ qreal tm21 = -sina * m_matrix[0][0];
+ qreal tm22 = cosa * m_matrix[1][1];
+ m_matrix[0][0] = tm11;
+ m_matrix[0][1] = tm12;
+ m_matrix[1][0] = tm21;
+ m_matrix[1][1] = tm22;
break;
}
case TxProject: {
- qreal tm13 = cosa*m_13 + sina*m_23;
- qreal tm23 = -sina*m_13 + cosa*m_23;
- m_13 = tm13;
- m_23 = tm23;
+ qreal tm13 = cosa * m_matrix[0][2] + sina * m_matrix[1][2];
+ qreal tm23 = -sina * m_matrix[0][2] + cosa * m_matrix[1][2];
+ m_matrix[0][2] = tm13;
+ m_matrix[1][2] = tm23;
Q_FALLTHROUGH();
}
case TxRotate:
case TxShear: {
- qreal tm11 = cosa*affine._m11 + sina*affine._m21;
- qreal tm12 = cosa*affine._m12 + sina*affine._m22;
- qreal tm21 = -sina*affine._m11 + cosa*affine._m21;
- qreal tm22 = -sina*affine._m12 + cosa*affine._m22;
- affine._m11 = tm11; affine._m12 = tm12;
- affine._m21 = tm21; affine._m22 = tm22;
+ qreal tm11 = cosa * m_matrix[0][0] + sina * m_matrix[1][0];
+ qreal tm12 = cosa * m_matrix[0][1] + sina * m_matrix[1][1];
+ qreal tm21 = -sina * m_matrix[0][0] + cosa * m_matrix[1][0];
+ qreal tm22 = -sina * m_matrix[0][1] + cosa * m_matrix[1][1];
+ m_matrix[0][0] = tm11;
+ m_matrix[0][1] = tm12;
+ m_matrix[1][0] = tm21;
+ m_matrix[1][1] = tm22;
break;
}
}
@@ -690,11 +663,11 @@ QTransform & QTransform::rotate(qreal a, Qt::Axis axis)
} else {
QTransform result;
if (axis == Qt::YAxis) {
- result.affine._m11 = cosa;
- result.m_13 = -sina * inv_dist_to_plane;
+ result.m_matrix[0][0] = cosa;
+ result.m_matrix[0][2] = -sina * inv_dist_to_plane;
} else {
- result.affine._m22 = cosa;
- result.m_23 = -sina * inv_dist_to_plane;
+ result.m_matrix[1][1] = cosa;
+ result.m_matrix[1][2] = -sina * inv_dist_to_plane;
}
result.m_type = TxProject;
*this = result * *this;
@@ -732,35 +705,39 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
switch(inline_type()) {
case TxNone:
case TxTranslate:
- affine._m11 = cosa;
- affine._m12 = sina;
- affine._m21 = -sina;
- affine._m22 = cosa;
+ m_matrix[0][0] = cosa;
+ m_matrix[0][1] = sina;
+ m_matrix[1][0] = -sina;
+ m_matrix[1][1] = cosa;
break;
case TxScale: {
- qreal tm11 = cosa*affine._m11;
- qreal tm12 = sina*affine._m22;
- qreal tm21 = -sina*affine._m11;
- qreal tm22 = cosa*affine._m22;
- affine._m11 = tm11; affine._m12 = tm12;
- affine._m21 = tm21; affine._m22 = tm22;
+ qreal tm11 = cosa * m_matrix[0][0];
+ qreal tm12 = sina * m_matrix[1][1];
+ qreal tm21 = -sina * m_matrix[0][0];
+ qreal tm22 = cosa * m_matrix[1][1];
+ m_matrix[0][0] = tm11;
+ m_matrix[0][1] = tm12;
+ m_matrix[1][0] = tm21;
+ m_matrix[1][1] = tm22;
break;
}
case TxProject: {
- qreal tm13 = cosa*m_13 + sina*m_23;
- qreal tm23 = -sina*m_13 + cosa*m_23;
- m_13 = tm13;
- m_23 = tm23;
+ qreal tm13 = cosa * m_matrix[0][2] + sina * m_matrix[1][2];
+ qreal tm23 = -sina * m_matrix[0][2] + cosa * m_matrix[1][2];
+ m_matrix[0][2] = tm13;
+ m_matrix[1][2] = tm23;
Q_FALLTHROUGH();
}
case TxRotate:
case TxShear: {
- qreal tm11 = cosa*affine._m11 + sina*affine._m21;
- qreal tm12 = cosa*affine._m12 + sina*affine._m22;
- qreal tm21 = -sina*affine._m11 + cosa*affine._m21;
- qreal tm22 = -sina*affine._m12 + cosa*affine._m22;
- affine._m11 = tm11; affine._m12 = tm12;
- affine._m21 = tm21; affine._m22 = tm22;
+ qreal tm11 = cosa * m_matrix[0][0] + sina * m_matrix[1][0];
+ qreal tm12 = cosa * m_matrix[0][1] + sina * m_matrix[1][1];
+ qreal tm21 = -sina * m_matrix[0][0] + cosa * m_matrix[1][0];
+ qreal tm22 = -sina * m_matrix[0][1] + cosa * m_matrix[1][1];
+ m_matrix[0][0] = tm11;
+ m_matrix[0][1] = tm12;
+ m_matrix[1][0] = tm21;
+ m_matrix[1][1] = tm22;
break;
}
}
@@ -769,11 +746,11 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
} else {
QTransform result;
if (axis == Qt::YAxis) {
- result.affine._m11 = cosa;
- result.m_13 = -sina * inv_dist_to_plane;
+ result.m_matrix[0][0] = cosa;
+ result.m_matrix[0][2] = -sina * inv_dist_to_plane;
} else {
- result.affine._m22 = cosa;
- result.m_23 = -sina * inv_dist_to_plane;
+ result.m_matrix[1][1] = cosa;
+ result.m_matrix[1][2] = -sina * inv_dist_to_plane;
}
result.m_type = TxProject;
*this = result * *this;
@@ -788,15 +765,15 @@ QTransform & QTransform::rotateRadians(qreal a, Qt::Axis axis)
*/
bool QTransform::operator==(const QTransform &o) const
{
- return affine._m11 == o.affine._m11 &&
- affine._m12 == o.affine._m12 &&
- affine._m21 == o.affine._m21 &&
- affine._m22 == o.affine._m22 &&
- affine._dx == o.affine._dx &&
- affine._dy == o.affine._dy &&
- m_13 == o.m_13 &&
- m_23 == o.m_23 &&
- m_33 == o.m_33;
+ return m_matrix[0][0] == o.m_matrix[0][0] &&
+ m_matrix[0][1] == o.m_matrix[0][1] &&
+ m_matrix[1][0] == o.m_matrix[1][0] &&
+ m_matrix[1][1] == o.m_matrix[1][1] &&
+ m_matrix[2][0] == o.m_matrix[2][0] &&
+ m_matrix[2][1] == o.m_matrix[2][1] &&
+ m_matrix[0][2] == o.m_matrix[0][2] &&
+ m_matrix[1][2] == o.m_matrix[1][2] &&
+ m_matrix[2][2] == o.m_matrix[2][2];
}
/*!
@@ -854,56 +831,59 @@ QTransform & QTransform::operator*=(const QTransform &o)
case TxNone:
break;
case TxTranslate:
- affine._dx += o.affine._dx;
- affine._dy += o.affine._dy;
+ m_matrix[2][0] += o.m_matrix[2][0];
+ m_matrix[2][1] += o.m_matrix[2][1];
break;
case TxScale:
{
- qreal m11 = affine._m11*o.affine._m11;
- qreal m22 = affine._m22*o.affine._m22;
+ qreal m11 = m_matrix[0][0] * o.m_matrix[0][0];
+ qreal m22 = m_matrix[1][1] * o.m_matrix[1][1];
- qreal m31 = affine._dx*o.affine._m11 + o.affine._dx;
- qreal m32 = affine._dy*o.affine._m22 + o.affine._dy;
+ qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + o.m_matrix[2][0];
+ qreal m32 = m_matrix[2][1] * o.m_matrix[1][1] + o.m_matrix[2][1];
- affine._m11 = m11;
- affine._m22 = m22;
- affine._dx = m31; affine._dy = m32;
+ m_matrix[0][0] = m11;
+ m_matrix[1][1] = m22;
+ m_matrix[2][0] = m31; m_matrix[2][1] = m32;
break;
}
case TxRotate:
case TxShear:
{
- qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21;
- qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22;
+ qreal m11 = m_matrix[0][0] * o.m_matrix[0][0] + m_matrix[0][1] * o.m_matrix[1][0];
+ qreal m12 = m_matrix[0][0] * o.m_matrix[0][1] + m_matrix[0][1] * o.m_matrix[1][1];
- qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21;
- qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22;
+ qreal m21 = m_matrix[1][0] * o.m_matrix[0][0] + m_matrix[1][1] * o.m_matrix[1][0];
+ qreal m22 = m_matrix[1][0] * o.m_matrix[0][1] + m_matrix[1][1] * o.m_matrix[1][1];
- qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + o.affine._dx;
- qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + o.affine._dy;
+ qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + m_matrix[2][1] * o.m_matrix[1][0] + o.m_matrix[2][0];
+ qreal m32 = m_matrix[2][0] * o.m_matrix[0][1] + m_matrix[2][1] * o.m_matrix[1][1] + o.m_matrix[2][1];
- affine._m11 = m11; affine._m12 = m12;
- affine._m21 = m21; affine._m22 = m22;
- affine._dx = m31; affine._dy = m32;
+ m_matrix[0][0] = m11;
+ m_matrix[0][1] = m12;
+ m_matrix[1][0] = m21;
+ m_matrix[1][1] = m22;
+ m_matrix[2][0] = m31;
+ m_matrix[2][1] = m32;
break;
}
case TxProject:
{
- qreal m11 = affine._m11*o.affine._m11 + affine._m12*o.affine._m21 + m_13*o.affine._dx;
- qreal m12 = affine._m11*o.affine._m12 + affine._m12*o.affine._m22 + m_13*o.affine._dy;
- qreal m13 = affine._m11*o.m_13 + affine._m12*o.m_23 + m_13*o.m_33;
+ qreal m11 = m_matrix[0][0] * o.m_matrix[0][0] + m_matrix[0][1] * o.m_matrix[1][0] + m_matrix[0][2] * o.m_matrix[2][0];
+ qreal m12 = m_matrix[0][0] * o.m_matrix[0][1] + m_matrix[0][1] * o.m_matrix[1][1] + m_matrix[0][2] * o.m_matrix[2][1];
+ qreal m13 = m_matrix[0][0] * o.m_matrix[0][2] + m_matrix[0][1] * o.m_matrix[1][2] + m_matrix[0][2] * o.m_matrix[2][2];
- qreal m21 = affine._m21*o.affine._m11 + affine._m22*o.affine._m21 + m_23*o.affine._dx;
- qreal m22 = affine._m21*o.affine._m12 + affine._m22*o.affine._m22 + m_23*o.affine._dy;
- qreal m23 = affine._m21*o.m_13 + affine._m22*o.m_23 + m_23*o.m_33;
+ qreal m21 = m_matrix[1][0] * o.m_matrix[0][0] + m_matrix[1][1] * o.m_matrix[1][0] + m_matrix[1][2] * o.m_matrix[2][0];
+ qreal m22 = m_matrix[1][0] * o.m_matrix[0][1] + m_matrix[1][1] * o.m_matrix[1][1] + m_matrix[1][2] * o.m_matrix[2][1];
+ qreal m23 = m_matrix[1][0] * o.m_matrix[0][2] + m_matrix[1][1] * o.m_matrix[1][2] + m_matrix[1][2] * o.m_matrix[2][2];
- qreal m31 = affine._dx*o.affine._m11 + affine._dy*o.affine._m21 + m_33*o.affine._dx;
- qreal m32 = affine._dx*o.affine._m12 + affine._dy*o.affine._m22 + m_33*o.affine._dy;
- qreal m33 = affine._dx*o.m_13 + affine._dy*o.m_23 + m_33*o.m_33;
+ qreal m31 = m_matrix[2][0] * o.m_matrix[0][0] + m_matrix[2][1] * o.m_matrix[1][0] + m_matrix[2][2] * o.m_matrix[2][0];
+ qreal m32 = m_matrix[2][0] * o.m_matrix[0][1] + m_matrix[2][1] * o.m_matrix[1][1] + m_matrix[2][2] * o.m_matrix[2][1];
+ qreal m33 = m_matrix[2][0] * o.m_matrix[0][2] + m_matrix[2][1] * o.m_matrix[1][2] + m_matrix[2][2] * o.m_matrix[2][2];
- affine._m11 = m11; affine._m12 = m12; m_13 = m13;
- affine._m21 = m21; affine._m22 = m22; m_23 = m23;
- affine._dx = m31; affine._dy = m32; m_33 = m33;
+ m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13;
+ m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23;
+ m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33;
}
}
@@ -937,56 +917,57 @@ QTransform QTransform::operator*(const QTransform &m) const
case TxNone:
break;
case TxTranslate:
- t.affine._dx = affine._dx + m.affine._dx;
- t.affine._dy += affine._dy + m.affine._dy;
+ t.m_matrix[2][0] = m_matrix[2][0] + m.m_matrix[2][0];
+ t.m_matrix[2][1] = m_matrix[2][1] + m.m_matrix[2][1];
break;
case TxScale:
{
- qreal m11 = affine._m11*m.affine._m11;
- qreal m22 = affine._m22*m.affine._m22;
+ qreal m11 = m_matrix[0][0] * m.m_matrix[0][0];
+ qreal m22 = m_matrix[1][1] * m.m_matrix[1][1];
- qreal m31 = affine._dx*m.affine._m11 + m.affine._dx;
- qreal m32 = affine._dy*m.affine._m22 + m.affine._dy;
+ qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m.m_matrix[2][0];
+ qreal m32 = m_matrix[2][1] * m.m_matrix[1][1] + m.m_matrix[2][1];
- t.affine._m11 = m11;
- t.affine._m22 = m22;
- t.affine._dx = m31; t.affine._dy = m32;
+ t.m_matrix[0][0] = m11;
+ t.m_matrix[1][1] = m22;
+ t.m_matrix[2][0] = m31;
+ t.m_matrix[2][1] = m32;
break;
}
case TxRotate:
case TxShear:
{
- qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21;
- qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22;
+ qreal m11 = m_matrix[0][0] * m.m_matrix[0][0] + m_matrix[0][1] * m.m_matrix[1][0];
+ qreal m12 = m_matrix[0][0] * m.m_matrix[0][1] + m_matrix[0][1] * m.m_matrix[1][1];
- qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21;
- qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22;
+ qreal m21 = m_matrix[1][0] * m.m_matrix[0][0] + m_matrix[1][1] * m.m_matrix[1][0];
+ qreal m22 = m_matrix[1][0] * m.m_matrix[0][1] + m_matrix[1][1] * m.m_matrix[1][1];
- qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m.affine._dx;
- qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m.affine._dy;
+ qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m_matrix[2][1] * m.m_matrix[1][0] + m.m_matrix[2][0];
+ qreal m32 = m_matrix[2][0] * m.m_matrix[0][1] + m_matrix[2][1] * m.m_matrix[1][1] + m.m_matrix[2][1];
- t.affine._m11 = m11; t.affine._m12 = m12;
- t.affine._m21 = m21; t.affine._m22 = m22;
- t.affine._dx = m31; t.affine._dy = m32;
+ t.m_matrix[0][0] = m11; t.m_matrix[0][1] = m12;
+ t.m_matrix[1][0] = m21; t.m_matrix[1][1] = m22;
+ t.m_matrix[2][0] = m31; t.m_matrix[2][1] = m32;
break;
}
case TxProject:
{
- qreal m11 = affine._m11*m.affine._m11 + affine._m12*m.affine._m21 + m_13*m.affine._dx;
- qreal m12 = affine._m11*m.affine._m12 + affine._m12*m.affine._m22 + m_13*m.affine._dy;
- qreal m13 = affine._m11*m.m_13 + affine._m12*m.m_23 + m_13*m.m_33;
+ qreal m11 = m_matrix[0][0] * m.m_matrix[0][0] + m_matrix[0][1] * m.m_matrix[1][0] + m_matrix[0][2] * m.m_matrix[2][0];
+ qreal m12 = m_matrix[0][0] * m.m_matrix[0][1] + m_matrix[0][1] * m.m_matrix[1][1] + m_matrix[0][2] * m.m_matrix[2][1];
+ qreal m13 = m_matrix[0][0] * m.m_matrix[0][2] + m_matrix[0][1] * m.m_matrix[1][2] + m_matrix[0][2] * m.m_matrix[2][2];
- qreal m21 = affine._m21*m.affine._m11 + affine._m22*m.affine._m21 + m_23*m.affine._dx;
- qreal m22 = affine._m21*m.affine._m12 + affine._m22*m.affine._m22 + m_23*m.affine._dy;
- qreal m23 = affine._m21*m.m_13 + affine._m22*m.m_23 + m_23*m.m_33;
+ qreal m21 = m_matrix[1][0] * m.m_matrix[0][0] + m_matrix[1][1] * m.m_matrix[1][0] + m_matrix[1][2] * m.m_matrix[2][0];
+ qreal m22 = m_matrix[1][0] * m.m_matrix[0][1] + m_matrix[1][1] * m.m_matrix[1][1] + m_matrix[1][2] * m.m_matrix[2][1];
+ qreal m23 = m_matrix[1][0] * m.m_matrix[0][2] + m_matrix[1][1] * m.m_matrix[1][2] + m_matrix[1][2] * m.m_matrix[2][2];
- qreal m31 = affine._dx*m.affine._m11 + affine._dy*m.affine._m21 + m_33*m.affine._dx;
- qreal m32 = affine._dx*m.affine._m12 + affine._dy*m.affine._m22 + m_33*m.affine._dy;
- qreal m33 = affine._dx*m.m_13 + affine._dy*m.m_23 + m_33*m.m_33;
+ qreal m31 = m_matrix[2][0] * m.m_matrix[0][0] + m_matrix[2][1] * m.m_matrix[1][0] + m_matrix[2][2] * m.m_matrix[2][0];
+ qreal m32 = m_matrix[2][0] * m.m_matrix[0][1] + m_matrix[2][1] * m.m_matrix[1][1] + m_matrix[2][2] * m.m_matrix[2][1];
+ qreal m33 = m_matrix[2][0] * m.m_matrix[0][2] + m_matrix[2][1] * m.m_matrix[1][2] + m_matrix[2][2] * m.m_matrix[2][2];
- t.affine._m11 = m11; t.affine._m12 = m12; t.m_13 = m13;
- t.affine._m21 = m21; t.affine._m22 = m22; t.m_23 = m23;
- t.affine._dx = m31; t.affine._dy = m32; t.m_33 = m33;
+ t.m_matrix[0][0] = m11; t.m_matrix[0][1] = m12; t.m_matrix[0][2] = m13;
+ t.m_matrix[1][0] = m21; t.m_matrix[1][1] = m22; t.m_matrix[1][2] = m23;
+ t.m_matrix[2][0] = m31; t.m_matrix[2][1] = m32; t.m_matrix[2][2] = m33;
}
}
@@ -1034,15 +1015,15 @@ QTransform QTransform::operator*(const QTransform &m) const
*/
QTransform & QTransform::operator=(const QTransform &matrix) noexcept
{
- affine._m11 = matrix.affine._m11;
- affine._m12 = matrix.affine._m12;
- affine._m21 = matrix.affine._m21;
- affine._m22 = matrix.affine._m22;
- affine._dx = matrix.affine._dx;
- affine._dy = matrix.affine._dy;
- m_13 = matrix.m_13;
- m_23 = matrix.m_23;
- m_33 = matrix.m_33;
+ m_matrix[0][0] = matrix.m_matrix[0][0];
+ m_matrix[0][1] = matrix.m_matrix[0][1];
+ m_matrix[1][0] = matrix.m_matrix[1][0];
+ m_matrix[1][1] = matrix.m_matrix[1][1];
+ m_matrix[2][0] = matrix.m_matrix[2][0];
+ m_matrix[2][1] = matrix.m_matrix[2][1];
+ m_matrix[0][2] = matrix.m_matrix[0][2];
+ m_matrix[1][2] = matrix.m_matrix[1][2];
+ m_matrix[2][2] = matrix.m_matrix[2][2];
m_type = matrix.m_type;
m_dirty = matrix.m_dirty;
@@ -1060,8 +1041,8 @@ QTransform & QTransform::operator=(const QTransform &matrix) noexcept
*/
void QTransform::reset()
{
- affine._m11 = affine._m22 = m_33 = 1.0;
- affine._m12 = m_13 = affine._m21 = m_23 = affine._dx = affine._dy = 0;
+ m_matrix[0][0] = m_matrix[1][1] = m_matrix[2][2] = 1.0;
+ m_matrix[0][1] = m_matrix[0][2] = m_matrix[1][0] = m_matrix[1][2] = m_matrix[2][0] = m_matrix[2][1] = 0;
m_type = TxNone;
m_dirty = TxNone;
}
@@ -1179,20 +1160,20 @@ QPoint QTransform::map(const QPoint &p) const
y = fy;
break;
case TxTranslate:
- x = fx + affine._dx;
- y = fy + affine._dy;
+ x = fx + m_matrix[2][0];
+ y = fy + m_matrix[2][1];
break;
case TxScale:
- x = affine._m11 * fx + affine._dx;
- y = affine._m22 * fy + affine._dy;
+ x = m_matrix[0][0] * fx + m_matrix[2][0];
+ y = m_matrix[1][1] * fy + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
- x = affine._m11 * fx + affine._m21 * fy + affine._dx;
- y = affine._m12 * fx + affine._m22 * fy + affine._dy;
+ x = m_matrix[0][0] * fx + m_matrix[1][0] * fy + m_matrix[2][0];
+ y = m_matrix[0][1] * fx + m_matrix[1][1] * fy + m_matrix[2][1];
if (t == TxProject) {
- qreal w = 1./(m_13 * fx + m_23 * fy + m_33);
+ qreal w = 1./(m_matrix[0][2] * fx + m_matrix[1][2] * fy + m_matrix[2][2]);
x *= w;
y *= w;
}
@@ -1230,20 +1211,20 @@ QPointF QTransform::map(const QPointF &p) const
y = fy;
break;
case TxTranslate:
- x = fx + affine._dx;
- y = fy + affine._dy;
+ x = fx + m_matrix[2][0];
+ y = fy + m_matrix[2][1];
break;
case TxScale:
- x = affine._m11 * fx + affine._dx;
- y = affine._m22 * fy + affine._dy;
+ x = m_matrix[0][0] * fx + m_matrix[2][0];
+ y = m_matrix[1][1] * fy + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
- x = affine._m11 * fx + affine._m21 * fy + affine._dx;
- y = affine._m12 * fx + affine._m22 * fy + affine._dy;
+ x = m_matrix[0][0] * fx + m_matrix[1][0] * fy + m_matrix[2][0];
+ y = m_matrix[0][1] * fx + m_matrix[1][1] * fy + m_matrix[2][1];
if (t == TxProject) {
- qreal w = 1./(m_13 * fx + m_23 * fy + m_33);
+ qreal w = 1./(m_matrix[0][2] * fx + m_matrix[1][2] * fy + m_matrix[2][2]);
x *= w;
y *= w;
}
@@ -1303,29 +1284,29 @@ QLine QTransform::map(const QLine &l) const
y2 = fy2;
break;
case TxTranslate:
- x1 = fx1 + affine._dx;
- y1 = fy1 + affine._dy;
- x2 = fx2 + affine._dx;
- y2 = fy2 + affine._dy;
+ x1 = fx1 + m_matrix[2][0];
+ y1 = fy1 + m_matrix[2][1];
+ x2 = fx2 + m_matrix[2][0];
+ y2 = fy2 + m_matrix[2][1];
break;
case TxScale:
- x1 = affine._m11 * fx1 + affine._dx;
- y1 = affine._m22 * fy1 + affine._dy;
- x2 = affine._m11 * fx2 + affine._dx;
- y2 = affine._m22 * fy2 + affine._dy;
+ x1 = m_matrix[0][0] * fx1 + m_matrix[2][0];
+ y1 = m_matrix[1][1] * fy1 + m_matrix[2][1];
+ x2 = m_matrix[0][0] * fx2 + m_matrix[2][0];
+ y2 = m_matrix[1][1] * fy2 + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
- x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;
- y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;
- x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;
- y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;
+ x1 = m_matrix[0][0] * fx1 + m_matrix[1][0] * fy1 + m_matrix[2][0];
+ y1 = m_matrix[0][1] * fx1 + m_matrix[1][1] * fy1 + m_matrix[2][1];
+ x2 = m_matrix[0][0] * fx2 + m_matrix[1][0] * fy2 + m_matrix[2][0];
+ y2 = m_matrix[0][1] * fx2 + m_matrix[1][1] * fy2 + m_matrix[2][1];
if (t == TxProject) {
- qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);
+ qreal w = 1./(m_matrix[0][2] * fx1 + m_matrix[1][2] * fy1 + m_matrix[2][2]);
x1 *= w;
y1 *= w;
- w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);
+ w = 1./(m_matrix[0][2] * fx2 + m_matrix[1][2] * fy2 + m_matrix[2][2]);
x2 *= w;
y2 *= w;
}
@@ -1362,29 +1343,29 @@ QLineF QTransform::map(const QLineF &l) const
y2 = fy2;
break;
case TxTranslate:
- x1 = fx1 + affine._dx;
- y1 = fy1 + affine._dy;
- x2 = fx2 + affine._dx;
- y2 = fy2 + affine._dy;
+ x1 = fx1 + m_matrix[2][0];
+ y1 = fy1 + m_matrix[2][1];
+ x2 = fx2 + m_matrix[2][0];
+ y2 = fy2 + m_matrix[2][1];
break;
case TxScale:
- x1 = affine._m11 * fx1 + affine._dx;
- y1 = affine._m22 * fy1 + affine._dy;
- x2 = affine._m11 * fx2 + affine._dx;
- y2 = affine._m22 * fy2 + affine._dy;
+ x1 = m_matrix[0][0] * fx1 + m_matrix[2][0];
+ y1 = m_matrix[1][1] * fy1 + m_matrix[2][1];
+ x2 = m_matrix[0][0] * fx2 + m_matrix[2][0];
+ y2 = m_matrix[1][1] * fy2 + m_matrix[2][1];
break;
case TxRotate:
case TxShear:
case TxProject:
- x1 = affine._m11 * fx1 + affine._m21 * fy1 + affine._dx;
- y1 = affine._m12 * fx1 + affine._m22 * fy1 + affine._dy;
- x2 = affine._m11 * fx2 + affine._m21 * fy2 + affine._dx;
- y2 = affine._m12 * fx2 + affine._m22 * fy2 + affine._dy;
+ x1 = m_matrix[0][0] * fx1 + m_matrix[1][0] * fy1 + m_matrix[2][0];
+ y1 = m_matrix[0][1] * fx1 + m_matrix[1][1] * fy1 + m_matrix[2][1];
+ x2 = m_matrix[0][0] * fx2 + m_matrix[1][0] * fy2 + m_matrix[2][0];
+ y2 = m_matrix[0][1] * fx2 + m_matrix[1][1] * fy2 + m_matrix[2][1];
if (t == TxProject) {
- qreal w = 1./(m_13 * fx1 + m_23 * fy1 + m_33);
+ qreal w = 1./(m_matrix[0][2] * fx1 + m_matrix[1][2] * fy1 + m_matrix[2][2]);
x1 *= w;
y1 *= w;
- w = 1./(m_13 * fx2 + m_23 * fy2 + m_33);
+ w = 1./(m_matrix[0][2] * fx2 + m_matrix[1][2] * fy2 + m_matrix[2][2]);
x2 *= w;
y2 *= w;
}
@@ -1445,7 +1426,7 @@ QPolygonF QTransform::map(const QPolygonF &a) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
- return a.translated(affine._dx, affine._dy);
+ return a.translated(m_matrix[2][0], m_matrix[2][1]);
if (t >= QTransform::TxProject)
return mapProjective(*this, a);
@@ -1475,7 +1456,7 @@ QPolygon QTransform::map(const QPolygon &a) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
- return a.translated(qRound(affine._dx), qRound(affine._dy));
+ return a.translated(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
if (t >= QTransform::TxProject)
return mapProjective(*this, QPolygonF(a)).toPolygon();
@@ -1524,7 +1505,7 @@ QRegion QTransform::map(const QRegion &r) const
if (t == TxTranslate) {
QRegion copy(r);
- copy.translate(qRound(affine._dx), qRound(affine._dy));
+ copy.translate(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
return copy;
}
@@ -1547,7 +1528,7 @@ QRegion QTransform::map(const QRegion &r) const
}
QPainterPath p = map(qt_regionToPath(r));
- return p.toFillPolygon(QTransform()).toPolygon();
+ return p.toFillPolygon().toPolygon();
}
struct QHomogeneousCoordinate
@@ -1703,7 +1684,7 @@ QPainterPath QTransform::map(const QPainterPath &path) const
QPainterPath copy = path;
if (t == TxTranslate) {
- copy.translate(affine._dx, affine._dy);
+ copy.translate(m_matrix[2][0], m_matrix[2][1]);
} else {
copy.detach();
// Full xform
@@ -1743,10 +1724,10 @@ QPolygon QTransform::mapToPolygon(const QRect &rect) const
QPolygon a(4);
qreal x[4] = { 0, 0, 0, 0 }, y[4] = { 0, 0, 0, 0 };
if (t <= TxScale) {
- x[0] = affine._m11*rect.x() + affine._dx;
- y[0] = affine._m22*rect.y() + affine._dy;
- qreal w = affine._m11*rect.width();
- qreal h = affine._m22*rect.height();
+ x[0] = m_matrix[0][0]*rect.x() + m_matrix[2][0];
+ y[0] = m_matrix[1][1]*rect.y() + m_matrix[2][1];
+ qreal w = m_matrix[0][0]*rect.width();
+ qreal h = m_matrix[1][1]*rect.height();
if (w < 0) {
w = -w;
x[0] -= w;
@@ -1903,9 +1884,9 @@ void QTransform::setMatrix(qreal m11, qreal m12, qreal m13,
qreal m21, qreal m22, qreal m23,
qreal m31, qreal m32, qreal m33)
{
- affine._m11 = m11; affine._m12 = m12; m_13 = m13;
- affine._m21 = m21; affine._m22 = m22; m_23 = m23;
- affine._dx = m31; affine._dy = m32; m_33 = m33;
+ m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13;
+ m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23;
+ m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33;
m_type = TxNone;
m_dirty = TxProject;
}
@@ -1922,13 +1903,13 @@ QRect QTransform::mapRect(const QRect &rect) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
- return rect.translated(qRound(affine._dx), qRound(affine._dy));
+ return rect.translated(qRound(m_matrix[2][0]), qRound(m_matrix[2][1]));
if (t <= TxScale) {
- int x = qRound(affine._m11*rect.x() + affine._dx);
- int y = qRound(affine._m22*rect.y() + affine._dy);
- int w = qRound(affine._m11*rect.width());
- int h = qRound(affine._m22*rect.height());
+ int x = qRound(m_matrix[0][0] * rect.x() + m_matrix[2][0]);
+ int y = qRound(m_matrix[1][1] * rect.y() + m_matrix[2][1]);
+ int w = qRound(m_matrix[0][0] * rect.width());
+ int h = qRound(m_matrix[1][1] * rect.height());
if (w < 0) {
w = -w;
x -= w;
@@ -1992,13 +1973,13 @@ QRectF QTransform::mapRect(const QRectF &rect) const
{
TransformationType t = inline_type();
if (t <= TxTranslate)
- return rect.translated(affine._dx, affine._dy);
+ return rect.translated(m_matrix[2][0], m_matrix[2][1]);
if (t <= TxScale) {
- qreal x = affine._m11*rect.x() + affine._dx;
- qreal y = affine._m22*rect.y() + affine._dy;
- qreal w = affine._m11*rect.width();
- qreal h = affine._m22*rect.height();
+ qreal x = m_matrix[0][0] * rect.x() + m_matrix[2][0];
+ qreal y = m_matrix[1][1] * rect.y() + m_matrix[2][1];
+ qreal w = m_matrix[0][0] * rect.width();
+ qreal h = m_matrix[1][1] * rect.height();
if (w < 0) {
w = -w;
x -= w;
@@ -2085,20 +2066,6 @@ void QTransform::map(int x, int y, int *tx, int *ty) const
*ty = qRound(fy);
}
-#if QT_DEPRECATED_SINCE(5, 15)
-/*!
- \obsolete
- Returns the QTransform as an affine matrix.
-
- \warning If a perspective transformation has been specified,
- then the conversion will cause loss of data.
-*/
-const QMatrix &QTransform::toAffine() const
-{
- return affine;
-}
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
/*!
Returns the transformation type of this matrix.
@@ -2118,15 +2085,15 @@ QTransform::TransformationType QTransform::type() const
switch (static_cast<TransformationType>(m_dirty)) {
case TxProject:
- if (!qFuzzyIsNull(m_13) || !qFuzzyIsNull(m_23) || !qFuzzyIsNull(m_33 - 1)) {
+ if (!qFuzzyIsNull(m_matrix[0][2]) || !qFuzzyIsNull(m_matrix[1][2]) || !qFuzzyIsNull(m_matrix[2][2] - 1)) {
m_type = TxProject;
break;
}
Q_FALLTHROUGH();
case TxShear:
case TxRotate:
- if (!qFuzzyIsNull(affine._m12) || !qFuzzyIsNull(affine._m21)) {
- const qreal dot = affine._m11 * affine._m12 + affine._m21 * affine._m22;
+ if (!qFuzzyIsNull(m_matrix[0][1]) || !qFuzzyIsNull(m_matrix[1][0])) {
+ const qreal dot = m_matrix[0][0] * m_matrix[0][1] + m_matrix[1][0] * m_matrix[1][1];
if (qFuzzyIsNull(dot))
m_type = TxRotate;
else
@@ -2135,13 +2102,13 @@ QTransform::TransformationType QTransform::type() const
}
Q_FALLTHROUGH();
case TxScale:
- if (!qFuzzyIsNull(affine._m11 - 1) || !qFuzzyIsNull(affine._m22 - 1)) {
+ if (!qFuzzyIsNull(m_matrix[0][0] - 1) || !qFuzzyIsNull(m_matrix[1][1] - 1)) {
m_type = TxScale;
break;
}
Q_FALLTHROUGH();
case TxTranslate:
- if (!qFuzzyIsNull(affine._dx) || !qFuzzyIsNull(affine._dy)) {
+ if (!qFuzzyIsNull(m_matrix[2][0]) || !qFuzzyIsNull(m_matrix[2][1])) {
m_type = TxTranslate;
break;
}
@@ -2390,4 +2357,50 @@ bool qt_scaleForTransform(const QTransform &transform, qreal *scale)
}
}
+QDataStream & operator>>(QDataStream &s, QTransform::Affine &m)
+{
+ if (s.version() == 1) {
+ float m11, m12, m21, m22, dx, dy;
+ s >> m11; s >> m12; s >> m21; s >> m22; s >> dx; s >> dy;
+
+ m.m_matrix[0][0] = m11;
+ m.m_matrix[0][1] = m12;
+ m.m_matrix[1][0] = m21;
+ m.m_matrix[1][1] = m22;
+ m.m_matrix[2][0] = dx;
+ m.m_matrix[2][1] = dy;
+ } else {
+ s >> m.m_matrix[0][0];
+ s >> m.m_matrix[0][1];
+ s >> m.m_matrix[1][0];
+ s >> m.m_matrix[1][1];
+ s >> m.m_matrix[2][0];
+ s >> m.m_matrix[2][1];
+ }
+ m.m_matrix[0][2] = 0;
+ m.m_matrix[1][2] = 0;
+ m.m_matrix[2][2] = 1;
+ return s;
+}
+
+QDataStream &operator<<(QDataStream &s, const QTransform::Affine &m)
+{
+ if (s.version() == 1) {
+ s << (float)m.m_matrix[0][0]
+ << (float)m.m_matrix[0][1]
+ << (float)m.m_matrix[1][0]
+ << (float)m.m_matrix[1][1]
+ << (float)m.m_matrix[2][0]
+ << (float)m.m_matrix[2][1];
+ } else {
+ s << m.m_matrix[0][0]
+ << m.m_matrix[0][1]
+ << m.m_matrix[1][0]
+ << m.m_matrix[1][1]
+ << m.m_matrix[2][0]
+ << m.m_matrix[2][1];
+ }
+ return s;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index 485caa5140..351f2b2e4e 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -40,7 +40,6 @@
#define QTRANSFORM_H
#include <QtGui/qtguiglobal.h>
-#include <QtGui/qmatrix.h>
#include <QtGui/qpainterpath.h>
#include <QtGui/qpolygon.h>
#include <QtGui/qregion.h>
@@ -66,16 +65,13 @@ public:
TxProject = 0x10
};
- inline explicit QTransform(Qt::Initialization) : affine(Qt::Uninitialized) {}
+ inline explicit QTransform(Qt::Initialization) {}
QTransform();
QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33 = 1.0);
QTransform(qreal h11, qreal h12, qreal h21,
qreal h22, qreal dx, qreal dy);
-#if QT_DEPRECATED_SINCE(5, 15)
- explicit QTransform(const QMatrix &mtx);
-#endif // QT_DEPRECATED_SINCE(5, 15)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// ### Qt 6: remove; the compiler-generated ones are fine!
@@ -160,10 +156,6 @@ public:
void map(int x, int y, int *tx, int *ty) const;
void map(qreal x, qreal y, qreal *tx, qreal *ty) const;
-#if QT_DEPRECATED_SINCE(5, 15)
- const QMatrix &toAffine() const;
-#endif // QT_DEPRECATED_SINCE(5, 15)
-
QTransform &operator*=(qreal div);
QTransform &operator/=(qreal div);
QTransform &operator+=(qreal div);
@@ -173,11 +165,20 @@ public:
static QTransform fromScale(qreal dx, qreal dy);
private:
+ struct Affine {
+ qreal (& m_matrix)[3][3];
+ };
+
+public:
+ auto asAffineMatrix() { return Affine { m_matrix }; }
+ friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &s, Affine &m);
+ friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &s, const Affine &m);
+
+private:
inline QTransform(qreal h11, qreal h12, qreal h13,
qreal h21, qreal h22, qreal h23,
qreal h31, qreal h32, qreal h33, bool)
- : affine(h11, h12, h21, h22, h31, h32, true)
- , m_13(h13), m_23(h23), m_33(h33)
+ : m_matrix{ {h11, h12, h13}, {h21, h22, h23}, {h31, h32, h33} }
, m_type(TxNone)
, m_dirty(TxProject)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -186,8 +187,7 @@ private:
{
}
inline QTransform(bool)
- : affine(true)
- , m_13(0), m_23(0), m_33(1)
+ : m_matrix{ {1, 0, 0}, {0, 1, 0}, {0, 0, 1} }
, m_type(TxNone)
, m_dirty(TxNone)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -196,10 +196,7 @@ private:
{
}
inline TransformationType inline_type() const;
- QMatrix affine;
- qreal m_13;
- qreal m_23;
- qreal m_33;
+ qreal m_matrix[3][3];
mutable uint m_type : 5;
mutable uint m_dirty : 5;
@@ -250,8 +247,9 @@ inline bool QTransform::isTranslating() const
inline qreal QTransform::determinant() const
{
- return affine._m11*(m_33*affine._m22-affine._dy*m_23) -
- affine._m21*(m_33*affine._m12-affine._dy*m_13)+affine._dx*(m_23*affine._m12-affine._m22*m_13);
+ return m_matrix[0][0] * (m_matrix[2][2] * m_matrix[1][1] - m_matrix[2][1] * m_matrix[1][2]) -
+ m_matrix[1][0] * (m_matrix[2][2] * m_matrix[0][1] - m_matrix[2][1] * m_matrix[0][2]) +
+ m_matrix[2][0] * (m_matrix[1][2] * m_matrix[0][1] - m_matrix[1][1] * m_matrix[0][2]);
}
#if QT_DEPRECATED_SINCE(5, 13)
inline qreal QTransform::det() const
@@ -261,47 +259,47 @@ inline qreal QTransform::det() const
#endif
inline qreal QTransform::m11() const
{
- return affine._m11;
+ return m_matrix[0][0];
}
inline qreal QTransform::m12() const
{
- return affine._m12;
+ return m_matrix[0][1];
}
inline qreal QTransform::m13() const
{
- return m_13;
+ return m_matrix[0][2];
}
inline qreal QTransform::m21() const
{
- return affine._m21;
+ return m_matrix[1][0];
}
inline qreal QTransform::m22() const
{
- return affine._m22;
+ return m_matrix[1][1];
}
inline qreal QTransform::m23() const
{
- return m_23;
+ return m_matrix[1][2];
}
inline qreal QTransform::m31() const
{
- return affine._dx;
+ return m_matrix[2][0];
}
inline qreal QTransform::m32() const
{
- return affine._dy;
+ return m_matrix[2][1];
}
inline qreal QTransform::m33() const
{
- return m_33;
+ return m_matrix[2][2];
}
inline qreal QTransform::dx() const
{
- return affine._dx;
+ return m_matrix[2][0];
}
inline qreal QTransform::dy() const
{
- return affine._dy;
+ return m_matrix[2][1];
}
QT_WARNING_PUSH
@@ -313,15 +311,15 @@ inline QTransform &QTransform::operator*=(qreal num)
{
if (num == 1.)
return *this;
- affine._m11 *= num;
- affine._m12 *= num;
- m_13 *= num;
- affine._m21 *= num;
- affine._m22 *= num;
- m_23 *= num;
- affine._dx *= num;
- affine._dy *= num;
- m_33 *= num;
+ m_matrix[0][0] *= num;
+ m_matrix[0][1] *= num;
+ m_matrix[0][2] *= num;
+ m_matrix[1][0] *= num;
+ m_matrix[1][1] *= num;
+ m_matrix[1][2] *= num;
+ m_matrix[2][0] *= num;
+ m_matrix[2][1] *= num;
+ m_matrix[2][2] *= num;
if (m_dirty < TxScale)
m_dirty = TxScale;
return *this;
@@ -337,15 +335,15 @@ inline QTransform &QTransform::operator+=(qreal num)
{
if (num == 0)
return *this;
- affine._m11 += num;
- affine._m12 += num;
- m_13 += num;
- affine._m21 += num;
- affine._m22 += num;
- m_23 += num;
- affine._dx += num;
- affine._dy += num;
- m_33 += num;
+ m_matrix[0][0] += num;
+ m_matrix[0][1] += num;
+ m_matrix[0][2] += num;
+ m_matrix[1][0] += num;
+ m_matrix[1][1] += num;
+ m_matrix[1][2] += num;
+ m_matrix[2][0] += num;
+ m_matrix[2][1] += num;
+ m_matrix[2][2] += num;
m_dirty = TxProject;
return *this;
}
@@ -353,15 +351,15 @@ inline QTransform &QTransform::operator-=(qreal num)
{
if (num == 0)
return *this;
- affine._m11 -= num;
- affine._m12 -= num;
- m_13 -= num;
- affine._m21 -= num;
- affine._m22 -= num;
- m_23 -= num;
- affine._dx -= num;
- affine._dy -= num;
- m_33 -= num;
+ m_matrix[0][0] -= num;
+ m_matrix[0][1] -= num;
+ m_matrix[0][2] -= num;
+ m_matrix[1][0] -= num;
+ m_matrix[1][1] -= num;
+ m_matrix[1][2] -= num;
+ m_matrix[2][0] -= num;
+ m_matrix[2][1] -= num;
+ m_matrix[2][2] -= num;
m_dirty = TxProject;
return *this;
}