summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/windows/qwindowsmime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/windows/qwindowsmime.cpp')
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 8233e82d8e..829dc99b5b 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -906,6 +906,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;
};
@@ -987,15 +988,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);
@@ -1004,6 +1031,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")) {
@@ -1012,6 +1040,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);