diff options
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/configure.json | 1 | ||||
-rw-r--r-- | src/gui/image/qimage_neon.cpp | 2 | ||||
-rw-r--r-- | src/gui/image/qimagereader.cpp | 7 | ||||
-rw-r--r-- | src/gui/image/qimagewriter.cpp | 7 | ||||
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 75 | ||||
-rw-r--r-- | src/gui/painting/qcolortrclut_p.h | 1 | ||||
-rw-r--r-- | src/gui/painting/qdrawhelper.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qtextdocumentwriter.cpp | 1 |
8 files changed, 46 insertions, 50 deletions
diff --git a/src/gui/configure.json b/src/gui/configure.json index 1f08795c57..7b80162faa 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -1363,6 +1363,7 @@ "vkgen": { "label": "vkgen", "condition": "features.xmlstreamreader", + "disable": "input.vulkan == 'no'", "output": [ "privateFeature" ] }, "vulkan": { diff --git a/src/gui/image/qimage_neon.cpp b/src/gui/image/qimage_neon.cpp index 9dbcb11db5..c17f76f2b0 100644 --- a/src/gui/image/qimage_neon.cpp +++ b/src/gui/image/qimage_neon.cpp @@ -54,7 +54,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons // align dst on 128 bits const int offsetToAlignOn16Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x3; - for (int i = 0; i < offsetToAlignOn16Bytes; ++i) { + for (int i = 0; i < qMin(len, offsetToAlignOn16Bytes); ++i) { *dst++ = qRgb(src[0], src[1], src[2]); src += 3; } diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index 5cb7e1328e..12bba77512 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -47,7 +47,6 @@ \inmodule QtGui \reentrant \ingroup painting - \ingroup io The most common way to read images is through QImage and QPixmap's constructors, or by calling QImage::load() and @@ -515,9 +514,9 @@ QImageReaderPrivate::QImageReaderPrivate(QImageReader *qq) */ QImageReaderPrivate::~QImageReaderPrivate() { + delete handler; if (deleteDevice) delete device; - delete handler; } /*! @@ -774,12 +773,12 @@ bool QImageReader::decideFormatFromContent() const */ void QImageReader::setDevice(QIODevice *device) { + delete d->handler; + d->handler = nullptr; if (d->device && d->deleteDevice) delete d->device; d->device = device; d->deleteDevice = false; - delete d->handler; - d->handler = nullptr; d->text.clear(); } diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp index 33f5e491c7..feb05413c2 100644 --- a/src/gui/image/qimagewriter.cpp +++ b/src/gui/image/qimagewriter.cpp @@ -45,7 +45,6 @@ \inmodule QtGui \reentrant \ingroup painting - \ingroup io QImageWriter supports setting format specific options, such as compression level and quality, prior to storing the @@ -349,9 +348,9 @@ QImageWriter::QImageWriter(const QString &fileName, const QByteArray &format) */ QImageWriter::~QImageWriter() { + delete d->handler; if (d->deleteDevice) delete d->device; - delete d->handler; delete d; } @@ -396,13 +395,13 @@ QByteArray QImageWriter::format() const */ void QImageWriter::setDevice(QIODevice *device) { + delete d->handler; + d->handler = nullptr; if (d->device && d->deleteDevice) delete d->device; d->device = device; d->deleteDevice = false; - delete d->handler; - d->handler = nullptr; } /*! diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 67f013c82e..4f6d063515 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -508,50 +508,47 @@ void QQuaternion::getEulerAngles(float *pitch, float *yaw, float *roll) const { Q_ASSERT(pitch && yaw && roll); - // Algorithm from: - // http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q37 - - float xx = xp * xp; - float xy = xp * yp; - float xz = xp * zp; - float xw = xp * wp; - float yy = yp * yp; - float yz = yp * zp; - float yw = yp * wp; - float zz = zp * zp; - float zw = zp * wp; - - const float lengthSquared = xx + yy + zz + wp * wp; - if (!qFuzzyIsNull(lengthSquared - 1.0f) && !qFuzzyIsNull(lengthSquared)) { - xx /= lengthSquared; - xy /= lengthSquared; // same as (xp / length) * (yp / length) - xz /= lengthSquared; - xw /= lengthSquared; - yy /= lengthSquared; - yz /= lengthSquared; - yw /= lengthSquared; - zz /= lengthSquared; - zw /= lengthSquared; - } + // Algorithm adapted from: + // https://ingmec.ual.es/~jlblanco/papers/jlblanco2010geometry3D_techrep.pdf + // "A tutorial on SE(3) transformation parameterizations and on-manifold optimization". + + // We can only detect Gimbal lock when we normalize, which we can't do when + // length is nearly zero. Do so before multiplying co-ordinates, to avoid + // underflow. + const float len = length(); + const bool rescale = !qFuzzyIsNull(len); + const float xps = rescale ? xp / len : xp; + const float yps = rescale ? yp / len : yp; + const float zps = rescale ? zp / len : zp; + const float wps = rescale ? wp / len : wp; + + const float xx = xps * xps; + const float xy = xps * yps; + const float xz = xps * zps; + const float xw = xps * wps; + const float yy = yps * yps; + const float yz = yps * zps; + const float yw = yps * wps; + const float zz = zps * zps; + const float zw = zps * wps; + + // For the common case, we have a hidden division by cos(pitch) to calculate + // yaw and roll: atan2(a / cos(pitch), b / cos(pitch)) = atan2(a, b). This equation + // wouldn't work if cos(pitch) is close to zero (i.e. abs(sin(pitch)) =~ 1.0). + // This threshold is copied from qFuzzyIsNull() to avoid the hidden division by zero. + constexpr float epsilon = 0.00001f; const float sinp = -2.0f * (yz - xw); - if (std::abs(sinp) >= 1.0f) - *pitch = std::copysign(M_PI_2, sinp); - else + if (std::abs(sinp) < 1.0f - epsilon) { *pitch = std::asin(sinp); - if (*pitch < M_PI_2) { - if (*pitch > -M_PI_2) { - *yaw = std::atan2(2.0f * (xz + yw), 1.0f - 2.0f * (xx + yy)); - *roll = std::atan2(2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz)); - } else { - // not a unique solution - *roll = 0.0f; - *yaw = -std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz)); - } + *yaw = std::atan2(2.0f * (xz + yw), 1.0f - 2.0f * (xx + yy)); + *roll = std::atan2(2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz)); } else { - // not a unique solution + // Gimbal lock case, which doesn't have a unique solution. We just use + // XY rotation. + *pitch = std::copysign(static_cast<float>(M_PI_2), sinp); + *yaw = 2.0f * std::atan2(yps, wps); *roll = 0.0f; - *yaw = std::atan2(-2.0f * (xy - zw), 1.0f - 2.0f * (yy + zz)); } *pitch = qRadiansToDegrees(*pitch); diff --git a/src/gui/painting/qcolortrclut_p.h b/src/gui/painting/qcolortrclut_p.h index 76a6a60803..24fd522e6c 100644 --- a/src/gui/painting/qcolortrclut_p.h +++ b/src/gui/painting/qcolortrclut_p.h @@ -118,6 +118,7 @@ public: return QRgba64::fromRgba64(r, g, b, qAlpha(rgb32) * 257); #endif } + QRgba64 toLinear64(QRgba64) const = delete; QRgb toLinear(QRgb rgb32) const { diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index a61793508a..5ba2d277b7 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -6091,7 +6091,7 @@ static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba static inline void rgbBlendPixel(QRgba64 &dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile) { // Do a gammacorrected RGB alphablend... - const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(dst) : dst; + const QRgba64 dlinear = colorProfile ? colorProfile->toLinear(dst) : dst; QRgba64 blend = rgbBlend(dlinear, slinear, coverage); diff --git a/src/gui/text/qtextdocumentwriter.cpp b/src/gui/text/qtextdocumentwriter.cpp index 312396fb29..800b72ea9c 100644 --- a/src/gui/text/qtextdocumentwriter.cpp +++ b/src/gui/text/qtextdocumentwriter.cpp @@ -83,7 +83,6 @@ public: \inmodule QtGui \ingroup richtext-processing - \ingroup io To write a document, construct a QTextDocumentWriter object with either a file name or a device object, and specify the document format to be |