QtGui/Windows: Move the QRegion conversion functions into QtGui

Task-number: QTBUG-81876
Change-Id: I2297291a4157e7015f499b0a6127301d9cb58526
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Friedemann Kleint 2020-07-16 10:05:18 +02:00
parent 777d6a546d
commit b2504af4da
3 changed files with 94 additions and 1 deletions

View File

@ -50,6 +50,10 @@
#include <private/qdebug_p.h>
#ifdef Q_OS_WIN
# include <qt_windows.h>
#endif
QT_BEGIN_NAMESPACE
/*!
@ -4314,4 +4318,65 @@ bool QRegion::intersects(const QRect &rect) const
#endif
#if defined(Q_OS_WIN) || defined(Q_QDOC)
static inline HRGN qt_RectToHRGN(const QRect &rc)
{
return CreateRectRgn(rc.left(), rc.top(), rc.right() + 1, rc.bottom() + 1);
}
/*!
\since 6.0
Returns a HRGN that is equivalent to the given region.
*/
HRGN QRegion::toHRGN() const
{
const int size = rectCount();
if (size == 0)
return nullptr;
HRGN resultRgn = nullptr;
const auto rects = begin();
resultRgn = qt_RectToHRGN(rects[0]);
for (int i = 1; i < size; ++i) {
HRGN tmpRgn = qt_RectToHRGN(rects[i]);
int err = CombineRgn(resultRgn, resultRgn, tmpRgn, RGN_OR);
if (err == ERROR)
qWarning("Error combining HRGNs.");
DeleteObject(tmpRgn);
}
return resultRgn;
}
/*!
\since 6.0
Returns a QRegion that is equivalent to the given \a hrgn.
*/
QRegion QRegion::fromHRGN(HRGN hrgn)
{
DWORD regionDataSize = GetRegionData(hrgn, 0, nullptr);
if (regionDataSize == 0)
return QRegion();
auto regionData = reinterpret_cast<LPRGNDATA>(malloc(regionDataSize));
if (!regionData)
return QRegion();
QRegion region;
if (GetRegionData(hrgn, regionDataSize, regionData) == regionDataSize) {
auto pRect = reinterpret_cast<LPRECT>(regionData->Buffer);
for (DWORD i = 0; i < regionData->rdh.nCount; ++i)
region += QRect(pRect[i].left, pRect[i].top,
pRect[i].right - pRect[i].left,
pRect[i].bottom - pRect[i].top);
}
free(regionData);
return region;
}
#endif // Q_OS_WIN || Q_QDOC
QT_END_NAMESPACE

View File

@ -134,6 +134,12 @@ public:
inline bool operator!=(const QRegion &r) const { return !(operator==(r)); }
operator QVariant() const;
// Platform specific conversion functions
#if defined(Q_OS_WIN) || defined(Q_QDOC)
HRGN toHRGN() const;
static QRegion fromHRGN(HRGN hrgn);
#endif
#ifndef QT_NO_DATASTREAM
friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QRegion &);
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QRegion &);

View File

@ -35,6 +35,10 @@
#include <qpainterpath.h>
#include <qpolygon.h>
#ifdef Q_OS_WIN
# include <qt_windows.h>
#endif
class tst_QRegion : public QObject
{
Q_OBJECT
@ -86,6 +90,10 @@ private slots:
void regionToPath_data();
void regionToPath();
#endif
#ifdef Q_OS_WIN
void winConversion();
#endif
};
tst_QRegion::tst_QRegion()
@ -1061,7 +1069,21 @@ void tst_QRegion::regionToPath()
QCOMPARE(a.boundingRect(), b.boundingRect());
}
}
#endif
#endif // QT_BUILD_INTERNAL
#ifdef Q_OS_WIN
void tst_QRegion::winConversion()
{
const QList<QRect> rects{QRect(10, 10, 10, 10), QRect(10, 20, 10, 10),
QRect(30, 20, 10, 10), QRect(10, 30, 10, 10)};
QRegion region;
region.setRects(rects.constData(), rects.size());
auto hrgn = region.toHRGN();
QVERIFY(hrgn);
QRegion convertedBack = QRegion::fromHRGN(hrgn);
QCOMPARE(region, convertedBack);
}
#endif // Q_OS_WIN
QTEST_MAIN(tst_QRegion)
#include "tst_qregion.moc"