diff options
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsmime.cpp')
-rw-r--r-- | src/plugins/platforms/windows/qwindowsmime.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp index 03e7b1ec03..51efb095fc 100644 --- a/src/plugins/platforms/windows/qwindowsmime.cpp +++ b/src/plugins/platforms/windows/qwindowsmime.cpp @@ -940,6 +940,7 @@ public: QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QMetaType preferredType) const override; QString mimeForFormat(const FORMATETC &formatetc) const override; private: + bool hasOriginalDIBV5(IDataObject *pDataObj) const; UINT CF_PNG; }; @@ -1021,15 +1022,41 @@ bool QWindowsMimeImage::convertFromMime(const FORMATETC &formatetc, const QMimeD return false; } +bool QWindowsMimeImage::hasOriginalDIBV5(IDataObject *pDataObj) const +{ + bool isSynthesized = true; + IEnumFORMATETC *pEnum = nullptr; + HRESULT res = pDataObj->EnumFormatEtc(1, &pEnum); + if (res == S_OK && pEnum) { + FORMATETC fc; + while ((res = pEnum->Next(1, &fc, nullptr)) == S_OK) { + if (fc.ptd) + CoTaskMemFree(fc.ptd); + if (fc.cfFormat == CF_DIB) + break; + if (fc.cfFormat == CF_DIBV5) { + isSynthesized = false; + break; + } + } + pEnum->Release(); + } + return !isSynthesized; +} + QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject *pDataObj, QMetaType preferredType) const { Q_UNUSED(preferredType); QVariant result; if (mimeType != u"application/x-qt-image") return result; - //Try to convert from DIBV5 as it is the most - //widespread format that support transparency - if (canGetData(CF_DIBV5, pDataObj)) { + // Try to convert from DIBV5 as it is the most widespread format that supports transparency, + // but avoid synthesizing it, as that typically loses transparency, e.g. from Office + const bool canGetDibV5 = canGetData(CF_DIBV5, pDataObj); + const bool hasOrigDibV5 = canGetDibV5 ? hasOriginalDIBV5(pDataObj) : false; + qCDebug(lcQpaMime) << "canGetDibV5:" << canGetDibV5 << "hasOrigDibV5:" << hasOrigDibV5; + if (hasOrigDibV5) { + qCDebug(lcQpaMime) << "Decoding DIBV5"; QImage img; QByteArray data = getData(CF_DIBV5, pDataObj); QBuffer buffer(&data); @@ -1038,6 +1065,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject * } //PNG, MS Office place this (undocumented) if (canGetData(CF_PNG, pDataObj)) { + qCDebug(lcQpaMime) << "Decoding PNG"; QImage img; QByteArray data = getData(CF_PNG, pDataObj); if (img.loadFromData(data, "PNG")) { @@ -1046,6 +1074,7 @@ QVariant QWindowsMimeImage::convertToMime(const QString &mimeType, IDataObject * } //Fallback to DIB if (canGetData(CF_DIB, pDataObj)) { + qCDebug(lcQpaMime) << "Decoding DIB"; QImage img; QByteArray data = getData(CF_DIBV5, pDataObj); QBuffer buffer(&data); |